[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