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:
authorAntony Riakiotakis <kalast@gmail.com>2014-04-17 20:02:55 +0400
committerAntony Riakiotakis <kalast@gmail.com>2014-04-17 20:03:08 +0400
commit38eef8deee4261f0139d29eb81584131a862bf59 (patch)
treeeabdfc91ed986342d938c1fbcda945e768c5b660
parent0ba3f7647071a7bd7fdf48e0d48a9e7e1ee79a7b (diff)
Refactor to Dyntopo node customdata commit.
Don't use a dedicated node layer but use temporary int layer instead. Works like a charm as long as we are careful resetting the layer when needed (after pbvh clearing and always after bmesh has been filled in undo) Tip by Campbell, thanks!
-rw-r--r--source/blender/blenkernel/BKE_paint.h2
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c3
-rw-r--r--source/blender/blenkernel/intern/customdata.c14
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c33
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c44
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c11
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h8
10 files changed, 71 insertions, 53 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 60c448608d7..df72cb988b1 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -135,6 +135,8 @@ typedef struct SculptSession {
/* BMesh for dynamic topology sculpting */
struct BMesh *bm;
+ int cd_vert_node_offset;
+ int cd_face_node_offset;
bool bm_smooth_shading;
/* Undo/redo log for dynamic topology sculpting */
struct BMLog *bm_log;
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index d29ded67717..c5f82babb6d 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -67,7 +67,7 @@ void BKE_pbvh_build_grids(PBVH *bvh, struct CCGElem **grid_elems,
struct DMGridAdjacency *gridadj, int totgrid,
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
unsigned int **grid_hidden);
-void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, bool smooth_shading, struct BMLog *log);
+void BKE_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, bool smooth_shading, struct BMLog *log, const int cd_vert_node_offset, const int cd_face_node_offset);
void BKE_pbvh_free(PBVH *bvh);
void BKE_pbvh_free_layer_disp(PBVH *bvh);
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 7faeecb87cd..5f38eb610fc 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -269,7 +269,8 @@ static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm,
ob->sculpt->bm_smooth_shading,
- ob->sculpt->bm_log);
+ ob->sculpt->bm_log, ob->sculpt->cd_vert_node_offset,
+ ob->sculpt->cd_face_node_offset);
pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 4a76abc0154..78c88cdfd0f 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1037,17 +1037,6 @@ static void layerDefault_mvert_skin(void *data, int count)
}
}
-static void layerDefault_dyntopo_node(void *data, int count)
-{
- int *indices = data;
- int i;
-
- for (i = 0; i < count; i++) {
- indices[i] = DYNTOPO_NODE_NONE;
- }
-}
-
-
static void layerInterp_mvert_skin(void **sources, const float *weights,
const float *UNUSED(sub_weights),
int count, void *dest)
@@ -1196,8 +1185,6 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(float[4]), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
/* 40: CD_TESSLOOPNORMAL */
{sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL},
- /* 41: CD_DYNTOPO_NODE */
- {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, layerDefault_dyntopo_node},
};
/* note, numbers are from trunk and need updating for bmesh */
@@ -1214,7 +1201,6 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
/* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask",
/* 35-36 */ "CDGridPaintMask", "CDMVertSkin",
/* 37-40 */ "CDFreestyleEdge", "CDFreestyleFace", "CDMLoopTangent", "CDTessLoopNormal",
- /* 41 */ "CDDyntopoNode"
};
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index cca24682f95..d316cbba86b 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -96,8 +96,7 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index, const int cd_ver
}
/* Recursively split the node if it exceeds the leaf_limit */
-static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index,
- const int cd_vert_node_offset, const int cd_face_node_offset)
+static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index)
{
GSet *empty, *other;
GSetIterator gs_iter;
@@ -105,7 +104,8 @@ static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index,
BB cb;
float mid;
int axis, children;
-
+ const int cd_vert_node_offset = bvh->cd_vert_node_offset;
+ const int cd_face_node_offset = bvh->cd_face_node_offset;
n = &bvh->nodes[node_index];
if (BLI_gset_size(n->bm_faces) <= bvh->leaf_limit) {
@@ -210,8 +210,8 @@ static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index,
/* Recurse */
c1 = c2 = NULL;
- pbvh_bmesh_node_split(bvh, prim_bbc, children, cd_vert_node_offset, cd_face_node_offset);
- pbvh_bmesh_node_split(bvh, prim_bbc, children + 1, cd_vert_node_offset, cd_face_node_offset);
+ pbvh_bmesh_node_split(bvh, prim_bbc, children);
+ pbvh_bmesh_node_split(bvh, prim_bbc, children + 1);
/* Array maybe reallocated, update current node pointer */
n = &bvh->nodes[node_index];
@@ -224,7 +224,7 @@ static void pbvh_bmesh_node_split(PBVH *bvh, GHash *prim_bbc, int node_index,
}
/* Recursively split the node if it exceeds the leaf_limit */
-static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index, const int cd_vert_node_offset, const int cd_face_node_offset)
+static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index)
{
GHash *prim_bbc;
GSet *bm_faces;
@@ -260,7 +260,7 @@ static bool pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index, const int cd
BLI_ghash_insert(prim_bbc, f, bbc);
}
- pbvh_bmesh_node_split(bvh, prim_bbc, node_index, cd_vert_node_offset, cd_face_node_offset);
+ pbvh_bmesh_node_split(bvh, prim_bbc, node_index);
BLI_ghash_free(prim_bbc, NULL, NULL);
MEM_freeN(bbc_array);
@@ -1144,16 +1144,16 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
/***************************** Public API *****************************/
/* Build a PBVH from a BMesh */
-void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, bool smooth_shading, BMLog *log)
+void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, bool smooth_shading, BMLog *log,
+ const int cd_vert_node_offset, const int cd_face_node_offset)
{
BMIter iter;
BMFace *f;
PBVHNode *n;
int node_index = 0;
- const int cd_vert_node_offset = CustomData_get_offset(&bm->vdata, CD_DYNTOPO_NODE);
- const int cd_face_node_offset = CustomData_get_offset(&bm->pdata, CD_DYNTOPO_NODE);
-
+ bvh->cd_vert_node_offset = cd_vert_node_offset;
+ bvh->cd_face_node_offset = cd_face_node_offset;
bvh->bm = bm;
BKE_pbvh_bmesh_detail_size_set(bvh, 0.75);
@@ -1178,7 +1178,7 @@ void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, bool smooth_shading, BMLog *log)
/* Recursively split the node until it is under the limit; if no
* splitting occurs then finalize the existing leaf node */
- if (!pbvh_bmesh_node_limit_ensure(bvh, node_index, cd_vert_node_offset, cd_face_node_offset))
+ if (!pbvh_bmesh_node_limit_ensure(bvh, node_index))
pbvh_bmesh_node_finalize(bvh, 0, cd_vert_node_offset, cd_face_node_offset);
}
@@ -1190,8 +1190,8 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
BLI_buffer_declare_static(BMFace *, edge_loops, BLI_BUFFER_NOP, 2);
BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
const int cd_vert_mask_offset = CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK);
- const int cd_vert_node_offset = CustomData_get_offset(&bvh->bm->vdata, CD_DYNTOPO_NODE);
- const int cd_face_node_offset = CustomData_get_offset(&bvh->bm->pdata, CD_DYNTOPO_NODE);
+ const int cd_vert_node_offset = bvh->cd_vert_node_offset;
+ const int cd_face_node_offset = bvh->cd_face_node_offset;
bool modified = false;
int n;
@@ -1312,9 +1312,6 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
{
int i;
- const int cd_vert_node_offset = CustomData_get_offset(&bvh->bm->vdata, CD_DYNTOPO_NODE);
- const int cd_face_node_offset = CustomData_get_offset(&bvh->bm->pdata, CD_DYNTOPO_NODE);
-
for (i = 0; i < bvh->totnode; i++) {
PBVHNode *n = &bvh->nodes[i];
if (n->flag & PBVH_Leaf) {
@@ -1323,7 +1320,7 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *bvh)
/* Recursively split nodes that have gotten too many
* elements */
- pbvh_bmesh_node_limit_ensure(bvh, i, cd_vert_node_offset, cd_face_node_offset);
+ pbvh_bmesh_node_limit_ensure(bvh, i);
}
}
}
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index ef5828e8097..6b3ef8eb5da 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -162,6 +162,8 @@ struct PBVH {
BMesh *bm;
float bm_max_edge_len;
float bm_min_edge_len;
+ int cd_vert_node_offset;
+ int cd_face_node_offset;
struct BMLog *bm_log;
};
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4873587e9f5..dbf99e96053 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -4793,15 +4793,14 @@ void sculpt_pbvh_clear(Object *ob)
BKE_object_free_derived_caches(ob);
}
-void sculpt_dyntopo_node_layers_reset(BMesh *bm)
+void sculpt_dyntopo_node_layers_reset(SculptSession *ss)
{
- /* A bit lame, but for now just recreate the PBVH. The alternative
- * is to store changes to the PBVH in the undo stack. */
BMFace *f;
BMVert *v;
BMIter iter;
- const int cd_vert_node_offset = CustomData_get_offset(&bm->vdata, CD_DYNTOPO_NODE);
- const int cd_face_node_offset = CustomData_get_offset(&bm->pdata, CD_DYNTOPO_NODE);
+ BMesh *bm = ss->bm;
+ int cd_vert_node_offset = ss->cd_vert_node_offset;
+ int cd_face_node_offset = ss->cd_face_node_offset;
/* clear the elements of the node information */
BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -4813,6 +4812,34 @@ void sculpt_dyntopo_node_layers_reset(BMesh *bm)
}
}
+void sculpt_dyntopo_node_layers_add(SculptSession *ss)
+{
+ int cd_node_layer_index;
+
+ char layer_id[] = "_dyntopo_node_id";
+
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT, layer_id);
+ if (cd_node_layer_index == -1) {
+ BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT, layer_id);
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT, layer_id);
+ }
+
+ ss->cd_vert_node_offset = CustomData_get_n_offset(&ss->bm->vdata, CD_PROP_INT, cd_node_layer_index);
+
+ ss->bm->vdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
+
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT, layer_id);
+ if (cd_node_layer_index == -1) {
+ BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT, layer_id);
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT, layer_id);
+ }
+
+ ss->cd_face_node_offset = CustomData_get_n_offset(&ss->bm->pdata, CD_PROP_INT, cd_node_layer_index);
+
+ ss->bm->pdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
+}
+
+
void sculpt_update_after_dynamic_topology_toggle(bContext *C)
{
Scene *scene = CTX_data_scene(C);
@@ -4845,8 +4872,9 @@ void sculpt_dynamic_topology_enable(bContext *C)
BM_mesh_bm_from_me(ss->bm, me, true, true, ob->shapenr);
sculpt_dynamic_topology_triangulate(ss->bm);
BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
- BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_DYNTOPO_NODE);
- BM_data_layer_add(ss->bm, &ss->bm->pdata, CD_DYNTOPO_NODE);
+ sculpt_dyntopo_node_layers_add(ss);
+ /* make sure the data for existing faces are initialized */
+ sculpt_dyntopo_node_layers_reset(ss);
BM_mesh_normals_update(ss->bm);
/* Enable dynamic topology */
@@ -5303,7 +5331,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
/* force rebuild of pbvh for better BB placement */
sculpt_pbvh_clear(ob);
- sculpt_dyntopo_node_layers_reset(ss->bm);
+ sculpt_dyntopo_node_layers_reset(ss);
/* Redraw */
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 79fd388e332..8cf5bf88bcc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -42,13 +42,13 @@
struct bContext;
struct Brush;
-struct BMesh;
struct KeyBlock;
struct Mesh;
struct MultiresModifierData;
struct Object;
struct Scene;
struct Sculpt;
+struct SculptSession;
struct SculptStroke;
struct SculptUndoNode;
@@ -68,7 +68,8 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
/* Dynamic topology */
void sculpt_pbvh_clear(Object *ob);
-void sculpt_dyntopo_node_layers_reset(struct BMesh *bm);
+void sculpt_dyntopo_node_layers_reset(struct SculptSession *ss);
+void sculpt_dyntopo_node_layers_add(struct SculptSession *ss);
void sculpt_update_after_dynamic_topology_toggle(bContext *C);
void sculpt_dynamic_topology_enable(struct bContext *C);
void sculpt_dynamic_topology_disable(struct bContext *C,
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index b0fd7faa70d..39df15bd985 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -301,7 +301,7 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
MEM_freeN(nodes);
}
else {
- sculpt_dyntopo_node_layers_reset(ss->bm);
+ sculpt_dyntopo_node_layers_reset(ss);
sculpt_pbvh_clear(ob);
}
}
@@ -318,8 +318,7 @@ static void sculpt_undo_bmesh_enable(Object *ob,
/* Create empty BMesh and enable logging */
ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
- BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_DYNTOPO_NODE);
- BM_data_layer_add(ss->bm, &ss->bm->pdata, CD_DYNTOPO_NODE);
+ sculpt_dyntopo_node_layers_add(ss);
me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
/* Restore the BMLog using saved entries */
@@ -342,6 +341,9 @@ static void sculpt_undo_bmesh_restore_begin(bContext *C,
/* Restore the mesh from the first log entry */
BM_log_redo(ss->bm, ss->bm_log);
+ /* reset layers for all bmesh data */
+ sculpt_dyntopo_node_layers_reset(ss);
+
unode->applied = true;
}
}
@@ -357,6 +359,9 @@ static void sculpt_undo_bmesh_restore_end(bContext *C,
/* Restore the mesh from the last log entry */
BM_log_undo(ss->bm, ss->bm_log);
+ /* reset layers for all bmesh data */
+ sculpt_dyntopo_node_layers_reset(ss);
+
unode->applied = false;
}
else {
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 4869c9a74f1..70dc43676ac 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -63,10 +63,9 @@ typedef struct CustomDataExternal {
* layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
typedef struct CustomData {
CustomDataLayer *layers; /* CustomDataLayers, ordered by type */
- int typemap[42]; /* runtime only! - maps types to indices of first layer of that type,
+ int typemap[41]; /* runtime only! - maps types to indices of first layer of that type,
* MUST be >= CD_NUMTYPES, but we cant use a define here.
* Correct size is ensured in CustomData_update_typemap assert() */
- int pad;
int totlayer, maxlayer; /* number of layers, size of layers array */
int totsize; /* in editmode, total size of all data layers */
struct BLI_mempool *pool; /* (BMesh Only): Memory pool for allocation of blocks */
@@ -121,8 +120,7 @@ enum {
CD_MLOOPTANGENT = 39,
CD_TESSLOOPNORMAL = 40,
- CD_DYNTOPO_NODE = 41,
- CD_NUMTYPES = 42
+ CD_NUMTYPES = 41
};
/* Bits for CustomDataMask */
@@ -170,8 +168,6 @@ enum {
#define CD_MASK_MLOOPTANGENT (1LL << CD_MLOOPTANGENT)
#define CD_MASK_TESSLOOPNORMAL (1LL << CD_TESSLOOPNORMAL)
-#define CD_MASK_DYNTOPO_NODE (1LL << CD_DYNTOPO_NODE)
-
/* CustomData.flag */
enum {
/* Indicates layer should not be copied by CustomData_from_template or CustomData_copy_data */