forked from bartvdbraak/blender
fix for crash dissolving faces, bmesh walkers were using freed mempool elements.
use a convention for freeing walker-states where freed-dangling pointers aren't left assigned to prevent errors like this happening in future.
This commit is contained in:
parent
94fdaa5d41
commit
87fb70cad2
@ -26,6 +26,8 @@
|
||||
* BMesh Walker Code.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
@ -34,6 +36,12 @@
|
||||
#include "intern/bmesh_private.h"
|
||||
#include "intern/bmesh_walkers_private.h"
|
||||
|
||||
/* pop into stack memory (common operation) */
|
||||
#define BMW_state_remove_r(walker, owalk) { \
|
||||
memcpy(owalk, BMW_current_state(walker), sizeof(*(owalk))); \
|
||||
BMW_state_remove(walker); \
|
||||
} (void)0
|
||||
|
||||
static bool bmw_mask_check_vert(BMWalker *walker, BMVert *v)
|
||||
{
|
||||
if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
|
||||
@ -140,14 +148,16 @@ static void *bmw_ShellWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_ShellWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwShellWalker *swalk = BMW_current_state(walker);
|
||||
BMwShellWalker *swalk, owalk;
|
||||
BMEdge *e, *e2;
|
||||
BMVert *v;
|
||||
BMIter iter;
|
||||
int i;
|
||||
|
||||
BMW_state_remove_r(walker, &owalk);
|
||||
swalk = &owalk;
|
||||
|
||||
e = swalk->curedge;
|
||||
BMW_state_remove(walker);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
v = i ? e->v2 : e->v1;
|
||||
@ -240,14 +250,15 @@ static void *bmw_ConnectedVertexWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_ConnectedVertexWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwConnectedVertexWalker *vwalk = BMW_current_state(walker);
|
||||
BMwConnectedVertexWalker *vwalk, owalk;
|
||||
BMVert *v, *v2;
|
||||
BMEdge *e;
|
||||
BMIter iter;
|
||||
|
||||
v = vwalk->curvert;
|
||||
BMW_state_remove_r(walker, &owalk);
|
||||
vwalk = &owalk;
|
||||
|
||||
BMW_state_remove(walker);
|
||||
v = vwalk->curvert;
|
||||
|
||||
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
|
||||
v2 = BM_edge_other_vert(e, v);
|
||||
@ -289,14 +300,19 @@ static void *bmw_IslandboundWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_IslandboundWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwIslandboundWalker *iwalk = BMW_current_state(walker), owalk;
|
||||
BMwIslandboundWalker *iwalk, owalk;
|
||||
BMVert *v;
|
||||
BMEdge *e = iwalk->curloop->e;
|
||||
BMEdge *e;
|
||||
BMFace *f;
|
||||
BMLoop *l = iwalk->curloop;
|
||||
BMLoop *l;
|
||||
/* int found = 0; */
|
||||
|
||||
owalk = *iwalk;
|
||||
memcpy(&owalk, BMW_current_state(walker), sizeof(owalk));
|
||||
/* normally we'd remove here, but delay until after error checking */
|
||||
iwalk = &owalk;
|
||||
|
||||
l = iwalk->curloop;
|
||||
e = l->e;
|
||||
|
||||
v = BM_edge_other_vert(e, iwalk->lastv);
|
||||
|
||||
@ -307,7 +323,7 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* pop off current stat */
|
||||
/* pop off current state */
|
||||
BMW_state_remove(walker);
|
||||
|
||||
f = l->f;
|
||||
@ -381,13 +397,13 @@ static void *bmw_IslandWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_IslandWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwIslandWalker *iwalk = BMW_current_state(walker);
|
||||
/* BMwIslandWalker *owalk = iwalk; */ /* UNUSED */
|
||||
BMwIslandWalker *iwalk, owalk;
|
||||
BMIter iter, liter;
|
||||
BMFace *f, *curf = iwalk->cur;
|
||||
BMFace *f;
|
||||
BMLoop *l;
|
||||
|
||||
BMW_state_remove(walker);
|
||||
BMW_state_remove_r(walker, &owalk);
|
||||
iwalk = &owalk;
|
||||
|
||||
l = BM_iter_new(&liter, walker->bm, BM_LOOPS_OF_FACE, iwalk->cur);
|
||||
for ( ; l; l = BM_iter_step(&liter)) {
|
||||
@ -419,7 +435,7 @@ static void *bmw_IslandWalker_step(BMWalker *walker)
|
||||
}
|
||||
}
|
||||
|
||||
return curf;
|
||||
return owalk.cur;
|
||||
}
|
||||
|
||||
|
||||
@ -507,15 +523,16 @@ static void *bmw_LoopWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_LoopWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwLoopWalker *lwalk = BMW_current_state(walker), owalk;
|
||||
BMEdge *e = lwalk->cur, *nexte = NULL;
|
||||
BMwLoopWalker *lwalk, owalk;
|
||||
BMEdge *e, *nexte = NULL;
|
||||
BMLoop *l;
|
||||
BMVert *v;
|
||||
int i = 0;
|
||||
|
||||
owalk = *lwalk;
|
||||
BMW_state_remove(walker);
|
||||
BMW_state_remove_r(walker, &owalk);
|
||||
lwalk = &owalk;
|
||||
|
||||
e = lwalk->cur;
|
||||
l = e->l;
|
||||
|
||||
if (owalk.f_hub) { /* NGON EDGE */
|
||||
@ -770,13 +787,15 @@ static void *bmw_FaceLoopWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_FaceLoopWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwFaceLoopWalker *lwalk = BMW_current_state(walker);
|
||||
BMFace *f = lwalk->l->f;
|
||||
BMLoop *l = lwalk->l, *origl = lwalk->l;
|
||||
BMwFaceLoopWalker *lwalk, owalk;
|
||||
BMFace *f;
|
||||
BMLoop *l;
|
||||
|
||||
BMW_state_remove(walker);
|
||||
BMW_state_remove_r(walker, &owalk);
|
||||
lwalk = &owalk;
|
||||
|
||||
l = l->radial_next;
|
||||
f = lwalk->l->f;
|
||||
l = lwalk->l->radial_next;
|
||||
|
||||
if (lwalk->no_calc) {
|
||||
return f;
|
||||
@ -797,7 +816,7 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
|
||||
|
||||
if (l->f->len != 4) {
|
||||
lwalk->no_calc = true;
|
||||
lwalk->l = origl;
|
||||
lwalk->l = owalk.l;
|
||||
}
|
||||
else {
|
||||
lwalk->no_calc = false;
|
||||
@ -878,19 +897,21 @@ static void *bmw_EdgeringWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_EdgeringWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwEdgeringWalker *lwalk = BMW_current_state(walker);
|
||||
BMEdge *e, *wireedge = lwalk->wireedge;
|
||||
BMLoop *l = lwalk->l, *origl = lwalk->l;
|
||||
BMwEdgeringWalker *lwalk, owalk;
|
||||
BMEdge *e;
|
||||
BMLoop *l;
|
||||
#ifdef BMW_EDGERING_NGON
|
||||
int i, len;
|
||||
#endif
|
||||
|
||||
#define EDGE_CHECK(e) (bmw_mask_check_edge(walker, e) && (BM_edge_is_boundary(e) || BM_edge_is_manifold(e)))
|
||||
|
||||
BMW_state_remove(walker);
|
||||
BMW_state_remove_r(walker, &owalk);
|
||||
lwalk = &owalk;
|
||||
|
||||
l = lwalk->l;
|
||||
if (!l)
|
||||
return wireedge;
|
||||
return lwalk->wireedge;
|
||||
|
||||
e = l->e;
|
||||
if (!EDGE_CHECK(e)) {
|
||||
@ -913,7 +934,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
|
||||
if ((len <= 0) || (len % 2 != 0) || !EDGE_CHECK(l->e) ||
|
||||
!bmw_mask_check_face(walker, l->f))
|
||||
{
|
||||
l = origl;
|
||||
l = owalk.l;
|
||||
i = len;
|
||||
while (i > 0) {
|
||||
l = l->next;
|
||||
@ -930,7 +951,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker)
|
||||
l = l->next->next;
|
||||
|
||||
if ((l->f->len != 4) || !EDGE_CHECK(l->e) || !bmw_mask_check_face(walker, l->f)) {
|
||||
l = origl->next->next;
|
||||
l = owalk.l->next->next;
|
||||
}
|
||||
/* only walk to manifold edge */
|
||||
if ((l->f->len == 4) && EDGE_CHECK(l->e) &&
|
||||
@ -975,17 +996,18 @@ static void *bmw_UVEdgeWalker_yield(BMWalker *walker)
|
||||
|
||||
static void *bmw_UVEdgeWalker_step(BMWalker *walker)
|
||||
{
|
||||
BMwUVEdgeWalker *lwalk = BMW_current_state(walker);
|
||||
const int type = walker->bm->ldata.layers[walker->layer].type;
|
||||
BMwUVEdgeWalker *lwalk, owalk;
|
||||
BMLoop *l, *l2, *l3, *nl, *cl;
|
||||
BMIter liter;
|
||||
void *d1, *d2;
|
||||
int i, j, rlen, type;
|
||||
int i, j, rlen;
|
||||
|
||||
BMW_state_remove_r(walker, &owalk);
|
||||
lwalk = &owalk;
|
||||
|
||||
l = lwalk->l;
|
||||
nl = l->next;
|
||||
type = walker->bm->ldata.layers[walker->layer].type;
|
||||
|
||||
BMW_state_remove(walker);
|
||||
|
||||
if (!bmw_mask_check_edge(walker, l->e)) {
|
||||
return l;
|
||||
|
Loading…
Reference in New Issue
Block a user