Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/bmesh/operators')
-rw-r--r--source/blender/bmesh/operators/bmo_connect_pair.c2
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c6
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c9
-rw-r--r--source/blender/bmesh/operators/bmo_planar_faces.c4
-rw-r--r--source/blender/bmesh/operators/bmo_similar.c18
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c153
6 files changed, 155 insertions, 37 deletions
diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c
index ead1c7126e4..12af8902dc5 100644
--- a/source/blender/bmesh/operators/bmo_connect_pair.c
+++ b/source/blender/bmesh/operators/bmo_connect_pair.c
@@ -215,7 +215,7 @@ static void state_calc_co_pair(
interp_v3_v3v3(r_co, co_a, co_b, fac);
}
-#ifdef DEBUG
+#ifndef NDEBUG
/**
* Ideally we wouldn't need this and for most cases we don't.
* But when a face has vertices that are on the boundary more than once this becomes tricky.
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 435b9e60949..3eae98b3c46 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -137,7 +137,7 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
* This function won't crash if its not but won't work right either.
* \a e_b is the new edge.
*
- * \note The edge this face comes from needs to be from the first and second verts fo the face.
+ * \note The edge this face comes from needs to be from the first and second verts to the face.
* The caller must ensure this else we will copy from the wrong source.
*/
static void bm_extrude_copy_face_loop_attributes(BMesh *bm, BMFace *f)
@@ -728,9 +728,9 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
if (BMO_elem_flag_test(bm, f, FACE_MARK)) {
/* array for passing verts to angle_poly_v3 */
- float *face_angles = BLI_buffer_resize_data(&face_angles_buf, float, f->len);
+ float *face_angles = BLI_buffer_reinit_data(&face_angles_buf, float, f->len);
/* array for receiving angles from angle_poly_v3 */
- float **verts = BLI_buffer_resize_data(&verts_buf, float *, f->len);
+ float **verts = BLI_buffer_reinit_data(&verts_buf, float *, f->len);
BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) {
verts[i] = l->v->co;
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index 6664bf6dc46..118a19d3082 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -208,14 +208,11 @@ static void bm_loop_customdata_merge(
*/
const void *data_src;
- CustomData_data_add(
+ CustomData_data_mix_value(
type,
BM_ELEM_CD_GET_VOID_P(l_a_inner_inset, offset),
- BM_ELEM_CD_GET_VOID_P(l_b_inner_inset, offset));
- CustomData_data_multiply(
- type,
- BM_ELEM_CD_GET_VOID_P(l_a_inner_inset, offset),
- 0.5f);
+ BM_ELEM_CD_GET_VOID_P(l_b_inner_inset, offset),
+ CDT_MIX_MIX, 0.5f);
CustomData_data_copy_value(
type,
BM_ELEM_CD_GET_VOID_P(l_a_inner_inset, offset),
diff --git a/source/blender/bmesh/operators/bmo_planar_faces.c b/source/blender/bmesh/operators/bmo_planar_faces.c
index 4e3ac58a813..2856d3d18a6 100644
--- a/source/blender/bmesh/operators/bmo_planar_faces.c
+++ b/source/blender/bmesh/operators/bmo_planar_faces.c
@@ -21,7 +21,7 @@
/** \file blender/bmesh/operators/bmo_planar_faces.c
* \ingroup bmesh
*
- * Iternatively flatten 4+ sided faces.
+ * Iteratively flatten 4+ sided faces.
*/
#include "MEM_guardedalloc.h"
@@ -117,7 +117,7 @@ void bmo_planar_faces_exec(BMesh *bm, BMOperator *op)
}
va = *va_p;
- closest_to_plane_v3(co, plane, l_iter->v->co);
+ closest_to_plane_normalized_v3(co, plane, l_iter->v->co);
va->co_tot += 1;
interp_v3_v3v3(va->co, va->co, co, 1.0f / (float)va->co_tot);
diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c
index 5f8438919df..708d57a7a08 100644
--- a/source/blender/bmesh/operators/bmo_similar.c
+++ b/source/blender/bmesh/operators/bmo_similar.c
@@ -102,7 +102,6 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
float angle = 0.0f;
SimSel_FaceExt *f_ext = NULL;
int *indices = NULL;
- float t_no[3]; /* temporary normal */
const int type = BMO_slot_int_get(op->slots_in, "type");
const float thresh = BMO_slot_float_get(op->slots_in, "thresh");
const float thresh_radians = thresh * (float)M_PI;
@@ -158,12 +157,8 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
/* compute the center of the polygon */
BM_face_calc_center_mean(f_ext[i].f, f_ext[i].c);
- /* normalize the polygon normal */
- copy_v3_v3(t_no, f_ext[i].f->no);
- normalize_v3(t_no);
-
/* compute the plane distance */
- f_ext[i].d = dot_v3v3(t_no, f_ext[i].c);
+ f_ext[i].d = dot_v3v3(f_ext[i].f->no, f_ext[i].c);
break;
case SIMFACE_AREA:
@@ -212,16 +207,23 @@ void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
break;
case SIMFACE_COPLANAR:
+ {
+ float sign = 1.0f;
angle = angle_normalized_v3v3(fs->no, fm->no); /* angle -> 0 */
+ /* allow for normal pointing in either direction (just check the plane) */
+ if (angle > (float)M_PI * 0.5f) {
+ angle = (float)M_PI - angle;
+ sign = -1.0f;
+ }
if (angle <= thresh_radians) { /* and dot product difference -> 0 */
- delta_fl = f_ext[i].d - f_ext[indices[idx]].d;
+ delta_fl = f_ext[i].d - (f_ext[indices[idx]].d * sign);
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
BMO_elem_flag_enable(bm, fm, FACE_MARK);
cont = false;
}
}
break;
-
+ }
case SIMFACE_AREA:
delta_fl = f_ext[i].area - f_ext[indices[idx]].area;
if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 45e3c8d193d..38fa2cfdcc8 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -163,6 +163,85 @@ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace
return NULL;
}
+
+/**
+ * Specialized slerp that uses a sphere defined by each points normal.
+ */
+static void interp_slerp_co_no_v3(
+ const float co_a[3], const float no_a[3],
+ const float co_b[3], const float no_b[3],
+ const float no_dir[3], /* caller already knows, avoid normalize */
+ float fac,
+ float r_co[3])
+{
+ /* center of the sphere defined by both normals */
+ float center[3];
+
+ BLI_assert(len_squared_v3v3(no_a, no_b) != 0);
+
+ /* calculate sphere 'center' */
+ {
+ /* use point on plane to */
+ float plane_a[4], plane_b[4], plane_c[4];
+ float no_mid[3], no_ortho[3];
+ /* pass this as an arg instead */
+#if 0
+ float no_dir[3];
+#endif
+
+ float v_a_no_ortho[3], v_b_no_ortho[3];
+
+ add_v3_v3v3(no_mid, no_a, no_b);
+ normalize_v3(no_mid);
+
+#if 0
+ sub_v3_v3v3(no_dir, co_a, co_b);
+ normalize_v3(no_dir);
+#endif
+
+ /* axis of slerp */
+ cross_v3_v3v3(no_ortho, no_mid, no_dir);
+ normalize_v3(no_ortho);
+
+ /* create planes */
+ cross_v3_v3v3(v_a_no_ortho, no_ortho, no_a);
+ cross_v3_v3v3(v_b_no_ortho, no_ortho, no_b);
+ project_v3_plane(v_a_no_ortho, no_ortho, v_a_no_ortho);
+ project_v3_plane(v_b_no_ortho, no_ortho, v_b_no_ortho);
+
+ plane_from_point_normal_v3(plane_a, co_a, v_a_no_ortho);
+ plane_from_point_normal_v3(plane_b, co_b, v_b_no_ortho);
+ plane_from_point_normal_v3(plane_c, co_b, no_ortho);
+
+ /* find the sphere center from 3 planes */
+ if (isect_plane_plane_plane_v3(plane_a, plane_b, plane_c, center)) {
+ /* pass */
+ }
+ else {
+ mid_v3_v3v3(center, co_a, co_b);
+ }
+ }
+
+ /* calculate the final output 'r_co' */
+ {
+ float ofs_a[3], ofs_b[3], ofs_slerp[3];
+ float dist_a, dist_b;
+
+ sub_v3_v3v3(ofs_a, co_a, center);
+ sub_v3_v3v3(ofs_b, co_b, center);
+
+ dist_a = normalize_v3(ofs_a);
+ dist_b = normalize_v3(ofs_b);
+
+ if (interp_v3_v3v3_slerp(ofs_slerp, ofs_a, ofs_b, fac)) {
+ madd_v3_v3v3fl(r_co, center, ofs_slerp, interpf(dist_b, dist_a, fac));
+ }
+ else {
+ interp_v3_v3v3(r_co, co_a, co_b, fac);
+ }
+ }
+}
+
/* calculates offset for co, based on fractal, sphere or smooth settings */
static void alter_co(
BMVert *v, BMEdge *UNUSED(e_orig),
@@ -179,32 +258,72 @@ static void alter_co(
mul_v3_fl(co, params->smooth);
}
else if (params->use_smooth) {
- /* we calculate an offset vector vec1[], to be added to *co */
- float dir[3], tvec[3];
- float fac, len, val;
+ /* calculating twice and blending gives smoother results,
+ * removing visible seams. */
+#define USE_SPHERE_DUAL_BLEND
- sub_v3_v3v3(dir, v_a->co, v_b->co);
- len = (float)M_SQRT1_2 * normalize_v3(dir);
+ const float eps_unit_vec = 1e-5f;
+ float smooth;
+ float no_dir[3];
- /* cosine angle */
- fac = dot_v3v3(dir, v_a->no);
- mul_v3_v3fl(tvec, v_a->no, fac);
+#ifdef USE_SPHERE_DUAL_BLEND
+ float no_reflect[3], co_a[3], co_b[3];
+#endif
- /* cosine angle */
- fac = -dot_v3v3(dir, v_b->no);
- madd_v3_v3fl(tvec, v_b->no, fac);
+ sub_v3_v3v3(no_dir, v_a->co, v_b->co);
+ normalize_v3(no_dir);
- /* falloff for multi subdivide */
- val = fabsf(1.0f - 2.0f * fabsf(0.5f - perc));
- val = bmesh_subd_falloff_calc(params->smooth_falloff, val);
+#ifndef USE_SPHERE_DUAL_BLEND
+ if (len_squared_v3v3(v_a->no, v_b->no) < eps_unit_vec) {
+ interp_v3_v3v3(co, v_a->co, v_b->co, perc);
+ }
+ else {
+ interp_slerp_co_no_v3(v_a->co, v_a->no, v_b->co, v_b->no, no_dir, perc, co);
+ }
+#else
+ /* sphere-a */
+ reflect_v3_v3v3(no_reflect, v_a->no, no_dir);
+ if (len_squared_v3v3(v_a->no, no_reflect) < eps_unit_vec) {
+ interp_v3_v3v3(co_a, v_a->co, v_b->co, perc);
+ }
+ else {
+ interp_slerp_co_no_v3(v_a->co, v_a->no, v_b->co, no_reflect, no_dir, perc, co_a);
+ }
+
+ /* sphere-b */
+ reflect_v3_v3v3(no_reflect, v_b->no, no_dir);
+ if (len_squared_v3v3(v_b->no, no_reflect) < eps_unit_vec) {
+ interp_v3_v3v3(co_b, v_a->co, v_b->co, perc);
+ }
+ else {
+ interp_slerp_co_no_v3(v_a->co, no_reflect, v_b->co, v_b->no, no_dir, perc, co_b);
+ }
+
+ /* blend both spheres */
+ interp_v3_v3v3(co, co_a, co_b, perc);
+#endif /* USE_SPHERE_DUAL_BLEND */
+
+ /* apply falloff */
+ if (params->smooth_falloff == SUBD_FALLOFF_LIN) {
+ smooth = 1.0f;
+ }
+ else {
+ smooth = fabsf(1.0f - 2.0f * fabsf(0.5f - perc));
+ smooth = 1.0f + bmesh_subd_falloff_calc(params->smooth_falloff, smooth);
+ }
if (params->use_smooth_even) {
- val *= shell_v3v3_mid_normalized_to_dist(v_a->no, v_b->no);
+ smooth *= shell_v3v3_mid_normalized_to_dist(v_a->no, v_b->no);
}
- mul_v3_fl(tvec, params->smooth * val * len);
+ smooth *= params->smooth;
+ if (smooth != 1.0f) {
+ float co_flat[3];
+ interp_v3_v3v3(co_flat, v_a->co, v_b->co, perc);
+ interp_v3_v3v3(co, co_flat, co, smooth);
+ }
- add_v3_v3(co, tvec);
+#undef USE_SPHERE_DUAL_BLEND
}
if (params->use_fractal) {