Sculpt: BMLog stuff

* BMLog now has a more fine-grained logging
  facility to track the call chains
  that produce specific log elements.
* Wrote a new function in bmesh_core.c to
  dump local geometry around an element to
  stdout in .obj format.
* Edge collapse now properly handles the
  fact that bmesh handles sharp flags
  inversely, i.e. edges *not* marked
  with BM_ELEM_SMOOTH are sharp.

* Wrote a new BMLog API that handles elements
  undergoing topological changes a bit better.
  - BM_log_[edge/face]_[pre/post]
  - Idea is to call the _pre before calling
    collapse or split edge, then _post afterwards.
  - No longer need to assign new IDs
    in certain cases to avoid confusing BMLog.
  - Other parts of BMLog may now be redundant;
    need to check.

* Deleted some #if 0'd code
* Fixed a bug in BLI_smallhash_ensure_p, it didn't properly
  set up state for when smallhash is used as a very simple
  set.
This commit is contained in:
Joseph Eagar 2021-10-13 02:12:30 -07:00
parent ffa62ecb60
commit b8fb46ab20
5 changed files with 873 additions and 860 deletions

File diff suppressed because it is too large Load Diff

View File

@ -19,12 +19,12 @@
#ifdef __GNUC__
/* I can't even *cast* signed ints in gcc's sign-conversion warning? gcc 10.3.0 -joeedh */
#pragma GCC diagnostic ignored "-Wsign-conversion"
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#ifdef __GNUC__
/* I can't even *cast* signed ints in gcc's sign-conversion warning? gcc 10.3.0 -joeedh */
#pragma GCC diagnostic ignored "-Wsign-conversion"
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
/** \file
@ -335,13 +335,16 @@ bool BLI_smallhash_ensure_p(SmallHash *sh, uintptr_t key, void ***item)
if (e->val == SMHASH_CELL_FREE || e->val == SMHASH_CELL_UNUSED) {
sh->nentries++;
sh->nfreecells--;
ret = false;
e->val = NULL;
}
else {
ret = true;
}
e->key = key;
*item = &e->val;
return ret;

View File

@ -27,6 +27,7 @@
#include "BLI_asan.h"
#include "BLI_linklist_stack.h"
#include "BLI_math_vector.h"
#include "BLI_smallhash.h"
#include "BLI_utildefines_stack.h"
#include "BLT_translation.h"
@ -40,6 +41,8 @@
#include "intern/bmesh_private.h"
#include "range_tree.h"
#include <stdarg.h>
/* use so valgrinds memcheck alerts us when undefined index is used.
* TESTING ONLY! */
// #define USE_DEBUG_INDEX_MEMCHECK
@ -581,6 +584,41 @@ BMFace *BM_face_create_verts(BMesh *bm,
return BM_face_create(bm, vert_arr, edge_arr, len, f_example, create_flag);
}
typedef enum {
IS_OK = 0,
IS_NULL = (1 << 0),
IS_WRONG_TYPE = (1 << 1),
IS_VERT_WRONG_EDGE_TYPE = (1 << 2),
IS_EDGE_NULL_DISK_LINK = (1 << 3),
IS_EDGE_WRONG_LOOP_TYPE = (1 << 4),
IS_EDGE_WRONG_FACE_TYPE = (1 << 5),
IS_EDGE_NULL_RADIAL_LINK = (1 << 6),
IS_EDGE_ZERO_FACE_LENGTH = (1 << 7),
IS_LOOP_WRONG_FACE_TYPE = (1 << 8),
IS_LOOP_WRONG_EDGE_TYPE = (1 << 9),
IS_LOOP_WRONG_VERT_TYPE = (1 << 10),
IS_LOOP_VERT_NOT_IN_EDGE = (1 << 11),
IS_LOOP_NULL_CYCLE_LINK = (1 << 12),
IS_LOOP_ZERO_FACE_LENGTH = (1 << 13),
IS_LOOP_WRONG_FACE_LENGTH = (1 << 14),
IS_LOOP_WRONG_RADIAL_LENGTH = (1 << 15),
IS_FACE_NULL_LOOP = (1 << 16),
IS_FACE_WRONG_LOOP_FACE = (1 << 17),
IS_FACE_NULL_EDGE = (1 << 18),
IS_FACE_NULL_VERT = (1 << 19),
IS_FACE_LOOP_VERT_NOT_IN_EDGE = (1 << 20),
IS_FACE_LOOP_WRONG_RADIAL_LENGTH = (1 << 21),
IS_FACE_LOOP_WRONG_DISK_LENGTH = (1 << 22),
IS_FACE_LOOP_DUPE_LOOP = (1 << 23),
IS_FACE_LOOP_DUPE_VERT = (1 << 24),
IS_FACE_LOOP_DUPE_EDGE = (1 << 25),
IS_FACE_WRONG_LENGTH = (1 << 26),
} BMeshInternalError;
#ifndef NDEBUG
/**
@ -592,39 +630,7 @@ BMFace *BM_face_create_verts(BMesh *bm,
int bmesh_elem_check(void *element, const char htype)
{
BMHeader *head = element;
enum {
IS_NULL = (1 << 0),
IS_WRONG_TYPE = (1 << 1),
IS_VERT_WRONG_EDGE_TYPE = (1 << 2),
IS_EDGE_NULL_DISK_LINK = (1 << 3),
IS_EDGE_WRONG_LOOP_TYPE = (1 << 4),
IS_EDGE_WRONG_FACE_TYPE = (1 << 5),
IS_EDGE_NULL_RADIAL_LINK = (1 << 6),
IS_EDGE_ZERO_FACE_LENGTH = (1 << 7),
IS_LOOP_WRONG_FACE_TYPE = (1 << 8),
IS_LOOP_WRONG_EDGE_TYPE = (1 << 9),
IS_LOOP_WRONG_VERT_TYPE = (1 << 10),
IS_LOOP_VERT_NOT_IN_EDGE = (1 << 11),
IS_LOOP_NULL_CYCLE_LINK = (1 << 12),
IS_LOOP_ZERO_FACE_LENGTH = (1 << 13),
IS_LOOP_WRONG_FACE_LENGTH = (1 << 14),
IS_LOOP_WRONG_RADIAL_LENGTH = (1 << 15),
IS_FACE_NULL_LOOP = (1 << 16),
IS_FACE_WRONG_LOOP_FACE = (1 << 17),
IS_FACE_NULL_EDGE = (1 << 18),
IS_FACE_NULL_VERT = (1 << 19),
IS_FACE_LOOP_VERT_NOT_IN_EDGE = (1 << 20),
IS_FACE_LOOP_WRONG_RADIAL_LENGTH = (1 << 21),
IS_FACE_LOOP_WRONG_DISK_LENGTH = (1 << 22),
IS_FACE_LOOP_DUPE_LOOP = (1 << 23),
IS_FACE_LOOP_DUPE_VERT = (1 << 24),
IS_FACE_LOOP_DUPE_EDGE = (1 << 25),
IS_FACE_WRONG_LENGTH = (1 << 26),
} err = 0;
BMeshInternalError err = IS_OK;
if (!element) {
return IS_NULL;
@ -799,7 +805,7 @@ int bmesh_elem_check(void *element, const char htype)
break;
}
BMESH_ASSERT(err == 0);
// BMESH_ASSERT(err == 0);
return err;
}
@ -2150,6 +2156,331 @@ static void check_vert_faces(BMVert *v_target)
}
}
#ifdef _
# undef _
#endif
#define _(s) \
case s: \
return #s;
static const char *get_err_code_str(BMeshInternalError code)
{
switch (code) {
_(IS_OK)
_(IS_NULL)
_(IS_WRONG_TYPE)
_(IS_VERT_WRONG_EDGE_TYPE)
_(IS_EDGE_NULL_DISK_LINK)
_(IS_EDGE_WRONG_LOOP_TYPE)
_(IS_EDGE_WRONG_FACE_TYPE)
_(IS_EDGE_NULL_RADIAL_LINK)
_(IS_EDGE_ZERO_FACE_LENGTH)
_(IS_LOOP_WRONG_FACE_TYPE)
_(IS_LOOP_WRONG_EDGE_TYPE)
_(IS_LOOP_WRONG_VERT_TYPE)
_(IS_LOOP_VERT_NOT_IN_EDGE)
_(IS_LOOP_NULL_CYCLE_LINK)
_(IS_LOOP_ZERO_FACE_LENGTH)
_(IS_LOOP_WRONG_FACE_LENGTH)
_(IS_LOOP_WRONG_RADIAL_LENGTH)
_(IS_FACE_NULL_LOOP)
_(IS_FACE_WRONG_LOOP_FACE)
_(IS_FACE_NULL_EDGE)
_(IS_FACE_NULL_VERT)
_(IS_FACE_LOOP_VERT_NOT_IN_EDGE)
_(IS_FACE_LOOP_WRONG_RADIAL_LENGTH)
_(IS_FACE_LOOP_WRONG_DISK_LENGTH)
_(IS_FACE_LOOP_DUPE_LOOP)
_(IS_FACE_LOOP_DUPE_VERT)
_(IS_FACE_LOOP_DUPE_EDGE)
_(IS_FACE_WRONG_LENGTH)
}
return "(unknown-code)";
}
#undef _
static char *get_err_str(int err)
{
static char buf[1024];
buf[0] = 0;
for (int i = 0; i < 27; i++) {
if (err & (1 << i)) {
strcat(buf, get_err_code_str(1 << i));
}
}
return buf;
}
void bm_local_obj_free(char *str, char *fixed)
{
if (str != fixed) {
MEM_freeN(str);
}
}
#define LOCAL_OBJ_SIZE 512
static char *obj_append_line(char *line, char *str, char *fixed, int *size, int *i)
{
int len = (int)strlen(line);
if (*i + len >= *size) {
*size += *size >> 1;
if (str == fixed) {
str = MEM_mallocN(*size, "buf");
memcpy(str, fixed, LOCAL_OBJ_SIZE);
}
else {
str = MEM_reallocN(str, *size);
}
}
memcpy(str + *i, line, len);
str[*i + len] = 0;
*i += len;
return str;
}
static char *bm_save_local_obj_text(
BMesh *bm, int depth, char buf[LOCAL_OBJ_SIZE], const char *fmt, ...)
{
va_list vl;
va_start(vl, fmt);
buf[0] = 0;
BMVert **vs = NULL;
BMEdge **es = NULL;
BMFace **fs = NULL;
BLI_array_staticdeclare(vs, 64);
BLI_array_staticdeclare(es, 64);
BLI_array_staticdeclare(fs, 64);
SmallHash visit;
BLI_smallhash_init(&visit);
const char *c = fmt;
while (*c) {
if (*c == ' ' || *c == '\t') {
c++;
continue;
}
void *ptr = va_arg(vl, void *);
switch (*c) {
case 'v':
BLI_array_append(vs, (BMVert *)ptr);
break;
case 'e':
BLI_array_append(es, (BMEdge *)ptr);
break;
case 'f':
BLI_array_append(fs, (BMFace *)ptr);
break;
}
c++;
}
va_end(vl);
int tag = 4;
for (int i = 0; i < BLI_array_len(fs); i++) {
BMFace *f = fs[i];
BMLoop *l = f->l_first;
do {
l->v->head.api_flag &= ~tag;
l->e->head.api_flag &= ~tag;
} while ((l = l->next) != f->l_first);
}
for (int i = 0; i < BLI_array_len(es); i++) {
BMEdge *e = es[i];
e->v1->head.api_flag &= ~tag;
e->v2->head.api_flag &= ~tag;
}
for (int i = 0; i < BLI_array_len(vs); i++) {
vs[i]->head.api_flag |= tag;
}
for (int i = 0; i < BLI_array_len(es); i++) {
BMEdge *e = es[i];
if (!(e->v1->head.api_flag & tag)) {
BLI_array_append(vs, e->v1);
e->v1->head.api_flag |= tag;
}
if (!(e->v2->head.api_flag & tag)) {
BLI_array_append(vs, e->v2);
e->v2->head.api_flag |= tag;
}
e->head.api_flag |= tag;
}
for (int i = 0; i < BLI_array_len(fs); i++) {
BMFace *f = fs[i];
BMLoop *l = f->l_first;
do {
if (!(l->v->head.api_flag & tag)) {
BLI_array_append(vs, l->v);
l->v->head.api_flag |= tag;
}
if (!(l->e->head.api_flag & tag)) {
BLI_array_append(es, l->e);
l->e->head.api_flag |= tag;
}
} while ((l = l->next) != f->l_first);
}
struct {
BMVert *v;
int depth;
} stack[256];
SmallHash elemset;
BLI_smallhash_init(&elemset);
for (int i = 0; i < BLI_array_len(vs); i++) {
BLI_smallhash_insert(&elemset, (uintptr_t)vs[i], NULL);
}
for (int i = 0; i < BLI_array_len(es); i++) {
BLI_smallhash_insert(&elemset, (uintptr_t)es[i], NULL);
}
for (int i = 0; i < BLI_array_len(fs); i++) {
BLI_smallhash_insert(&elemset, (uintptr_t)fs[i], NULL);
}
for (int i = 0; i < BLI_array_len(vs); i++) {
int si = 0;
// connected islands only
if (i > 0) {
break;
}
stack[si].v = vs[i];
stack[si].depth = 0;
si++;
while (si > 0) {
si--;
BMVert *v = stack[si].v;
int startdepth = stack[si].depth;
void **val;
if (!BLI_smallhash_ensure_p(&elemset, (uintptr_t)v, &val)) {
*val = NULL;
BLI_array_append(vs, v);
}
if (!v->e || stack[si].depth > depth) {
continue;
}
BMEdge *e = v->e;
do {
if (!BLI_smallhash_ensure_p(&visit, (uintptr_t)e, &val)) {
*val = NULL;
stack[si].v = e->v1;
stack[si].depth = startdepth + 1;
si++;
stack[si].v = e->v2;
stack[si].depth = startdepth + 1;
si++;
}
if (!e->l) {
continue;
}
BMLoop *l = e->l;
do {
if (!BLI_smallhash_ensure_p(&visit, (uintptr_t)l->f, &val)) {
if (!BLI_smallhash_ensure_p(&elemset, (uintptr_t)l->f, &val)) {
*val = NULL;
BLI_array_append(fs, l->f);
}
BMLoop *l2 = l;
do {
if (!BLI_smallhash_ensure_p(&visit, (uintptr_t)l->v, &val)) {
*val = NULL;
stack[si].v = l->v;
stack[si].depth = startdepth + 1;
si++;
}
} while ((l2 = l2->next) != l);
}
} while ((l = l->radial_next) != e->l);
} while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
}
}
char *str = buf;
int size = LOCAL_OBJ_SIZE - 1;
int stri = 0;
for (int i = 0; i < BLI_array_len(es); i++) {
es[i]->head.api_flag &= ~tag;
}
char line[256];
for (int i = 0; i < BLI_array_len(vs); i++) {
BMVert *v = vs[i];
v->head.index = i + 1;
sprintf(line, "v %.4f %.4f %.4f\n", v->co[0], v->co[1], v->co[2]);
str = obj_append_line(line, str, buf, &size, &stri);
}
for (int i = 0; i < BLI_array_len(fs); i++) {
BMFace *f = fs[i];
BMLoop *l = f->l_first;
sprintf(line, "f");
str = obj_append_line(line, str, buf, &size, &stri);
do {
sprintf(line, " %d", l->v->head.index);
str = obj_append_line(line, str, buf, &size, &stri);
} while ((l = l->next) != f->l_first);
str = obj_append_line("\n", str, buf, &size, &stri);
}
BLI_smallhash_release(&visit);
BLI_smallhash_release(&elemset);
BLI_array_free(vs);
BLI_array_free(es);
BLI_array_free(fs);
return str;
}
/**
* \brief Join Vert Kill Edge (JVKE)
*
@ -2168,11 +2499,33 @@ static void check_vert_faces(BMVert *v_target)
* +-+-+-+ +-+-+-+
* </pre>
*/
static void trigger_jvke_error(int err, char *obj_text)
{
printf("========= ERROR %s============\n\n%s\n\n", get_err_str(err), obj_text);
}
#if 0
# define JVKE_CHECK_ELEMENT(elem) \
{ \
int err = 0; \
if ((err = bmesh_elem_check(elem, (elem)->head.htype))) { \
trigger_jvke_error(err, saved_obj); \
} \
}
#else
# define JVKE_CHECK_ELEMENT(elem)
#endif
BMVert *bmesh_kernel_join_vert_kill_edge(
BMesh *bm, BMEdge *e, BMVert *v_kill, const bool do_del, const bool combine_flags)
{
BMVert *v_conn = BM_edge_other_vert(e, v_kill);
char buf[LOCAL_OBJ_SIZE];
char *saved_obj = bm_save_local_obj_text(bm, 2, buf, "e", e);
bm_local_obj_free(saved_obj, buf);
BMFace **fs = NULL;
BMEdge **deles = NULL;
BLI_array_staticdeclare(fs, 32);
@ -2181,6 +2534,9 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
BMVert *v_del = BM_edge_other_vert(e, v_conn);
const int tag = _FLAG_WALK_ALT; // using bmhead.api_flag here
JVKE_CHECK_ELEMENT(v_conn);
JVKE_CHECK_ELEMENT(v_del);
/* first clear tags */
for (int i = 0; i < 2; i++) {
BMVert *v = i ? v_del : v_conn;
@ -2284,7 +2640,15 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
if ((e3 = BM_edge_exists(v_conn, v_other))) {
if (combine_flags) {
/* TODO: stop flagging sharp edges by the abscene of the BM_ELEM_SMOOTH flag*/
bool remove_smooth = !BM_elem_flag_test(l->e, BM_ELEM_SMOOTH);
remove_smooth = remove_smooth || !BM_elem_flag_test(e3, BM_ELEM_SMOOTH);
e3->head.hflag |= l->e->head.hflag;
if (remove_smooth) {
BM_elem_flag_disable(e3, BM_ELEM_SMOOTH);
}
}
/* flag for later deletion */
@ -2305,7 +2669,12 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
}
for (int i = 0; i < BLI_array_len(deles); i++) {
deles[i]->l = NULL;
BMEdge *e2 = deles[i];
if (e2->l != NULL) {
printf("%s: eek!\n", __func__);
}
e2->l = NULL;
BM_edge_kill(bm, deles[i]);
}
@ -2316,7 +2685,7 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
/* validate */
l = f->l_first;
do {
lnext = l->next;
lnext = l == l->next ? NULL : l->next;
if (l->v == l->next->v) {
l->prev->next = l->next;
@ -2327,9 +2696,14 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
}
l->f->len--;
if (l == l->f->l_first) {
l->f->l_first = NULL;
}
bm_kill_only_loop(bm, l);
}
} while ((l = lnext) != f->l_first);
} while (lnext && (l = lnext) != f->l_first);
if (f->len <= 2) {
/* kill face */
@ -2375,8 +2749,34 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
} while ((l = l->next) != f->l_first);
}
JVKE_CHECK_ELEMENT(v_conn);
for (int step = 0; step < 2; step++) {
BMVert *v = step ? v_conn : v_del;
BMEdge *e1 = v->e;
if (e1) {
do {
JVKE_CHECK_ELEMENT(e1);
BMLoop *l = e1->l;
if (!l) {
continue;
}
do {
JVKE_CHECK_ELEMENT(l);
JVKE_CHECK_ELEMENT(l->v);
JVKE_CHECK_ELEMENT(l->e);
JVKE_CHECK_ELEMENT(l->f);
} while ((l = l->radial_next) != e1->l);
} while ((e1 = BM_DISK_EDGE_NEXT(e1, v)) != v->e);
}
}
// printf("v_del: %p, v_conn: %p\n", v_del->e, v_conn->e);
if (do_del) {
JVKE_CHECK_ELEMENT(v_del);
BM_vert_kill(bm, v_del);
}

