* BM_mesh_remap can now reorder loops
* Wrote yet another BKE_pbvh_reorder_bmesh function
This commit is contained in:
parent
106f542ac4
commit
de1f2c41fa
|
@ -48,8 +48,10 @@ Topology rake:
|
|||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_sort_utils.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
#include "atomic_ops.h"
|
||||
|
||||
|
@ -1339,6 +1341,87 @@ void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh)
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_pbvh_update_all_boundary_bmesh(PBVH *pbvh)
|
||||
{
|
||||
// update boundary flags in a hopefully faster manner then v->e iteration
|
||||
// XXX or not, it's slower
|
||||
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
BMVert *v;
|
||||
|
||||
const int cd_fset = CustomData_get_offset(&pbvh->bm->pdata, CD_SCULPT_FACE_SETS);
|
||||
|
||||
BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
|
||||
MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
|
||||
mv->flag &= ~(DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY | DYNVERT_NEED_BOUNDARY |
|
||||
DYNVERT_VERT_FSET_HIDDEN);
|
||||
|
||||
if (cd_fset >= 0 && v->e && v->e->l) {
|
||||
mv->flag |= DYNVERT_VERT_FSET_HIDDEN;
|
||||
}
|
||||
}
|
||||
|
||||
BM_ITER_MESH (e, &iter, pbvh->bm, BM_EDGES_OF_MESH) {
|
||||
if (!e->l || e->l == e->l->radial_next) {
|
||||
MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v1);
|
||||
MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v2);
|
||||
|
||||
mv1->flag |= DYNVERT_BOUNDARY;
|
||||
mv2->flag |= DYNVERT_BOUNDARY;
|
||||
}
|
||||
|
||||
if (!e->l) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cd_fset < 0) {
|
||||
MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v1);
|
||||
MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v2);
|
||||
|
||||
BMLoop *l = e->l;
|
||||
|
||||
do {
|
||||
if (l->f->len > 3) {
|
||||
mv1->flag |= DYNVERT_NEED_TRIANGULATE;
|
||||
mv2->flag |= DYNVERT_NEED_TRIANGULATE;
|
||||
break;
|
||||
}
|
||||
|
||||
l = l->radial_next;
|
||||
} while (l != e->l);
|
||||
continue;
|
||||
}
|
||||
|
||||
MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v1);
|
||||
MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, e->v2);
|
||||
|
||||
BMLoop *l = e->l;
|
||||
int lastfset = BM_ELEM_CD_GET_INT(l->f, cd_fset);
|
||||
do {
|
||||
int fset = BM_ELEM_CD_GET_INT(l->f, cd_fset);
|
||||
|
||||
if (l->f->len > 3) {
|
||||
mv1->flag |= DYNVERT_NEED_TRIANGULATE;
|
||||
mv2->flag |= DYNVERT_NEED_TRIANGULATE;
|
||||
}
|
||||
|
||||
if (fset > 0) {
|
||||
MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, l->v);
|
||||
mv->flag &= ~DYNVERT_VERT_FSET_HIDDEN;
|
||||
}
|
||||
|
||||
if (lastfset != fset) {
|
||||
mv1->flag |= DYNVERT_FSET_BOUNDARY;
|
||||
mv2->flag |= DYNVERT_FSET_BOUNDARY;
|
||||
}
|
||||
|
||||
lastfset = fset;
|
||||
|
||||
l = l->radial_next;
|
||||
} while (l != e->l);
|
||||
}
|
||||
}
|
||||
/* Build a PBVH from a BMesh */
|
||||
void BKE_pbvh_build_bmesh(PBVH *pbvh,
|
||||
BMesh *bm,
|
||||
|
@ -1373,6 +1456,8 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
|
|||
BMIter iter;
|
||||
BMVert *v;
|
||||
|
||||
// BKE_pbvh_update_all_boundary_bmesh(pbvh);
|
||||
|
||||
int cd_vcol_offset = CustomData_get_offset(&bm->vdata, CD_PROP_COLOR);
|
||||
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
|
@ -2558,6 +2643,316 @@ static void scan_edge_split(BMesh *bm, BMEdge **edges, int totedge)
|
|||
BLI_array_free(fmap);
|
||||
}
|
||||
|
||||
#define MAX_RE_CHILD 3
|
||||
typedef struct ReVertNode {
|
||||
int totvert, totchild;
|
||||
struct ReVertNode *parent;
|
||||
struct ReVertNode *children[MAX_RE_CHILD];
|
||||
BMVert *verts[];
|
||||
} ReVertNode;
|
||||
|
||||
ATTR_NO_OPT BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
|
||||
{
|
||||
/*try to compute size of verts per node*/
|
||||
int vsize = sizeof(BMVert);
|
||||
vsize += pbvh->bm->vdata.totsize;
|
||||
|
||||
// perhaps aim for l2 cache?
|
||||
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");
|
||||
|
||||
printf("leaf_limit: %d\n", leaf_limit);
|
||||
|
||||
BMIter iter;
|
||||
BMVert *v;
|
||||
const char flag = BM_ELEM_TAG_ALT;
|
||||
int i = 0;
|
||||
|
||||
BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
|
||||
BM_elem_flag_disable(v, flag);
|
||||
v->head.index = i++;
|
||||
}
|
||||
|
||||
BMVert **stack = NULL;
|
||||
BLI_array_declare(stack);
|
||||
|
||||
BM_ITER_MESH (v, &iter, pbvh->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, flag)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ReVertNode *node = BLI_mempool_calloc(pool);
|
||||
|
||||
BLI_array_clear(stack);
|
||||
BLI_array_append(stack, v);
|
||||
|
||||
BM_elem_flag_enable(v, flag);
|
||||
|
||||
vnodemap[v->head.index] = node;
|
||||
node->verts[node->totvert++] = v;
|
||||
|
||||
while (BLI_array_len(stack) > 0) {
|
||||
BMVert *v2 = BLI_array_pop(stack);
|
||||
BMEdge *e;
|
||||
|
||||
if (node->totvert >= leaf_limit) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!v2->e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int len = node->totvert;
|
||||
|
||||
e = v2->e;
|
||||
do {
|
||||
BMVert *v3 = BM_edge_other_vert(e, v2);
|
||||
|
||||
if (!BM_elem_flag_test(v3, flag) && len < leaf_limit) {
|
||||
BM_elem_flag_enable(v3, flag);
|
||||
vnodemap[v3->head.index] = node;
|
||||
node->verts[node->totvert++] = v3;
|
||||
|
||||
len++;
|
||||
|
||||
BLI_array_append(stack, v3);
|
||||
}
|
||||
|
||||
e = e->v1 == v2 ? e->v1_disk_link.next : e->v2_disk_link.next;
|
||||
} while (e != v2->e);
|
||||
}
|
||||
}
|
||||
|
||||
const int steps = 4;
|
||||
ReVertNode **roots = NULL;
|
||||
BLI_array_declare(roots);
|
||||
|
||||
for (int step = 0; step < steps; step++) {
|
||||
const bool last_step = step == steps - 1;
|
||||
|
||||
BM_ITER_MESH_INDEX (v, &iter, pbvh->bm, BM_VERTS_OF_MESH, i) {
|
||||
BMEdge *e = v->e;
|
||||
|
||||
if (!e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ReVertNode *node = vnodemap[v->head.index];
|
||||
if (node->parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ReVertNode *other_node = NULL;
|
||||
|
||||
ReVertNode *parent = BLI_mempool_calloc(pool);
|
||||
parent->children[0] = node;
|
||||
parent->totchild = 1;
|
||||
|
||||
do {
|
||||
BMVert *v2 = BM_edge_other_vert(e, v);
|
||||
|
||||
ReVertNode *node2 = vnodemap[v2->head.index];
|
||||
|
||||
bool ok = node != node2 && !node2->parent;
|
||||
for (int j = 0; j < parent->totchild; j++) {
|
||||
if (parent->children[j] == node2) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
parent->children[parent->totchild++] = node2;
|
||||
break;
|
||||
}
|
||||
|
||||
e = e->v1 == v ? e->v1_disk_link.next : e->v2_disk_link.next;
|
||||
} while (e != v->e);
|
||||
|
||||
if (parent->totchild == 1) {
|
||||
BLI_mempool_free(pool, parent);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (last_step) {
|
||||
BLI_array_append(roots, parent);
|
||||
}
|
||||
|
||||
for (int j = 0; j < parent->totchild; j++) {
|
||||
parent->children[j]->parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
BM_ITER_MESH_INDEX (v, &iter, pbvh->bm, BM_VERTS_OF_MESH, i) {
|
||||
while (vnodemap[i]->parent) {
|
||||
vnodemap[i] = vnodemap[i]->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_mempool_iter loopiter;
|
||||
BLI_mempool_iternew(pbvh->bm->lpool, &loopiter);
|
||||
BMLoop *l = BLI_mempool_iterstep(&loopiter);
|
||||
BMEdge *e;
|
||||
BMFace *f;
|
||||
|
||||
for (i = 0; l; l = BLI_mempool_iterstep(&loopiter), i++) {
|
||||
l->head.hflag &= ~flag;
|
||||
}
|
||||
BM_ITER_MESH (e, &iter, pbvh->bm, BM_EDGES_OF_MESH) {
|
||||
e->head.hflag &= ~flag;
|
||||
}
|
||||
|
||||
BM_ITER_MESH (f, &iter, pbvh->bm, BM_FACES_OF_MESH) {
|
||||
f->head.hflag &= ~flag;
|
||||
}
|
||||
|
||||
int totroot = BLI_array_len(roots);
|
||||
ReVertNode **nstack = NULL;
|
||||
BLI_array_declare(nstack);
|
||||
int vorder = 0, eorder = 0, lorder = 0, forder = 0;
|
||||
|
||||
for (i = 0; i < totroot; i++) {
|
||||
BLI_array_clear(nstack);
|
||||
|
||||
ReVertNode *node = roots[i];
|
||||
BLI_array_append(nstack, node);
|
||||
|
||||
while (BLI_array_len(nstack) > 0) {
|
||||
ReVertNode *node2 = BLI_array_pop(nstack);
|
||||
|
||||
if (node2->totchild == 0) {
|
||||
for (int j = 0; j < node2->totvert; j++) {
|
||||
v = node2->verts[j];
|
||||
|
||||
#if 0
|
||||
if (cd_vcol >= 0) {
|
||||
MPropCol *col = BM_ELEM_CD_GET_VOID_P(node2->verts[j], cd_vcol);
|
||||
|
||||
float r = 0.0f, g = 0.0f, b = 0.0f;
|
||||
|
||||
unsigned int p = (unsigned int)node2->parent;
|
||||
p = p % 65535;
|
||||
|
||||
unsigned int p2 = (unsigned int)node2->parent;
|
||||
p2 = p2 % 65535;
|
||||
|
||||
r = ((float)vorder) * 0.01;
|
||||
g = ((float)p2) / 65535.0f;
|
||||
b = ((float)p) / 65535.0f;
|
||||
|
||||
r = cosf(r * 17.2343) * 0.5 + 0.5;
|
||||
g = cosf(g * 11.2343) * 0.5 + 0.5;
|
||||
b = cosf(b * 19.2343) * 0.5 + 0.5;
|
||||
|
||||
col->color[0] = r;
|
||||
col->color[1] = g;
|
||||
col->color[2] = b;
|
||||
col->color[3] = 1.0f;
|
||||
}
|
||||
#endif
|
||||
v->head.index = vorder++;
|
||||
|
||||
BMEdge *e = v->e;
|
||||
if (!e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
if (!(e->head.hflag & flag)) {
|
||||
e->head.hflag |= flag;
|
||||
e->head.index = eorder++;
|
||||
}
|
||||
|
||||
if (e->l) {
|
||||
BMLoop *l = e->l;
|
||||
|
||||
do {
|
||||
if (!(l->head.hflag & flag)) {
|
||||
l->head.hflag |= flag;
|
||||
l->head.index = lorder++;
|
||||
}
|
||||
|
||||
if (!(l->f->head.hflag & flag)) {
|
||||
l->f->head.hflag |= flag;
|
||||
l->f->head.index = forder++;
|
||||
}
|
||||
|
||||
l = l->radial_next;
|
||||
} while (l != e->l);
|
||||
}
|
||||
e = e->v1 == v ? e->v1_disk_link.next : e->v2_disk_link.next;
|
||||
} while (e != v->e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int j = 0; j < node2->totchild; j++) {
|
||||
BLI_array_append(nstack, node2->children[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint *vidx, *eidx, *lidx, *fidx;
|
||||
|
||||
vidx = MEM_malloc_arrayN(pbvh->bm->totvert, sizeof(*vidx), "vorder");
|
||||
eidx = MEM_malloc_arrayN(pbvh->bm->totedge, sizeof(*eidx), "eorder");
|
||||
lidx = MEM_malloc_arrayN(pbvh->bm->totloop, sizeof(*lidx), "lorder");
|
||||
fidx = MEM_malloc_arrayN(pbvh->bm->totface, sizeof(*fidx), "forder");
|
||||
|
||||
printf("v %d %d\n", vorder, pbvh->bm->totvert);
|
||||
printf("e %d %d\n", eorder, pbvh->bm->totedge);
|
||||
printf("l %d %d\n", lorder, pbvh->bm->totloop);
|
||||
printf("f %d %d\n", forder, pbvh->bm->totface);
|
||||
|
||||
BM_ITER_MESH_INDEX (v, &iter, pbvh->bm, BM_VERTS_OF_MESH, i) {
|
||||
vidx[i] = (uint)v->head.index;
|
||||
}
|
||||
|
||||
BM_ITER_MESH_INDEX (e, &iter, pbvh->bm, BM_EDGES_OF_MESH, i) {
|
||||
eidx[i] = (uint)e->head.index;
|
||||
}
|
||||
BM_ITER_MESH_INDEX (f, &iter, pbvh->bm, BM_FACES_OF_MESH, i) {
|
||||
fidx[i] = (uint)f->head.index;
|
||||
}
|
||||
|
||||
BLI_mempool_iternew(pbvh->bm->lpool, &loopiter);
|
||||
l = BLI_mempool_iterstep(&loopiter);
|
||||
|
||||
for (i = 0; l; l = BLI_mempool_iterstep(&loopiter), i++) {
|
||||
// handle orphaned loops
|
||||
if (!(l->head.hflag & flag)) {
|
||||
printf("warning in %s: orphaned loop!\n", __func__);
|
||||
l->head.index = lorder++;
|
||||
}
|
||||
|
||||
lidx[i] = (uint)l->head.index;
|
||||
}
|
||||
|
||||
BM_mesh_remap(pbvh->bm, vidx, eidx, fidx, lidx);
|
||||
|
||||
printf("roots: %d\n", BLI_array_len(roots));
|
||||
|
||||
MEM_SAFE_FREE(vidx);
|
||||
MEM_SAFE_FREE(eidx);
|
||||
MEM_SAFE_FREE(lidx);
|
||||
MEM_SAFE_FREE(fidx);
|
||||
|
||||
MEM_SAFE_FREE(nstack);
|
||||
MEM_SAFE_FREE(roots);
|
||||
BLI_mempool_destroy(pool);
|
||||
MEM_SAFE_FREE(stack);
|
||||
MEM_SAFE_FREE(vnodemap);
|
||||
|
||||
return pbvh->bm;
|
||||
}
|
||||
|
||||
BMesh *BKE_pbvh_reorder_bmesh2(PBVH *pbvh)
|
||||
{
|
||||
if (BKE_pbvh_type(pbvh) != PBVH_BMESH || pbvh->totnode == 0) {
|
||||
|
@ -2826,7 +3221,7 @@ static int sort_edges(const void *va, const void *vb)
|
|||
return (ni1 + ni2) - (ni3 + ni4);
|
||||
}
|
||||
|
||||
BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
|
||||
BMesh *BKE_pbvh_reorder_bmesh1(PBVH *pbvh)
|
||||
{
|
||||
BMesh *bm = pbvh->bm;
|
||||
|
||||
|
@ -2920,7 +3315,7 @@ BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
|
|||
faces[i].elem->head.index = faces[i].index;
|
||||
}
|
||||
|
||||
BM_mesh_remap(bm, vs, es, fs);
|
||||
BM_mesh_remap(bm, vs, es, fs, NULL);
|
||||
|
||||
// create new mappings
|
||||
BMVert **mapvs = MEM_malloc_arrayN(bm->totvert, sizeof(BMVert *), __func__);
|
||||
|
|
|
@ -1200,7 +1200,7 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
|
|||
}
|
||||
BLI_ghash_free(id_to_idx, NULL, NULL);
|
||||
|
||||
BM_mesh_remap(bm, varr, NULL, farr);
|
||||
BM_mesh_remap(bm, varr, NULL, farr, NULL);
|
||||
|
||||
MEM_freeN(varr);
|
||||
MEM_freeN(farr);
|
||||
|
|
|
@ -72,7 +72,7 @@ static void bm_mempool_init_ex(const BMAllocTemplate *allocsize,
|
|||
}
|
||||
if (r_lpool) {
|
||||
*r_lpool = BLI_mempool_create(
|
||||
loop_size, allocsize->totloop, bm_mesh_chunksize_default.totloop, BLI_MEMPOOL_NOP);
|
||||
loop_size, allocsize->totloop, bm_mesh_chunksize_default.totloop, BLI_MEMPOOL_ALLOW_ITER);
|
||||
}
|
||||
if (r_fpool) {
|
||||
*r_fpool = BLI_mempool_create(
|
||||
|
@ -875,7 +875,11 @@ int BM_mesh_elem_count(BMesh *bm, const char htype)
|
|||
* \warning Be careful if you keep pointers to affected BM elements,
|
||||
* or arrays, when using this func!
|
||||
*/
|
||||
void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const uint *face_idx)
|
||||
void BM_mesh_remap(BMesh *bm,
|
||||
const uint *vert_idx,
|
||||
const uint *edge_idx,
|
||||
const uint *face_idx,
|
||||
const uint *loop_idx)
|
||||
{
|
||||
/* Mapping old to new pointers. */
|
||||
GHash *vptr_map = NULL, *eptr_map = NULL, *fptr_map = NULL;
|
||||
|
@ -944,6 +948,70 @@ void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const
|
|||
}
|
||||
}
|
||||
|
||||
GHash *lptr_map = NULL;
|
||||
|
||||
/* Remap Loops */
|
||||
if (loop_idx) {
|
||||
BMLoop **ltable = MEM_malloc_arrayN(bm->totloop, sizeof(*ltable), "ltable");
|
||||
|
||||
BMLoop *ed;
|
||||
BLI_mempool_iter liter;
|
||||
BLI_mempool_iternew(bm->lpool, &liter);
|
||||
BMLoop *l = (BMLoop *)BLI_mempool_iterstep(&liter);
|
||||
|
||||
int i = 0;
|
||||
for (; l; l = (BMLoop *)BLI_mempool_iterstep(&liter), i++) {
|
||||
l->head.index = i;
|
||||
ltable[i] = l;
|
||||
}
|
||||
|
||||
BMLoop **loops_pool, *loops_copy, **edl;
|
||||
int totloop = bm->totloop;
|
||||
const uint *new_idx;
|
||||
/* Special case: Python uses custom data layers to hold PyObject references.
|
||||
* These have to be kept in place, else the PyObjects we point to, won't point back to us. */
|
||||
const int cd_loop_pyptr = CustomData_get_offset(&bm->ldata, CD_BM_ELEM_PYPTR);
|
||||
|
||||
/* Init the old-to-new vert pointers mapping */
|
||||
lptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap loop pointers mapping", bm->totloop);
|
||||
|
||||
/* Make a copy of all vertices. */
|
||||
loops_pool = ltable;
|
||||
loops_copy = MEM_mallocN(sizeof(BMLoop) * totloop, "BM_mesh_remap loops copy");
|
||||
|
||||
void **pyptrs = (cd_loop_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totloop, __func__) : NULL;
|
||||
for (i = totloop, ed = loops_copy + totloop - 1, edl = loops_pool + totloop - 1; i--;
|
||||
ed--, edl--) {
|
||||
*ed = **edl;
|
||||
if (cd_loop_pyptr != -1) {
|
||||
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)ed), cd_loop_pyptr);
|
||||
pyptrs[i] = *pyptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy back verts to their new place, and update old2new pointers mapping. */
|
||||
new_idx = loop_idx + totloop - 1;
|
||||
ed = loops_copy + totloop - 1;
|
||||
edl = loops_pool + totloop - 1; /* old, org pointer */
|
||||
for (i = totloop; i--; new_idx--, ed--, edl--) {
|
||||
BMLoop *new_edl = loops_pool[*new_idx];
|
||||
*new_edl = *ed;
|
||||
BLI_ghash_insert(lptr_map, *edl, new_edl);
|
||||
#if 0
|
||||
printf(
|
||||
"mapping loop from %d to %d (%p/%p to %p)\n", i, *new_idx, *edl, loops_pool[i], new_edl);
|
||||
#endif
|
||||
if (cd_loop_pyptr != -1) {
|
||||
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_edl), cd_loop_pyptr);
|
||||
*pyptr = pyptrs[*new_idx];
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(ltable);
|
||||
MEM_SAFE_FREE(loops_copy);
|
||||
MEM_SAFE_FREE(pyptrs);
|
||||
}
|
||||
|
||||
/* Remap Edges */
|
||||
if (edge_idx) {
|
||||
BMEdge **edges_pool, *edges_copy, **edp;
|
||||
|
@ -976,6 +1044,11 @@ void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const
|
|||
for (i = totedge; i--; new_idx--, ed--, edp--) {
|
||||
BMEdge *new_edp = edges_pool[*new_idx];
|
||||
*new_edp = *ed;
|
||||
|
||||
if (new_edp->l && lptr_map) {
|
||||
new_edp->l = BLI_ghash_lookup(lptr_map, (BMLoop *)new_edp->l);
|
||||
}
|
||||
|
||||
BLI_ghash_insert(eptr_map, *edp, new_edp);
|
||||
#if 0
|
||||
printf(
|
||||
|
@ -1028,6 +1101,22 @@ void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const
|
|||
BMFace *new_fap = faces_pool[*new_idx];
|
||||
*new_fap = *fa;
|
||||
BLI_ghash_insert(fptr_map, *fap, new_fap);
|
||||
|
||||
if (lptr_map) {
|
||||
new_fap->l_first = BLI_ghash_lookup(lptr_map, (void *)new_fap->l_first);
|
||||
|
||||
BMLoop *l = new_fap->l_first;
|
||||
|
||||
do {
|
||||
l->next = BLI_ghash_lookup(lptr_map, (void *)l->next);
|
||||
l->prev = BLI_ghash_lookup(lptr_map, (void *)l->prev);
|
||||
l->radial_next = BLI_ghash_lookup(lptr_map, (void *)l->radial_next);
|
||||
l->radial_prev = BLI_ghash_lookup(lptr_map, (void *)l->radial_prev);
|
||||
|
||||
l = l->next;
|
||||
} while (l != new_fap->l_first);
|
||||
}
|
||||
|
||||
if (cd_poly_pyptr != -1) {
|
||||
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_fap), cd_poly_pyptr);
|
||||
*pyptr = pyptrs[*new_idx];
|
||||
|
|
|
@ -99,7 +99,11 @@ BMFace *BM_face_at_index_find_or_table(BMesh *bm, const int index);
|
|||
|
||||
int BM_mesh_elem_count(BMesh *bm, const char htype);
|
||||
|
||||
void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const uint *face_idx);
|
||||
void BM_mesh_remap(BMesh *bm,
|
||||
const uint *vert_idx,
|
||||
const uint *edge_idx,
|
||||
const uint *face_idx,
|
||||
const uint *loop_idx);
|
||||
|
||||
void BM_mesh_rebuild(BMesh *bm,
|
||||
const struct BMeshCreateParams *params,
|
||||
|
|
|
@ -7105,7 +7105,7 @@ static void sort_bmelem_flag(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
BM_mesh_remap(em->bm, map[0], map[1], map[2]);
|
||||
BM_mesh_remap(em->bm, map[0], map[1], map[2], NULL);
|
||||
DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
||||
|
||||
|
|
|
@ -2764,7 +2764,7 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BM_mesh_remap(bm, vert_idx, edge_idx, face_idx);
|
||||
BM_mesh_remap(bm, vert_idx, edge_idx, face_idx, NULL);
|
||||
|
||||
PyMem_FREE(elem_map_idx);
|
||||
PyMem_FREE(elem_idx);
|
||||
|
|
Loading…
Reference in New Issue