sculpt-dev: Dyntopo collapse now works with new id system
. . .but subdivide is now broken.
This commit is contained in:
parent
f68b5cd7e1
commit
b4cc9b67fc
|
@ -80,7 +80,6 @@ static void edge_queue_create_local(struct EdgeQueueContext *eq_ctx,
|
|||
const bool use_projected,
|
||||
PBVHTopologyUpdateMode local_mode);
|
||||
|
||||
|
||||
BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
|
||||
{
|
||||
float co[3];
|
||||
|
@ -714,7 +713,7 @@ static float maskcb_get(EdgeQueueContext *eq_ctx, BMVert *v1, BMVert *v2)
|
|||
return min_ff(w1, w2);
|
||||
//}
|
||||
|
||||
return (w1 + w2) * 0.5f;
|
||||
// return (w1 + w2) * 0.5f;
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
|
@ -1392,8 +1391,7 @@ bool check_face_is_tri(PBVH *pbvh, BMFace *f)
|
|||
|
||||
ATTR_NO_OPT bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
||||
{
|
||||
return false;
|
||||
|
||||
#if 0
|
||||
bm_logstack_push();
|
||||
|
||||
static int max_faces = 64;
|
||||
|
@ -1436,7 +1434,6 @@ ATTR_NO_OPT bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
|||
continue;
|
||||
}
|
||||
|
||||
void **val = nullptr;
|
||||
BMFace *f2 = l->radial_next->f;
|
||||
|
||||
if (visit.add(f2)) {
|
||||
|
@ -1469,7 +1466,7 @@ ATTR_NO_OPT bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
|||
return false;
|
||||
}
|
||||
|
||||
printf("manifold fin size: %d\n", minfs.size());
|
||||
printf("manifold fin size: %d\n", (int)minfs.size());
|
||||
const int tag = BM_ELEM_TAG_ALT;
|
||||
|
||||
for (int i = 0; i < minfs.size(); i++) {
|
||||
|
@ -1534,9 +1531,9 @@ ATTR_NO_OPT bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
|||
}
|
||||
|
||||
pbvh_bmesh_face_remove(pbvh, f, true, false, false);
|
||||
#ifdef USE_NEW_IDMAP
|
||||
# ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, (BMElem *)f, true);
|
||||
#endif
|
||||
# endif
|
||||
BM_face_kill(pbvh->header.bm, f);
|
||||
}
|
||||
|
||||
|
@ -1547,9 +1544,9 @@ ATTR_NO_OPT bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
|||
|
||||
if (!e->l) {
|
||||
BM_log_edge_removed(pbvh->bm_log, e);
|
||||
#ifdef USE_NEW_IDMAP
|
||||
# ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, (BMElem *)e, true);
|
||||
#endif
|
||||
# endif
|
||||
BM_edge_kill(pbvh->header.bm, e);
|
||||
}
|
||||
}
|
||||
|
@ -1561,9 +1558,9 @@ ATTR_NO_OPT bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
|||
pbvh_bmesh_vert_remove(pbvh, v);
|
||||
|
||||
BM_log_vert_removed(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
|
||||
#ifdef USE_NEW_IDMAP
|
||||
# ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, (BMElem *)v, true);
|
||||
#endif
|
||||
# endif
|
||||
BM_vert_kill(pbvh->header.bm, v);
|
||||
}
|
||||
else {
|
||||
|
@ -1576,6 +1573,9 @@ ATTR_NO_OPT bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root)
|
|||
|
||||
bm_logstack_pop();
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool check_for_fins(PBVH *pbvh, BMVert *v)
|
||||
|
@ -3192,16 +3192,6 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
for (int i = 0; i < totedge; i++) {
|
||||
BMEdge *e = edges[i];
|
||||
|
||||
#if 0
|
||||
BMLoop *l = e->l;
|
||||
while (e->l) {
|
||||
BMFace *f = e->l->f;
|
||||
BM_log_face_removed(pbvh->bm_log, f);
|
||||
BKE_pbvh_bmesh_remove_face(pbvh, f, false);
|
||||
BM_idmap_release(pbvh->bm_idmap, (BMElem *)f, true);
|
||||
BM_face_kill(pbvh->header.bm, f);
|
||||
}
|
||||
#endif
|
||||
check_vert_fan_are_tris(pbvh, e->v1);
|
||||
check_vert_fan_are_tris(pbvh, e->v2);
|
||||
}
|
||||
|
@ -3287,7 +3277,6 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
BMFace *f = faces[i];
|
||||
BMLoop *l = f->l_first;
|
||||
|
||||
// pbvh_bmesh_face_remove(pbvh, f, true, false, false);
|
||||
if (!ignore_isolated_edges) {
|
||||
f->head.hflag |= SPLIT_TAG;
|
||||
BM_log_face_pre(pbvh->bm_log, f);
|
||||
|
|
|
@ -47,6 +47,11 @@ using blender::Vector;
|
|||
|
||||
namespace blender::dyntopo {
|
||||
|
||||
typedef struct TraceData {
|
||||
PBVH *pbvh;
|
||||
BMEdge *e;
|
||||
} TraceData;
|
||||
|
||||
// copied from decimate modifier code
|
||||
inline bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
|
||||
{
|
||||
|
@ -130,128 +135,6 @@ inline bool bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
|
|||
return false;
|
||||
}
|
||||
|
||||
typedef struct TraceData {
|
||||
PBVH *pbvh;
|
||||
blender::Set<void *> visit;
|
||||
BMEdge *e;
|
||||
} TraceData;
|
||||
|
||||
ATTR_NO_OPT void col_on_vert_kill(BMesh *bm, BMVert *v, void *userdata)
|
||||
{
|
||||
TraceData *data = (TraceData *)userdata;
|
||||
PBVH *pbvh = data->pbvh;
|
||||
|
||||
if (BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
// printf("vert pbvh remove!\n");
|
||||
blender::dyntopo::pbvh_bmesh_vert_remove(pbvh, v);
|
||||
}
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(v))) {
|
||||
// printf("vert kill!\n");
|
||||
BM_log_vert_pre(pbvh->bm_log, v);
|
||||
#ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, reinterpret_cast<BMElem *>(v), true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void col_on_edge_kill(BMesh *bm, BMEdge *e, void *userdata)
|
||||
{
|
||||
TraceData *data = (TraceData *)userdata;
|
||||
PBVH *pbvh = data->pbvh;
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(e))) {
|
||||
// printf("edge kill!\n");
|
||||
BM_log_edge_pre(pbvh->bm_log, e);
|
||||
#ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, reinterpret_cast<BMElem *>(e), true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void col_on_face_kill(BMesh *bm, BMFace *f, void *userdata)
|
||||
{
|
||||
TraceData *data = (TraceData *)userdata;
|
||||
PBVH *pbvh = data->pbvh;
|
||||
|
||||
if (BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
pbvh_bmesh_face_remove(pbvh, f, false, false, false);
|
||||
}
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(f))) {
|
||||
BM_log_face_pre(pbvh->bm_log, f);
|
||||
#ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, reinterpret_cast<BMElem *>(f), true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT static void collapse_restore_id(BMIdMap *idmap, BMElem *elem)
|
||||
{
|
||||
int id = BM_idmap_get_id(idmap, elem);
|
||||
|
||||
if (id < 0 || id >= idmap->map_size || idmap->map[id]) {
|
||||
BM_idmap_alloc(idmap, elem);
|
||||
}
|
||||
else {
|
||||
BM_idmap_assign(idmap, elem, id);
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void col_on_vert_add(BMesh *bm, BMVert *v, void *userdata)
|
||||
{
|
||||
TraceData *data = (TraceData *)userdata;
|
||||
PBVH *pbvh = data->pbvh;
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(v))) {
|
||||
// return;
|
||||
}
|
||||
|
||||
pbvh_boundary_update_bmesh(pbvh, v);
|
||||
|
||||
MSculptVert *mv = (MSculptVert *)BM_ELEM_CD_GET_VOID_P(v, data->pbvh->cd_sculpt_vert);
|
||||
mv->flag |= SCULPTVERT_NEED_VALENCE | SCULPTVERT_NEED_DISK_SORT;
|
||||
|
||||
collapse_restore_id(pbvh->bm_idmap, (BMElem *)v);
|
||||
BM_log_vert_post(pbvh->bm_log, v);
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void col_on_edge_add(BMesh *bm, BMEdge *e, void *userdata)
|
||||
{
|
||||
TraceData *data = (TraceData *)userdata;
|
||||
PBVH *pbvh = data->pbvh;
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(e))) {
|
||||
// return;
|
||||
}
|
||||
|
||||
collapse_restore_id(pbvh->bm_idmap, (BMElem *)e);
|
||||
BM_log_edge_post(pbvh->bm_log, e);
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void col_on_face_add(BMesh *bm, BMFace *f, void *userdata)
|
||||
{
|
||||
TraceData *data = (TraceData *)userdata;
|
||||
PBVH *pbvh = data->pbvh;
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(f))) {
|
||||
// return;
|
||||
}
|
||||
|
||||
if (bm_elem_is_free((BMElem *)f, BM_FACE)) {
|
||||
printf("%s: error, f was freed!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
pbvh_bmesh_face_remove(pbvh, f, false, false, false);
|
||||
}
|
||||
|
||||
collapse_restore_id(pbvh->bm_idmap, (BMElem *)f);
|
||||
BM_log_face_post(pbvh->bm_log, f);
|
||||
BKE_pbvh_bmesh_add_face(pbvh, f, false, false);
|
||||
}
|
||||
|
||||
/* Faces *outside* the ring region are tagged with facetag, used to detect
|
||||
* border edges.
|
||||
*/
|
||||
|
@ -382,31 +265,11 @@ ATTR_NO_OPT void vert_ring_do_apply(BMVert *v,
|
|||
const int COLLAPSE_TAG = BM_ELEM_INTERNAL_TAG;
|
||||
const int COLLAPSE_FACE_TAG = BM_ELEM_TAG_ALT;
|
||||
|
||||
ATTR_NO_OPT static void vert_ring_do_old(BMVert *v,
|
||||
void (*callback)(BMElem *elem, void *userdata),
|
||||
void *userdata,
|
||||
int tag,
|
||||
int facetag,
|
||||
int depth)
|
||||
{
|
||||
if (!v->e) {
|
||||
v->head.hflag &= ~tag;
|
||||
callback((BMElem *)v, userdata);
|
||||
return;
|
||||
}
|
||||
|
||||
vert_ring_do_tag(v, tag, facetag, depth);
|
||||
vert_ring_untag_inner_faces(v, tag, facetag, depth);
|
||||
vert_ring_do_apply(v, callback, userdata, tag, facetag, depth);
|
||||
}
|
||||
|
||||
ATTR_NO_OPT static void collapse_ring_callback_pre(BMElem *elem, void *userdata)
|
||||
{
|
||||
TraceData *data = static_cast<TraceData *>(userdata);
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(elem))) {
|
||||
return;
|
||||
}
|
||||
BM_idmap_check_assign(data->pbvh->bm_idmap, elem);
|
||||
|
||||
switch (elem->head.htype) {
|
||||
case BM_VERT: {
|
||||
|
@ -414,44 +277,74 @@ ATTR_NO_OPT static void collapse_ring_callback_pre(BMElem *elem, void *userdata)
|
|||
|
||||
BM_log_vert_removed(data->pbvh->bm_log, v, -1);
|
||||
pbvh_bmesh_vert_remove(data->pbvh, v);
|
||||
BM_idmap_release(data->pbvh->bm_idmap, elem, false);
|
||||
break;
|
||||
}
|
||||
case BM_EDGE: {
|
||||
BMEdge *e = reinterpret_cast<BMEdge *>(elem);
|
||||
BM_log_edge_removed(data->pbvh->bm_log, e);
|
||||
BM_idmap_release(data->pbvh->bm_idmap, elem, false);
|
||||
break;
|
||||
}
|
||||
case BM_FACE: {
|
||||
BMFace *f = reinterpret_cast<BMFace *>(elem);
|
||||
BM_log_face_removed(data->pbvh->bm_log, f);
|
||||
pbvh_bmesh_face_remove(data->pbvh, f, false, false, false);
|
||||
BM_idmap_release(data->pbvh->bm_idmap, elem, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT static void check_new_elem_id(BMElem *elem, TraceData *data)
|
||||
{
|
||||
int id = BM_ELEM_CD_GET_INT(elem, data->pbvh->bm_idmap->cd_id_off[elem->head.htype]);
|
||||
if (id >= 0) {
|
||||
BMElem *existing = id < data->pbvh->bm_idmap->map_size ?
|
||||
BM_idmap_lookup(data->pbvh->bm_idmap, id) :
|
||||
nullptr;
|
||||
|
||||
if (existing) {
|
||||
BM_idmap_release(data->pbvh->bm_idmap, existing, true);
|
||||
}
|
||||
|
||||
BM_idmap_assign(data->pbvh->bm_idmap, elem, id);
|
||||
|
||||
if (existing) {
|
||||
BM_idmap_check_assign(data->pbvh->bm_idmap, existing);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_idmap_check_assign(data->pbvh->bm_idmap, elem);
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT static void collapse_ring_callback_post(BMElem *elem, void *userdata)
|
||||
{
|
||||
TraceData *data = static_cast<TraceData *>(userdata);
|
||||
|
||||
if (!data->visit.add(static_cast<void *>(elem))) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (elem->head.htype) {
|
||||
case BM_VERT: {
|
||||
BMVert *v = reinterpret_cast<BMVert *>(elem);
|
||||
|
||||
MSculptVert *mv = (MSculptVert *)BM_ELEM_CD_GET_VOID_P(v, data->pbvh->cd_sculpt_vert);
|
||||
mv->flag |= SCULPTVERT_NEED_VALENCE | SCULPTVERT_NEED_DISK_SORT;
|
||||
|
||||
check_new_elem_id(elem, data);
|
||||
BM_log_vert_added(data->pbvh->bm_log, v, -1);
|
||||
break;
|
||||
}
|
||||
case BM_EDGE: {
|
||||
BMEdge *e = reinterpret_cast<BMEdge *>(elem);
|
||||
check_new_elem_id(elem, data);
|
||||
|
||||
BM_log_edge_added(data->pbvh->bm_log, e);
|
||||
break;
|
||||
}
|
||||
case BM_FACE: {
|
||||
BMFace *f = reinterpret_cast<BMFace *>(elem);
|
||||
check_new_elem_id(elem, data);
|
||||
|
||||
BM_log_face_added(data->pbvh->bm_log, f);
|
||||
BKE_pbvh_bmesh_add_face(data->pbvh, f, false, false);
|
||||
break;
|
||||
|
@ -485,14 +378,14 @@ ATTR_NO_OPT static void vert_ring_do(BMVert *v,
|
|||
int facetag,
|
||||
int depth)
|
||||
{
|
||||
blender::Set<BMFace *> faces;
|
||||
blender::Set<BMFace *, 128> faces;
|
||||
|
||||
std::function<void(BMVert * v, int depth)> recurse = [&](BMVert *v, int depth) {
|
||||
if (!v->e) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int max_depth = 2;
|
||||
const int max_depth = 1;
|
||||
BMEdge *e = v->e;
|
||||
do {
|
||||
BMVert *v2 = BM_edge_other_vert(e, v);
|
||||
|
@ -520,8 +413,8 @@ ATTR_NO_OPT static void vert_ring_do(BMVert *v,
|
|||
recurse(v_extra, 0);
|
||||
}
|
||||
|
||||
blender::Set<BMVert *> verts;
|
||||
blender::Set<BMEdge *> edges;
|
||||
blender::Set<BMVert *, 64> verts;
|
||||
blender::Set<BMEdge *, 128> edges;
|
||||
|
||||
for (BMFace *f : faces) {
|
||||
BMLoop *l = f->l_first;
|
||||
|
@ -802,44 +695,14 @@ ATTR_NO_OPT BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
const int facetag = COLLAPSE_FACE_TAG;
|
||||
const int log_rings = 1;
|
||||
|
||||
blender::dyntopo::pbvh_bmesh_vert_remove(pbvh, v_del);
|
||||
|
||||
BM_log_edge_pre(pbvh->bm_log, e);
|
||||
tdata.visit.add(static_cast<void *>(e));
|
||||
|
||||
#ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, (BMElem *)e, true);
|
||||
#endif
|
||||
|
||||
BM_log_vert_removed(pbvh->bm_log, v_del, pbvh->cd_vert_mask_offset);
|
||||
tdata.visit.add(static_cast<void *>(v_del));
|
||||
#ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, (BMElem *)v_del, true);
|
||||
#endif
|
||||
|
||||
if (deleted_verts) {
|
||||
BLI_ghash_insert(deleted_verts, (void *)v_del, nullptr);
|
||||
}
|
||||
|
||||
pbvh_bmesh_check_nodes(pbvh);
|
||||
validate_vert_faces(pbvh, pbvh->header.bm, v_conn, false, true);
|
||||
|
||||
BMTracer tracer;
|
||||
BM_empty_tracer(&tracer, &tdata);
|
||||
|
||||
//#define USE_TRACER
|
||||
|
||||
#ifdef USE_TRACER
|
||||
tracer.on_vert_kill = col_on_vert_kill;
|
||||
tracer.on_edge_kill = col_on_edge_kill;
|
||||
tracer.on_face_kill = col_on_face_kill;
|
||||
|
||||
tracer.on_vert_create = col_on_vert_add;
|
||||
tracer.on_edge_create = col_on_edge_add;
|
||||
tracer.on_face_create = col_on_face_add;
|
||||
#else
|
||||
vert_ring_do(e->v1, e->v2, collapse_ring_callback_pre, &tdata, tag, facetag, log_rings - 1);
|
||||
#endif
|
||||
|
||||
if (!uvs_snapped) {
|
||||
float co[3];
|
||||
|
@ -861,9 +724,6 @@ ATTR_NO_OPT BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
copy_v3_v3(v_conn->co, co);
|
||||
}
|
||||
|
||||
#ifdef USE_TRACER
|
||||
#else
|
||||
tdata.visit.clear();
|
||||
vert_ring_do(v_conn,
|
||||
nullptr,
|
||||
collapse_ring_callback_post,
|
||||
|
@ -871,7 +731,6 @@ ATTR_NO_OPT BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
tag,
|
||||
facetag,
|
||||
log_rings - 1);
|
||||
#endif
|
||||
|
||||
if (!v_conn->e) {
|
||||
printf("%s: pbvh error, v_conn->e was null\n", __func__);
|
||||
|
@ -942,13 +801,7 @@ ATTR_NO_OPT BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
blender::dyntopo::pbvh_bmesh_vert_remove(pbvh, v_conn);
|
||||
}
|
||||
|
||||
// if (!tdata.visit.contains(static_cast<void *>(v_conn))) {
|
||||
BM_log_vert_removed(pbvh->bm_log, v_conn, 0);
|
||||
//}
|
||||
|
||||
#ifdef USE_NEW_IDMAP
|
||||
BM_idmap_release(pbvh->bm_idmap, (BMElem *)v_conn, true);
|
||||
#endif
|
||||
BM_vert_kill(pbvh->header.bm, v_conn);
|
||||
|
||||
bm_logstack_pop();
|
||||
|
@ -959,20 +812,6 @@ ATTR_NO_OPT BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
printf("%s: error: failed to remove vert from pbvh?\n", __func__);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
e = v_conn->e;
|
||||
if (e) {
|
||||
do {
|
||||
enext = BM_DISK_EDGE_NEXT(e, v_conn);
|
||||
BMVert *v2 = BM_edge_other_vert(e, v_conn);
|
||||
|
||||
MSculptVert *mv4 = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, v2);
|
||||
|
||||
} while ((e = enext) != v_conn->e);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (v_conn) {
|
||||
check_for_fins(pbvh, v_conn);
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ ATTR_NO_OPT int BM_idmap_alloc(BMIdMap *idmap, BMElem *elem)
|
|||
|
||||
while (idmap->freelist.size()) {
|
||||
id = idmap->freelist.pop_last();
|
||||
|
||||
|
||||
if (id == -1) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -3487,7 +3487,7 @@ void _BM_log_vert_removed(BMLog *log, BMVert *v, int UNUSED(cd_vert_mask_offset)
|
|||
BM_idmap_check_assign(log->idmap, (BMElem *)v);
|
||||
|
||||
if (bm_log_vert_from_id(log, (uint)bm_log_vert_id_get(log, v)) != v) {
|
||||
fprintf(DEBUG_FILE, "%s: idmap error\n", __func__);
|
||||
fprintf(DEBUG_FILE, "%s: idmap error: %d\n", __func__, bm_log_vert_id_get(log, v));
|
||||
bm_logstack_pop();
|
||||
return;
|
||||
}
|
||||
|
@ -3517,10 +3517,13 @@ BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, fl
|
|||
}
|
||||
|
||||
BM_log_edge_pre(log, e);
|
||||
BM_idmap_release(log->idmap, (BMElem *)e, true);
|
||||
|
||||
BMVert *newv = BM_edge_split(log->bm, e, v, newe, t);
|
||||
|
||||
BM_idmap_alloc(log->idmap, (BMElem *)newv);
|
||||
BM_idmap_alloc(log->idmap, (BMElem *)e);
|
||||
BM_idmap_alloc(log->idmap, (BMElem *)*newe);
|
||||
BM_idmap_alloc(log->idmap, (BMElem *)newv);
|
||||
|
||||
BMIter iter;
|
||||
BMLoop *l;
|
||||
|
|
|
@ -1164,7 +1164,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
|||
const int mode = RNA_enum_get(op->ptr, "mode");
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
|
||||
BKE_sculpt_face_sets_ensure(ob);
|
||||
ss->face_sets = BKE_sculpt_face_sets_ensure(ob);
|
||||
|
||||
/* Dyntopo not supported. */
|
||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
|
||||
|
|
Loading…
Reference in New Issue