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:
authorCampbell Barton <ideasman42@gmail.com>2015-11-03 09:38:47 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-11-03 09:46:09 +0300
commit77e223ddd5ab69b94f04c34f596b0378f707508c (patch)
treed6b22e3f5061d1bcaf7306f80be641cc800984fd /source/blender/bmesh/intern/bmesh_polygon.c
parentac7abb55d7c8ff0aed19c022e5cb519d93d8ae47 (diff)
BMesh: inline vert-loop iteration for normal calc
Calculating normals is called often (sculpting for eg), so avoid using high-level iterator here.
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_polygon.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c127
1 files changed, 80 insertions, 47 deletions
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 2b2c62e274a..1aa2717d03b 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -421,32 +421,42 @@ void BM_edge_normals_update(BMEdge *e)
BM_vert_normal_update(e->v2);
}
-bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3])
+static void bm_loop_normal_accum(const BMLoop *l, float no[3])
{
- /* TODO, we can normalize each edge only once, then compare with previous edge */
+ float vec1[3], vec2[3], fac;
- BMIter liter;
- BMLoop *l;
- int len = 0;
-
- zero_v3(r_no);
+ /* Same calculation used in BM_mesh_normals_update */
+ sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
+ sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
+ normalize_v3(vec1);
+ normalize_v3(vec2);
- BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- if (BM_elem_flag_test(l->f, hflag)) {
- float vec1[3], vec2[3], fac;
+ fac = saacos(-dot_v3v3(vec1, vec2));
- /* Same calculation used in BM_mesh_normals_update */
- sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
- sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
- normalize_v3(vec1);
- normalize_v3(vec2);
+ madd_v3_v3fl(no, l->f->no, fac);
+}
- fac = saacos(-dot_v3v3(vec1, vec2));
+bool BM_vert_calc_normal_ex(const BMVert *v, const char hflag, float r_no[3])
+{
+ int len = 0;
- madd_v3_v3fl(r_no, l->f->no, fac);
+ zero_v3(r_no);
- len++;
- }
+ if (v->e) {
+ const BMEdge *e = v->e;
+ do {
+ if (e->l) {
+ const BMLoop *l = e->l;
+ do {
+ if (l->v == v) {
+ if (BM_elem_flag_test(l->f, hflag)) {
+ bm_loop_normal_accum(l, r_no);
+ len++;
+ }
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
}
if (len) {
@@ -458,50 +468,73 @@ bool BM_vert_normal_update_ex(BMVert *v, const char hflag, float r_no[3])
}
}
-/**
- * update a vert normal (but not the faces incident on it)
- */
-void BM_vert_normal_update(BMVert *v)
+bool BM_vert_calc_normal(const BMVert *v, float r_no[3])
{
- /* TODO, we can normalize each edge only once, then compare with previous edge */
-
- BMIter liter;
- BMLoop *l;
int len = 0;
- zero_v3(v->no);
+ zero_v3(r_no);
- BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- float vec1[3], vec2[3], fac;
+ if (v->e) {
+ const BMEdge *e = v->e;
+ do {
+ if (e->l) {
+ const BMLoop *l = e->l;
+ do {
+ if (l->v == v) {
+ bm_loop_normal_accum(l, r_no);
+ len++;
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
+ }
- /* Same calculation used in BM_mesh_normals_update */
- sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
- sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
- normalize_v3(vec1);
- normalize_v3(vec2);
+ if (len) {
+ normalize_v3(r_no);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
- fac = saacos(-dot_v3v3(vec1, vec2));
+void BM_vert_normal_update_all(BMVert *v)
+{
+ int len = 0;
- madd_v3_v3fl(v->no, l->f->no, fac);
+ zero_v3(v->no);
- len++;
+ if (v->e) {
+ const BMEdge *e = v->e;
+ do {
+ if (e->l) {
+ const BMLoop *l = e->l;
+ do {
+ if (l->v == v) {
+ BM_face_normal_update(l->f);
+ bm_loop_normal_accum(l, v->no);
+ len++;
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
}
if (len) {
normalize_v3(v->no);
+ return true;
+ }
+ else {
+ return false;
}
}
-void BM_vert_normal_update_all(BMVert *v)
+/**
+ * update a vert normal (but not the faces incident on it)
+ */
+void BM_vert_normal_update(BMVert *v)
{
- BMIter iter;
- BMFace *f;
-
- BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
- BM_face_normal_update(f);
- }
-
- BM_vert_normal_update(v);
+ BM_vert_calc_normal(v, v->no);
}
/**