[Bf-blender-cvs] [b701cd63add] sculpt-dev: Sculpt: various bugfixes
Joseph Eagar
noreply at git.blender.org
Thu Oct 28 19:58:09 CEST 2021
Commit: b701cd63adddda402d1e0206008e9c1d55eb6639
Author: Joseph Eagar
Date: Thu Oct 28 10:50:38 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rBb701cd63adddda402d1e0206008e9c1d55eb6639
Sculpt: various bugfixes
* BMLog now saves face material indices
* Fixed id corruption in join mesh edge case.
* The mesh->bmesh conversion function now checks
if IDs are corrupted in a bit smarter way:
+ Any id that's greater then 5 times the sum of
total elements with ids is assumed to be corrupt.
Avoids very large allocations for the fast element->id
map, which is a simple lookup table.
+ Alternative is to automatically switch to the slower
GHash id->element map.
+ Sculpt code would have to detect this case and regenerate
IDs?
* The slide relax brush is now internally split into two
seperate commands.
* Basic smoothing now uses fewer iterations, velocity smooth
is used to speed up convergence.
===================================================================
M source/blender/blenkernel/intern/brush_engine.c
M source/blender/bmesh/intern/bmesh_log.c
M source/blender/bmesh/intern/bmesh_mesh_convert.c
M source/blender/editors/mesh/meshtools.c
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_brushes.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/editors/sculpt_paint/sculpt_smooth.c
M source/blender/makesdna/DNA_brush_enums.h
===================================================================
diff --git a/source/blender/blenkernel/intern/brush_engine.c b/source/blender/blenkernel/intern/brush_engine.c
index 7fce1d8ab5c..717bcad902e 100644
--- a/source/blender/blenkernel/intern/brush_engine.c
+++ b/source/blender/blenkernel/intern/brush_engine.c
@@ -1699,11 +1699,11 @@ void BKE_builtin_apply_hard_edge_mode(BrushChannelSet *chset, bool do_apply)
}
}
-void BKE_builtin_commandlist_create(Brush *brush,
- BrushChannelSet *chset,
- BrushCommandList *cl,
- int tool,
- BrushMappingData *mapdata)
+ATTR_NO_OPT void BKE_builtin_commandlist_create(Brush *brush,
+ BrushChannelSet *chset,
+ BrushCommandList *cl,
+ int tool,
+ BrushMappingData *mapdata)
{
BrushCommand *cmd;
BrushChannel *ch;
@@ -1736,7 +1736,7 @@ void BKE_builtin_commandlist_create(Brush *brush,
float autosmooth_projection = BKE_brush_channelset_get_float(
chset, "autosmooth_projection", NULL);
- bool is_cloth = tool = SCULPT_TOOL_CLOTH;
+ bool is_cloth = tool == SCULPT_TOOL_CLOTH;
is_cloth = is_cloth ||
(ELEM(tool, SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_POSE) &&
BRUSHSET_GET_INT(chset, deform_target, NULL) == BRUSH_DEFORM_TARGET_CLOTH_SIM);
@@ -1761,7 +1761,9 @@ void BKE_builtin_commandlist_create(Brush *brush,
float autosmooth = BKE_brush_channelset_get_float(chset, "autosmooth", NULL);
if (!no_autosmooth && autosmooth > 0.0f) {
- cmd = BKE_brush_command_init(BKE_brush_commandlist_add(cl, chset, true), SCULPT_TOOL_SMOOTH);
+ int smooth_tool = tool != SCULPT_TOOL_SLIDE_RELAX ? SCULPT_TOOL_SMOOTH : SCULPT_TOOL_RELAX;
+
+ cmd = BKE_brush_command_init(BKE_brush_commandlist_add(cl, chset, true), smooth_tool);
BKE_builtin_apply_hard_edge_mode(cmd->params, hard_edge_mode);
BKE_brush_commandset_inherit_all_mappings(cmd->params);
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 7ea7c76557f..cc0074aa8f8 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -464,7 +464,8 @@ typedef struct {
void *customdata_f;
char hflag;
- size_t len;
+ uint len;
+ short mat_nr;
void *customdata_res[MAX_FACE_RESERVED];
uint v_ids_res[MAX_FACE_RESERVED];
@@ -844,6 +845,7 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
lf->len = (size_t)f->len;
lf->id = (uint)BM_ELEM_GET_ID(log->bm, f);
+ lf->mat_nr = f->mat_nr;
SET_TRACE(lf);
@@ -1379,7 +1381,9 @@ static void bm_log_faces_restore(
BMFace *f = BM_face_create_verts(
bm, vs_tmp, (int)BLI_array_len(vs_tmp), NULL, BM_CREATE_SKIP_ID, true);
+
f->head.hflag = lf->hflag;
+ f->mat_nr = lf->mat_nr;
copy_v3_v3(f->no, lf->no);
@@ -1515,6 +1519,7 @@ static void bm_log_face_values_swap(BMLog *log,
swap_v3_v3(f->no, lf->no);
SWAP(char, f->head.hflag, lf->hflag);
+ SWAP(short, f->mat_nr, lf->mat_nr);
void *old_cdata = NULL;
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.c b/source/blender/bmesh/intern/bmesh_mesh_convert.c
index fe8b58658da..4deaa9f6802 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.c
@@ -280,9 +280,9 @@ void BM_enter_multires_space(Object *ob, BMesh *bm, int space)
*/
void BM_mesh_bm_from_me(Object *ob,
- BMesh *bm,
- const Mesh *me,
- const struct BMeshFromMeshParams *params)
+ BMesh *bm,
+ const Mesh *me,
+ const struct BMeshFromMeshParams *params)
{
const bool is_new = !(bm->totvert || (bm->vdata.totlayer || bm->edata.totlayer ||
bm->pdata.totlayer || bm->ldata.totlayer));
@@ -500,18 +500,30 @@ void BM_mesh_bm_from_me(Object *ob,
BM_mesh_cd_flag_apply(bm, me->cd_flag);
}
+#define IS_GARBAGE_ID(id) ((id) < 0 || (id) > id_garbage_threshold)
+
int *existing_id_layers[4] = {NULL, NULL, NULL, NULL};
+
+ /* threshold to detect garbage IDs, number of elements with ids multiplied by 5 */
+ int id_garbage_threshold = 0;
+
int use_exist_ids = 0;
int has_ids = bm->idmap.flag & BM_HAS_IDS ?
(bm->idmap.flag & (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)) :
0;
-
if (bm->idmap.flag & BM_HAS_IDS) {
+ int tots[4] = {me->totvert + bm->totvert,
+ me->totedge + bm->totedge,
+ me->totloop + bm->totloop,
+ me->totpoly + bm->totface};
+
if (!params->ignore_id_layers) {
for (int i = 0; i < 4; i++) {
existing_id_layers[i] = (int *)CustomData_get_layer(cdatas[i], CD_MESH_ID);
if (existing_id_layers[i]) {
+ id_garbage_threshold += tots[i];
+
use_exist_ids |= 1 << i;
}
}
@@ -522,6 +534,8 @@ void BM_mesh_bm_from_me(Object *ob,
bm_init_idmap_cdlayers(bm);
}
+ id_garbage_threshold *= 5;
+
const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
@@ -560,7 +574,7 @@ void BM_mesh_bm_from_me(Object *ob,
bm_elem_check_toolflags(bm, (BMElem *)v);
if (has_ids & BM_VERT) {
- if (use_exist_ids & BM_VERT) {
+ if ((use_exist_ids & BM_VERT) && !IS_GARBAGE_ID(existing_id_layers[0][i])) {
bm_assign_id(bm, (BMElem *)v, existing_id_layers[0][i], false);
}
else {
@@ -611,7 +625,7 @@ void BM_mesh_bm_from_me(Object *ob,
bm_elem_check_toolflags(bm, (BMElem *)e);
if (has_ids & BM_EDGE) {
- if (use_exist_ids & BM_EDGE) {
+ if ((use_exist_ids & BM_EDGE) && !IS_GARBAGE_ID(existing_id_layers[1][i])) {
bm_assign_id(bm, (BMElem *)e, existing_id_layers[1][i], false);
}
else {
@@ -682,7 +696,7 @@ void BM_mesh_bm_from_me(Object *ob,
CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
if (has_ids & BM_LOOP) {
- if (use_exist_ids & BM_LOOP) {
+ if ((use_exist_ids & BM_LOOP) && !IS_GARBAGE_ID(existing_id_layers[2][j - 1])) {
bm_assign_id(bm, (BMElem *)l_iter, existing_id_layers[2][j - 1], false);
}
else {
@@ -697,7 +711,7 @@ void BM_mesh_bm_from_me(Object *ob,
bm_elem_check_toolflags(bm, (BMElem *)f);
if (has_ids & BM_FACE) {
- if (use_exist_ids & BM_FACE) {
+ if ((use_exist_ids & BM_FACE) && !IS_GARBAGE_ID(existing_id_layers[3][i])) {
bm_assign_id(bm, (BMElem *)f, existing_id_layers[3][i], false);
}
else {
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 1b720f2c14d..a26a74a9cb7 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -77,6 +77,134 @@
/* join selected meshes into the active mesh, context sensitive
* return 0 if no join is made (error) and 1 if the join is done */
+static void get_id_range(Mesh *mesh,
+ CustomData *vdata,
+ CustomData *edata,
+ CustomData *ldata,
+ CustomData *pdata,
+ int totvert,
+ int totedge,
+ int totloop,
+ int totpoly,
+ int *r_min,
+ int *r_max)
+{
+ const CustomData *datas[4] = {vdata, edata, ldata, pdata};
+ int tots[4] = {totvert, totedge, totloop, totpoly};
+ int min_id = 0, max_id = 0;
+
+ for (int i = 0; i < 4; i++) {
+ int *ids = CustomData_get_layer(datas[i], CD_MESH_ID);
+ if (!ids) {
+ continue;
+ }
+
+ if (!tots[i]) {
+ continue;
+ }
+
+ if (i == 0) {
+ min_id = max_id = *ids;
+ }
+ else {
+ min_id = MIN2(min_id, *ids);
+ max_id = MAX2(max_id, *ids);
+ }
+
+ ids++;
+
+ for (int j = 1; j < tots[i]; j++, ids++) {
+ min_id = MIN2(min_id, *ids);
+ max_id = MAX2(max_id, *ids);
+ }
+ }
+
+ *r_min = min_id;
+ *r_max = max_id;
+}
+
+static void handle_missing_id_layers(Mesh *src,
+ Mesh *dst,
+ CustomData *vdata,
+ CustomData *edata,
+ CustomData *ldata,
+ CustomData *pdata,
+ int totvert,
+ int totedge,
+ int totloop,
+ int totpoly)
+{
+ const CustomData *src_datas[4] = {&src->vdata, &src->edata, &src->ldata, &src->pdata};
+ const CustomData *dst_datas[4] = {vdata, edata, ldata, pdata};
+ int srctots[4] = {src->totvert, src->totedge, src->totloop, src->totpoly};
+ int dsttots[4] = {totvert, totedge, totloop, totpoly};
+
+ // find starting max id in dst
+ int dst_range[2], src_range[2];
+
+ get_id_range(src,
+ &src->vdata,
+ &src->edata,
+ &src->ldata,
+ &src->pdata,
+ src->totvert,
+ src->totedge,
+ src->totloop,
+ src->totpoly,
+ src_range,
+ src_range + 1);
+
+ get_id_range(dst,
+ vdata,
+ edata,
+ ldata,
+ pdata,
+ totvert,
+ totedge,
+ totloop,
+ totpoly,
+ dst_range,
+ dst_range + 1);
+
+ for (int i = 0; i < 4; i++) {
+ const CustomData *srcdata = src_datas[i];
+ const CustomData *dstdata = dst_datas[i];
+
+ const bool haveid_src = Cus
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list