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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-11-04 06:22:56 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-11-04 06:22:56 +0400
commitdd8e83606776d1d3c51cd8f5c89bf6d1a7e05f74 (patch)
tree710d8682910d03d019ca0f4a1cb86fcf2b268c2e /source/blender/bmesh
parent6dfa1601092b9aa4de88420ce1e60371cd6aed69 (diff)
parent2f2c0a51a5b108213004dcda3da6defda82e6e41 (diff)
Merged changes in the trunk up to revision 51853.
Conflicts resolved: source/blender/blenloader/intern/readfile.c source/blender/bmesh/operators/bmo_utils.c This commit also includes a fix of a bug identified during the merge and committed in revision 51853. Thanks Thomas (dingto) for the timely fix!
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r--source/blender/bmesh/CMakeLists.txt5
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate_collapse.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate_dissolve.c17
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c9
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c3
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c5
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c27
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c2
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c2
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c9
-rw-r--r--source/blender/bmesh/operators/bmo_similar.c620
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c129
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c2
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c552
19 files changed, 749 insertions, 658 deletions
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index f811dcf956e..d7858ebbc0d 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -30,7 +30,9 @@ set(INC
../blenlib
../makesdna
../../../intern/guardedalloc
- ../../../extern/bullet2/src ../../../intern/opennl/extern)
+ ../../../extern/bullet2/src
+ ../../../intern/opennl/extern
+)
set(INC_SYS
@@ -52,6 +54,7 @@ set(SRC
operators/bmo_mirror.c
operators/bmo_primitive.c
operators/bmo_removedoubles.c
+ operators/bmo_similar.c
operators/bmo_smooth_laplacian.c
operators/bmo_symmetrize.c
operators/bmo_subdivide.c
diff --git a/source/blender/bmesh/intern/bmesh_decimate_collapse.c b/source/blender/bmesh/intern/bmesh_decimate_collapse.c
index fbdbe2ffe94..feeb2a926f3 100644
--- a/source/blender/bmesh/intern/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/intern/bmesh_decimate_collapse.c
@@ -52,9 +52,9 @@
#define BOUNDARY_PRESERVE_WEIGHT 100.0f
typedef enum CD_UseFlag {
- CD_DO_VERT,
- CD_DO_EDGE,
- CD_DO_LOOP
+ CD_DO_VERT = (1 << 0),
+ CD_DO_EDGE = (1 << 1),
+ CD_DO_LOOP = (1 << 2)
} CD_UseFlag;
diff --git a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
index 91eac527047..d1371a18160 100644
--- a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
@@ -179,10 +179,10 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
/* simple version of the branch below, sincve we will dissolve _all_ verts that use 2 edges */
for (i = 0; i < vinput_len; i++) {
BMVert *v = vinput_arr[i];
- if (v) {
- if (BM_vert_edge_count(v) == 2) {
- BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */
- }
+ if (LIKELY(v != NULL) &&
+ BM_vert_edge_count(v) == 2)
+ {
+ BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */
}
}
}
@@ -207,10 +207,11 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
for (i = 0; i < tot_found; i++) {
BMVert *v = (BMVert *)weight_elems[i].ele;
- if (/* topology changes may cause this to be un-collapsable */
- (BM_vert_edge_count(v) == 2) &&
- /* check twice because cumulative effect could dissolve over angle limit */
- bm_vert_edge_face_angle(v) < angle_limit)
+ if (LIKELY(v != NULL) &&
+ /* topology changes may cause this to be un-collapsable */
+ (BM_vert_edge_count(v) == 2) &&
+ /* check twice because cumulative effect could dissolve over angle limit */
+ bm_vert_edge_face_angle(v) < angle_limit)
{
BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index ffe79923730..508b3b8fcdf 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -224,10 +224,8 @@ static int compute_mdisp_quad(BMLoop *l, float v1[3], float v2[3], float v3[3],
/* computer center */
BM_face_calc_center_mean(l->f, cent);
- add_v3_v3v3(p, l->prev->v->co, l->v->co);
- mul_v3_fl(p, 0.5);
- add_v3_v3v3(n, l->next->v->co, l->v->co);
- mul_v3_fl(n, 0.5);
+ mid_v3_v3v3(p, l->prev->v->co, l->v->co);
+ mid_v3_v3v3(n, l->next->v->co, l->v->co);
copy_v3_v3(v1, cent);
copy_v3_v3(v2, p);
@@ -525,8 +523,7 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
sides = (int)sqrt(mdp->totdisp);
for (y = 0; y < sides; y++) {
- add_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]);
- mul_v3_fl(co1, 0.5);
+ mid_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]);
copy_v3_v3(mdn->disps[y * sides], co1);
copy_v3_v3(mdl->disps[y], co1);
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index e4a838fe893..9af65d7dd7e 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -584,8 +584,7 @@ void BM_editselection_center(BMEditSelection *ese, float r_center[3])
}
else if (ese->htype == BM_EDGE) {
BMEdge *eed = (BMEdge *)ese->ele;
- add_v3_v3v3(r_center, eed->v1->co, eed->v2->co);
- mul_v3_fl(r_center, 0.5);
+ mid_v3_v3v3(r_center, eed->v1->co, eed->v2->co);
}
else if (ese->htype == BM_FACE) {
BMFace *efa = (BMFace *)ese->ele;
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 32879caec71..d3e3bcd3556 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -85,6 +85,11 @@ BMesh *BM_mesh_create(BMAllocTemplate *allocsize)
bm->stackdepth = 1;
bm->totflags = 1;
+ CustomData_reset(&bm->vdata);
+ CustomData_reset(&bm->edata);
+ CustomData_reset(&bm->ldata);
+ CustomData_reset(&bm->pdata);
+
return bm;
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index b0a9168ffda..62abf43829b 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -536,7 +536,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess)
oldverts = me->mvert;
/* don't free this yet */
- CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
+ if (oldverts) {
+ CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
+ }
/* free custom data */
CustomData_free(&me->vdata, me->totvert);
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index e12e28f8cff..31698f0abc1 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -822,10 +822,11 @@ static BMOpDefine bmo_spin_def = {
*/
static BMOpDefine bmo_similar_faces_def = {
"similar_faces",
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
+ {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */
+ {BMO_OP_SLOT_INT, "type"}, /* type of selection */
+ {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
+ {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
{0} /* null-terminating sentinel */},
bmo_similar_faces_exec,
0
@@ -838,10 +839,11 @@ static BMOpDefine bmo_similar_faces_def = {
*/
static BMOpDefine bmo_similar_edges_def = {
"similar_edges",
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
+ {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */
+ {BMO_OP_SLOT_INT, "type"}, /* type of selection */
+ {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
+ {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
{0} /* null-terminating sentinel */},
bmo_similar_edges_exec,
0
@@ -854,10 +856,11 @@ static BMOpDefine bmo_similar_edges_def = {
*/
static BMOpDefine bmo_similar_verts_def = {
"similar_verts",
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
+ {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
+ {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
+ {BMO_OP_SLOT_INT, "type"}, /* type of selection */
+ {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
+ {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
{0} /* null-terminating sentinel */},
bmo_similar_verts_exec,
0
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 015052e685d..2413f3a7be0 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -1026,7 +1026,7 @@ static void bmo_flag_layer_alloc(BMesh *bm)
int i;
BMIter iter;
- BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */
+ BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */
BLI_mempool *newpool;
void *oldflags;
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 05113576ca4..79b8c450fd9 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -46,11 +46,18 @@ enum {
SUBDIV_SELECT_LOOPCUT
};
+enum {
+ SIM_CMP_EQ = 0,
+ SIM_CMP_GT,
+ SIM_CMP_LT
+};
+
/* similar face selection slot values */
enum {
SIMFACE_MATERIAL = 201,
SIMFACE_IMAGE,
SIMFACE_AREA,
+ SIMFACE_SIDES,
SIMFACE_PERIMETER,
SIMFACE_NORMAL,
SIMFACE_COPLANAR,
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index bd0f93ee7aa..98edceb30a2 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -313,7 +313,7 @@ void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nvert
float up[3] = {0.0f, 0.0f, 1.0f}, axis[3], q[4];
float mat[3][3];
- double angle;
+ float angle;
int i;
cross_v3_v3v3(axis, normal, up);
@@ -329,7 +329,7 @@ void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nvert
axis[2] = 0.0f;
}
- axis_angle_to_quat(q, axis, (float)angle);
+ axis_angle_to_quat(q, axis, angle);
quat_to_mat3(mat, q);
for (i = 0; i < nverts; i++)
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index fbbb9c2a825..4b07dd74eef 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -344,7 +344,7 @@ BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l)
BMLoop *l_other;
// BLI_assert(BM_edge_is_manifold(e)); // TOO strict, just check if we have another radial face
- BLI_assert(e->l && e->l->radial_next != l);
+ BLI_assert(e->l && e->l->radial_next != e->l);
BLI_assert(BM_vert_in_edge(e, l->v));
l_other = (l->e == e) ? l : l->prev;
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index bb1e599f097..bb013e6428e 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -598,7 +598,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
}
}
}
- else { /* WIRE EDGE */
+ else { /* WIRE EDGE */
BMIter eiter;
/* match trunk: mark all connected wire edges */
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 30561e47d20..d7b163cb760 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -365,7 +365,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
len2 = len_v3v3(vec, vec2);
/* use shortest segment length divided by 3 as merge threshold */
- BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, MIN2(len, len2) / 3.0f);
+ BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, min_ff(len, len2) / 3.0f);
}
/* and now do imat */
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index d3e98dd96c1..cd792f911a9 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -371,7 +371,7 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
BMIter iter;
BMEdge *e, **edges = NULL;
BLI_array_declare(edges);
- float min[3], max[3];
+ float min[3], max[3], center[3];
int i, tot;
BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges");
@@ -400,13 +400,12 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
minmax_v3v3_v3(min, max, e->v2->co);
}
- add_v3_v3v3(min, min, max);
- mul_v3_fl(min, 0.5f);
+ mid_v3_v3v3(center, min, max);
/* snap edges to a point. for initial testing purposes anyway */
for (i = 0; i < tot; i++) {
- copy_v3_v3(edges[i]->v1->co, min);
- copy_v3_v3(edges[i]->v2->co, min);
+ copy_v3_v3(edges[i]->v1->co, center);
+ copy_v3_v3(edges[i]->v2->co, center);
if (edges[i]->v1 != edges[0]->v1)
BMO_slot_map_ptr_insert(bm, &weldop, "targetmap", edges[i]->v1, edges[0]->v1);
diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c
new file mode 100644
index 00000000000..b4566f6c8a9
--- /dev/null
+++ b/source/blender/bmesh/operators/bmo_similar.c
@@ -0,0 +1,620 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Joseph Eagar, Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/operators/bmo_similar.c
+ * \ingroup bmesh
+ *
+ * bmesh operators to select based on
+ * comparisons with the existing selection.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_customdata.h"
+#include "BKE_deform.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_operators_private.h" /* own include */
+
+/* in fact these could all be the same */
+
+/*
+ * extra face data (computed data)
+ */
+typedef struct SimSel_FaceExt {
+ BMFace *f; /* the face */
+ float c[3]; /* center */
+ union {
+ float area; /* area */
+ float perim; /* perimeter */
+ float d; /* 4th component of plane (the first three being the normal) */
+ struct Image *t; /* image pointer */
+ };
+} SimSel_FaceExt;
+
+static int bm_sel_similar_cmp_fl(const float delta, const float thresh, const int compare)
+{
+ switch (compare) {
+ case SIM_CMP_EQ:
+ return (fabsf(delta) <= thresh);
+ case SIM_CMP_GT:
+ return ((delta + thresh) >= 0.0f);
+ case SIM_CMP_LT:
+ return ((delta - thresh) <= 0.0f);
+ default:
+ BLI_assert(0);
+ return 0;
+ }
+}
+
+static int bm_sel_similar_cmp_i(const int delta, const int compare)
+{
+ switch (compare) {
+ case SIM_CMP_EQ:
+ return (delta == 0);
+ case SIM_CMP_GT:
+ return (delta > 0);
+ case SIM_CMP_LT:
+ return (delta < 0);
+ default:
+ BLI_assert(0);
+ return 0;
+ }
+}
+
+/*
+ * Select similar faces, the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+ * We select either similar faces based on material, image, area, perimeter, normal, or the coplanar faces
+ */
+void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
+{
+#define FACE_MARK 1
+
+ BMIter fm_iter;
+ BMFace *fs, *fm;
+ BMOIter fs_iter;
+ int num_sels = 0, num_total = 0, i = 0, idx = 0;
+ 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, "type");
+ const float thresh = BMO_slot_float_get(op, "thresh");
+ const float thresh_radians = thresh * (float)M_PI;
+ const int compare = BMO_slot_int_get(op, "compare");
+
+ /* initial_elem - other_elem */
+ float delta_fl;
+ int delta_i;
+
+ num_total = BM_mesh_elem_count(bm, BM_FACE);
+
+ /*
+ * The first thing to do is to iterate through all the the selected items and mark them since
+ * they will be in the selection anyway.
+ * This will increase performance, (especially when the number of originally selected faces is high)
+ * so the overall complexity will be less than $O(mn)$ where is the total number of selected faces,
+ * and n is the total number of faces
+ */
+ BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
+ if (!BMO_elem_flag_test(bm, fs, FACE_MARK)) { /* is this really needed ? */
+ BMO_elem_flag_enable(bm, fs, FACE_MARK);
+ num_sels++;
+ }
+ }
+
+ /* allocate memory for the selected faces indices and for all temporary faces */
+ indices = (int *)MEM_callocN(sizeof(int) * num_sels, "face indices util.c");
+ f_ext = (SimSel_FaceExt *)MEM_callocN(sizeof(SimSel_FaceExt) * num_total, "f_ext util.c");
+
+ /* loop through all the faces and fill the faces/indices structure */
+ BM_ITER_MESH (fm, &fm_iter, bm, BM_FACES_OF_MESH) {
+ f_ext[i].f = fm;
+ if (BMO_elem_flag_test(bm, fm, FACE_MARK)) {
+ indices[idx] = i;
+ idx++;
+ }
+ i++;
+ }
+
+ /*
+ * Save us some computation burden: In case of perimeter/area/coplanar selection we compute
+ * only once.
+ */
+ if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE) {
+ for (i = 0; i < num_total; i++) {
+ switch (type) {
+ case SIMFACE_PERIMETER:
+ /* set the perimeter */
+ f_ext[i].perim = BM_face_calc_perimeter(f_ext[i].f);
+ break;
+
+ case SIMFACE_COPLANAR:
+ /* 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);
+ break;
+
+ case SIMFACE_AREA:
+ f_ext[i].area = BM_face_calc_area(f_ext[i].f);
+ break;
+
+ case SIMFACE_IMAGE:
+ f_ext[i].t = NULL;
+ if (CustomData_has_layer(&(bm->pdata), CD_MTEXPOLY)) {
+ MTexPoly *mtpoly = CustomData_bmesh_get(&bm->pdata, f_ext[i].f->head.data, CD_MTEXPOLY);
+ f_ext[i].t = mtpoly->tpage;
+ }
+ break;
+ }
+ }
+ }
+
+ /* now select the rest (if any) */
+ for (i = 0; i < num_total; i++) {
+ fm = f_ext[i].f;
+ if (!BMO_elem_flag_test(bm, fm, FACE_MARK) && !BM_elem_flag_test(fm, BM_ELEM_HIDDEN)) {
+ int cont = TRUE;
+ for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+ fs = f_ext[indices[idx]].f;
+ switch (type) {
+ case SIMFACE_MATERIAL:
+ if (fm->mat_nr == fs->mat_nr) {
+ BMO_elem_flag_enable(bm, fm, FACE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMFACE_IMAGE:
+ if (f_ext[i].t == f_ext[indices[idx]].t) {
+ BMO_elem_flag_enable(bm, fm, FACE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMFACE_NORMAL:
+ angle = angle_normalized_v3v3(fs->no, fm->no); /* if the angle between the normals -> 0 */
+ if (angle <= thresh_radians) {
+ BMO_elem_flag_enable(bm, fm, FACE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMFACE_COPLANAR:
+ angle = angle_normalized_v3v3(fs->no, fm->no); /* angle -> 0 */
+ if (angle <= thresh_radians) { /* and dot product difference -> 0 */
+ delta_fl = f_ext[i].d - f_ext[indices[idx]].d;
+ 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)) {
+ BMO_elem_flag_enable(bm, fm, FACE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMFACE_SIDES:
+ delta_i = fm->len - fs->len;
+ if (bm_sel_similar_cmp_i(delta_i, compare)) {
+ BMO_elem_flag_enable(bm, fm, FACE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMFACE_PERIMETER:
+ delta_fl = f_ext[i].perim - f_ext[indices[idx]].perim;
+ if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+ BMO_elem_flag_enable(bm, fm, FACE_MARK);
+ cont = FALSE;
+ }
+ break;
+ default:
+ BLI_assert(0);
+ }
+ }
+ }
+ }
+
+ MEM_freeN(f_ext);
+ MEM_freeN(indices);
+
+ /* transfer all marked faces to the output slot */
+ BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_MARK);
+#undef FACE_MARK
+}
+
+/**************************************************************************** *
+ * Similar Edges
+ **************************************************************************** */
+
+/*
+ * extra edge information
+ */
+typedef struct SimSel_EdgeExt {
+ BMEdge *e;
+ union {
+ float dir[3];
+ float angle; /* angle between the face */
+ };
+
+ union {
+ float length; /* edge length */
+ int faces; /* faces count */
+ };
+} SimSel_EdgeExt;
+
+/*
+ * select similar edges: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+ * choices are length, direction, face, ...
+ */
+void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
+{
+#define EDGE_MARK 1
+
+ BMOIter es_iter; /* selected edges iterator */
+ BMIter e_iter; /* mesh edges iterator */
+ BMEdge *es; /* selected edge */
+ BMEdge *e; /* mesh edge */
+ int idx = 0, i = 0 /* , f = 0 */;
+ int *indices = NULL;
+ SimSel_EdgeExt *e_ext = NULL;
+ // float *angles = NULL;
+ float angle;
+
+ int num_sels = 0, num_total = 0;
+ const int type = BMO_slot_int_get(op, "type");
+ const float thresh = BMO_slot_float_get(op, "thresh");
+ const int compare = BMO_slot_int_get(op, "compare");
+
+ /* initial_elem - other_elem */
+ float delta_fl;
+ int delta_i;
+
+ /* sanity checks that the data we need is available */
+ switch (type) {
+ case SIMEDGE_CREASE:
+ if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ return;
+ }
+ break;
+ case SIMEDGE_BEVEL:
+ if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ return;
+ }
+ break;
+ }
+
+ num_total = BM_mesh_elem_count(bm, BM_EDGE);
+
+ /* iterate through all selected edges and mark them */
+ BMO_ITER (es, &es_iter, bm, op, "edges", BM_EDGE) {
+ BMO_elem_flag_enable(bm, es, EDGE_MARK);
+ num_sels++;
+ }
+
+ /* allocate memory for the selected edges indices and for all temporary edges */
+ indices = (int *)MEM_callocN(sizeof(int) * num_sels, __func__);
+ e_ext = (SimSel_EdgeExt *)MEM_callocN(sizeof(SimSel_EdgeExt) * num_total, __func__);
+
+ /* loop through all the edges and fill the edges/indices structure */
+ BM_ITER_MESH (e, &e_iter, bm, BM_EDGES_OF_MESH) {
+ e_ext[i].e = e;
+ if (BMO_elem_flag_test(bm, e, EDGE_MARK)) {
+ indices[idx] = i;
+ idx++;
+ }
+ i++;
+ }
+
+ /* save us some computation time by doing heavy computation once */
+ if (type == SIMEDGE_LENGTH || type == SIMEDGE_FACE || type == SIMEDGE_DIR || type == SIMEDGE_FACE_ANGLE) {
+ for (i = 0; i < num_total; i++) {
+ switch (type) {
+ case SIMEDGE_LENGTH: /* compute the length of the edge */
+ e_ext[i].length = len_v3v3(e_ext[i].e->v1->co, e_ext[i].e->v2->co);
+ break;
+
+ case SIMEDGE_DIR: /* compute the direction */
+ sub_v3_v3v3(e_ext[i].dir, e_ext[i].e->v1->co, e_ext[i].e->v2->co);
+ normalize_v3(e_ext[i].dir);
+ break;
+
+ case SIMEDGE_FACE: /* count the faces around the edge */
+ e_ext[i].faces = BM_edge_face_count(e_ext[i].e);
+ break;
+
+ case SIMEDGE_FACE_ANGLE:
+ e_ext[i].faces = BM_edge_face_count(e_ext[i].e);
+ if (e_ext[i].faces == 2)
+ e_ext[i].angle = BM_edge_calc_face_angle(e_ext[i].e);
+ break;
+ }
+ }
+ }
+
+ /* select the edges if any */
+ for (i = 0; i < num_total; i++) {
+ e = e_ext[i].e;
+ if (!BMO_elem_flag_test(bm, e, EDGE_MARK) && !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ int cont = TRUE;
+ for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+ es = e_ext[indices[idx]].e;
+ switch (type) {
+ case SIMEDGE_LENGTH:
+ delta_fl = e_ext[i].length - e_ext[indices[idx]].length;
+ if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMEDGE_DIR:
+ /* compute the angle between the two edges */
+ angle = angle_normalized_v3v3(e_ext[i].dir, e_ext[indices[idx]].dir);
+
+ if (angle > (float)(M_PI / 2.0)) /* use the smallest angle between the edges */
+ angle = fabsf(angle - (float)M_PI);
+
+ if (angle / (float)(M_PI / 2.0) <= thresh) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMEDGE_FACE:
+ delta_i = e_ext[i].faces - e_ext[indices[idx]].faces;
+ if (bm_sel_similar_cmp_i(delta_i, compare)) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMEDGE_FACE_ANGLE:
+ if (e_ext[i].faces == 2) {
+ if (e_ext[indices[idx]].faces == 2) {
+ if (fabsf(e_ext[i].angle - e_ext[indices[idx]].angle) <= thresh) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ }
+ }
+ else {
+ cont = FALSE;
+ }
+ break;
+
+ case SIMEDGE_CREASE:
+ {
+ float *c1, *c2;
+
+ c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
+ c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_CREASE);
+ delta_fl = *c1 - *c2;
+
+ if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ }
+ break;
+
+ case SIMEDGE_BEVEL:
+ {
+ float *c1, *c2;
+
+ c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
+ c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_BWEIGHT);
+ delta_fl = *c1 - *c2;
+
+ if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ }
+ break;
+
+ case SIMEDGE_SEAM:
+ if (BM_elem_flag_test(e, BM_ELEM_SEAM) == BM_elem_flag_test(es, BM_ELEM_SEAM)) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMEDGE_SHARP:
+ if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == BM_elem_flag_test(es, BM_ELEM_SMOOTH)) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = FALSE;
+ }
+ break;
+ case SIMEDGE_FREESTYLE:
+ if (BM_elem_flag_test(e, BM_ELEM_FREESTYLE) == BM_elem_flag_test(es, BM_ELEM_FREESTYLE)) {
+ BMO_elem_flag_enable(bm, e, EDGE_MARK);
+ cont = 0;
+ }
+ break;
+ default:
+ BLI_assert(0);
+ }
+ }
+ }
+ }
+
+ MEM_freeN(e_ext);
+ MEM_freeN(indices);
+
+ /* transfer all marked edges to the output slot */
+ BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_MARK);
+
+#undef EDGE_MARK
+}
+
+/**************************************************************************** *
+ * Similar Vertices
+ **************************************************************************** */
+
+typedef struct SimSel_VertExt {
+ BMVert *v;
+ union {
+ int num_faces; /* adjacent faces */
+ int num_edges; /* adjacent edges */
+ MDeformVert *dvert; /* deform vertex */
+ };
+} SimSel_VertExt;
+
+/*
+ * select similar vertices: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+ * choices are normal, face, vertex group...
+ */
+void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
+{
+#define VERT_MARK 1
+
+ BMOIter vs_iter; /* selected verts iterator */
+ BMIter v_iter; /* mesh verts iterator */
+ BMVert *vs; /* selected vertex */
+ BMVert *v; /* mesh vertex */
+ SimSel_VertExt *v_ext = NULL;
+ int *indices = NULL;
+ int num_total = 0, num_sels = 0, i = 0, idx = 0;
+ const int type = BMO_slot_int_get(op, "type");
+ const float thresh = BMO_slot_float_get(op, "thresh");
+ const float thresh_radians = thresh * (float)M_PI;
+ const int compare = BMO_slot_int_get(op, "compare");
+
+ /* initial_elem - other_elem */
+// float delta_fl;
+ int delta_i;
+
+ num_total = BM_mesh_elem_count(bm, BM_VERT);
+
+ /* iterate through all selected edges and mark them */
+ BMO_ITER (vs, &vs_iter, bm, op, "verts", BM_VERT) {
+ BMO_elem_flag_enable(bm, vs, VERT_MARK);
+ num_sels++;
+ }
+
+ /* allocate memory for the selected vertices indices and for all temporary vertices */
+ indices = (int *)MEM_mallocN(sizeof(int) * num_sels, "vertex indices");
+ v_ext = (SimSel_VertExt *)MEM_mallocN(sizeof(SimSel_VertExt) * num_total, "vertex extra");
+
+ /* loop through all the vertices and fill the vertices/indices structure */
+ BM_ITER_MESH (v, &v_iter, bm, BM_VERTS_OF_MESH) {
+ v_ext[i].v = v;
+ if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
+ indices[idx] = i;
+ idx++;
+ }
+
+ switch (type) {
+ case SIMVERT_FACE:
+ /* calling BM_vert_face_count every time is time consumming, so call it only once per vertex */
+ v_ext[i].num_faces = BM_vert_face_count(v);
+ break;
+
+ case SIMVERT_VGROUP:
+ if (CustomData_has_layer(&(bm->vdata), CD_MDEFORMVERT)) {
+ v_ext[i].dvert = CustomData_bmesh_get(&bm->vdata, v_ext[i].v->head.data, CD_MDEFORMVERT);
+ }
+ else {
+ v_ext[i].dvert = NULL;
+ }
+ break;
+ case SIMVERT_EDGE:
+ v_ext[i].num_edges = BM_vert_edge_count(v);
+ break;
+ }
+
+ i++;
+ }
+
+ /* select the vertices if any */
+ for (i = 0; i < num_total; i++) {
+ v = v_ext[i].v;
+ if (!BMO_elem_flag_test(bm, v, VERT_MARK) && !BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ int cont = TRUE;
+ for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
+ vs = v_ext[indices[idx]].v;
+ switch (type) {
+ case SIMVERT_NORMAL:
+ /* compare the angle between the normals */
+ if (angle_normalized_v3v3(v->no, vs->no) <= thresh_radians) {
+ BMO_elem_flag_enable(bm, v, VERT_MARK);
+ cont = FALSE;
+ }
+ break;
+ case SIMVERT_FACE:
+ /* number of adjacent faces */
+ delta_i = v_ext[i].num_faces - v_ext[indices[idx]].num_faces;
+ if (bm_sel_similar_cmp_i(delta_i, compare)) {
+ BMO_elem_flag_enable(bm, v, VERT_MARK);
+ cont = FALSE;
+ }
+ break;
+
+ case SIMVERT_VGROUP:
+ if (v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL) {
+ if (defvert_find_shared(v_ext[i].dvert, v_ext[indices[idx]].dvert) != -1) {
+ BMO_elem_flag_enable(bm, v, VERT_MARK);
+ cont = FALSE;
+ }
+ }
+ break;
+ case SIMVERT_EDGE:
+ /* number of adjacent edges */
+ delta_i = v_ext[i].num_edges - v_ext[indices[idx]].num_edges;
+ if (bm_sel_similar_cmp_i(delta_i, compare)) {
+ BMO_elem_flag_enable(bm, v, VERT_MARK);
+ cont = FALSE;
+ }
+ break;
+ default:
+ BLI_assert(0);
+ }
+ }
+ }
+ }
+
+ MEM_freeN(indices);
+ MEM_freeN(v_ext);
+
+ BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
+
+#undef VERT_MARK
+}
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 9a2a9c022e6..51b9adb5de3 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -45,19 +45,19 @@
#define SMOOTH_LAPLACIAN_AREA_FACTOR 4.0f
#define SMOOTH_LAPLACIAN_EDGE_FACTOR 2.0f
-#define SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE 1.8
-#define SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE 0.15
+#define SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE 1.8f
+#define SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE 0.15f
struct BLaplacianSystem {
- float *eweights; /* Length weights per Edge */
+ float *eweights; /* Length weights per Edge */
float (*fweights)[3]; /* Cotangent weights per face */
- float *ring_areas; /* Total area per ring*/
- float *vlengths; /* Total sum of lengths(edges) per vertice*/
- float *vweights; /* Total sum of weights per vertice*/
- int numEdges; /* Number of edges*/
- int numFaces; /* Number of faces*/
- int numVerts; /* Number of verts*/
- short *zerola; /* Is zero area or length*/
+ float *ring_areas; /* Total area per ring*/
+ float *vlengths; /* Total sum of lengths(edges) per vertice*/
+ float *vweights; /* Total sum of weights per vertice*/
+ int numEdges; /* Number of edges*/
+ int numFaces; /* Number of faces*/
+ int numVerts; /* Number of verts*/
+ short *zerola; /* Is zero area or length*/
/* Pointers to data*/
BMesh *bm;
@@ -72,13 +72,13 @@ typedef struct BLaplacianSystem LaplacianSystem;
static float compute_volume(BMesh *bm);
static float cotan_weight(float *v1, float *v2, float *v3);
static int vert_is_boundary(BMVert *v);
-static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces, int a_numVerts);
-static void init_laplacian_matrix(LaplacianSystem * sys);
-static void delete_laplacian_system(LaplacianSystem * sys);
+static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts);
+static void init_laplacian_matrix(LaplacianSystem *sys);
+static void delete_laplacian_system(LaplacianSystem *sys);
static void delete_void_pointer(void *data);
-static void fill_laplacian_matrix(LaplacianSystem * sys);
+static void fill_laplacian_matrix(LaplacianSystem *sys);
static void memset_laplacian_system(LaplacianSystem *sys, int val);
-static void validate_solution(LaplacianSystem * sys, int usex, int usey, int usez, int volumepreservation);
+static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int volumepreservation);
static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float vend, int usex, int usey, int usez);
static void delete_void_pointer(void *data)
@@ -89,7 +89,7 @@ static void delete_void_pointer(void *data)
}
}
-static void delete_laplacian_system(LaplacianSystem * sys)
+static void delete_laplacian_system(LaplacianSystem *sys)
{
delete_void_pointer(sys->eweights);
delete_void_pointer(sys->fweights);
@@ -107,17 +107,17 @@ static void delete_laplacian_system(LaplacianSystem * sys)
static void memset_laplacian_system(LaplacianSystem *sys, int val)
{
- memset(sys->eweights , val, sizeof(float) * sys->numEdges);
- memset(sys->fweights , val, sizeof(float) * sys->numFaces * 3);
- memset(sys->ring_areas , val, sizeof(float) * sys->numVerts);
- memset(sys->vlengths , val, sizeof(float) * sys->numVerts);
- memset(sys->vweights , val, sizeof(float) * sys->numVerts);
- memset(sys->zerola , val, sizeof(short) * sys->numVerts);
+ memset(sys->eweights, val, sizeof(float) * sys->numEdges);
+ memset(sys->fweights, val, sizeof(float) * sys->numFaces * 3);
+ memset(sys->ring_areas, val, sizeof(float) * sys->numVerts);
+ memset(sys->vlengths, val, sizeof(float) * sys->numVerts);
+ memset(sys->vweights, val, sizeof(float) * sys->numVerts);
+ memset(sys->zerola, val, sizeof(short) * sys->numVerts);
}
-static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces, int a_numVerts)
+static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts)
{
- LaplacianSystem * sys;
+ LaplacianSystem *sys;
sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem");
sys->numEdges = a_numEdges;
sys->numFaces = a_numFaces;
@@ -128,19 +128,19 @@ static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces,
delete_laplacian_system(sys);
return NULL;
}
-
+
sys->fweights = MEM_callocN(sizeof(float) * 3 * sys->numFaces, "ModLaplSmoothFWeight");
if (!sys->fweights) {
delete_laplacian_system(sys);
return NULL;
}
-
+
sys->ring_areas = MEM_callocN(sizeof(float) * sys->numVerts, "ModLaplSmoothRingAreas");
if (!sys->ring_areas) {
delete_laplacian_system(sys);
return NULL;
}
-
+
sys->vlengths = MEM_callocN(sizeof(float) * sys->numVerts, "ModLaplSmoothVlengths");
if (!sys->vlengths) {
delete_laplacian_system(sys);
@@ -163,7 +163,7 @@ static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces,
}
/* Compute weigth between vertice v_i and all your neighbors
- * weight between v_i and v_neighbor
+ * weight between v_i and v_neighbor
* Wij = cot(alpha) + cot(beta) / (4.0 * total area of all faces * sum all weight)
* v_i *
* / | \
@@ -172,15 +172,15 @@ static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces,
* \ | /
* \ | /
* * v_neighbor
-*/
+ */
-static void init_laplacian_matrix(LaplacianSystem * sys)
+static void init_laplacian_matrix(LaplacianSystem *sys)
{
float areaf;
float *v1, *v2, *v3, *v4;
float w1, w2, w3, w4;
int i, j;
- int has_4_vert ;
+ int has_4_vert;
unsigned int idv1, idv2, idv3, idv4, idv[4];
BMEdge *e;
BMFace *f;
@@ -196,7 +196,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys)
v2 = e->v2->co;
idv1 = BM_elem_index_get(e->v1);
idv2 = BM_elem_index_get(e->v2);
-
+
w1 = len_v3v3(v1, v2);
if (w1 > sys->min_area) {
w1 = 1.0f / w1;
@@ -204,7 +204,8 @@ static void init_laplacian_matrix(LaplacianSystem * sys)
sys->eweights[i] = w1;
sys->vlengths[idv1] += w1;
sys->vlengths[idv2] += w1;
- }else{
+ }
+ else {
sys->zerola[idv1] = 1;
sys->zerola[idv2] = 1;
}
@@ -235,7 +236,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys)
areaf = area_tri_v3(v1, v2, v3);
}
- if (fabs(areaf) < sys->min_area) {
+ if (fabsf(areaf) < sys->min_area) {
sys->zerola[idv1] = 1;
sys->zerola[idv2] = 1;
sys->zerola[idv3] = 1;
@@ -248,7 +249,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys)
if (has_4_vert) sys->ring_areas[idv4] += areaf;
if (has_4_vert) {
-
+
idv[0] = idv1;
idv[1] = idv2;
idv[2] = idv3;
@@ -268,7 +269,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys)
w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2);
w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3);
w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1);
-
+
sys->vweights[idv1] += (w2 + w3 + w4) / 4.0f;
}
}
@@ -282,7 +283,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys)
sys->fweights[i][0] += w1;
sys->fweights[i][1] += w2;
sys->fweights[i][2] += w3;
-
+
sys->vweights[idv1] += w2 + w3;
sys->vweights[idv2] += w1 + w3;
sys->vweights[idv3] += w1 + w2;
@@ -291,12 +292,12 @@ static void init_laplacian_matrix(LaplacianSystem * sys)
}
}
-static void fill_laplacian_matrix(LaplacianSystem * sys)
+static void fill_laplacian_matrix(LaplacianSystem *sys)
{
float *v1, *v2, *v3, *v4;
float w2, w3, w4;
int i, j;
- int has_4_vert ;
+ int has_4_vert;
unsigned int idv1, idv2, idv3, idv4, idv[4];
BMEdge *e;
@@ -336,8 +337,8 @@ static void fill_laplacian_matrix(LaplacianSystem * sys)
w2 = w2 / 4.0f;
w3 = w3 / 4.0f;
w4 = w4 / 4.0f;
-
- if (!vert_is_boundary(vf[j]) && sys->zerola[idv1] == 0) {
+
+ if (!vert_is_boundary(vf[j]) && sys->zerola[idv1] == 0) {
nlMatrixAdd(idv1, idv2, w2 * sys->vweights[idv1]);
nlMatrixAdd(idv1, idv3, w3 * sys->vweights[idv1]);
nlMatrixAdd(idv1, idv4, w4 * sys->vweights[idv1]);
@@ -350,15 +351,15 @@ static void fill_laplacian_matrix(LaplacianSystem * sys)
idv3 = BM_elem_index_get(vf[2]);
/* Is ring if number of faces == number of edges around vertice*/
i = BM_elem_index_get(f);
- if (!vert_is_boundary(vf[0]) && sys->zerola[idv1] == 0) {
+ if (!vert_is_boundary(vf[0]) && sys->zerola[idv1] == 0) {
nlMatrixAdd(idv1, idv2, sys->fweights[i][2] * sys->vweights[idv1]);
nlMatrixAdd(idv1, idv3, sys->fweights[i][1] * sys->vweights[idv1]);
}
- if (!vert_is_boundary(vf[1]) && sys->zerola[idv2] == 0) {
+ if (!vert_is_boundary(vf[1]) && sys->zerola[idv2] == 0) {
nlMatrixAdd(idv2, idv1, sys->fweights[i][2] * sys->vweights[idv2]);
nlMatrixAdd(idv2, idv3, sys->fweights[i][0] * sys->vweights[idv2]);
}
- if (!vert_is_boundary(vf[2]) && sys->zerola[idv3] == 0) {
+ if (!vert_is_boundary(vf[2]) && sys->zerola[idv3] == 0) {
nlMatrixAdd(idv3, idv1, sys->fweights[i][1] * sys->vweights[idv3]);
nlMatrixAdd(idv3, idv2, sys->fweights[i][0] * sys->vweights[idv3]);
}
@@ -392,7 +393,7 @@ static float cotan_weight(float *v1, float *v2, float *v3)
if (clen == 0.0f)
return 0.0f;
-
+
return dot_v3v3(a, b) / clen;
}
@@ -402,7 +403,7 @@ static int vert_is_boundary(BMVert *v)
BMFace *f;
BMIter ei;
BMIter fi;
- BM_ITER_ELEM(ed, &ei, v, BM_EDGES_OF_VERT) {
+ BM_ITER_ELEM (ed, &ei, v, BM_EDGES_OF_VERT) {
if (BM_edge_is_boundary(ed)) {
return 1;
}
@@ -425,7 +426,7 @@ static float compute_volume(BMesh *bm)
BMIter vi;
BMVert *vn;
BMVert *vf[4];
-
+
BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM_INDEX (vn, &vi, f, BM_VERTS_OF_FACE, i) {
vf[i] = vn;
@@ -442,13 +443,13 @@ static float compute_volume(BMesh *bm)
y3 = vf[2]->co[1];
z3 = vf[2]->co[2];
- vol += (1.0 / 6.0) * (0.0 - x3*y2*z1 + x2*y3*z1 + x3*y1*z2 - x1*y3*z2 - x2*y1*z3 + x1*y2*z3);
+ vol += (1.0f / 6.0f) * (0.0f - x3 * y2 * z1 + x2 * y3 * z1 + x3 * y1 * z2 - x1 * y3 * z2 - x2 * y1 * z3 + x1 * y2 * z3);
if (i == 4) {
x4 = vf[3]->co[0];
y4 = vf[3]->co[1];
z4 = vf[3]->co[2];
- vol += (1.0 / 6.0) * (x1*y3*z4 - x1*y4*z3 - x3*y1*z4 + x3*z1*y4 + y1*x4*z3 - x4*y3*z1);
+ vol += (1.0f / 6.0f) * (x1 * y3 * z4 - x1 * y4 * z3 - x3 * y1 * z4 + x3 * z1 * y4 + y1 * x4 * z3 - x4 * y3 * z1);
}
}
return fabs(vol);
@@ -460,8 +461,8 @@ static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float ven
BMOIter siter;
BMVert *v;
- if (vend != 0.0f) {
- beta = pow (vini / vend, 1.0f / 3.0f);
+ if (vend != 0.0f) {
+ beta = pow(vini / vend, 1.0f / 3.0f);
BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
if (usex) {
v->co[0] *= beta;
@@ -472,12 +473,12 @@ static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float ven
if (usez) {
v->co[2] *= beta;
}
-
+
}
}
}
-static void validate_solution(LaplacianSystem * sys, int usex, int usey, int usez, int volumepreservation)
+static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int volumepreservation)
{
int m_vertex_id;
float leni, lene;
@@ -502,7 +503,7 @@ static void validate_solution(LaplacianSystem * sys, int usex, int usey, int use
ve2[2] = nlGetVariable(2, idv2);
leni = len_v3v3(vi1, vi2);
lene = len_v3v3(ve1, ve2);
- if ( lene > leni* SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE || lene < leni*SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE) {
+ if (lene > leni * SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE || lene < leni * SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE) {
sys->zerola[idv1] = 1;
sys->zerola[idv2] = 1;
}
@@ -541,7 +542,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
float w;
BMOIter siter;
BMVert *v;
- LaplacianSystem * sys;
+ LaplacianSystem *sys;
sys = init_laplacian_system(bm->totedge, bm->totface, bm->totvert);
if (!sys) return;
@@ -568,16 +569,16 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
nlSolverParameteri(NL_NB_ROWS, bm->totvert);
nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3);
- nlBegin(NL_SYSTEM);
- for (i=0; i < bm->totvert; i++) {
+ nlBegin(NL_SYSTEM);
+ for (i = 0; i < bm->totvert; i++) {
nlLockVariable(i);
}
BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) {
m_vertex_id = BM_elem_index_get(v);
nlUnlockVariable(m_vertex_id);
- nlSetVariable(0,m_vertex_id, v->co[0]);
- nlSetVariable(1,m_vertex_id, v->co[1]);
- nlSetVariable(2,m_vertex_id, v->co[2]);
+ nlSetVariable(0, m_vertex_id, v->co[0]);
+ nlSetVariable(1, m_vertex_id, v->co[1]);
+ nlSetVariable(2, m_vertex_id, v->co[2]);
}
nlBegin(NL_MATRIX);
@@ -594,7 +595,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
w = sys->vlengths[i];
sys->vlengths[i] = (w == 0.0f) ? 0.0f : -lambda_border * 2.0f / w;
- if (!vert_is_boundary(v)) {
+ if (!vert_is_boundary(v)) {
nlMatrixAdd(i, i, 1.0f + lambda / (4.0f * sys->ring_areas[i]));
}
else {
@@ -603,16 +604,16 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
}
else {
nlMatrixAdd(i, i, 1.0f);
- }
+ }
}
fill_laplacian_matrix(sys);
-
+
nlEnd(NL_MATRIX);
nlEnd(NL_SYSTEM);
if (nlSolveAdvanced(NULL, NL_TRUE) ) {
validate_solution(sys, usex, usey, usez, volumepreservation);
}
-
+
delete_laplacian_system(sys);
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index c6726ec6f3e..346daf830d0 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -54,7 +54,7 @@
#define ELE_SPLIT 16
/* see bug [#32665], 0.00005 means a we get face splits at a little under 1.0 degrees */
-#define FLT_FACE_SPLIT_EPSILON 0.00005
+#define FLT_FACE_SPLIT_EPSILON 0.00005f
/*
* NOTE: beauty has been renamed to flag!
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index b396da3b8d1..e311b383b86 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -479,554 +479,6 @@ void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op)
BLI_array_free(cos);
}
-/*
- * compute the fake surface of an ngon
- * This is done by decomposing the ngon into triangles who share the centroid of the ngon
- * while this method is far from being exact, it should guarantee an invariance.
- *
- * NOTE: This should probably go to bmesh_polygon.c
- */
-static float ngon_fake_area(BMFace *f)
-{
- BMIter liter;
- BMLoop *l;
- int num_verts = 0;
- float v[3], sv[3], c[3];
- float area = 0.0f;
-
- BM_face_calc_center_mean(f, c);
-
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- if (num_verts == 0) {
- copy_v3_v3(v, l->v->co);
- copy_v3_v3(sv, l->v->co);
- num_verts++;
- }
- else {
- area += area_tri_v3(v, c, l->v->co);
- copy_v3_v3(v, l->v->co);
- num_verts++;
- }
- }
-
- area += area_tri_v3(v, c, sv);
-
- return area;
-}
-
-/*
- * extra face data (computed data)
- */
-typedef struct SimSel_FaceExt {
- BMFace *f; /* the face */
- float c[3]; /* center */
- union {
- float area; /* area */
- float perim; /* perimeter */
- float d; /* 4th component of plane (the first three being the normal) */
- struct Image *t; /* image pointer */
- };
-} SimSel_FaceExt;
-
-/*
- * Select similar faces, the choices are in the enum in source/blender/bmesh/bmesh_operators.h
- * We select either similar faces based on material, image, area, perimeter, normal, or the coplanar faces
- */
-void bmo_similar_faces_exec(BMesh *bm, BMOperator *op)
-{
- BMIter fm_iter;
- BMFace *fs, *fm;
- BMOIter fs_iter;
- int num_sels = 0, num_total = 0, i = 0, idx = 0;
- float angle = 0.0f;
- SimSel_FaceExt *f_ext = NULL;
- int *indices = NULL;
- float t_no[3]; /* temporary normal */
- int type = BMO_slot_int_get(op, "type");
- const float thresh = BMO_slot_float_get(op, "thresh");
- const float thresh_radians = thresh * (float)M_PI;
-
- num_total = BM_mesh_elem_count(bm, BM_FACE);
-
- /*
- * The first thing to do is to iterate through all the the selected items and mark them since
- * they will be in the selection anyway.
- * This will increase performance, (especially when the number of originally selected faces is high)
- * so the overall complexity will be less than $O(mn)$ where is the total number of selected faces,
- * and n is the total number of faces
- */
- BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) {
- if (!BMO_elem_flag_test(bm, fs, FACE_MARK)) { /* is this really needed ? */
- BMO_elem_flag_enable(bm, fs, FACE_MARK);
- num_sels++;
- }
- }
-
- /* allocate memory for the selected faces indices and for all temporary faces */
- indices = (int *)MEM_callocN(sizeof(int) * num_sels, "face indices util.c");
- f_ext = (SimSel_FaceExt *)MEM_callocN(sizeof(SimSel_FaceExt) * num_total, "f_ext util.c");
-
- /* loop through all the faces and fill the faces/indices structure */
- BM_ITER_MESH (fm, &fm_iter, bm, BM_FACES_OF_MESH) {
- f_ext[i].f = fm;
- if (BMO_elem_flag_test(bm, fm, FACE_MARK)) {
- indices[idx] = i;
- idx++;
- }
- i++;
- }
-
- /*
- * Save us some computation burden: In case of perimeter/area/coplanar selection we compute
- * only once.
- */
- if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE) {
- for (i = 0; i < num_total; i++) {
- switch (type) {
- case SIMFACE_PERIMETER:
- /* set the perimeter */
- f_ext[i].perim = BM_face_calc_perimeter(f_ext[i].f);
- break;
-
- case SIMFACE_COPLANAR:
- /* 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);
- break;
-
- case SIMFACE_AREA:
- f_ext[i].area = ngon_fake_area(f_ext[i].f);
- break;
-
- case SIMFACE_IMAGE:
- f_ext[i].t = NULL;
- if (CustomData_has_layer(&(bm->pdata), CD_MTEXPOLY)) {
- MTexPoly *mtpoly = CustomData_bmesh_get(&bm->pdata, f_ext[i].f->head.data, CD_MTEXPOLY);
- f_ext[i].t = mtpoly->tpage;
- }
- break;
- }
- }
- }
-
- /* now select the rest (if any) */
- for (i = 0; i < num_total; i++) {
- fm = f_ext[i].f;
- if (!BMO_elem_flag_test(bm, fm, FACE_MARK) && !BM_elem_flag_test(fm, BM_ELEM_HIDDEN)) {
- int cont = TRUE;
- for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
- fs = f_ext[indices[idx]].f;
- switch (type) {
- case SIMFACE_MATERIAL:
- if (fm->mat_nr == fs->mat_nr) {
- BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMFACE_IMAGE:
- if (f_ext[i].t == f_ext[indices[idx]].t) {
- BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMFACE_NORMAL:
- angle = angle_normalized_v3v3(fs->no, fm->no); /* if the angle between the normals -> 0 */
- if (angle <= thresh_radians) {
- BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMFACE_COPLANAR:
- angle = angle_normalized_v3v3(fs->no, fm->no); /* angle -> 0 */
- if (angle <= thresh_radians) { /* and dot product difference -> 0 */
- if (fabsf(f_ext[i].d - f_ext[indices[idx]].d) <= thresh) {
- BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
- }
- }
- break;
-
- case SIMFACE_AREA:
- if (fabsf(f_ext[i].area - f_ext[indices[idx]].area) <= thresh) {
- BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMFACE_PERIMETER:
- if (fabsf(f_ext[i].perim - f_ext[indices[idx]].perim) <= thresh) {
- BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMFACE_FREESTYLE:
- if (BM_elem_flag_test(fm, BM_ELEM_FREESTYLE) == BM_elem_flag_test(fs, BM_ELEM_FREESTYLE)) {
- BMO_elem_flag_enable(bm, fm, FACE_MARK);
- cont = 0;
- }
- break;
- }
- }
- }
- }
-
- MEM_freeN(f_ext);
- MEM_freeN(indices);
-
- /* transfer all marked faces to the output slot */
- BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_MARK);
-}
-
-/**************************************************************************** *
- * Similar Edges
- **************************************************************************** */
-#define EDGE_MARK 1
-
-/*
- * extra edge information
- */
-typedef struct SimSel_EdgeExt {
- BMEdge *e;
- union {
- float dir[3];
- float angle; /* angle between the face */
- };
-
- union {
- float length; /* edge length */
- int faces; /* faces count */
- };
-} SimSel_EdgeExt;
-
-/*
- * select similar edges: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
- * choices are length, direction, face, ...
- */
-void bmo_similar_edges_exec(BMesh *bm, BMOperator *op)
-{
- BMOIter es_iter; /* selected edges iterator */
- BMIter e_iter; /* mesh edges iterator */
- BMEdge *es; /* selected edge */
- BMEdge *e; /* mesh edge */
- int idx = 0, i = 0 /* , f = 0 */;
- int *indices = NULL;
- SimSel_EdgeExt *e_ext = NULL;
- // float *angles = NULL;
- float angle;
-
- int num_sels = 0, num_total = 0;
- int type = BMO_slot_int_get(op, "type");
- const float thresh = BMO_slot_float_get(op, "thresh");
-
- /* sanity checks that the data we need is available */
- switch (type) {
- case SIMEDGE_CREASE:
- if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
- return;
- }
- break;
- case SIMEDGE_BEVEL:
- if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
- return;
- }
- break;
- }
-
- num_total = BM_mesh_elem_count(bm, BM_EDGE);
-
- /* iterate through all selected edges and mark them */
- BMO_ITER (es, &es_iter, bm, op, "edges", BM_EDGE) {
- BMO_elem_flag_enable(bm, es, EDGE_MARK);
- num_sels++;
- }
-
- /* allocate memory for the selected edges indices and for all temporary edges */
- indices = (int *)MEM_callocN(sizeof(int) * num_sels, __func__);
- e_ext = (SimSel_EdgeExt *)MEM_callocN(sizeof(SimSel_EdgeExt) * num_total, __func__);
-
- /* loop through all the edges and fill the edges/indices structure */
- BM_ITER_MESH (e, &e_iter, bm, BM_EDGES_OF_MESH) {
- e_ext[i].e = e;
- if (BMO_elem_flag_test(bm, e, EDGE_MARK)) {
- indices[idx] = i;
- idx++;
- }
- i++;
- }
-
- /* save us some computation time by doing heavy computation once */
- if (type == SIMEDGE_LENGTH || type == SIMEDGE_FACE || type == SIMEDGE_DIR || type == SIMEDGE_FACE_ANGLE) {
- for (i = 0; i < num_total; i++) {
- switch (type) {
- case SIMEDGE_LENGTH: /* compute the length of the edge */
- e_ext[i].length = len_v3v3(e_ext[i].e->v1->co, e_ext[i].e->v2->co);
- break;
-
- case SIMEDGE_DIR: /* compute the direction */
- sub_v3_v3v3(e_ext[i].dir, e_ext[i].e->v1->co, e_ext[i].e->v2->co);
- normalize_v3(e_ext[i].dir);
- break;
-
- case SIMEDGE_FACE: /* count the faces around the edge */
- e_ext[i].faces = BM_edge_face_count(e_ext[i].e);
- break;
-
- case SIMEDGE_FACE_ANGLE:
- e_ext[i].faces = BM_edge_face_count(e_ext[i].e);
- if (e_ext[i].faces == 2)
- e_ext[i].angle = BM_edge_calc_face_angle(e_ext[i].e);
- break;
- }
- }
- }
-
- /* select the edges if any */
- for (i = 0; i < num_total; i++) {
- e = e_ext[i].e;
- if (!BMO_elem_flag_test(bm, e, EDGE_MARK) && !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- int cont = TRUE;
- for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
- es = e_ext[indices[idx]].e;
- switch (type) {
- case SIMEDGE_LENGTH:
- if (fabsf(e_ext[i].length - e_ext[indices[idx]].length) <= thresh) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMEDGE_DIR:
- /* compute the angle between the two edges */
- angle = angle_normalized_v3v3(e_ext[i].dir, e_ext[indices[idx]].dir);
-
- if (angle > (float)(M_PI / 2.0)) /* use the smallest angle between the edges */
- angle = fabsf(angle - (float)M_PI);
-
- if (angle / (float)(M_PI / 2.0) <= thresh) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMEDGE_FACE:
- if (e_ext[i].faces == e_ext[indices[idx]].faces) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMEDGE_FACE_ANGLE:
- if (e_ext[i].faces == 2) {
- if (e_ext[indices[idx]].faces == 2) {
- if (fabsf(e_ext[i].angle - e_ext[indices[idx]].angle) <= thresh) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- }
- }
- else {
- cont = FALSE;
- }
- break;
-
- case SIMEDGE_CREASE:
- {
- float *c1, *c2;
-
- c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE);
- c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_CREASE);
-
- if (fabsf(*c1 - *c2) <= thresh) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- }
- break;
-
- case SIMEDGE_BEVEL:
- {
- float *c1, *c2;
-
- c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT);
- c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_BWEIGHT);
-
- if (fabsf(*c1 - *c2) <= thresh) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- }
- break;
-
- case SIMEDGE_SEAM:
- if (BM_elem_flag_test(e, BM_ELEM_SEAM) == BM_elem_flag_test(es, BM_ELEM_SEAM)) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMEDGE_SHARP:
- if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == BM_elem_flag_test(es, BM_ELEM_SMOOTH)) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMEDGE_FREESTYLE:
- if (BM_elem_flag_test(e, BM_ELEM_FREESTYLE) == BM_elem_flag_test(es, BM_ELEM_FREESTYLE)) {
- BMO_elem_flag_enable(bm, e, EDGE_MARK);
- cont = 0;
- }
- break;
- }
- }
- }
- }
-
- MEM_freeN(e_ext);
- MEM_freeN(indices);
-
- /* transfer all marked edges to the output slot */
- BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_MARK);
-}
-
-/**************************************************************************** *
- * Similar Vertices
- **************************************************************************** */
-#define VERT_MARK 1
-
-typedef struct SimSel_VertExt {
- BMVert *v;
- union {
- int num_faces; /* adjacent faces */
- int num_edges; /* adjacent edges */
- MDeformVert *dvert; /* deform vertex */
- };
-} SimSel_VertExt;
-
-/*
- * select similar vertices: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
- * choices are normal, face, vertex group...
- */
-void bmo_similar_verts_exec(BMesh *bm, BMOperator *op)
-{
- BMOIter vs_iter; /* selected verts iterator */
- BMIter v_iter; /* mesh verts iterator */
- BMVert *vs; /* selected vertex */
- BMVert *v; /* mesh vertex */
- SimSel_VertExt *v_ext = NULL;
- int *indices = NULL;
- int num_total = 0, num_sels = 0, i = 0, idx = 0;
- int type = BMO_slot_int_get(op, "type");
- const float thresh = BMO_slot_float_get(op, "thresh");
- const float thresh_radians = thresh * (float)M_PI;
-
- num_total = BM_mesh_elem_count(bm, BM_VERT);
-
- /* iterate through all selected edges and mark them */
- BMO_ITER (vs, &vs_iter, bm, op, "verts", BM_VERT) {
- BMO_elem_flag_enable(bm, vs, VERT_MARK);
- num_sels++;
- }
-
- /* allocate memory for the selected vertices indices and for all temporary vertices */
- indices = (int *)MEM_mallocN(sizeof(int) * num_sels, "vertex indices");
- v_ext = (SimSel_VertExt *)MEM_mallocN(sizeof(SimSel_VertExt) * num_total, "vertex extra");
-
- /* loop through all the vertices and fill the vertices/indices structure */
- BM_ITER_MESH (v, &v_iter, bm, BM_VERTS_OF_MESH) {
- v_ext[i].v = v;
- if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
- indices[idx] = i;
- idx++;
- }
-
- switch (type) {
- case SIMVERT_FACE:
- /* calling BM_vert_face_count every time is time consumming, so call it only once per vertex */
- v_ext[i].num_faces = BM_vert_face_count(v);
- break;
-
- case SIMVERT_VGROUP:
- if (CustomData_has_layer(&(bm->vdata), CD_MDEFORMVERT)) {
- v_ext[i].dvert = CustomData_bmesh_get(&bm->vdata, v_ext[i].v->head.data, CD_MDEFORMVERT);
- }
- else {
- v_ext[i].dvert = NULL;
- }
- break;
- case SIMVERT_EDGE:
- v_ext[i].num_edges = BM_vert_edge_count(v);
- break;
- }
-
- i++;
- }
-
- /* select the vertices if any */
- for (i = 0; i < num_total; i++) {
- v = v_ext[i].v;
- if (!BMO_elem_flag_test(bm, v, VERT_MARK) && !BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- int cont = TRUE;
- for (idx = 0; idx < num_sels && cont == TRUE; idx++) {
- vs = v_ext[indices[idx]].v;
- switch (type) {
- case SIMVERT_NORMAL:
- /* compare the angle between the normals */
- if (angle_normalized_v3v3(v->no, vs->no) <= thresh_radians) {
- BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
- }
- break;
- case SIMVERT_FACE:
- /* number of adjacent faces */
- if (v_ext[i].num_faces == v_ext[indices[idx]].num_faces) {
- BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
- }
- break;
-
- case SIMVERT_VGROUP:
- if (v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL) {
- int v1, v2;
- for (v1 = 0; v1 < v_ext[i].dvert->totweight && cont == 1; v1++) {
- for (v2 = 0; v2 < v_ext[indices[idx]].dvert->totweight; v2++) {
- if (v_ext[i].dvert->dw[v1].def_nr == v_ext[indices[idx]].dvert->dw[v2].def_nr) {
- BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
- break;
- }
- }
- }
- }
- break;
- case SIMVERT_EDGE:
- /* number of adjacent edges */
- if (v_ext[i].num_edges == v_ext[indices[idx]].num_edges) {
- BMO_elem_flag_enable(bm, v, VERT_MARK);
- cont = FALSE;
- }
- break;
- }
- }
- }
- }
-
- MEM_freeN(indices);
- MEM_freeN(v_ext);
-
- BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK);
-}
-
/**************************************************************************** *
* Cycle UVs for a face
**************************************************************************** */
@@ -1245,6 +697,8 @@ typedef struct ElemNode {
HeapNode *hn; /* heap node */
} ElemNode;
+#define VERT_MARK 1
+
void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
{
BMOIter vs_iter /* , vs2_iter */; /* selected verts iterator */
@@ -1256,7 +710,7 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
ElemNode *vert_list = NULL;
int num_total = 0 /*, num_sels = 0 */, i = 0;
- int type = BMO_slot_int_get(op, "type");
+ const int type = BMO_slot_int_get(op, "type");
BMO_ITER (vs, &vs_iter, bm, op, "startv", BM_VERT) {
sv = vs;