Sculpt dyntopo: Cleanup past few commits

* Removed some ATTR_NO_OPTs
* Made pbvh_split_edges disallowed
  4-valence splits if cleanup topology
  mode is on
This commit is contained in:
Joseph Eagar 2021-08-26 20:10:54 -07:00
parent 8ea7c93a37
commit 3508c699fb
6 changed files with 117 additions and 57 deletions

View File

@ -156,7 +156,8 @@ static void pbvh_bmesh_verify(PBVH *pbvh);
static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge);
static void pbvh_split_edges(
PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge, bool ignore_isolated_edges);
void bm_log_message(const char *fmt, ...);
static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge *e_example)
@ -241,7 +242,7 @@ BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
atomic_cas_float(&v->co[2], z, z + co[2] * DYNTOPO_SAFE_SMOOTH_FAC);
}
ATTR_NO_OPT static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
{
BMEdge *e = v->e;
@ -255,7 +256,7 @@ ATTR_NO_OPT static void pbvh_kill_vert(PBVH *pbvh, BMVert *v)
BM_vert_kill(pbvh->bm, v);
}
ATTR_NO_OPT static void pbvh_log_vert_edges_kill(PBVH *pbvh, BMVert *v)
static void pbvh_log_vert_edges_kill(PBVH *pbvh, BMVert *v)
{
BMEdge *e = v->e;
@ -1619,7 +1620,7 @@ static void short_edge_queue_task_cb(void *__restrict userdata,
TGSET_ITER_END
}
ATTR_NO_OPT static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
{
bool origlen = f->len;
@ -2269,10 +2270,8 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
// pbvh_bmesh_check_nodes(pbvh);
}
static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
PBVH *pbvh,
BLI_Buffer *edge_loops,
int max_steps)
static bool pbvh_bmesh_subdivide_long_edges(
EdgeQueueContext *eq_ctx, PBVH *pbvh, BLI_Buffer *edge_loops, int max_steps, bool has_cleanup)
{
bool any_subdivided = false;
double time = PIL_check_seconds_timer();
@ -2370,7 +2369,7 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
#endif
#ifdef USE_NEW_SPLIT
pbvh_split_edges(pbvh, pbvh->bm, edges, BLI_array_len(edges));
pbvh_split_edges(pbvh, pbvh->bm, edges, BLI_array_len(edges), has_cleanup);
BLI_array_free(edges);
#endif
@ -2379,13 +2378,13 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
return any_subdivided;
}
ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BMEdge *e,
BMVert *v1,
BMVert *v2,
GHash *deleted_verts,
BLI_Buffer *deleted_faces,
EdgeQueueContext *eq_ctx)
static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BMEdge *e,
BMVert *v1,
BMVert *v2,
GHash *deleted_verts,
BLI_Buffer *deleted_faces,
EdgeQueueContext *eq_ctx)
{
BMVert *v_del, *v_conn;
@ -2738,10 +2737,10 @@ ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BLI_array_free(ls);
}
ATTR_NO_OPT static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
PBVH *pbvh,
BLI_Buffer *deleted_faces,
int max_steps)
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
PBVH *pbvh,
BLI_Buffer *deleted_faces,
int max_steps)
{
const float min_len_squared = pbvh->bm_min_edge_len * pbvh->bm_min_edge_len;
bool any_collapsed = false;
@ -3146,6 +3145,38 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
BLI_assert(len_squared_v3(view_normal) != 0.0f);
}
#if 1
{
size_t totmem;
BMesh *bm = pbvh->bm;
int vmem = (int)((size_t)bm->totvert * (sizeof(BMVert) + bm->vdata.totsize));
int emem = (int)((size_t)bm->totedge * (sizeof(BMEdge) + bm->edata.totsize));
int lmem = (int)((size_t)bm->totloop * (sizeof(BMLoop) + bm->ldata.totsize));
int fmem = (int)((size_t)bm->totface * (sizeof(BMFace) + bm->pdata.totsize));
double fvmem = (double)vmem / 1024.0 / 1024.0;
double femem = (double)emem / 1024.0 / 1024.0;
double flmem = (double)lmem / 1024.0 / 1024.0;
double ffmem = (double)fmem / 1024.0 / 1024.0;
printf("totmem: %.2fmb\n", fvmem + femem + flmem + ffmem);
printf("v: %.2f e: %.2f l: %.2f f: %.2f\n", fvmem, femem, flmem, ffmem);
printf("custom attributes only:\n");
vmem = (int)((size_t)bm->totvert * (bm->vdata.totsize));
emem = (int)((size_t)bm->totedge * (bm->edata.totsize));
lmem = (int)((size_t)bm->totloop * (bm->ldata.totsize));
fmem = (int)((size_t)bm->totface * (bm->pdata.totsize));
fvmem = (double)vmem / 1024.0 / 1024.0;
femem = (double)emem / 1024.0 / 1024.0;
flmem = (double)lmem / 1024.0 / 1024.0;
ffmem = (double)fmem / 1024.0 / 1024.0;
printf("v: %.2f e: %.2f l: %.2f f: %.2f\n", fvmem, femem, flmem, ffmem);
}
#endif
EdgeQueueContext eq_ctx = {NULL,
NULL,
pbvh->bm,
@ -3259,7 +3290,8 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
printf("max_steps %d\n", max_steps);
pbvh_bmesh_check_nodes(pbvh);
modified |= pbvh_bmesh_subdivide_long_edges(&eq_ctx, pbvh, &edge_loops, max_steps);
modified |= pbvh_bmesh_subdivide_long_edges(
&eq_ctx, pbvh, &edge_loops, max_steps, (mode & PBVH_Cleanup));
pbvh_bmesh_check_nodes(pbvh);
if (q.elems) {
@ -3508,7 +3540,8 @@ static const int splitmap[43][16] = {
{6, -1, 3, -1, 5, -1, 1, -1}, // 42
};
ATTR_NO_OPT static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge)
static void pbvh_split_edges(
PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge, bool ignore_isolated_edges)
{
BMFace **faces = NULL;
BLI_array_staticdeclare(faces, 512);
@ -3567,6 +3600,7 @@ ATTR_NO_OPT static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges,
BMEdge *e = edges[i];
BMLoop *l = e->l;
e->head.index = 0;
e->head.hflag |= SPLIT_TAG;
if (!l) {
@ -3588,19 +3622,33 @@ ATTR_NO_OPT static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges,
BMLoop *l = f->l_first;
// pbvh_bmesh_face_remove(pbvh, f, true, false, false);
BM_log_face_removed(pbvh->bm_log, f);
if (!ignore_isolated_edges) {
f->head.hflag |= SPLIT_TAG;
BM_log_face_removed(pbvh->bm_log, f);
}
else {
f->head.hflag &= ~SPLIT_TAG;
}
int mask = 0;
int j = 0;
int count = 0;
do {
if (l->e->head.hflag & SPLIT_TAG) {
mask |= 1 << j;
count++;
}
j++;
} while ((l = l->next) != f->l_first);
if (ignore_isolated_edges) {
do {
l->e->head.index = MAX2(l->e->head.index, count);
} while ((l = l->next) != f->l_first);
}
f->head.index = mask;
}
@ -3617,6 +3665,26 @@ ATTR_NO_OPT static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges,
continue;
}
if (ignore_isolated_edges && e->head.index < 2) {
BMLoop *l = e->l;
do {
l->f->head.hflag &= ~SPLIT_TAG;
} while ((l = l->radial_next) != e->l);
continue;
}
if (ignore_isolated_edges) {
BMLoop *l = e->l;
do {
if (!(l->f->head.hflag & SPLIT_TAG)) {
l->f->head.hflag |= SPLIT_TAG;
BM_log_face_removed(pbvh->bm_log, l->f);
}
} while ((l = l->radial_next) != e->l);
}
e->head.hflag &= ~SPLIT_TAG;
MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v1);
@ -3721,6 +3789,10 @@ ATTR_NO_OPT static void pbvh_split_edges(PBVH *pbvh, BMesh *bm, BMEdge **edges,
BMFace *f = faces[i];
int mask = 0;
if (!(f->head.hflag & SPLIT_TAG)) {
continue;
}
int ni = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
BMLoop *l = f->l_first;

View File

@ -70,7 +70,7 @@ Topology rake:
#include <stdio.h>
#include <stdlib.h>
ATTR_NO_OPT void pbvh_bmesh_check_nodes(PBVH *pbvh)
void pbvh_bmesh_check_nodes(PBVH *pbvh)
{
#if 0
for (int i = 0; i < pbvh->totnode; i++) {
@ -791,7 +791,7 @@ void BKE_pbvh_bmesh_update_origvert(
/************************* Called from pbvh.c *************************/
ATTR_NO_OPT bool BKE_pbvh_bmesh_check_origdata(PBVH *pbvh, BMVert *v, int stroke_id)
bool BKE_pbvh_bmesh_check_origdata(PBVH *pbvh, BMVert *v, int stroke_id)
{
MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
@ -2156,14 +2156,12 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
tri->eflag = mat_tri->eflag = 0;
for (int j = 0; j < 3; j++) {
BMLoop *l0 = loops[loops_idx[i][(j + 2) % 3]];
// BMLoop *l0 = loops[loops_idx[i][(j + 2) % 3]];
BMLoop *l = loops[loops_idx[i][j]];
BMLoop *l2 = loops[loops_idx[i][(j + 1) % 3]];
void **val = NULL;
bool has_edge = false;
if (BM_edge_exists(l->v, l2->v)) {
tri->eflag |= 1 << j;
mat_tri->eflag |= 1 << j;
@ -2759,7 +2757,7 @@ static void recursive_delete_nodes(PBVH *pbvh, int ni)
// static float bbox_overlap()
/* works by detect overlay of leaf nodes, destroying them
and then re-inserting them*/
ATTR_NO_OPT static void pbvh_bmesh_balance_tree(PBVH *pbvh)
static void pbvh_bmesh_balance_tree(PBVH *pbvh)
{
PBVHNode **stack = NULL;
float *overlaps = MEM_calloc_arrayN(pbvh->totnode, sizeof(float), "overlaps");
@ -3370,8 +3368,6 @@ BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
const int limit = 1024;
int leaf_limit = MAX2(limit / vsize, 4);
const int cd_vcol = CustomData_get_offset(&pbvh->bm->vdata, CD_PROP_COLOR);
BLI_mempool *pool = BLI_mempool_create(sizeof(ReVertNode) + sizeof(void *) * vsize, 0, 8192, 0);
ReVertNode **vnodemap = MEM_calloc_arrayN(pbvh->bm->totvert, sizeof(void *), "vnodemap");
@ -3458,8 +3454,6 @@ BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
continue;
}
ReVertNode *other_node = NULL;
ReVertNode *parent = BLI_mempool_calloc(pool);
parent->children[0] = node;
parent->totchild = 1;
@ -4232,7 +4226,6 @@ static MeshTest2 *meshtest2_from_bm(BMesh *bm)
BMVert *v;
BMEdge *e;
BMLoop *l;
BMFace *f;
BMIter iter;
@ -4342,7 +4335,6 @@ static MeshTest *meshtest_from_bm(BMesh *bm)
BMVert *v;
BMEdge *e;
BMLoop *l;
BMFace *f;
BMIter iter;
@ -4376,7 +4368,7 @@ static MeshTest *meshtest_from_bm(BMesh *bm)
}
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
m->f_l = f->l_first->head.index;
m->f_l[f->head.index] = f->l_first->head.index;
BMLoop *l = f->l_first;
do {
@ -4802,10 +4794,7 @@ void pbvh_bmesh_cache_test(CacheParams *params, BMesh **r_bm, PBVH **r_pbvh_out)
cd_face_node = bm->pdata.layers[cd_face_node].offset;
cd_face_area = bm->pdata.layers[cd_face_area].offset;
const int cd_fset = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
const int cd_dyn_vert = CustomData_get_offset(&bm->vdata, CD_DYNTOPO_VERT);
const int cd_mask = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
const int cd_vcol = CustomData_get_offset(&bm->vdata, CD_PROP_COLOR);
BMLog *bmlog = BM_log_create(bm, cd_dyn_vert);
PBVH *pbvh = BKE_pbvh_new();

View File

@ -149,7 +149,7 @@ BMVert *BM_vert_create(BMesh *bm,
* so unless you need a unique edge or know the edge won't exist,
* you should call with \a no_double = true.
*/
ATTR_NO_OPT BMEdge *BM_edge_create(
BMEdge *BM_edge_create(
BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
{
BMEdge *e;

View File

@ -41,7 +41,7 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
ATTR_NO_OPT int bm_save_id(BMesh *bm, BMElem *elem)
int bm_save_id(BMesh *bm, BMElem *elem)
{
if (!elem->head.data) {
return -1;
@ -55,7 +55,7 @@ ATTR_NO_OPT int bm_save_id(BMesh *bm, BMElem *elem)
}
}
ATTR_NO_OPT void bm_restore_id(BMesh *bm, BMElem *elem, int id)
void bm_restore_id(BMesh *bm, BMElem *elem, int id)
{
if (!elem->head.data || id == -1) {
return;

View File

@ -70,7 +70,7 @@ static char msg_buffer[256] = {0};
printf(__VA_ARGS__)
struct Mesh;
#else
# define GET_MSG(le) ""
# define GET_MSG(le) le ? "" : " "
# define SET_MSG(le)
# define LOGPRINT(...)
#endif
@ -598,7 +598,7 @@ static void bm_log_verts_unmake_pre(
}
// exec vert kill callbacks before killing faces
ATTR_NO_OPT static void bm_log_edges_unmake_pre(
static void bm_log_edges_unmake_pre(
BMesh *bm, BMLog *log, GHash *edges, BMLogEntry *entry, BMLogCallbacks *callbacks)
{
GHashIterator gh_iter;
@ -609,14 +609,14 @@ ATTR_NO_OPT static void bm_log_edges_unmake_pre(
BMEdge *e = bm_log_edge_from_id(log, id);
if (!e) {
printf("%s: missing edge; id: %d [%s]\n", __func__, (int)key, GET_MSG(le));
printf("%s: missing edge; id: %d [%s]\n", __func__, id, GET_MSG(le));
continue;
}
if (e->head.htype != BM_EDGE) {
printf("%s: not an edge; edge id: %d, type was: %d [%s]\n",
__func__,
(int)key,
id,
e->head.htype,
GET_MSG(le));
continue;
@ -632,7 +632,7 @@ ATTR_NO_OPT static void bm_log_edges_unmake_pre(
}
}
ATTR_NO_OPT static void bm_log_edges_unmake(
static void bm_log_edges_unmake(
BMesh *bm, BMLog *log, GHash *edges, BMLogEntry *entry, BMLogCallbacks *callbacks)
{
GHashIterator gh_iter;
@ -643,14 +643,14 @@ ATTR_NO_OPT static void bm_log_edges_unmake(
BMEdge *e = bm_log_edge_from_id(log, id);
if (!e) {
printf("%s: missing edge; edge id: %d [%s]\n", __func__, (int)key, GET_MSG(le));
printf("%s: missing edge; edge id: %d [%s]\n", __func__, id, GET_MSG(le));
continue;
}
if (e->head.htype != BM_EDGE) {
printf("%s: not an edge; edge id: %d, type: %d [%s]\n",
__func__,
(int)key,
id,
e->head.htype,
GET_MSG(le));
continue;
@ -678,7 +678,7 @@ static void bm_log_verts_unmake(
}
}
ATTR_NO_OPT static void bm_log_faces_unmake(
static void bm_log_faces_unmake(
BMesh *bm, BMLog *log, GHash *faces, BMLogEntry *entry, BMLogCallbacks *callbacks)
{
GHashIterator gh_iter;
@ -692,7 +692,7 @@ ATTR_NO_OPT static void bm_log_faces_unmake(
BMFace *f = bm_log_face_from_id(log, id);
if (!f) {
printf("bmlog error in %s: missing face %d\n", __func__, key);
printf("bmlog error in %s: missing face %d\n", __func__, id);
continue;
}
@ -771,7 +771,7 @@ static void bm_log_verts_restore(
}
}
ATTR_NO_OPT static void bm_log_edges_restore(
static void bm_log_edges_restore(
BMesh *bm, BMLog *log, GHash *edges, BMLogEntry *entry, BMLogCallbacks *callbacks)
{
GHashIterator gh_iter;
@ -1666,7 +1666,7 @@ static void log_idmap_free(BMLogEntry *entry)
}
}
ATTR_NO_OPT static void log_idmap_save(BMesh *bm, BMLog *log, BMLogEntry *entry)
static void log_idmap_save(BMesh *bm, BMLog *log, BMLogEntry *entry)
{
log_idmap_free(entry);
@ -2296,7 +2296,7 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
}
}
ATTR_NO_OPT void BM_log_edge_removed_post(BMLog *log, BMEdge *e)
void BM_log_edge_removed_post(BMLog *log, BMEdge *e)
{
BMLogEntry *entry = log->current_entry;
uint e_id = (uint)BM_ELEM_GET_ID(log->bm, e);
@ -2346,7 +2346,7 @@ ATTR_NO_OPT void BM_log_edge_removed_post(BMLog *log, BMEdge *e)
Splits e and logs the new edge and vertex.
e is assigned a new ID.
*/
ATTR_NO_OPT BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, float t)
BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, float t)
{
#if 0
BMVert *newv = BM_edge_split(log->bm, e, v, newe, t);

View File

@ -149,8 +149,7 @@ void BM_mesh_elem_toolflags_clear(BMesh *bm)
*
* \note ob is needed by multires
*/
ATTR_NO_OPT BMesh *BM_mesh_create(const BMAllocTemplate *allocsize,
const struct BMeshCreateParams *params)
BMesh *BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
{
/* allocate the structure */
BMesh *bm = MEM_callocN(sizeof(BMesh), __func__);