[Bf-blender-cvs] [e4b36fb6bc4] temp_bmesh_multires: Sculpt dyntopo: split face set boundaries on mirror boundary

Joseph Eagar noreply at git.blender.org
Sat Aug 28 05:03:58 CEST 2021


Commit: e4b36fb6bc4cc19ecd699ec9f1066a067e5ed032
Author: Joseph Eagar
Date:   Fri Aug 27 20:02:20 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBe4b36fb6bc4cc19ecd699ec9f1066a067e5ed032

Sculpt dyntopo: split face set boundaries on mirror boundary

Added an option to split face set boundaries on mirror
boundaries; currently only DynTopo supports this.

Very useful for making hard edges along mirror lines.

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

M	release/scripts/startup/bl_ui/space_view3d.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/makesdna/DNA_mesh_types.h
M	source/blender/makesrna/intern/rna_mesh.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index c6bc6d9b5d3..c8c1858d914 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -171,6 +171,7 @@ class VIEW3D_HT_tool_header(Header):
                 row.popover(panel="VIEW3D_PT_tools_weightpaint_symmetry_for_topbar", text="")
             elif mode_string == 'SCULPT':
                 row.popover(panel="VIEW3D_PT_sculpt_symmetry_for_topbar", text="")
+                layout.prop(context.object.data, "use_fset_boundary_mirror");
             elif mode_string == 'PAINT_VERTEX':
                 row.popover(panel="VIEW3D_PT_tools_vertexpaint_symmetry_for_topbar", text="")
 
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 25e4f2d501a..5cf797bd075 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1009,6 +1009,7 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel):
         row.prop(sculpt, "tile_z", text="Z", toggle=True)
 
         layout.prop(sculpt, "use_symmetry_feather", text="Feather")
+        layout.prop(mesh, "use_fset_boundary_mirror")
         layout.prop(sculpt, "radial_symmetry", text="Radial")
         layout.prop(sculpt, "tile_offset", text="Tile Offset")
 
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 2b829e8f569..53d59c42a81 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -655,7 +655,7 @@ typedef struct SculptSession {
 
   // id of current stroke, used to detect
   // if vertex original data needs to be updated
-  int stroke_id;
+  int stroke_id, boundary_symmetry;
 
   bool fast_draw;  // hides facesets/masks and forces smooth to save GPU bandwidth
 } SculptSession;
@@ -701,6 +701,8 @@ void BKE_sculpt_ensure_orig_mesh_data(struct Scene *scene, struct Object *object
 
 bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d);
 
+char BKE_get_fset_boundary_symflag(struct Object *object);
+
 enum {
   SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
   SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1),
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index a63768633e7..4ccdc66349b 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -768,13 +768,17 @@ PBVHNode *BKE_pbvh_node_from_face_bmesh(PBVH *pbvh, struct BMFace *f);
 PBVHNode *BKE_pbvh_node_from_index(PBVH *pbvh, int node_i);
 
 struct BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh);
-void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, struct BMVert *v);
+void BKE_pbvh_update_vert_boundary(int cd_dyn_vert,
+                                   int cd_faceset_offset,
+                                   struct BMVert *v,
+                                   int symmetry);
 
 #define DYNTOPO_DYNAMIC_TESS
 
 PBVHNode *BKE_pbvh_get_node_leaf_safe(PBVH *pbvh, int i);
 
 void BKE_pbvh_get_vert_face_areas(PBVH *pbvh, SculptVertRef vertex, float *r_areas, int valence);
+void BKE_pbvh_set_symmetry(PBVH *pbvh, int symmetry, int boundary_symmetry);
 
 #if 0
 typedef enum {
@@ -870,3 +874,4 @@ typedef struct SculptLayerEntry {
 #ifdef __cplusplus
 }
 #endif
+
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 1c7a4303754..e5c7d4a183a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1630,6 +1630,12 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
   return false;
 }
 
+char BKE_get_fset_boundary_symflag(Object *object) 
+{
+  const Mesh *mesh = BKE_mesh_from_object(object);
+  return mesh->flag & ME_SCULPT_MIRROR_FSET_BOUNDARIES ? mesh->symmetry : 0;
+}
+
 /**
  * \param need_mask: So that the evaluated mesh that is returned has mask data.
  */