View File

@ -35,6 +35,7 @@
#include "BLI_array.h"
#include "BLI_compiler_attrs.h"
#include "BLI_ghash.h"
#include "BLI_hash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
@ -131,6 +132,58 @@ typedef struct myiter {
//#define DEBUG_LOG_REFCOUNTNG
//#define PRINT_LOG_REF_COUNTING
#ifdef DEBUG_LOG_CALL_STACKS
static struct {
char tag[1024];
} fine_namestack[256] = {0};
static int fine_namestack_i = 0;
static SmallHash *small_str_hash = NULL;
# define bm_logstack_head _bm_logstack_head
# define SET_TRACE(le) (le)->tag = bm_logstack_head()
# define GET_TRACE(le) ((le)->tag)
const char *small_str_get(const char *str)
{
void **val;
uint hash = BLI_hash_string(str);
if (!small_str_hash) {
small_str_hash = MEM_callocN(sizeof(*small_str_hash), "small_str_hash");
BLI_smallhash_init(small_str_hash);
}
if (!BLI_smallhash_ensure_p(small_str_hash, (uintptr_t)hash, &val)) {
*val = strdup(str);
}
return (const char *)*val;
}
void _bm_logstack_push(const char *name)
{
fine_namestack_i++;
strcpy(fine_namestack[fine_namestack_i].tag, fine_namestack[fine_namestack_i - 1].tag);
strcat(fine_namestack[fine_namestack_i].tag, ".");
strcat(fine_namestack[fine_namestack_i].tag, name);
}
const char *_bm_logstack_head()
{
return small_str_get(fine_namestack[fine_namestack_i].tag);
}
void _bm_logstack_pop()
{
fine_namestack_i--;
}
#else
# define SET_TRACE(le)
# define GET_TRACE(le) (((void *)le) ? __func__ : __func__)
#endif
#ifdef DEBUG_LOG_REFCOUNTNG
static struct {
char tag[4192];
@ -217,6 +270,12 @@ struct BMLogEntry {
GHash *deleted_edges_post; // used for split edges
GHash *deleted_faces;
GHash *topo_modified_edges_pre;
GHash *topo_modified_faces_pre;
GHash *topo_modified_edges_post;
GHash *topo_modified_faces_post;
/* Elements that were not in the previous entry, but are in the
* result of this entry */
GHash *added_verts;
@ -316,6 +375,10 @@ typedef struct BMLogVert {
char msg[64];
#endif
#ifdef DEBUG_LOG_CALL_STACKS
const char *tag;
#endif
float co[3];
float no[3];
char hflag;
@ -327,6 +390,10 @@ typedef struct BMLogEdge {
char msg[64];
#endif
#ifdef DEBUG_LOG_CALL_STACKS
const char *tag;
#endif
uint v1, v2;
char hflag;
void *customdata;
@ -340,6 +407,10 @@ typedef struct {
char msg[64];
#endif
#ifdef DEBUG_LOG_CALL_STACKS
const char *tag;
#endif
uint *v_ids;
uint *l_ids;
void **customdata;
@ -353,10 +424,48 @@ typedef struct {
void *customdata_res[MAX_FACE_RESERVED];
uint v_ids_res[MAX_FACE_RESERVED];
uint l_ids_res[MAX_FACE_RESERVED];
uint id;
} BMLogFace;
/************************* Get/set element IDs ************************/
BLI_INLINE int get_edge_id(BMesh *bm, BMEdge *e)
{
return BM_ELEM_GET_ID(bm, e);
#if 0
return id;
int id = BM_ELEM_GET_ID(bm, e);
int v1id = BM_ELEM_GET_ID(bm, e->v1);
int v2id = BM_ELEM_GET_ID(bm, e->v2);
// if (v2id < v1id) {
// SWAP(int, v2id, v1id);
//}
id = id | (((v1id ^ v2id) & 1023) << 20);
// return id;
#endif
}
BLI_INLINE int get_face_id(BMesh *bm, BMFace *f)
{
return BM_ELEM_GET_ID(bm, f);
#if 0
int id = BM_ELEM_GET_ID(bm, f);
int id2 = 0;
BMLoop *l = f->l_first;
do {
id2 ^= BM_ELEM_GET_ID(bm, l->v);
} while ((l = l->next) != f->l_first);
return id + ((id2 & 1023) << 20);
#endif
}
/* bypass actual hashing, the keys don't overlap */
#define logkey_hash BLI_ghashutil_inthash_p_simple
#define logkey_cmp BLI_ghashutil_intcmp
@ -477,7 +586,7 @@ BMVert *BM_log_id_vert_get(BMLog *log, uint id)
/* Get the vertex's unique ID from the log */
static uint bm_log_edge_id_get(BMLog *log, BMEdge *e)
{
return (uint)BM_ELEM_GET_ID(log->bm, e);
return (uint)get_edge_id(log->bm, e);
}
/* Get a vertex from its unique ID */
@ -494,7 +603,7 @@ BMEdge *BM_log_id_edge_get(BMLog *log, uint id)
/* Get the face's unique ID from the log */
static uint bm_log_face_id_get(BMLog *log, BMFace *f)
{
return (uint)BM_ELEM_GET_ID(log->bm, f);
return (uint)get_face_id(log->bm, f);
}
uint BM_log_vert_id_get(BMLog *log, BMVert *v)
@ -557,7 +666,7 @@ static void bm_log_face_customdata(BMesh *bm, BMLog *log, BMFace *f, BMLogFace *
BMLogEntry *entry = log->current_entry;
if (!entry || !lf) {
printf("bmlog error\n");
printf("%s: bmlog error\n", __func__);
return;
}
@ -611,6 +720,8 @@ static BMLogVert *bm_log_vert_alloc(BMLog *log,
BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
lv->customdata = NULL;
SET_TRACE(lv);
bm_log_vert_bmvert_copy(log, entry, lv, v, -1, log_customdata);
return lv;
@ -620,7 +731,7 @@ static void bm_log_edge_bmedge_copy(
BMLog *log, BMLogEntry *entry, BMLogEdge *le, BMEdge *e, bool copy_customdata)
{
if (e->head.htype != BM_EDGE) {
printf("%s: e is not an edge; htype: %d\n", __func__, (int)e->head.htype);
printf("%s: e is not an edge; htype: %d\n", GET_TRACE(le), (int)e->head.htype);
}
le->v1 = (uint)BM_ELEM_GET_ID(log->bm, e->v1);
@ -641,6 +752,8 @@ static BMLogEdge *bm_log_edge_alloc(BMLog *log, BMEdge *e, bool log_customdata)
BMLogEdge *le = BLI_mempool_alloc(entry->pool_edges);
le->customdata = NULL;
SET_TRACE(le);
#ifdef DO_LOG_PRINT
le->msg[0] = 0;
#endif
@ -657,6 +770,9 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
BMLogFace *lf = BLI_mempool_alloc(entry->pool_faces);
lf->len = (size_t)f->len;
lf->id = (uint)BM_ELEM_GET_ID(log->bm, f);
SET_TRACE(lf);
bool have_loop_ids = (log->bm->idmap.flag & BM_LOOP);
@ -708,12 +824,12 @@ static void bm_log_verts_unmake_pre(
BMVert *v = bm_log_vert_from_id(log, id);
if (!v) {
printf("bm_log error; vertex id: %p\n", key);
printf("%s: vertex id: %p\n", GET_TRACE(lv), key);
continue;
}
if (v->head.htype != BM_VERT) {
printf("bm_log error; vertex id: %p, type was: %d\n", key, v->head.htype);
printf("%s: vertex id: %p, type was: %d\n", GET_TRACE(lv), key, v->head.htype);
continue;
}
@ -733,20 +849,18 @@ static void bm_log_edges_unmake_pre(
{
GHashIterator gh_iter;
GHASH_ITER (gh_iter, edges) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogEdge *le = BLI_ghashIterator_getValue(&gh_iter);
uint id = POINTER_AS_UINT(key);
BMEdge *e = bm_log_edge_from_id(log, id);
BMEdge *e = bm_log_edge_from_id(log, le->id);
if (!e) {
printf("%s: missing edge; id: %d [%s]\n", __func__, id, GET_MSG(le));
printf("%s: missing edge; id: %d [%s]\n", GET_TRACE(le), le->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__,
id,
GET_TRACE(le),
le->id,
e->head.htype,
GET_MSG(le));
continue;
@ -767,20 +881,18 @@ static void bm_log_edges_unmake(
{
GHashIterator gh_iter;
GHASH_ITER (gh_iter, edges) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
uint id = POINTER_AS_UINT(key);
BMLogEdge *le = BLI_ghashIterator_getValue(&gh_iter);
BMEdge *e = bm_log_edge_from_id(log, id);
BMEdge *e = bm_log_edge_from_id(log, le->id);
if (!e) {
printf("%s: missing edge; edge id: %d [%s]\n", __func__, id, GET_MSG(le));
printf("%s: missing edge; edge id: %d [%s]\n", GET_TRACE(le), le->id, GET_MSG(le));
continue;
}
if (e->head.htype != BM_EDGE) {
printf("%s: not an edge; edge id: %d, type: %d [%s]\n",
__func__,
id,
GET_TRACE(le),
le->id,
e->head.htype,
GET_MSG(le));
continue;
@ -798,9 +910,10 @@ static void bm_log_verts_unmake(
void *key = BLI_ghashIterator_getKey(&gh_iter);
uint id = POINTER_AS_UINT(key);
BMVert *v = bm_log_vert_from_id(log, id);
BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
if (!v || v->head.htype != BM_VERT) {
printf("bmlog error. vertex id: %p\n", key);
printf("%s: error, vertex id: %p\n", GET_TRACE(lv), key);
continue;
}
@ -816,18 +929,16 @@ static void bm_log_faces_unmake(
BLI_array_staticdeclare(e_tri, 32);
GHASH_ITER (gh_iter, faces) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
uint id = POINTER_AS_UINT(key);
BMFace *f = bm_log_face_from_id(log, id);
BMFace *f = bm_log_face_from_id(log, lf->id);
if (!f) {
printf("bmlog error in %s: missing face %d\n", __func__, id);
printf("%s: missing face %d\n", GET_TRACE(lf), lf->id);
continue;
}
if (f->head.htype != BM_FACE) {
printf("bmlog error in %s: f was not a face, type was: %d\n", __func__, f->head.htype);
printf("%s: f was not a face, type was: %d\n", GET_TRACE(lf), f->head.htype);
continue;
}
@ -906,30 +1017,25 @@ static void bm_log_edges_restore(
{
GHashIterator gh_iter;
GHASH_ITER (gh_iter, edges) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogEdge *le = BLI_ghashIterator_getValue(&gh_iter);
uint id = POINTER_AS_UINT(key);
if (id != le->id) {
printf("%s: id differs from stored id in BMLogEdge!\n", __func__);
}
BMVert *v1 = bm_log_vert_from_id(log, le->v1);
BMVert *v2 = bm_log_vert_from_id(log, le->v2);
if (!v1 || !v2) {
printf("%s: missing edge verts: %p %p\n", __func__, v1, v2);
printf("%s: missing edge verts: %p %p\n", GET_TRACE(le), v1, v2);
continue;
}
if (v1->head.htype != BM_VERT || v2->head.htype != BM_VERT) {
printf("%s: edge verts were not verts: %d %d\n", __func__, v1->head.htype, v2->head.htype);
printf(
"%s: edge verts were not verts: %d %d\n", GET_TRACE(le), v1->head.htype, v2->head.htype);
continue;
}
BMEdge *e = BM_edge_exists(v1, v2);
if (e) {
printf("%s: edge already %d existed\n", __func__, (int)id);
printf("%s: edge already %d existed\n", GET_TRACE(le), (int)le->id);
bm_free_id(bm, (BMElem *)e);
}
else {
@ -944,10 +1050,10 @@ static void bm_log_edges_restore(
}
#endif
bm_assign_id(bm, (BMElem *)e, POINTER_AS_UINT(key), false);
bm_assign_id(bm, (BMElem *)e, le->id, false);
if ((uint)BM_ELEM_GET_ID(bm, e) != id) {
printf("%s: error assigning id\n", __func__);
if ((uint)BM_ELEM_GET_ID(bm, e) != le->id) {
printf("%s: error assigning id\n", GET_TRACE(le));
}
if (callbacks) {
@ -966,7 +1072,6 @@ static void bm_log_faces_restore(
bool have_loop_ids = (log->bm->idmap.flag & BM_LOOP);
GHASH_ITER (gh_iter, faces) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
BLI_array_clear(vs_tmp);
@ -994,7 +1099,7 @@ static void bm_log_faces_restore(
}
if (bad) {
printf("Undo error! %p\n", v);
printf("%s: Undo error! %p\n", GET_TRACE(lf), v);
break;
}
}
@ -1004,14 +1109,15 @@ static void bm_log_faces_restore(
}
if (v->head.htype != BM_VERT) {
printf("vert %d in face %d was not a vertex\n", (int)lf->v_ids[i], POINTER_AS_INT(key));
printf(
"%s: vert %d in face %d was not a vertex\n", GET_TRACE(lf), (int)lf->v_ids[i], lf->id);
continue;
}
BLI_array_append(vs_tmp, v);
}
if ((int)BLI_array_len(vs_tmp) < 2) {
printf("severely malformed face %d in %s\n", POINTER_AS_INT(key), __func__);
printf("%s: severely malformed face %d in %s\n", GET_TRACE(lf), lf->id, __func__);
continue;
}
@ -1041,7 +1147,7 @@ static void bm_log_faces_restore(
CustomData_bmesh_copy_data(&entry->pdata, &bm->pdata, lf->customdata_f, &f->head.data);
}
bm_assign_id(bm, (BMElem *)f, POINTER_AS_UINT(key), false);
bm_assign_id(bm, (BMElem *)f, lf->id, false);
BMLoop *l = f->l_first;
int j = 0;
@ -1077,12 +1183,12 @@ static void bm_log_vert_values_swap(
BMVert *v = bm_log_vert_from_id(log, id);
if (!v) {
printf("missing vert in bmlog! %d", id);
printf("%s: missing vert in bmlog! %d", GET_TRACE(lv), id);
continue;
}
if (v->head.htype != BM_VERT) {
printf("not a vertex: %d\n", v->head.htype);
printf("%s: not a vertex: %d\n", GET_TRACE(lv), v->head.htype);
continue;
}
@ -1119,10 +1225,8 @@ static void bm_log_edge_values_swap(
GHashIterator gh_iter;
GHASH_ITER (gh_iter, edges) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogEdge *le = BLI_ghashIterator_getValue(&gh_iter);
uint id = POINTER_AS_UINT(key);
BMEdge *e = bm_log_edge_from_id(log, id);
BMEdge *e = bm_log_edge_from_id(log, le->id);
SWAP(char, e->head.hflag, le->hflag);
@ -1156,10 +1260,8 @@ static void bm_log_face_values_swap(BMLog *log,
GHashIterator gh_iter;
GHASH_ITER (gh_iter, faces) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
uint id = POINTER_AS_UINT(key);
BMFace *f = bm_log_face_from_id(log, id);
BMFace *f = bm_log_face_from_id(log, lf->id);
swap_v3_v3(f->no, lf->no);
SWAP(char, f->head.hflag, lf->hflag);
@ -1226,6 +1328,11 @@ static BMLogEntry *bm_log_entry_create(BMLogEntryType type)
entry->deleted_edges_post = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->deleted_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->topo_modified_edges_pre = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->topo_modified_edges_post = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->topo_modified_faces_pre = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->topo_modified_faces_post = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->added_verts = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->added_edges = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
entry->added_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
@ -1263,6 +1370,11 @@ static void bm_log_entry_free_direct(BMLogEntry *entry)
BLI_ghash_free(entry->deleted_edges_post, NULL, NULL);
BLI_ghash_free(entry->deleted_faces, NULL, NULL);
BLI_ghash_free(entry->topo_modified_edges_pre, NULL, NULL);
BLI_ghash_free(entry->topo_modified_edges_post, NULL, NULL);
BLI_ghash_free(entry->topo_modified_faces_pre, NULL, NULL);
BLI_ghash_free(entry->topo_modified_faces_post, NULL, NULL);
BLI_ghash_free(entry->added_verts, NULL, NULL);
BLI_ghash_free(entry->added_edges, NULL, NULL);
BLI_ghash_free(entry->added_faces, NULL, NULL);
@ -2203,13 +2315,17 @@ static void bm_log_undo_intern(
bm_log_verts_unmake_pre(bm, log, entry->added_verts, entry, callbacks);
bm_log_faces_unmake(bm, log, entry->added_faces, entry, callbacks);
bm_log_faces_unmake(bm, log, entry->topo_modified_faces_post, entry, callbacks);
bm_log_edges_unmake(bm, log, entry->topo_modified_edges_post, entry, callbacks);
bm_log_edges_unmake(bm, log, entry->added_edges, entry, callbacks);
bm_log_verts_unmake(bm, log, entry->added_verts, entry, callbacks);
/* Restore deleted verts and faces */
bm_log_verts_restore(bm, log, entry->deleted_verts, entry, callbacks);
bm_log_edges_restore(bm, log, entry->deleted_edges, entry, callbacks);
bm_log_edges_restore(bm, log, entry->topo_modified_edges_pre, entry, callbacks);
bm_log_faces_restore(bm, log, entry->deleted_faces, entry, callbacks);
bm_log_faces_restore(bm, log, entry->topo_modified_faces_pre, entry, callbacks);
/* Restore vertex coordinates, mask, and hflag */
bm_log_vert_values_swap(bm, log, entry->modified_verts, entry, callbacks);
@ -2306,13 +2422,17 @@ static void bm_log_redo_intern(
bm_log_verts_unmake_pre(bm, log, entry->deleted_verts, entry, callbacks);
bm_log_faces_unmake(bm, log, entry->deleted_faces, entry, callbacks);
bm_log_faces_unmake(bm, log, entry->topo_modified_faces_pre, entry, callbacks);
bm_log_edges_unmake(bm, log, entry->topo_modified_edges_pre, entry, callbacks);
bm_log_edges_unmake(bm, log, entry->deleted_edges, entry, callbacks);
bm_log_verts_unmake(bm, log, entry->deleted_verts, entry, callbacks);
/* Restore previously added verts and faces */
bm_log_verts_restore(bm, log, entry->added_verts, entry, callbacks);
bm_log_edges_restore(bm, log, entry->added_edges, entry, callbacks);
bm_log_edges_restore(bm, log, entry->topo_modified_edges_post, entry, callbacks);
bm_log_faces_restore(bm, log, entry->added_faces, entry, callbacks);
bm_log_faces_restore(bm, log, entry->topo_modified_faces_post, entry, callbacks);
bm_log_edges_unmake(bm, log, entry->deleted_edges_post, entry, callbacks);
@ -2415,7 +2535,7 @@ void BM_log_edge_before_modified(BMLog *log, BMEdge *e, bool log_customdata)
{
BMLogEntry *entry = log->current_entry;
BMLogEdge *le;
uint e_id = (uint)BM_ELEM_GET_ID(log->bm, e);
uint e_id = (uint)get_edge_id(log->bm, e);
void *key = POINTER_FROM_UINT(e_id);
void **val_p;
@ -2433,9 +2553,10 @@ void BM_log_edge_before_modified(BMLog *log, BMEdge *e, bool log_customdata)
*/
void BM_log_edge_added(BMLog *log, BMEdge *e)
{
// return; // XXX
bm_logstack_push();
BMLogEdge *le;
uint e_id = (uint)BM_ELEM_GET_ID(log->bm, e);
uint e_id = (uint)get_edge_id(log->bm, e);
void *key = POINTER_FROM_UINT(e_id);
void **val = NULL;
@ -2449,12 +2570,16 @@ void BM_log_edge_added(BMLog *log, BMEdge *e)
}
*val = le;
bm_logstack_pop();
}
/* Log a new vertex as added to the BMesh
*/
void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
bm_logstack_push();
BMLogVert *lv;
uint v_id = (uint)BM_ELEM_GET_ID(log->bm, v);
void *key = POINTER_FROM_UINT(v_id);
@ -2463,6 +2588,8 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
lv = bm_log_vert_alloc(log, v, -1, true);
log_ghash_insert(log, log->current_entry->added_verts, key, lv);
bm_logstack_pop();
}
/* Log a face before it is modified
@ -2472,7 +2599,7 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
void BM_log_face_modified(BMLog *log, BMFace *f)
{
BMLogFace *lf;
uint f_id = (uint)BM_ELEM_GET_ID(log->bm, f);
uint f_id = (uint)get_face_id(log->bm, f);
void *key = POINTER_FROM_UINT(f_id);
// LOGPRINT("key %d\n", (int)key);
@ -2496,7 +2623,7 @@ bool BM_log_has_vert(BMLog *log, BMVert *v)
bool BM_log_has_edge(BMLog *log, BMEdge *e)
{
int id = BM_ELEM_GET_ID(log->bm, e);
int id = get_edge_id(log->bm, e);
bool ret = BLI_ghash_haskey(log->current_entry->added_edges, POINTER_FROM_INT(id));
ret = ret || BLI_ghash_haskey(log->current_entry->deleted_edges, POINTER_FROM_INT(id));
@ -2508,7 +2635,7 @@ bool BM_log_has_edge(BMLog *log, BMEdge *e)
bool BM_log_has_face(BMLog *log, BMFace *f)
{
int id = BM_ELEM_GET_ID(log->bm, f);
int id = get_face_id(log->bm, f);
bool ret = BLI_ghash_haskey(log->current_entry->added_faces, POINTER_FROM_INT(id));
ret = ret || BLI_ghash_haskey(log->current_entry->deleted_faces, POINTER_FROM_INT(id));
@ -2525,8 +2652,10 @@ bool BM_log_has_face(BMLog *log, BMFace *f)
*/
void BM_log_face_added(BMLog *log, BMFace *f)
{
bm_logstack_push();
BMLogFace *lf;
uint f_id = (uint)BM_ELEM_GET_ID(log->bm, f);
uint f_id = (uint)get_face_id(log->bm, f);
void *key = POINTER_FROM_UINT(f_id);
LOGPRINT("key %d\n", (int)key);
@ -2535,8 +2664,115 @@ void BM_log_face_added(BMLog *log, BMFace *f)
log_ghash_insert(log, log->current_entry->added_faces, key, lf);
bm_log_face_customdata(log->bm, log, f, lf);
bm_logstack_pop();
}
void BM_log_face_topo_pre(BMLog *log, BMFace *f)
{
bm_logstack_push();
BMLogEntry *entry = log->current_entry;
uint f_id = (uint)get_face_id(log->bm, f);
void *key = POINTER_FROM_UINT(f_id);
void **val = NULL;
BLI_ghash_remove(entry->topo_modified_faces_post, key, NULL, NULL);
if (!BLI_ghash_ensure_p(entry->topo_modified_faces_pre, key, &val)) {
BMLogFace *lf;
LOGPRINT("key %d\n", (int)key);
lf = bm_log_face_alloc(log, f);
bm_log_face_customdata(log->bm, log, f, lf);
*val = (void *)lf;
}
bm_logstack_pop();
}
void BM_log_face_topo_post(BMLog *log, BMFace *f)
{
bm_logstack_push();
BMLogEntry *entry = log->current_entry;
uint f_id = (uint)get_face_id(log->bm, f);
void *key = POINTER_FROM_UINT(f_id);
BMLogFace *lf;
LOGPRINT("key %d\n", (int)key);
lf = bm_log_face_alloc(log, f);
bm_log_face_customdata(log->bm, log, f, lf);
void **val = NULL;
if (BLI_ghash_ensure_p(entry->topo_modified_faces_post, key, &val)) {
BMLogFace *lf_old = (BMLogFace *)*val;
*lf_old = *lf;
BLI_mempool_free(entry->pool_faces, lf);
}
else {
*val = (void *)lf;
}
bm_logstack_pop();
}
void BM_log_edge_topo_pre(BMLog *log, BMEdge *e)
{
bm_logstack_push();
BMLogEntry *entry = log->current_entry;
uint f_id = (uint)get_edge_id(log->bm, e);
void *key = POINTER_FROM_UINT(f_id);
void **val = NULL;
BLI_ghash_remove(entry->topo_modified_edges_post, key, NULL, NULL);
if (!BLI_ghash_ensure_p(entry->topo_modified_edges_pre, key, &val)) {
BMLogEdge *le;
LOGPRINT("key %d\n", (int)key);
le = bm_log_edge_alloc(log, e, true);
*val = (void *)le;
}
bm_logstack_pop();
}
void BM_log_edge_topo_post(BMLog *log, BMEdge *e)
{
bm_logstack_push();
BMLogEntry *entry = log->current_entry;
uint f_id = (uint)get_edge_id(log->bm, e);
void *key = POINTER_FROM_UINT(f_id);
BMLogEdge *le;
LOGPRINT("key %d\n", (int)key);
le = bm_log_edge_alloc(log, e, true);
void **val = NULL;
if (BLI_ghash_ensure_p(entry->topo_modified_edges_post, key, &val)) {
BMLogEdge *le_old = (BMLogEdge *)*val;
*le_old = *le;
BLI_mempool_free(entry->pool_edges, le);
}
else {
*val = (void *)le;
}
bm_logstack_pop();
}
/* Log a vertex as removed from the BMesh
*
* A couple things can happen here:
@ -2555,6 +2791,8 @@ void BM_log_face_added(BMLog *log, BMFace *f)
*/
void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
bm_logstack_push();
BMLogEntry *entry = log->current_entry;
uint v_id = (uint)BM_ELEM_GET_ID(log->bm, v);
void *key = POINTER_FROM_UINT(v_id);
@ -2584,16 +2822,25 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
bm_log_vert_customdata(log->bm, log, entry, v, lv);
}
}
bm_logstack_pop();
}
void BM_log_edge_removed_post(BMLog *log, BMEdge *e)
{
bm_logstack_push();
BMLogEntry *entry = log->current_entry;
uint e_id = (uint)BM_ELEM_GET_ID(log->bm, e);
uint e_id = (uint)get_edge_id(log->bm, e);
void *key = POINTER_FROM_UINT(e_id);
LOGPRINT("key %d\n", (int)key);
BLI_ghash_remove(entry->topo_modified_edges_post, key, NULL, NULL);
if (BLI_ghash_haskey(entry->topo_modified_edges_pre, key)) {
return;
}
if (1) { //! log_ghash_remove(log, entry->added_edges, key, NULL, NULL)) {
BMLogEdge *le, *le_mod;
void **val;
@ -2630,6 +2877,8 @@ void BM_log_edge_removed_post(BMLog *log, BMEdge *e)
bm_log_edge_customdata(log->bm, log, entry, e, le);
#endif
}
bm_logstack_pop();
}
/**
@ -2638,13 +2887,28 @@ e is assigned a new ID.
*/
BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, float t)
{
#if 0
bm_logstack_push();
bm_log_message("edge split");
BMEdge *tmp = NULL;
if (!newe) {
newe = &tmp;
}
BM_log_edge_topo_pre(log, e);
BMVert *newv = BM_edge_split(log->bm, e, v, newe, t);
BM_log_edge_topo_post(log, e);
BM_log_edge_added(log, *newe);
BM_log_vert_added(log, newv, -1);
bm_logstack_pop();
return newv;
#else
#if 0
BMEdge *tmp = NULL;
if (!newe) {
newe = &tmp;
@ -2689,22 +2953,33 @@ BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, fl
bm_log_message(" esplit: add new edge %d", nid);
BM_log_edge_added(log, *newe);
bm_logstack_pop();
return newv;
#endif
}
void BM_log_edge_removed(BMLog *log, BMEdge *e)
{
bm_logstack_push();
if (e->head.htype != BM_EDGE) {
bm_logstack_pop();
printf("%s: e is not an edge; htype: %d\n", __func__, (int)e->head.htype);
return;
}
// return; // XXX
BMLogEntry *entry = log->current_entry;
uint e_id = (uint)BM_ELEM_GET_ID(log->bm, e);
uint e_id = (uint)get_edge_id(log->bm, e);
void *key = POINTER_FROM_UINT(e_id);
BLI_ghash_remove(entry->topo_modified_edges_post, key, NULL, NULL);
if (BLI_ghash_haskey(entry->topo_modified_edges_pre, key)) {
bm_logstack_pop();
return;
}
LOGPRINT("key %d\n", (int)key);
if (!log_ghash_remove(log, entry->added_edges, key, NULL, NULL)) {
@ -2742,6 +3017,8 @@ void BM_log_edge_removed(BMLog *log, BMEdge *e)
bm_log_edge_customdata(log->bm, log, entry, e, le);
#endif
}
bm_logstack_pop();
}
/* Log a face as removed from the BMesh
@ -2760,11 +3037,19 @@ void BM_log_edge_removed(BMLog *log, BMEdge *e)
void BM_log_face_removed(BMLog *log, BMFace *f)
{
BMLogEntry *entry = log->current_entry;
uint f_id = (uint)BM_ELEM_GET_ID(log->bm, f);
uint f_id = (uint)get_face_id(log->bm, f);
void *key = POINTER_FROM_UINT(f_id);
bm_logstack_push();
LOGPRINT("key %d\n", (int)key);
BLI_ghash_remove(entry->topo_modified_faces_post, key, NULL, NULL);
if (BLI_ghash_haskey(entry->topo_modified_faces_pre, key)) {
bm_logstack_pop();
return;
}
/* if it has a key, it shouldn't be NULL */
BLI_assert(!!log_ghash_lookup(log, entry->added_faces, key) ==
!!log_ghash_haskey(log, entry->added_faces, key));
@ -2796,6 +3081,8 @@ void BM_log_face_removed(BMLog *log, BMFace *f)
*val = lf;
}
bm_logstack_pop();
}
/* Log all vertices/faces in the BMesh as added */

View File

@ -46,6 +46,20 @@ typedef struct BMLogCallbacks {
void *userdata;
} BMLogCallbacks;
//#define DEBUG_LOG_CALL_STACKS
#ifdef DEBUG_LOG_CALL_STACKS
void _bm_logstack_pop();
const char *_bm_logstack_head();
void _bm_logstack_push(const char *name);
# define bm_logstack_push() _bm_logstack_push(__func__)
# define bm_logstack_pop() _bm_logstack_pop()
#else
# define bm_logstack_push()
# define bm_logstack_head ""
# define bm_logstack_pop()
#endif
/* Allocate and initialize a new BMLog */
BMLog *BM_log_create(BMesh *bm, int cd_sculpt_vert);
void BM_log_set_cd_offsets(BMLog *log, int cd_sculpt_vert);
@ -160,3 +174,15 @@ int BM_log_entry_size(BMLogEntry *entry);
bool BM_log_has_vert(BMLog *log, BMVert *v);
bool BM_log_has_edge(BMLog *log, BMEdge *e);
bool BM_log_has_face(BMLog *log, BMFace *f);
/*Log an edge before changing its topological connections*/
void BM_log_edge_topo_pre(BMLog *log, BMEdge *f);
/*Log an edge after changing its topological connections*/
void BM_log_edge_topo_post(BMLog *log, BMEdge *f);
/*Log a face before changing its topological connections*/
void BM_log_face_topo_pre(BMLog *log, BMFace *f);
/*Log a face after changing its topological connections*/
void BM_log_face_topo_post(BMLog *log, BMFace *f);