[Bf-blender-cvs] [cf811e7828d] soc-2017-normal-tools: Cached lnorspace array and added dirty Mechanic
RohanRathi
noreply at git.blender.org
Thu Jun 1 07:34:14 CEST 2017
Commit: cf811e7828d75d9e4b4e83869e60a0069010f68f
Author: RohanRathi
Date: Thu Jun 1 11:00:56 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rBcf811e7828d75d9e4b4e83869e60a0069010f68f
Cached lnorspace array and added dirty Mechanic
===================================================================
M source/blender/blenkernel/intern/editderivedmesh.c
M source/blender/bmesh/bmesh_class.h
M source/blender/bmesh/intern/bmesh_mesh.c
M source/blender/bmesh/intern/bmesh_mesh.h
M source/blender/bmesh/intern/bmesh_opdefines.c
M source/blender/bmesh/intern/bmesh_operator_api.h
M source/blender/editors/mesh/editmesh_tools.c
===================================================================
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 5591ee2a0d4..47987567349 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -210,7 +210,7 @@ static void emDM_calcLoopNormalsSpaceArray(
cd_loop_clnors_offset = clnors_data ? -1 : CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos,
- r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
+ r_lnors_spacearr, clnors_data, cd_loop_clnors_offset, false);
#ifdef DEBUG_CLNORS
if (r_lnors_spacearr) {
int i;
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 64a5cad812a..2613759ac9a 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -20,6 +20,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include "BKE_mesh.h"
+
#ifndef __BMESH_CLASS_H__
#define __BMESH_CLASS_H__
@@ -253,6 +255,9 @@ typedef struct BMesh {
ListBase errorstack;
void *py_handle;
+
+ MLoopNorSpaceArray bmspacearr; /* Stores MLoopNorSpaceArray for this BMesh */
+ char spacearr_dirty;
} BMesh;
/* BMHeader->htype (char) */
@@ -266,6 +271,9 @@ enum {
#define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
#define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
+#define BM_SPACEARR_DIRTY (1 << 1)
+#define BM_SPACEARR_DIRTY_ALL (1 << 2)
+
/* args for _Generic */
#define _BM_GENERIC_TYPE_ELEM_NONCONST \
void *, BMVert *, BMEdge *, BMLoop *, BMFace *, \
@@ -345,6 +353,9 @@ enum {
* since tools may want to tag verts and
* not have functions clobber them */
BM_ELEM_INTERNAL_TAG = (1 << 7),
+
+ /* Space invalid when set */
+ BM_ELEM_LNORSPACE = (1 << 6)
};
struct BPy_BMGeneric;
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index d5d9e4abe2c..ef22c22c3b1 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -589,7 +589,7 @@ static bool bm_mesh_loop_check_cyclic_smooth_fan(BMLoop *l_curr)
* Will use first clnors_data array, and fallback to cd_loop_clnors_offset (use NULL and -1 to not use clnors). */
static void bm_mesh_loops_calc_normals(
BMesh *bm, const float (*vcos)[3], const float (*fnos)[3], float (*r_lnos)[3],
- MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset)
+ MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset, bool rebuild)
{
BMIter fiter;
BMFace *f_curr;
@@ -645,6 +645,9 @@ static void bm_mesh_loops_calc_normals(
l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
do {
+ if (rebuild && !BM_elem_flag_test(l_curr, BM_ELEM_LNORSPACE) && !(bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL))
+ continue;
+
/* A smooth edge, we have to check for cyclic smooth fan case.
* If we find a new, never-processed cyclic smooth fan, we can do it now using that loop/edge as
* 'entry point', otherwise we can skip it. */
@@ -960,7 +963,7 @@ void BM_mesh_loop_normals_update(
void BM_loops_calc_normal_vcos(
BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*fnos)[3],
const bool use_split_normals, const float split_angle, float (*r_lnos)[3],
- MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset)
+ MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset, bool rebuild)
{
const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
@@ -970,7 +973,7 @@ void BM_loops_calc_normal_vcos(
bm_mesh_edges_sharp_tag(bm, vnos, fnos, has_clnors ? (float)M_PI : split_angle, r_lnos);
/* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
- bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
+ bm_mesh_loops_calc_normals(bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset, rebuild);
}
else {
BLI_assert(!r_lnors_spacearr);
@@ -978,6 +981,103 @@ void BM_loops_calc_normal_vcos(
}
}
+void BM_lnorspacearr_store(BMesh *bm, float (*r_lnors)[3])
+{
+ if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) {
+ BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL);
+ }
+
+ int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, M_PI, r_lnors, &bm->bmspacearr, NULL, cd_loop_clnors_offset, false);
+}
+
+/* will change later */
+#define CLEAR_SPACEARRAY_THRESHOLD(x) x/2
+
+void BM_lnorspace_invalidate(BMesh *bm, bool inval_all)
+{
+ if (inval_all || bm->totvertsel > CLEAR_SPACEARRAY_THRESHOLD(bm->totvert)) {
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ return;
+ }
+ BMVert *v;
+ BMIter viter, fiter, liter;
+ BLI_bitmap *faces = BLI_BITMAP_NEW(bm->totface, __func__);
+
+ if (bm->elem_index_dirty & BM_FACE) {
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+ }
+
+ BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+
+ BMFace *f;
+ BM_ITER_ELEM(f, &fiter, v, BM_FACES_OF_VERT) {
+ if (!BLI_BITMAP_TEST(faces, BM_elem_index_get(f))) {
+
+ BMLoop *l;
+ BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
+ BM_elem_flag_enable(l, BM_ELEM_LNORSPACE);
+ }
+ BLI_BITMAP_ENABLE(faces, BM_elem_index_get(f));
+ }
+ }
+ }
+ }
+}
+
+void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor)
+{
+ if (!(bm->spacearr_dirty & (BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL))) {
+ return;
+ }
+ BMFace *f;
+ BMLoop *l;
+ BMIter fiter, liter;
+
+ float(*r_lnors)[3] = MEM_callocN(sizeof(*r_lnors) * bm->totloop, "__func__");
+ float(*oldnors)[3] = MEM_mallocN(sizeof(*oldnors) * bm->totloop, "__func__");
+ int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ if (bm->elem_index_dirty & BM_LOOP) {
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+ }
+
+ if (preserve_clnor) {
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+
+ BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (BM_elem_flag_test(l, BM_ELEM_LNORSPACE))
+ {
+ short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset);
+ int l_index = BM_elem_index_get(l);
+
+ BKE_lnor_space_custom_data_to_normal(bm->bmspacearr.lspacearr[l_index], *clnor, oldnors[l_index]);
+ }
+ }
+ }
+ }
+ BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, M_PI, r_lnors, &bm->bmspacearr, NULL, cd_loop_clnors_offset, true);
+ MEM_freeN(r_lnors);
+
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
+
+ if (BM_elem_flag_test(l, BM_ELEM_LNORSPACE)) {
+ if (preserve_clnor) {
+ short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset);
+ int l_index = BM_elem_index_get(l);
+ BKE_lnor_space_custom_normal_to_data(bm->bmspacearr.lspacearr[l_index], oldnors[l_index], *clnor);
+ }
+ BM_elem_flag_disable(l, BM_ELEM_LNORSPACE);
+ }
+ }
+ }
+ MEM_freeN(oldnors);
+ bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL);
+}
+
static void UNUSED_FUNCTION(bm_mdisps_space_set)(Object *ob, BMesh *bm, int from, int to)
{
/* switch multires data out of tangent space */
@@ -1094,6 +1194,9 @@ void bmesh_edit_end(BMesh *bm, BMOpTypeFlag type_flag)
if ((type_flag & BMO_OPTYPE_FLAG_SELECT_VALIDATE) == 0) {
bm->selected = select_history;
}
+ if (type_flag & BMO_OPTYPE_FLAG_INVALIDATE_NORMAL_SPACE) {
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY;
+ }
}
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 01f11f6f942..bf1a24d9ce4 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -50,7 +50,11 @@ void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*
void BM_loops_calc_normal_vcos(
BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*pnos)[3],
const bool use_split_normals, const float split_angle, float (*r_lnos)[3],
- struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset);
+ struct MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset,
+ bool rebuild);
+void BM_lnorspacearr_store(BMesh *bm, float (*r_lnors)[3]);
+void BM_lnorspace_invalidate(BMesh *bm, bool inval_all);
+void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor);
void bmesh_edit_begin(BMesh *bm, const BMOpTypeFlag type_flag);
void bmesh_edit_end(BMesh *bm, const BMOpTypeFlag type_flag);
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index d2f0fc1721c..3d78ef0dd40 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -116,7 +116,8 @@ static BMOpDefine bmo_smooth_vert_def = {
},
{{{'\0'}}}, /* no output */
bmo_smooth_vert_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_INVALIDATE_NORMAL_SPACE),
};
/*
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 30cd1df9c4e..e894d81220e 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -244,6 +244,7 @@ typedef enum {
BMO_OPTYPE_FLAG_NORMALS_CALC = (1 << 1),
BMO_OPTYPE_FLAG_SELECT_FLUSH = (1 << 2),
BMO_OPTYPE_FLAG_SELECT_VALIDATE = (1 << 3),
+ BMO_OPTYPE_FLAG_INVALIDATE_NORMAL_SPACE = (1 << 4)
} BMOpTypeFlag;
typedef struct BMOperator {
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 1f90b60a1f5..c6a0dfd129d 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list