Sculpt dyntopo: Another fix for faceset boundary handling

* Turned out pbvh->cd_faceset_offset wasn't being updated
  correctly.
This commit is contained in:
Joseph Eagar 2021-07-20 05:47:08 -07:00
parent 7bd521a5c4
commit 7cd74015f8
7 changed files with 43 additions and 32 deletions

View File

@ -157,6 +157,7 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
pbvh_check_vert_boundary(pbvh, v);
const int cd_dyn_vert = pbvh->cd_dyn_vert;
MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
const bool bound1 = mv1->flag & DYNVERT_ALL_BOUNDARY;
@ -2408,15 +2409,16 @@ ATTR_NO_OPT static bool cleanup_valence_3_4(PBVH *pbvh,
continue;
}
pbvh_check_vert_boundary(pbvh, v);
MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_dyn_vert);
if (mv->flag & DYNVERT_ALL_BOUNDARY) {
const int val = BM_vert_edge_count(v);
if (val != 4 && val != 3) {
continue;
}
const int val = BM_vert_edge_count(v);
if (val != 4 && val != 3) {
MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
pbvh_check_vert_boundary(pbvh, v);
if (mv->flag & DYNVERT_ALL_BOUNDARY) {
continue;
}

View File

@ -1194,13 +1194,13 @@ void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh)
}
/* Build a PBVH from a BMesh */
void BKE_pbvh_build_bmesh(PBVH *pbvh,
BMesh *bm,
bool smooth_shading,
BMLog *log,
const int cd_vert_node_offset,
const int cd_face_node_offset,
const int cd_dyn_vert)
ATTR_NO_OPT void BKE_pbvh_build_bmesh(PBVH *pbvh,
BMesh *bm,
bool smooth_shading,
BMLog *log,
const int cd_vert_node_offset,
const int cd_face_node_offset,
const int cd_dyn_vert)
{
pbvh->cd_vert_node_offset = cd_vert_node_offset;
pbvh->cd_face_node_offset = cd_face_node_offset;
@ -2103,6 +2103,7 @@ void BKE_pbvh_update_offsets(PBVH *pbvh,
pbvh->cd_vert_mask_offset = CustomData_get_offset(&pbvh->bm->vdata, CD_PAINT_MASK);
pbvh->cd_vcol_offset = CustomData_get_offset(&pbvh->bm->vdata, CD_PROP_COLOR);
pbvh->cd_dyn_vert = cd_dyn_vert;
pbvh->cd_faceset_offset = CustomData_get_offset(&pbvh->bm->pdata, CD_SCULPT_FACE_SETS);
}
static void scan_edge_split(BMesh *bm, BMEdge **edges, int totedge)

View File

@ -1508,6 +1508,11 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, const SculptVertRef vert
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_BMESH: {
MDynTopoVert *mv = BKE_PBVH_DYNVERT(ss->cd_dyn_vert, ((BMVert *)(vertex.i)));
if (mv->flag & DYNVERT_NEED_BOUNDARY) {
BKE_pbvh_update_vert_boundary(ss->cd_dyn_vert, ss->cd_faceset_offset, (BMVert *)vertex.i);
}
return mv->flag & DYNVERT_BOUNDARY;
}
case PBVH_FACES: {

View File

@ -515,7 +515,6 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
BMIter iter;
BMVert *v;
int cd_vcol_offset = CustomData_get_offset(&ss->bm->vdata, CD_PROP_COLOR);
int cd_pers_co = -1, cd_pers_no = -1, cd_pers_disp = -1;
int cd_layer_disp = -1;
@ -533,13 +532,12 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
cd_pers_no = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_NO);
cd_pers_disp = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_PERS_DISP);
cd_layer_disp = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_DISP);
cd_vcol_offset = CustomData_get_offset(&ss->bm->vdata, CD_PROP_COLOR);
}
else {
cd_layer_disp = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_PERS_DISP);
}
int cd_vcol_offset = CustomData_get_offset(&ss->bm->vdata, CD_PROP_COLOR);
SCULPT_dyntopo_node_layers_update_offsets(ss);
int i = 0;

