[Bf-blender-cvs] [db932ccde66] sculpt-dev: Array Brush: Implement symmetry datalayers

aousdfh noreply at git.blender.org
Thu Jul 15 21:12:24 CEST 2021


Commit: db932ccde664d843e547ffa1b752786aa9fb09ca
Author: aousdfh
Date:   Tue Jul 6 00:44:49 2021 +0200
Branches: sculpt-dev
https://developer.blender.org/rBdb932ccde664d843e547ffa1b752786aa9fb09ca

Array Brush: Implement symmetry datalayers

===================================================================

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/editors/sculpt_paint/paint_stroke.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_array.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 880b7c7de59..321d04557f3 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -448,6 +448,20 @@ typedef struct SculptBoundary {
   } circle;
 } SculptBoundary;
 
+/* Array Brush. */
+typedef struct SculptArrayCopy {
+  int index;
+  int symm_pass;
+  float mat[4][4];
+  float origin[3];
+} SculptArrayCopy;
+
+typedef struct SculptArray {
+  float (*orco)[3];
+  SculptArrayCopy *copies[PAINT_SYMM_AREAS];
+  int num_copies;
+} SculptArray;
+
 typedef struct SculptFakeNeighbors {
   bool use_fake_neighbors;
 
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index b3b20c9e540..938b7acd74b 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -227,6 +227,7 @@ static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
     case PAINT_MODE_SCULPT:
       if (ELEM(brush->sculpt_tool,
                SCULPT_TOOL_GRAB,
+               SCULPT_TOOL_ARRAY,
                SCULPT_TOOL_ELASTIC_DEFORM,
                SCULPT_TOOL_POSE,
                SCULPT_TOOL_BOUNDARY,
@@ -269,6 +270,7 @@ static bool paint_tool_require_inbetween_mouse_events(Brush *brush, ePaintMode m
     case PAINT_MODE_SCULPT:
       if (ELEM(brush->sculpt_tool,
                SCULPT_TOOL_GRAB,
+               SCULPT_TOOL_ARRAY,
                SCULPT_TOOL_ROTATE,
                SCULPT_TOOL_THUMB,
                SCULPT_TOOL_SNAKE_HOOK,
@@ -1043,6 +1045,7 @@ static bool sculpt_is_grab_tool(Brush *br)
               SCULPT_TOOL_POSE,
               SCULPT_TOOL_BOUNDARY,
               SCULPT_TOOL_THUMB,
+              SCULPT_TOOL_ARRAY, 
               SCULPT_TOOL_ROTATE,
               SCULPT_TOOL_SNAKE_HOOK);
 }
@@ -1056,6 +1059,9 @@ bool paint_supports_dynamic_size(Brush *br, ePaintMode mode)
 
   switch (mode) {
     case PAINT_MODE_SCULPT:
+      if (br->sculpt_tool == SCULPT_TOOL_ARRAY) {
+        return true;
+      }
       if (sculpt_is_grab_tool(br)) {
         return false;
       }
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e387b47b7d4..b42e455cce6 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -6718,6 +6718,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
     return;
   }
 
+  if (brush->sculpt_tool == SCULPT_TOOL_ARRAY && type != PBVH_FACES) {
+    return;
+  }
+
   /* Build a list of all nodes that are potentially within the brush's area of influence */
 
   if (SCULPT_tool_needs_all_pbvh_nodes(brush)) {
@@ -8969,6 +8973,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
 
   if (brush->sculpt_tool == SCULPT_TOOL_ARRAY) {
     SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY);
+    SCULPT_array_datalayers_free(ob);
   }
   
   SCULPT_undo_push_end();
diff --git a/source/blender/editors/sculpt_paint/sculpt_array.c b/source/blender/editors/sculpt_paint/sculpt_array.c
index 0983562fa95..e7c2a19f0e4 100644
--- a/source/blender/editors/sculpt_paint/sculpt_array.c
+++ b/source/blender/editors/sculpt_paint/sculpt_array.c
@@ -61,62 +61,46 @@
 static const char array_symmetry_pass_cd_name[] = "v_symmetry_pass";
 static const char array_instance_cd_name[] = "v_array_instance";
 
-#define SCUPT_ARRAY_COUNT 5
+#define SCULPT_ARRAY_COUNT 5
 #define ARRAY_INSTANCE_ORIGINAL -1 
 
-static void sculpt_array_modify_sculpt_mesh(Object *ob, Mesh *array_mesh)
-{
-  SculptSession *ss = ob->sculpt;	
-  Mesh *sculpt_mesh = BKE_object_get_original_mesh(ob);
-  BMesh *bm;
-  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh, array_mesh);
-  bm = BM_mesh_create(&allocsize,
-                      &((struct BMeshCreateParams){
-                          .use_toolflags = false,
-                      }));
-
-  BM_mesh_bm_from_me(bm,
-                     sculpt_mesh,
-                     &((struct BMeshFromMeshParams){
-                         .calc_face_normal = true,
-                     }));
 
-  BM_mesh_bm_from_me(bm,
-                     array_mesh,
-                     &((struct BMeshFromMeshParams){
-                         .calc_face_normal = true,
-                     }));
-
-
-  Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, sculpt_mesh);
-  BM_mesh_free(bm);
-  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
-  BKE_mesh_nomain_to_mesh(result, ob->data, ob, &CD_MASK_MESH, true);
-  BKE_mesh_free(result);
-  BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
-  ss->needs_pbvh_rebuild = true;
-}
-
-
-const float source_geometry_threshold = 0.5f;
-static BMesh *sculpt_array_source_mesh_calculate(Sculpt *sd, Object *ob) {
-  SculptSession *ss = ob->sculpt;
-  Mesh *sculpt_mesh = BKE_object_get_original_mesh(ob);
-  const int totvert = SCULPT_vertex_count_get(ss);
-
-  int *v_array_instance = CustomData_add_layer_named(&sculpt_mesh->vdata,
+static void sculpt_array_datalayers_add(Mesh *mesh) {
+  int *v_array_instance = CustomData_add_layer_named(&mesh->vdata,
                                                     CD_PROP_INT32,
                                                     CD_CALLOC,
                                                     NULL,
-                                                    sculpt_mesh->totvert,
+                                                    mesh->totvert,
                                                     array_instance_cd_name);
-
-  for (int i = 0; i < sculpt_mesh->totvert; i++) {
+  for (int i = 0; i < mesh->totvert; i++) {
     v_array_instance[i] = ARRAY_INSTANCE_ORIGINAL;
   }
 
-  printf("ARRAY INSTANCE SET\n");
+  CustomData_add_layer_named(&mesh->vdata,
+                                                    CD_PROP_INT32,
+                                                    CD_CALLOC,
+                                                    NULL,
+                                                    mesh->totvert,
+                                                    array_symmetry_pass_cd_name);
+}
+
+void SCULPT_array_datalayers_free(Object *ob) {
+  Mesh *mesh = BKE_object_get_original_mesh(ob);
+  int v_layer_index = CustomData_get_named_layer_index(&mesh->vdata, CD_PROP_INT32, array_instance_cd_name);
+  if (v_layer_index != -1) {
+    CustomData_free_layer(&mesh->vdata, CD_PROP_INT32, mesh->totvert, v_layer_index);
+  }
+
+  v_layer_index = CustomData_get_named_layer_index(&mesh->vdata, CD_PROP_INT32, array_symmetry_pass_cd_name);
+  if (v_layer_index != -1) {
+    CustomData_free_layer(&mesh->vdata, CD_PROP_INT32, mesh->totvert, v_layer_index);
+  }
+}
 
+const float source_geometry_threshold = 0.5f;
+
+static BMesh *sculpt_array_source_build(Object *ob, Brush *brush) {
+  Mesh *sculpt_mesh = BKE_object_get_original_mesh(ob);
 
   BMesh *srcbm;
   const BMAllocTemplate allocsizea = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh);
@@ -134,6 +118,7 @@ static BMesh *sculpt_array_source_mesh_calculate(Sculpt *sd, Object *ob) {
   BM_mesh_elem_table_ensure(srcbm, BM_VERT);
   BM_mesh_elem_index_ensure(srcbm, BM_VERT); 
 
+  SculptSession *ss = ob->sculpt;
   for (int i = 0; i < srcbm->totvert; i++) {
 	const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, i);
 	const float mask = 1.0f - SCULPT_vertex_mask_get(ss, i);
@@ -144,23 +129,51 @@ static BMesh *sculpt_array_source_mesh_calculate(Sculpt *sd, Object *ob) {
 	BMVert *vert = BM_vert_at_index(srcbm, i);
 	BM_elem_flag_set(vert, BM_ELEM_TAG, true);
   }
-
-  /* TODO: Handle individual Face Sets for Face Set automasking. */
-  BM_mesh_delete_hflag_context(srcbm, BM_ELEM_TAG, DEL_VERTS);
   
-  
-  /*
-  BMO_op_callf(srcbm,
-               (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
-               "duplicate geom=%hvef use_select_history=%b use_edge_flip_from_face=%b",
-               BM_ELEM_TAG, false, false);
-	       */
-	       
+  /* TODO(pablodp606): Handle individual Face Sets for Face Set automasking. */
+  BM_mesh_delete_hflag_context(srcbm, BM_ELEM_TAG, DEL_VERTS);
 
+  return srcbm;
+}
 
-  //CustomData_bmesh_merge(&srcbm->vdata, &destbm->vdata, CD_NA, 0, destbm, BM_VERT).
+void sculpt_array_source_datalayer_update(BMesh *bm, const int symm_pass, const int copy_index) {
+  const int cd_array_instance_index = CustomData_get_named_layer_index(
+      &bm->vdata, CD_PROP_INT32, array_instance_cd_name);
+  const int cd_array_instance_offset = CustomData_get_n_offset(
+      &bm->vdata, CD_PROP_INT32, cd_array_instance_index);
 
-  
+  const int cd_array_symm_pass_index = CustomData_get_named_layer_index(
+      &bm->vdata, CD_PROP_INT32, array_symmetry_pass_cd_name);
+  const int cd_array_symm_pass_offset = CustomData_get_n_offset(
+      &bm->vdata, CD_PROP_INT32, cd_array_symm_pass_index);
+
+  BM_mesh_elem_table_ensure(bm, BM_VERT);
+  BM_mesh_elem_index_ensure(bm, BM_VERT); 
+
+  BMVert *v;
+  BMIter iter;
+  BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+		  BM_ELEM_CD_SET_INT(v, cd_array_instance_offset, copy_index);
+		  BM_ELEM_CD_SET_INT(v, cd_array_symm_pass_offset, symm_pass);
+  }
+}
+
+static void sculpt_array_final_mesh_write(Object *ob, BMesh *final_mesh) {
+  SculptSession *ss = ob->sculpt;
+  Mesh *sculpt_mesh = BKE_object_get_original_mesh(ob);
+  Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(final_mesh, NULL, sculpt_mesh);
+  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+  BKE_mesh_nomain_to_mesh(result, ob->data, ob, &CD_MASK_MESH, true);
+  BKE_mesh_free(result);
+  BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+  ss->needs_pbvh_rebuild = true;
+}
+
+static void sculpt_array_mesh_build(Sculpt *sd, Object *ob) {
+  Mesh *sculpt_mesh = BKE_object_get_original_mesh(ob);
+  sculpt_array_datalayers_add(sculpt_mesh);
+
+  BMesh *srcbm = sculpt_array_source_build(ob, NULL);
   
   BMesh *destbm;
   const BMAllocTemplate allocsizeb = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh);
@@ -168,83 +181,179 @@ static BMesh *sculpt_array_source_mesh_calculate(Sculpt *sd, Object *ob) {
               

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list