Move layer displacements from SculptUndoNode to PBVHNode
authorNicholas Bishop <nicholasbishop@gmail.com>
Sun, 30 Dec 2012 18:26:11 +0000 (18:26 +0000)
committerNicholas Bishop <nicholasbishop@gmail.com>
Sun, 30 Dec 2012 18:26:11 +0000 (18:26 +0000)
* This doesn't make much difference for regular mesh/multires
  sculpting, but for dynamic topology sculpting the undo stack isn't
  split up by PBVH nodes, so it's more convenient to store the layer
  data in PBVH nodes.

* Note that the life cycle of the layer displacement data is
  unchanged -- it's only valid during a stroke with the layer brush,
  gets free'd when the undo step ends.

source/blender/blenkernel/BKE_pbvh.h
source/blender/blenkernel/intern/pbvh.c
source/blender/blenkernel/intern/pbvh_intern.h
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_undo.c

index 302de59396397adf97f1bd336721030f978b9e8b..5b6acdb97528cbda66a578c83a855c88903d364d 100644 (file)
@@ -156,6 +156,14 @@ void BLI_pbvh_grids_update(PBVH *bvh, struct CCGElem **grid_elems,
                            struct DMGridAdjacency *gridadj, void **gridfaces,
                            struct DMFlagMat *flagmats, unsigned int **grid_hidden);
 
+/* Layer displacement */
+
+/* Get the node's displacement layer, creating it if necessary */
+float *BLI_pbvh_node_layer_disp_get(PBVH *pbvh, PBVHNode *node);
+
+/* If the node has a displacement layer, free it and set to null */
+void BLI_pbvh_node_layer_disp_free(PBVHNode *node);
+
 /* vertex deformer */
 float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];
 void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
index 4341e7018102e71a4acf2b76a289c505ce37bfd7..e9009050d4bc6dd5d61fb4a337f4058eba3a3757 100644 (file)
@@ -600,6 +600,7 @@ void BLI_pbvh_free(PBVH *bvh)
                                MEM_freeN(node->vert_indices);
                        if (node->face_vert_indices)
                                MEM_freeN(node->face_vert_indices);
+                       BLI_pbvh_node_layer_disp_free(node);
                }
        }
 
@@ -1611,6 +1612,26 @@ void BLI_pbvh_grids_update(PBVH *bvh, CCGElem **grids, DMGridAdjacency *gridadj,
        }
 }
 
+/* Get the node's displacement layer, creating it if necessary */
+float *BLI_pbvh_node_layer_disp_get(PBVH *bvh, PBVHNode *node)
+{
+       if (!node->layer_disp) {
+               int totvert = 0;
+               BLI_pbvh_node_num_verts(bvh, node, &totvert, NULL);
+               node->layer_disp = MEM_callocN(sizeof(float) * totvert, "layer disp");
+       }
+       return node->layer_disp;
+}
+
+/* If the node has a displacement layer, free it and set to null */
+void BLI_pbvh_node_layer_disp_free(PBVHNode *node)
+{
+       if (node->layer_disp) {
+               MEM_freeN(node->layer_disp);
+               node->layer_disp = NULL;
+       }
+}
+
 float (*BLI_pbvh_get_vertCos(PBVH * pbvh))[3]
 {
        int a;
index fe9965366094a185721a5b4223550a5240f70a63..d3539245d11e23875f7788553cff54d07e411920 100644 (file)
@@ -91,6 +91,9 @@ struct PBVHNode {
        /* Used for raycasting: how close bb is to the ray point. */
        float tmin;
 
+       /* Scalar displacements for sculpt mode's layer brush. */
+       float *layer_disp;
+
        int proxy_count;
        PBVHProxyNode *proxies;
 };
index 8325b47beab86aadc6271bf570414504b7f683d7..2f0d69bfd98676b3529965ed08a28d7e998190a3 100644 (file)
@@ -1908,13 +1908,12 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
                
                unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS);
                origco = unode->co;
-               if (!unode->layer_disp) {
-                       #pragma omp critical 
-                       unode->layer_disp = MEM_callocN(sizeof(float) * unode->totvert, "layer disp");
-               }
-
-               layer_disp = unode->layer_disp;
 
+               #pragma omp critical
+               {
+                       layer_disp = BLI_pbvh_node_layer_disp_get(ss->pbvh, nodes[n]);
+               }
+               
                sculpt_brush_test_init(ss, &test);
 
                BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE)
index 44068122b897d322686b548c9eaf0e9344bc51d4..cfc908bf45363e01dd0f11e376605ecf08b2204a 100644 (file)
@@ -101,9 +101,6 @@ typedef struct SculptUndoNode {
        int *grids;                 /* to restore into right location */
        BLI_bitmap *grid_hidden;
 
-       /* layer brush */
-       float *layer_disp;
-
        /* shape keys */
        char shapeName[sizeof(((KeyBlock *)0))->name];
 } SculptUndoNode;
index 1b3fd24ae2218540931b814f3bf5da8a303dd2e3..053e17cde075c821bab05162f0f5d830f773a040 100644 (file)
@@ -374,8 +374,6 @@ static void sculpt_undo_free(ListBase *lb)
                        MEM_freeN(unode->index);
                if (unode->grids)
                        MEM_freeN(unode->grids);
-               if (unode->layer_disp)
-                       MEM_freeN(unode->layer_disp);
                if (unode->orig_co)
                        MEM_freeN(unode->orig_co);
                if (unode->vert_hidden)
@@ -612,10 +610,8 @@ void sculpt_undo_push_end(void)
                        unode->no = NULL;
                }
 
-               if (unode->layer_disp) {
-                       MEM_freeN(unode->layer_disp);
-                       unode->layer_disp = NULL;
-               }
+               if (unode->node)
+                       BLI_pbvh_node_layer_disp_free(unode->node);
        }
 
        undo_paint_push_end(UNDO_PAINT_MESH);