diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-07-22 20:49:37 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-07-22 20:49:37 +0400 |
commit | 90fdaa82195c2eb9b6412ffa8b4f4f70e16a35dc (patch) | |
tree | 189bcebbbd82c301f2a1ee4be9f6406fc9bf54f1 /source | |
parent | be7004237c2143ddf1811c2e4ba20e6f2eb1c7f8 (diff) |
optimization: lazy initialize EditDerivedBMesh members vertexNos, polyNos.
also add polyCos array which cache's face centers, gives overall ~20% speedup to drawing on a high-poly mesh in face-editmode.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/editderivedmesh.c | 289 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 60 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.h | 6 |
3 files changed, 235 insertions, 120 deletions
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index ddd5e4a1e02..9f873cafa55 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -69,11 +69,121 @@ typedef struct EditDerivedBMesh { BMEditMesh *em; - float (*vertexCos)[3]; - float (*vertexNos)[3]; - float (*polyNos)[3]; + /** when set, \a vertexNos, polyNos are lazy initialized */ + const float (*vertexCos)[3]; + + /** lazy initialize (when \a vertexCos is set) */ + float const (*vertexNos)[3]; + float const (*polyNos)[3]; + /** also lazy init but dont depend on \a vertexCos */ + const float (*polyCos)[3]; } EditDerivedBMesh; +/* -------------------------------------------------------------------- */ +/* Lazy initialize datastructures */ + +static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm); + +static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm) +{ + + if (bmdm->vertexCos && (bmdm->vertexNos == NULL)) { + + BMesh *bm = bmdm->em->bm; + const float (*vertexCos)[3], (*polyNos)[3]; + float (*vertexNos)[3]; + + BMFace *efa; + BMVert *eve; + BMIter fiter; + BMIter viter; + int i; + + vertexCos = bmdm->vertexCos; + vertexNos = MEM_callocN(sizeof(*vertexNos) * bm->totvert, __func__); + + /* calculate vertex normals from poly normals */ + emDM_ensurePolyNormals(bmdm); + + BM_mesh_elem_index_ensure(bm, BM_FACE); + + vertexCos = bmdm->vertexCos; + polyNos = bmdm->polyNos; + + BM_ITER_MESH_INDEX (eve, &viter, bm, BM_VERTS_OF_MESH, i) { + float *no = vertexNos[i]; + BM_ITER_ELEM (efa, &fiter, eve, BM_FACES_OF_VERT) { + add_v3_v3(no, polyNos[BM_elem_index_get(efa)]); + } + + /* following Mesh convention; we use vertex coordinate itself + * for normal in this case */ + if (UNLIKELY(normalize_v3(no) == 0.0f)) { + normalize_v3_v3(no, vertexCos[i]); + } + } + + bmdm->vertexNos = (const float (*)[3])vertexNos; + } +} + +static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm) +{ + if (bmdm->vertexCos && (bmdm->polyNos == NULL)) { + BMesh *bm = bmdm->em->bm; + const float (*vertexCos)[3]; + float (*polyNos)[3]; + + BMFace *efa; + BMIter fiter; + int i; + + BM_mesh_elem_index_ensure(bm, BM_VERT); + + polyNos = MEM_mallocN(sizeof(*polyNos) * bm->totface, __func__); + + vertexCos = bmdm->vertexCos; + + BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { + BM_elem_index_set(efa, i); /* set_inline */ + BM_face_calc_normal_vcos(bm, efa, polyNos[i], vertexCos); + } + bm->elem_index_dirty &= ~BM_FACE; + + bmdm->polyNos = (const float (*)[3])polyNos; + } +} + +static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm) +{ + if (bmdm->polyCos == NULL) { + BMesh *bm = bmdm->em->bm; + float (*polyCos)[3]; + + BMFace *efa; + BMIter fiter; + int i; + + polyCos = MEM_mallocN(sizeof(*polyCos) * bm->totface, __func__); + + if (bmdm->vertexCos) { + const float (*vertexCos)[3]; + vertexCos = bmdm->vertexCos; + + BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { + BM_face_calc_center_mean_vcos(bm, efa, polyCos[i], vertexCos); + } + } + else { + BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { + BM_face_calc_center_mean(efa, polyCos[i]); + } + } + + bmdm->polyCos = (const float (*)[3])polyCos; + } +} + static void emDM_calcNormals(DerivedMesh *dm) { /* Nothing to do: normals are already calculated and stored on the @@ -97,6 +207,7 @@ static void emDM_foreachMappedVert(DerivedMesh *dm, int i; if (bmdm->vertexCos) { + emDM_ensureVertNormals(bmdm); BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL); } @@ -248,56 +359,25 @@ static void emDM_drawUVEdges(DerivedMesh *dm) glEnd(); } -static void emDM__calcFaceCent(BMFace *efa, float cent[3], float (*vertexCos)[3]) -{ - BMIter liter; - BMLoop *l; - int tot = 0; - - zero_v3(cent); - - /*simple (and stupid) median (average) based method :/ */ - - if (vertexCos) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - add_v3_v3(cent, vertexCos[BM_elem_index_get(l->v)]); - tot++; - } - } - else { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - add_v3_v3(cent, l->v->co); - tot++; - } - } - - if (tot == 0) return; - mul_v3_fl(cent, 1.0f / (float)tot); -} - static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no[3]), void *userData) { EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; BMesh *bm = bmdm->em->bm; - float (*polyNos)[3] = NULL; + const float (*polyNos)[3]; + const float (*polyCos)[3]; BMFace *efa; BMIter iter; - float cent[3]; int i; - /* ensure for face center calculation */ - if (bmdm->vertexCos) { - BM_mesh_elem_index_ensure(bm, BM_VERT); - polyNos = bmdm->polyNos; - - BLI_assert(polyNos != NULL); - } + emDM_ensurePolyNormals(bmdm); + emDM_ensurePolyCenters(bmdm); + polyNos = bmdm->polyNos; /* maybe NULL */ + polyCos = bmdm->polyCos; /* always set */ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - emDM__calcFaceCent(efa, cent, bmdm->vertexCos); - func(userData, i, cent, polyNos ? polyNos[i] : efa->no); + func(userData, i, polyCos[i], polyNos ? polyNos[i] : efa->no); } } @@ -349,10 +429,14 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, if (bmdm->vertexCos) { /* add direct access */ - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; - // int *triPolyMap = bmdm->triPolyMap; + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; + + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); @@ -561,9 +645,6 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, BMEditMesh *em = bmdm->em; BMesh *bm = em->bm; struct BMLoop *(*looptris)[3] = em->looptris; - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; BMFace *efa; MLoopUV *luv[3], dummyluv = {{0}}; MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */; @@ -593,7 +674,17 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm, BM_mesh_elem_index_ensure(bm, BM_VERT); } - if (vertexCos) { + if (bmdm->vertexCos) { + /* add direct access */ + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; + + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; + BM_mesh_elem_index_ensure(bm, BM_VERT); for (i = 0; i < em->tottri; i++) { @@ -791,9 +882,11 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, BMEditMesh *em = bmdm->em; BMesh *bm = em->bm; struct BMLoop *(*looptris)[3] = em->looptris; - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; + /* add direct access */ + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; + BMFace *efa; DMVertexAttribs attribs; GPUVertexAttribs gattribs; @@ -805,6 +898,11 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, memset(&attribs, 0, sizeof(attribs)); + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; + /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); @@ -926,9 +1024,9 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, BMEditMesh *em = bmdm->em; BMesh *bm = em->bm; struct BMLoop *(*looptris)[3] = em->looptris; - float (*vertexCos)[3] = bmdm->vertexCos; - float (*vertexNos)[3] = bmdm->vertexNos; - float (*polyNos)[3] = bmdm->polyNos; + const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexNos)[3]; + const float (*polyNos)[3]; BMFace *efa; DMVertexAttribs attribs = {{{0}}}; GPUVertexAttribs gattribs; @@ -936,6 +1034,12 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm, matnr = -1; + emDM_ensureVertNormals(bmdm); + emDM_ensurePolyNormals(bmdm); + + vertexNos = bmdm->vertexNos; + polyNos = bmdm->polyNos; + /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); @@ -1139,7 +1243,9 @@ static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3]) return; } - if (bmdm->vertexNos) { + + if (bmdm->vertexCos) { + emDM_ensureVertNormals(bmdm); copy_v3_v3(r_no, bmdm->vertexNos[index]); } else { @@ -1159,7 +1265,8 @@ static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3]) return; } - if (bmdm->polyNos) { + if (bmdm->vertexCos) { + emDM_ensurePolyNormals(bmdm); copy_v3_v3(r_no, bmdm->polyNos[index]); } else { @@ -1439,8 +1546,16 @@ static void emDM_release(DerivedMesh *dm) if (DM_release(dm)) { if (bmdm->vertexCos) { MEM_freeN(bmdm->vertexCos); - MEM_freeN(bmdm->vertexNos); - MEM_freeN(bmdm->polyNos); + if (bmdm->vertexNos) { + MEM_freeN(bmdm->vertexNos); + } + if (bmdm->polyNos) { + MEM_freeN(bmdm->polyNos); + } + } + + if (bmdm->polyCos) { + MEM_freeN(bmdm->polyCos); } MEM_freeN(bmdm); @@ -1549,7 +1664,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, bmdm->dm.release = emDM_release; - bmdm->vertexCos = vertexCos; + bmdm->vertexCos = (const float (*)[3])vertexCos; bmdm->dm.deformedOnly = (vertexCos != NULL); if (cd_dvert_offset != -1) { @@ -1578,38 +1693,6 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, } } - if (vertexCos) { - BMFace *efa; - BMVert *eve; - BMIter fiter; - BMIter viter; - int i; - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos) * bm->totvert, "bmdm_vno"); - bmdm->polyNos = MEM_mallocN(sizeof(*bmdm->polyNos) * bm->totface, "bmdm_pno"); - - BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { - BM_elem_index_set(efa, i); /* set_inline */ - BM_face_normal_update_vcos(bm, efa, bmdm->polyNos[i], (float const (*)[3])vertexCos); - } - bm->elem_index_dirty &= ~BM_FACE; - - BM_ITER_MESH_INDEX (eve, &viter, bm, BM_VERTS_OF_MESH, i) { - float *no = bmdm->vertexNos[i]; - BM_ITER_ELEM (efa, &fiter, eve, BM_FACES_OF_VERT) { - add_v3_v3(no, bmdm->polyNos[BM_elem_index_get(efa)]); - } - - /* following Mesh convention; we use vertex coordinate itself - * for normal in this case */ - if (UNLIKELY(normalize_v3(no) == 0.0f)) { - normalize_v3_v3(no, vertexCos[i]); - } - } - } - return (DerivedMesh *)bmdm; } @@ -1877,7 +1960,7 @@ static void statvis_calc_intersect( static void statvis_calc_distort( BMEditMesh *em, - const float (*vertexCos)[3], + const float (*vertexCos)[3], const float (*polyNos)[3], /* values for calculating */ const float min, const float max, /* result */ @@ -1886,7 +1969,7 @@ static void statvis_calc_distort( BMIter iter; BMesh *bm = em->bm; BMFace *f; - float f_no[3]; + const float *f_no; int index; const float minmax_irange = 1.0f / (max - min); @@ -1903,10 +1986,10 @@ static void statvis_calc_distort( else { BMLoop *l_iter, *l_first; if (vertexCos) { - BM_face_normal_update_vcos(bm, f, f_no, vertexCos); + f_no = polyNos[index]; } else { - copy_v3_v3(f_no, f->no); + f_no = f->no; } fac = 0.0f; @@ -2006,7 +2089,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, { BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_overhang( - em, bmdm ? (const float (*)[3])bmdm->polyNos : NULL, + em, bmdm ? bmdm->polyNos : NULL, statvis->overhang_min / (float)M_PI, statvis->overhang_max / (float)M_PI, statvis->overhang_axis, @@ -2018,7 +2101,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, const float scale = 1.0f / mat4_to_scale(em->ob->obmat); BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_thickness( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, statvis->thickness_min * scale, statvis->thickness_max * scale, statvis->thickness_samples, @@ -2029,15 +2112,19 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, { BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_intersect( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, em->derivedFaceColor); break; } case SCE_STATVIS_DISTORT: { BKE_editmesh_color_ensure(em, BM_FACE); + + if (bmdm) + emDM_ensurePolyNormals(bmdm); + statvis_calc_distort( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, bmdm ? bmdm->polyNos : NULL, statvis->distort_min, statvis->distort_max, em->derivedFaceColor); @@ -2047,7 +2134,7 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm, { BKE_editmesh_color_ensure(em, BM_VERT); statvis_calc_sharp( - em, bmdm ? (const float (*)[3])bmdm->vertexCos : NULL, + em, bmdm ? bmdm->vertexCos : NULL, statvis->sharp_min, statvis->sharp_max, /* in this case they are vertex colors */ diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 88186df89fb..1ecb3c2b9ac 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -125,7 +125,7 @@ static void bm_face_calc_poly_normal(BMFace *f, float n[3]) * Same as #calc_poly_normal and #bm_face_calc_poly_normal * but takes an array of vertex locations. */ -static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3], +static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float r_no[3], float const (*vertexCos)[3]) { BMLoop *l_first = BM_FACE_FIRST_LOOP(f); @@ -133,23 +133,41 @@ static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3], float const *v_prev = vertexCos[BM_elem_index_get(l_first->prev->v)]; float const *v_curr = vertexCos[BM_elem_index_get(l_first->v)]; - zero_v3(n); + zero_v3(r_no); /* Newell's Method */ do { - add_newell_cross_v3_v3v3(n, v_prev, v_curr); + add_newell_cross_v3_v3v3(r_no, v_prev, v_curr); l_iter = l_iter->next; v_prev = v_curr; v_curr = vertexCos[BM_elem_index_get(l_iter->v)]; } while (l_iter != l_first); - if (UNLIKELY(normalize_v3(n) == 0.0f)) { - n[2] = 1.0f; /* other axis set to 0.0 */ + if (UNLIKELY(normalize_v3(r_no) == 0.0f)) { + r_no[2] = 1.0f; /* other axis set to 0.0 */ } } /** + * \brief COMPUTE POLY CENTER (BMFace) + */ +static void bm_face_calc_poly_center_mean_vertex_cos(BMFace *f, float r_cent[3], + float const (*vertexCos)[3]) +{ + BMLoop *l_first = BM_FACE_FIRST_LOOP(f); + BMLoop *l_iter = l_first; + + zero_v3(r_cent); + + /* Newell's Method */ + do { + add_v3_v3(r_cent, vertexCos[BM_elem_index_get(l_iter->v)]); + } while ((l_iter = l_iter->next) != l_first); + mul_v3_fl(r_cent, 1.0f / f->len); +} + +/** * For tools that insist on using triangles, ideally we would cache this data. * * \param r_loops Store face loop pointers, (f->len) @@ -370,8 +388,7 @@ void BM_face_calc_center_bounds(BMFace *f, float r_cent[3]) */ void BM_face_calc_center_mean(BMFace *f, float r_cent[3]) { - BMLoop *l_iter; - BMLoop *l_first; + BMLoop *l_iter, *l_first; zero_v3(r_cent); @@ -379,9 +396,7 @@ void BM_face_calc_center_mean(BMFace *f, float r_cent[3]) do { add_v3_v3(r_cent, l_iter->v->co); } while ((l_iter = l_iter->next) != l_first); - - if (f->len) - mul_v3_fl(r_cent, 1.0f / (float) f->len); + mul_v3_fl(r_cent, 1.0f / (float) f->len); } /** @@ -601,9 +616,9 @@ void BM_face_normal_update(BMFace *f) BM_face_calc_normal(f, f->no); } -/* exact same as 'bmesh_face_normal_update' but accepts vertex coords */ -void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], - float const (*vertexCos)[3]) +/* exact same as 'BM_face_calc_normal' but accepts vertex coords */ +void BM_face_calc_normal_vcos(BMesh *bm, BMFace *f, float r_no[3], + float const (*vertexCos)[3]) { BMLoop *l; @@ -620,7 +635,7 @@ void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], const float *co3 = vertexCos[BM_elem_index_get((l = l->next)->v)]; const float *co4 = vertexCos[BM_elem_index_get((l->next)->v)]; - normal_quad_v3(no, co1, co2, co3, co4); + normal_quad_v3(r_no, co1, co2, co3, co4); break; } case 3: @@ -629,22 +644,33 @@ void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], const float *co2 = vertexCos[BM_elem_index_get((l = l->next)->v)]; const float *co3 = vertexCos[BM_elem_index_get((l->next)->v)]; - normal_tri_v3(no, co1, co2, co3); + normal_tri_v3(r_no, co1, co2, co3); break; } case 0: { - zero_v3(no); + zero_v3(r_no); break; } default: { - bm_face_calc_poly_normal_vertex_cos(f, no, vertexCos); + bm_face_calc_poly_normal_vertex_cos(f, r_no, vertexCos); break; } } } +/* exact same as 'BM_face_calc_normal' but accepts vertex coords */ +void BM_face_calc_center_mean_vcos(BMesh *bm, BMFace *f, float r_cent[3], + float const (*vertexCos)[3]) +{ + /* must have valid index data */ + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + (void)bm; + + bm_face_calc_poly_center_mean_vertex_cos(f, r_cent, vertexCos); +} + /** * \brief Face Flip Normal * diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 2f6b54b91d3..91fe94f8e48 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -34,16 +34,18 @@ int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*r_index)[3]) #endif ; void BM_face_calc_normal(BMFace *f, float r_no[3]); +void BM_face_calc_normal_vcos(BMesh *bm, BMFace *f, float r_no[3], + float const (*vertexCos)[3]); float BM_face_calc_area(BMFace *f); float BM_face_calc_perimeter(BMFace *f); void BM_face_calc_plane(BMFace *f, float r_plane[3]); void BM_face_calc_center_bounds(BMFace *f, float center[3]); void BM_face_calc_center_mean(BMFace *f, float center[3]); +void BM_face_calc_center_mean_vcos(BMesh *bm, BMFace *f, float r_cent[3], + float const (*vertexCos)[3]); void BM_face_calc_center_mean_weighted(BMFace *f, float center[3]); void BM_face_normal_update(BMFace *f); -void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3], - float const (*vertexCos)[3]); void BM_edge_normals_update(BMEdge *e); |