View File

@ -291,8 +291,12 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
int fset = BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset);
if (fade > 0.05f && fset > 0) {
MDynTopoVert *mv = BKE_PBVH_DYNVERT(ss->cd_dyn_vert, v);
mv->flag |= DYNVERT_NEED_BOUNDARY;
BMLoop *l = f->l_first;
do {
MDynTopoVert *mv = BKE_PBVH_DYNVERT(ss->cd_dyn_vert, l->v);
mv->flag |= DYNVERT_NEED_BOUNDARY;
} while ((l = l->next) != f->l_first);
BM_ELEM_CD_SET_INT(f, ss->cd_faceset_offset, active_fset);
}

View File

@ -710,6 +710,11 @@ static void rna_Brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
/*WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL); */
}
static void rna_Brush_dyntopo_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
}
static void rna_Brush_material_update(bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
{
/* number of material users changed */
@ -1181,21 +1186,21 @@ static void rna_def_dyntopo_settings(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 1, 500, 5, -1);
RNA_def_property_ui_text(
prop, "Spacing", "Spacing between DynTopo daubs as a percentage of brush diameter");
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "detail_percent", PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_float_sdna(prop, NULL, "detail_percent");
RNA_def_property_range(prop, 1, 1000);
RNA_def_property_ui_range(prop, 1, 500, 5, -1);
RNA_def_property_ui_text(prop, "Detail Percent", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "detail_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "detail_size");
RNA_def_property_range(prop, 0.0, 100.0);
RNA_def_property_ui_range(prop, 0.0, 50.0, 0.1, 4);
RNA_def_property_ui_text(prop, "Detail Size", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "detail_range", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "detail_range");
@ -1203,7 +1208,7 @@ static void rna_def_dyntopo_settings(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.0, 1.0, 0.001, 4);
RNA_def_property_ui_text(
prop, "Detail Range", "Higher values are faster but produce lower quality topology");
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "constant_detail", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "constant_detail");
@ -1213,35 +1218,35 @@ static void rna_def_dyntopo_settings(BlenderRNA *brna)
"Resolution",
"Maximum edge length for dynamic topology sculpting (as divisor "
"of blender unit - higher value means smaller edge length)");
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "subdivide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYNTOPO_SUBDIVIDE);
RNA_def_property_ui_icon(prop, ICON_NONE, 0);
RNA_def_property_ui_text(prop, "Subdivide", "Enable Dyntopo Subdivision");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "disabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYNTOPO_DISABLED);
RNA_def_property_ui_icon(prop, ICON_NONE, 0);
RNA_def_property_ui_text(prop, "Disable", "Disable Dyntopo for this brush");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "cleanup", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYNTOPO_CLEANUP);
RNA_def_property_ui_icon(prop, ICON_NONE, 0);
RNA_def_property_ui_text(prop, "Cleanup", "Dissolve Verts With Only 3 or 4 faces");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "collapse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYNTOPO_COLLAPSE);
RNA_def_property_ui_icon(prop, ICON_NONE, 0);
RNA_def_property_ui_text(prop, "Collapse", "Enable Dyntopo Decimation");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Brush_update");
RNA_def_property_update(prop, 0, "rna_Brush_dyntopo_update");
prop = RNA_def_property(srna, "mode", PROP_ENUM, 0);
RNA_def_property_enum_sdna(prop, NULL, "mode");

View File

@ -833,11 +833,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_dyntopo_cleanup", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_CLEANUP);
RNA_def_property_ui_text(prop,
"Cleanup",
"Removes verts surrounded by only 3 or 4 edges");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
RNA_def_property_ui_text(prop, "Cleanup", "Removes verts surrounded by only 3 or 4 edges");
prop = RNA_def_property(srna, "use_flat_vcol_shading", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_FLAT_VCOL_SHADING);