@@ -1668,6 +1674,8 @@ static void sculpt_update_object(Depsgraph *depsgraph,
 
   ss->shapekey_active = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
 
+  ss->boundary_symmetry = (int) BKE_get_fset_boundary_symflag(ob);
+
   /* NOTE: Weight pPaint require mesh info for loop lookup, but it never uses multires code path,
    * so no extra checks is needed here. */
   if (mmd) {
@@ -2146,6 +2154,9 @@ void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object)
 static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
 {
   PBVH *pbvh = BKE_pbvh_new();
+
+  BKE_pbvh_set_symmetry(pbvh, 0, (int)BKE_get_fset_boundary_symflag(ob));
+
   BKE_pbvh_build_bmesh(pbvh,
                        ob->sculpt->bm,
                        ob->sculpt->bm_smooth_shading,
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index cbf95a035e0..a7c24e2c82f 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -4006,3 +4006,23 @@ void BKE_pbvh_set_stroke_id(PBVH *pbvh, int stroke_id)
 {
   pbvh->stroke_id = stroke_id;
 }
+
+void BKE_pbvh_set_symmetry(PBVH *pbvh, int symmetry, int boundary_symmetry) {
+  if (symmetry == pbvh->symmetry && boundary_symmetry == pbvh->boundary_symmetry) {
+    return;
+  }
+
+  pbvh->symmetry = symmetry;
+  pbvh->boundary_symmetry = boundary_symmetry;
+
+  if (pbvh->bm && BKE_pbvh_type(pbvh) == PBVH_BMESH) {
+    BMIter iter;
+    BMVert *v;
+
+    BM_ITER_MESH(v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
+      MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+
+      mv->flag |= DYNVERT_NEED_BOUNDARY;
+    }
+  }
+}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index d8dadd707e2..57b794307b0 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1362,7 +1362,26 @@ typedef struct FSetTemp {
   bool boundary;
 } FSetTemp;
 
-void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVert *v)
+static int do_fset_sym(int fset, const int symflag, const float *co) {
+  fset = abs(fset);
+
+  //surely we don't need more then 8 million face sets?
+  if (co[0] < 0.0f) {
+    fset |= (symflag&1) << 24;
+  }
+
+  if (co[1] < 0.0f) {
+    fset |= (symflag&2) << 24;
+  }
+
+  if (co[2] < 0.0f) {
+    fset |= (symflag&4) << 24;
+  }
+
+  return fset;
+}
+
+void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVert *v, int bound_symmetry)
 {
   MDynTopoVert *mv = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
 
@@ -1417,7 +1436,7 @@ void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVer
     }
 
     if (e->l) {
-      int fset = abs(BM_ELEM_CD_GET_INT(e->l->f, cd_faceset_offset));
+      int fset = do_fset_sym(BM_ELEM_CD_GET_INT(e->l->f, cd_faceset_offset), bound_symmetry, v2->co);
 
       if (e->l->f->len > 3) {
         mv->flag |= DYNVERT_NEED_TRIANGULATE;
@@ -1458,7 +1477,8 @@ void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVer
       // also check e->l->radial_next, in case we are not manifold
       // which can mess up the loop order
       if (e->l->radial_next != e->l) {
-        fset = abs(BM_ELEM_CD_GET_INT(e->l->radial_next->f, cd_faceset_offset));
+        //fset = abs(BM_ELEM_CD_GET_INT(e->l->radial_next->f, cd_faceset_offset));
+        fset = do_fset_sym(BM_ELEM_CD_GET_INT(e->l->radial_next->f, cd_faceset_offset), bound_symmetry, v2->co);
 
         if (e->l->radial_next->f->len > 3) {
           mv->flag |= DYNVERT_NEED_TRIANGULATE;
@@ -1566,9 +1586,9 @@ void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVer
   BLI_array_free(fsets);
 }
 
-void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVert *v)
+void BKE_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVert *v, int bound_symmetry)
 {
-  bke_pbvh_update_vert_boundary(cd_dyn_vert, cd_faceset_offset, v);
+  bke_pbvh_update_vert_boundary(cd_dyn_vert, cd_faceset_offset, v, bound_symmetry);
 }
 
 /*Used by symmetrize to update boundary flags*/
@@ -1578,7 +1598,7 @@ void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh)
   BMIter iter;
 
   BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
-    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v);
+    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v, pbvh->boundary_symmetry);
   }
 }
 
@@ -1708,7 +1728,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
 
     mv->flag = DYNVERT_NEED_DISK_SORT;
 
-    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v);
+    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v, pbvh->boundary_symmetry);
     BKE_pbvh_bmesh_update_valence(pbvh->cd_dyn_vert, (SculptVertRef){(intptr_t)v});
 
     copy_v3_v3(mv->origco, v->co);
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index c91a97bdf83..050869ea351 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -203,6 +203,9 @@ struct PBVH {
   float planes[6][4];
   int num_planes;
 
+  int symmetry;
+  int boundary_symmetry;
+
   struct BMLog *bm_log;
   struct SubdivCCG *subdiv_ccg;
 
@@ -317,14 +320,14 @@ bool pbvh_bmesh_node_limit_ensure(PBVH *pbvh, int node_index);
 void pbvh_bmesh_check_nodes(PBVH *pbvh);
 void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni);
 void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f);
-void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVert *v);
+void bke_pbvh_update_vert_boundary(int cd_dyn_vert, int cd_faceset_offset, BMVert *v, int bound_symmetry);
 
 BLI_INLINE bool pbvh_check_vert_boundary(PBVH *pbvh, struct BMVert *v)
 {
   MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_dyn_vert);
 
   if (mv->flag & DYNVERT_NEED_BOUNDARY) {
-    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v);
+    bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v, pbvh->boundary_symmetry);
     

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list