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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-05-08 18:58:38 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-05-08 18:58:38 +0400
commit6f20ef6d870464a66ffa108b85c9ace405235f43 (patch)
treef0e712f275338e8b8aab1b6fefe46c2d5e90bc24 /source
parentd7bc2c7f0639d808095d600b534a879daec7b8d7 (diff)
optimize ngon angle calculation in solidify modifier (was doing prev/next vector subtract and normalize for every vertex). now store the previous normalized vector for re-use.
also add BKE_mesh_poly_calc_angles() which is mostly a reference for now.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_mesh.h3
-rw-r--r--source/blender/blenkernel/intern/mesh.c48
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c44
3 files changed, 80 insertions, 15 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 88a92d9028e..bdadce2c7c7 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -304,6 +304,9 @@ void BKE_mesh_loops_to_mface_corners(struct CustomData *fdata, struct CustomData
const int polyindex, const int mf_len,
const int numTex, const int numCol, const int hasPCol, const int hasOrigSpace);
+void BKE_mesh_poly_calc_angles(struct MVert *mvert, struct MLoop *mloop,
+ struct MPoly *mp, float angles[]);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index ecf6fd8e5de..3ccd09257e6 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -3103,3 +3103,51 @@ void BKE_mesh_tessface_clear(Mesh *mesh)
{
mesh_tessface_clear_intern(mesh, TRUE);
}
+
+#if 0 /* slow version of the function below */
+void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop,
+ MPoly *mp, float angles[])
+{
+ MLoop *ml;
+
+ int j;
+ for (j = 0, ml = mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
+ MLoop *ml_prev = ME_POLY_LOOP_PREV(mloop, mp, j);
+ MLoop *ml_next = ME_POLY_LOOP_NEXT(mloop, mp, j);
+
+ float e1[3], e2[3];
+
+ sub_v3_v3v3(e1, mvert[ml_next->v].co, mvert[ml->v].co);
+ sub_v3_v3v3(e2, mvert[ml_prev->v].co, mvert[ml->v].co);
+
+ angles[j] = (float)M_PI - angle_v3v3(e1, e2);
+ }
+}
+
+#else /* equivalent the function above but avoid multiple subtractions + normalize */
+
+void BKE_mesh_poly_calc_angles(MVert *mvert, MLoop *mloop,
+ MPoly *mp, float angles[])
+{
+ MLoop *ml = mloop + mp->loopstart;
+ float nor_prev[3];
+ float nor_next[3];
+
+ int i_this = mp->totloop - 1;
+ int i_next = 0;
+
+ sub_v3_v3v3(nor_prev, mvert[ml[i_this - 1].v].co, mvert[ml[i_this].v].co);
+ normalize_v3(nor_prev);
+
+ while (i_next < mp->totloop) {
+ sub_v3_v3v3(nor_next, mvert[ml[i_this].v].co, mvert[ml[i_next].v].co);
+ normalize_v3(nor_next);
+ angles[i_this] = angle_normalized_v3v3(nor_prev, nor_next);
+
+ /* step */
+ copy_v3_v3(nor_prev, nor_next);
+ i_this = i_next;
+ i_next++;
+ }
+}
+#endif
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index b45304a315f..4ce1a283acf 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -451,7 +451,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* same as EM_solidify() in editmesh_lib.c */
float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */
float *vert_accum = vert_angles + numVerts;
- int j, vidx;
+ int vidx;
face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
if (!face_nors) {
@@ -467,30 +467,44 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
for (i = 0, mp = mpoly; i < numFaces; i++, mp++) {
+ /* #BKE_mesh_poly_calc_angles logic is inlined here */
+ float nor_prev[3];
+ float nor_next[3];
+
+ int i_this = mp->totloop - 1;
+ int i_next = 0;
+
+ ml = &mloop[mp->loopstart];
+
+ /* --- not related to angle calc --- */
if (face_nors_calc)
- mesh_calc_poly_normal(mp, &mloop[mp->loopstart], mvert, face_nors[i]);
-
- /* just added, calc the normal */
- for (j = 0, ml = mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
- MLoop *ml_prev = ME_POLY_LOOP_PREV(mloop, mp, j);
- MLoop *ml_next = ME_POLY_LOOP_NEXT(mloop, mp, j);
+ mesh_calc_poly_normal(mp, ml, mvert, face_nors[i]);
+ /* --- end non-angle-calc section --- */
- float e1[3], e2[3];
+ sub_v3_v3v3(nor_prev, mvert[ml[i_this - 1].v].co, mvert[ml[i_this].v].co);
+ normalize_v3(nor_prev);
+
+ while (i_next < mp->totloop) {
float angle;
+ sub_v3_v3v3(nor_next, mvert[ml[i_this].v].co, mvert[ml[i_next].v].co);
+ normalize_v3(nor_next);
+ angle = angle_normalized_v3v3(nor_prev, nor_next);
- /* TODO - we could speed this up by _not_ normalizing both verts each time
- * and always re-usingthe last vector. */
- sub_v3_v3v3(e1, mvert[ml_next->v].co, mvert[ml->v].co);
- sub_v3_v3v3(e2, mvert[ml_prev->v].co, mvert[ml->v].co);
- angle = (float)M_PI - angle_v3v3(e1, e2);
+ /* --- not related to angle calc --- */
if (angle < FLT_EPSILON) {
angle = FLT_EPSILON;
}
-
- vidx = ml->v;
+ vidx = ml[i_this].v;
vert_accum[vidx] += angle;
vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle;
+ /* --- end non-angle-calc section --- */
+
+
+ /* step */
+ copy_v3_v3(nor_prev, nor_next);
+ i_this = i_next;
+ i_next++;
}
}