From 133a1c2699946fa992156c474a5dadefbe8e5d90 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 22 Apr 2011 23:37:58 +0000 Subject: [PATCH] =bmesh= fixed edge split modifier, and a bug in knifetool reported by letterrip. also brought back beautify-fill. --- .../startup/bl_ui/properties_data_modifier.py | 6 +- .../blender/blenkernel/intern/cdderivedmesh.c | 11 +- source/blender/blenlib/BLI_math_geom.h | 2 + source/blender/blenlib/intern/math_geom.c | 36 +++ source/blender/bmesh/intern/bmesh_opdefines.c | 16 ++ .../bmesh/intern/bmesh_operators_private.h | 1 + source/blender/bmesh/operators/createops.c | 48 +--- .../blender/bmesh/operators/triangulateop.c | 74 ++++++ source/blender/editors/mesh/bmesh_tools.c | 13 +- source/blender/editors/mesh/knifetool.c | 21 +- .../blender/modifiers/intern/MOD_edgesplit.c | 214 +----------------- 11 files changed, 177 insertions(+), 265 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 0e1bd870e7d..2c1ef5d6f32 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -45,7 +45,11 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel): # the mt.type enum is (ab)used for a lookup on function names # ...to avoid lengthy if statements # so each type must have a function here. - + + def NGONINTERP(self, layout, ob, md): + split = layout.split() + split.prop(md, "resolution") + def ARMATURE(self, layout, ob, md): split = layout.split() diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 58e11042bf3..dcbf3898862 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -2748,7 +2748,10 @@ void CDDM_tessfaces_to_faces(DerivedMesh *dm) void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - + + if (!CustomData_has_layer(&dm->vertData, CD_MVERT)) + CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData); + cddm->mvert = mvert; } @@ -2756,6 +2759,9 @@ void CDDM_set_medge(DerivedMesh *dm, MEdge *medge) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE)) + CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData); + cddm->medge = medge; } @@ -2763,5 +2769,8 @@ void CDDM_set_mface(DerivedMesh *dm, MFace *mface) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; + if (!CustomData_has_layer(&dm->faceData, CD_MFACE)) + CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numFaceData); + cddm->mface = mface; } diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 3174c65beac..d6b0aa750f2 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -70,6 +70,8 @@ void closest_to_line_segment_v3(float r[3], float p[3], float l1[3], float l2[3] /* TODO int return value consistency */ + int is_quad_convex_v3(float *v1, float *v2, float *v3, float *v4); + /* line-line */ #define ISECT_LINE_LINE_COLINEAR -1 #define ISECT_LINE_LINE_NONE 0 diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 75e8892f4b7..3077a00166c 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -2678,3 +2678,39 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl return contrib; } + +/* evaluate if entire quad is a proper convex quad */ + int is_quad_convex_v3(float *v1, float *v2, float *v3, float *v4) + { + float nor[3], nor1[3], nor2[3], vec[4][2]; + + /* define projection, do both trias apart, quad is undefined! */ + normal_tri_v3( nor1,v1, v2, v3); + normal_tri_v3( nor2,v1, v3, v4); + nor[0]= ABS(nor1[0]) + ABS(nor2[0]); + nor[1]= ABS(nor1[1]) + ABS(nor2[1]); + nor[2]= ABS(nor1[2]) + ABS(nor2[2]); + + if(nor[2] >= nor[0] && nor[2] >= nor[1]) { + vec[0][0]= v1[0]; vec[0][1]= v1[1]; + vec[1][0]= v2[0]; vec[1][1]= v2[1]; + vec[2][0]= v3[0]; vec[2][1]= v3[1]; + vec[3][0]= v4[0]; vec[3][1]= v4[1]; + } + else if(nor[1] >= nor[0] && nor[1]>= nor[2]) { + vec[0][0]= v1[0]; vec[0][1]= v1[2]; + vec[1][0]= v2[0]; vec[1][1]= v2[2]; + vec[2][0]= v3[0]; vec[2][1]= v3[2]; + vec[3][0]= v4[0]; vec[3][1]= v4[2]; + } + else { + vec[0][0]= v1[1]; vec[0][1]= v1[2]; + vec[1][0]= v2[1]; vec[1][1]= v2[2]; + vec[2][0]= v3[1]; vec[2][1]= v3[2]; + vec[3][0]= v4[1]; vec[3][1]= v4[2]; + } + + /* linetests, the 2 diagonals have to instersect to be convex */ + if( isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0 ) return 1; + return 0; +} diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index ad88d97284c..6140f05e518 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -940,6 +940,21 @@ BMOpDefine def_bevel = { BMOP_UNTAN_MULTIRES }; +/* + Beautify Fill + + Makes triangle a bit nicer + */ +BMOpDefine def_beautify_fill = { + "beautify_fill", + {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */ + {BMOP_OPSLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */ + {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, /* new flipped faces and edges */ + {0} /*null-terminating sentinel*/}, + bmesh_beautify_fill_exec, + BMOP_UNTAN_MULTIRES +}; + BMOpDefine *opdefines[] = { &def_splitop, &def_dupeop, @@ -1000,6 +1015,7 @@ BMOpDefine *opdefines[] = { &def_create_cube, &def_join_triangles, &def_bevel, + &def_beautify_fill, }; int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*)); diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index b81475d314f..96a560b6511 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -69,5 +69,6 @@ void bmesh_create_grid_exec(BMesh *bm, BMOperator *op); void bmesh_create_cube_exec(BMesh *bm, BMOperator *op); void bmesh_jointriangles_exec(BMesh *bm, BMOperator *op); void bmesh_bevel_exec(BMesh *bm, BMOperator *op); +void bmesh_beautify_fill_exec(BMesh *bm, BMOperator *op); #endif diff --git a/source/blender/bmesh/operators/createops.c b/source/blender/bmesh/operators/createops.c index fda4bd83b5f..260bc4e292c 100644 --- a/source/blender/bmesh/operators/createops.c +++ b/source/blender/bmesh/operators/createops.c @@ -964,42 +964,6 @@ void bmesh_edgenet_fill_exec(BMesh *bm, BMOperator *op) MEM_freeN(vdata); } -/* evaluate if entire quad is a proper convex quad */ -static int convex(float *v1, float *v2, float *v3, float *v4) -{ - float nor[3], nor1[3], nor2[3], vec[4][2]; - - /* define projection, do both trias apart, quad is undefined! */ - normal_tri_v3( nor1,v1, v2, v3); - normal_tri_v3( nor2,v1, v3, v4); - nor[0]= ABS(nor1[0]) + ABS(nor2[0]); - nor[1]= ABS(nor1[1]) + ABS(nor2[1]); - nor[2]= ABS(nor1[2]) + ABS(nor2[2]); - - if(nor[2] >= nor[0] && nor[2] >= nor[1]) { - vec[0][0]= v1[0]; vec[0][1]= v1[1]; - vec[1][0]= v2[0]; vec[1][1]= v2[1]; - vec[2][0]= v3[0]; vec[2][1]= v3[1]; - vec[3][0]= v4[0]; vec[3][1]= v4[1]; - } - else if(nor[1] >= nor[0] && nor[1]>= nor[2]) { - vec[0][0]= v1[0]; vec[0][1]= v1[2]; - vec[1][0]= v2[0]; vec[1][1]= v2[2]; - vec[2][0]= v3[0]; vec[2][1]= v3[2]; - vec[3][0]= v4[0]; vec[3][1]= v4[2]; - } - else { - vec[0][0]= v1[1]; vec[0][1]= v1[2]; - vec[1][0]= v2[1]; vec[1][1]= v2[2]; - vec[2][0]= v3[1]; vec[2][1]= v3[2]; - vec[3][0]= v4[1]; vec[3][1]= v4[2]; - } - - /* linetests, the 2 diagonals have to instersect to be convex */ - if( isect_line_line_v2(vec[0], vec[2], vec[1], vec[3]) > 0 ) return 1; - return 0; -} - BMEdge *edge_next(BMesh *bm, BMEdge *e) { BMIter iter; @@ -1257,22 +1221,22 @@ void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op) f = NULL; /* the order of vertices can be anything, 6 cases to check */ - if( convex(verts[0]->co, verts[1]->co, verts[2]->co, verts[3]->co) ) { + if( is_quad_convex_v3(verts[0]->co, verts[1]->co, verts[2]->co, verts[3]->co) ) { f= BM_Make_QuadTri(bm, verts[0], verts[1], verts[2], verts[3], NULL, 1); } - else if( convex(verts[0]->co, verts[2]->co, verts[3]->co, verts[1]->co) ) { + else if( is_quad_convex_v3(verts[0]->co, verts[2]->co, verts[3]->co, verts[1]->co) ) { f= BM_Make_QuadTri(bm, verts[0], verts[2], verts[3], verts[1], NULL, 1); } - else if( convex(verts[0]->co, verts[2]->co, verts[1]->co, verts[3]->co) ) { + else if( is_quad_convex_v3(verts[0]->co, verts[2]->co, verts[1]->co, verts[3]->co) ) { f= BM_Make_QuadTri(bm, verts[0], verts[2], verts[1], verts[3], NULL, 1); } - else if( convex(verts[0]->co, verts[1]->co, verts[3]->co, verts[2]->co) ) { + else if( is_quad_convex_v3(verts[0]->co, verts[1]->co, verts[3]->co, verts[2]->co) ) { f= BM_Make_QuadTri(bm, verts[0], verts[1], verts[3], verts[2], NULL, 1); } - else if( convex(verts[0]->co, verts[3]->co, verts[2]->co, verts[1]->co) ) { + else if( is_quad_convex_v3(verts[0]->co, verts[3]->co, verts[2]->co, verts[1]->co) ) { f= BM_Make_QuadTri(bm, verts[0], verts[3], verts[2], verts[1], NULL, 1); } - else if( convex(verts[0]->co, verts[3]->co, verts[1]->co, verts[2]->co) ) { + else if( is_quad_convex_v3(verts[0]->co, verts[3]->co, verts[1]->co, verts[2]->co) ) { f= BM_Make_QuadTri(bm, verts[0], verts[3], verts[1], verts[2], NULL, 1); } else { diff --git a/source/blender/bmesh/operators/triangulateop.c b/source/blender/bmesh/operators/triangulateop.c index ebcca7f7116..0a4707b0b2b 100644 --- a/source/blender/bmesh/operators/triangulateop.c +++ b/source/blender/bmesh/operators/triangulateop.c @@ -14,6 +14,10 @@ #define EDGE_NEW 1 #define FACE_NEW 1 +#define ELE_NEW 1 +#define FACE_MARK 2 +#define EDGE_MARK 4 + void triangulate_exec(BMesh *bm, BMOperator *op) { BMOIter siter; @@ -54,3 +58,73 @@ void triangulate_exec(BMesh *bm, BMOperator *op) BLI_array_free(projectverts); BLI_array_free(newfaces); } + +void bmesh_beautify_fill_exec(BMesh *bm, BMOperator *op) +{ + BMOIter siter; + BMIter iter; + BMFace *f; + BMEdge *e; + int stop=0; + + BMO_Flag_Buffer(bm, op, "constrain_edges", EDGE_MARK, BM_EDGE); + + BMO_ITER(f, &siter, bm, op, "faces", BM_FACE) { + if (f->len == 3) + BMO_SetFlag(bm, f, FACE_MARK); + } + + while (!stop) { + stop = 1; + + BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { + BMVert *v1, *v2, *v3, *v4, *d1, *d2; + float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2; + int ok; + + if (BM_Edge_FaceCount(e) != 2 || BMO_TestFlag(bm, e, EDGE_MARK)) + continue; + if (!BMO_TestFlag(bm, e->l->f, FACE_MARK) || !BMO_TestFlag(bm, e->l->radial_next->f, FACE_MARK)) + continue; + + v1 = e->l->prev->v; + v2 = e->l->v; + v3 = e->l->radial_next->prev->v; + v4 = e->l->next->v; + + if (is_quad_convex_v3(v1->co, v2->co, v3->co, v4->co)) { + /* testing rule: + * the area divided by the total edge lengths + */ + len1= len_v3v3(v1->co, v2->co); + len2= len_v3v3(v2->co, v3->co); + len3= len_v3v3(v3->co, v4->co); + len4= len_v3v3(v4->co, v1->co); + len5= len_v3v3(v1->co, v3->co); + len6= len_v3v3(v2->co, v4->co); + + opp1= area_tri_v3(v1->co, v2->co, v3->co); + opp2= area_tri_v3(v1->co, v3->co, v4->co); + + fac1= opp1/(len1+len2+len5) + opp2/(len3+len4+len5); + + opp1= area_tri_v3(v2->co, v3->co, v4->co); + opp2= area_tri_v3(v2->co, v4->co, v1->co); + + fac2= opp1/(len2+len3+len6) + opp2/(len4+len1+len6); + ok = 0; + + if (fac1 > fac2) { + e = BM_Rotate_Edge(bm, e, 0); + BMO_SetFlag(bm, e, ELE_NEW); + + BMO_SetFlag(bm, e->l->f, FACE_MARK|ELE_NEW); + BMO_SetFlag(bm, e->l->radial_next->f, FACE_MARK|ELE_NEW); + stop = 0; + } + } + } + } + + BMO_Flag_To_Slot(bm, op, "geomout", ELE_NEW, BM_EDGE|BM_FACE); +} diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 397693da230..b169e68d231 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -3884,19 +3884,16 @@ void MESH_OT_fill(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int beauty_fill_exec(bContext *C, wmOperator *op) +static int beautify_fill_exec(bContext *C, wmOperator *op) { -#if 0 Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh; - beauty_fill(em); - - BKE_mesh_end_editmesh(obedit->data, em); + if (!EDBM_CallOpf(em, op, "beautify_fill faces=%hf", BM_SELECT)) + return OPERATOR_CANCELLED; DAG_id_tag_update(obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); -#endif return OPERATOR_FINISHED; } @@ -3907,7 +3904,7 @@ void MESH_OT_beautify_fill(wmOperatorType *ot) ot->idname= "MESH_OT_beautify_fill"; /* api callbacks */ - ot->exec= beauty_fill_exec; + ot->exec= beautify_fill_exec; ot->poll= ED_operator_editmesh; /* flags */ diff --git a/source/blender/editors/mesh/knifetool.c b/source/blender/editors/mesh/knifetool.c index 1632e2cd97e..2684a82bf0f 100755 --- a/source/blender/editors/mesh/knifetool.c +++ b/source/blender/editors/mesh/knifetool.c @@ -804,9 +804,10 @@ BMEdgeHit *knife_edge_tri_isect(knifetool_opdata *kcd, BMBVHTree *bmtree, float ls = (BMLoop**)kcd->em->looptris[result->indexA]; for (j=0; j<3; j++) { - BMLoop *l1 = ls[j]; + BMLoop *l1 = ls[j]; + BMFace *hitf; ListBase *lst = knife_get_face_kedges(kcd, l1->f); - Ref *ref; + Ref *ref, *ref2; for (ref=lst->first; ref; ref=ref->next) { KnifeEdge *kfe = ref->ref; @@ -845,7 +846,13 @@ BMEdgeHit *knife_edge_tri_isect(knifetool_opdata *kcd, BMBVHTree *bmtree, float /*go backwards toward view a bit*/ add_v3_v3(p, no); - if (!BMBVH_RayCast(bmtree, p, no, NULL) && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) { + hitf = BMBVH_RayCast(bmtree, p, no, NULL); + for (ref2=kfe->faces.first; ref2; ref2=ref2->next) { + if (ref2->ref == hitf) + hitf = NULL; + } + + if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) { BMEdgeHit hit; if (len_v3v3(p, kcd->vertco) < FLT_EPSILON*50 || len_v3v3(p, kcd->prevco) < FLT_EPSILON*50) @@ -1274,8 +1281,16 @@ static void remerge_faces(knifetool_opdata *kcd) BLI_array_declare(stack); BMFace **faces = NULL; BLI_array_declare(faces); + BMOperator bmop; int idx; + BMO_InitOpf(bm, &bmop, "beautify_fill faces=%ff constrain_edges=%fe", FACE_NEW, BOUNDARY); + + BMO_Exec_Op(bm, &bmop); + BMO_Flag_Buffer(bm, &bmop, "geomout", FACE_NEW, BM_FACE); + + BMO_Finish_Op(bm, &bmop); + BLI_smallhash_init(visit); BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { BMIter eiter; diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index c98905a8be1..82731ee69c2 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -306,215 +306,6 @@ DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) if (!vu) continue; ml->v = vu->v; - -#if 0 //BMESH_TODO should really handle edges here, but for now use cddm_calc_edges - /*ok, now we have to deal with edges. . .*/ - if (etags[ml->e].tag) { - if (etags[ml->e].used) { - BLI_array_growone(medge); - BLI_array_growone(etags); - medge[cure] = medge[ml->e]; - - ml->e = cure; - etags[cure].used = 1; - cure++; - } - - vu = etags[ml->e].v1user; - vu2 = etags[ml->e].v2user; - -<<<<<<< .working - if (vu) - medge[ml->e].v1 = vu->v; - if (vu2) - medge[ml->e].v2 = vu2->v; -======= -/* finds another sharp edge which uses vert, by traversing faces around the - * vert until it does one of the following: - * - hits a loose edge (the edge is returned) - * - hits a sharp edge (the edge is returned) - * - returns to the start edge (NULL is returned) - */ -static SmoothEdge *find_other_sharp_edge(SmoothVert *vert, SmoothEdge *edge, LinkNode **visited_faces) -{ - SmoothFace *face = NULL; - SmoothEdge *edge2 = NULL; - /* holds the edges we've seen so we can avoid looping indefinitely */ - LinkNode *visited_edges = NULL; -#ifdef EDGESPLIT_DEBUG_1 - printf("=== START === find_other_sharp_edge(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif - - /* get a face on which to start */ - if(edge->faces) face = edge->faces->link; - else return NULL; - - /* record this edge as visited */ - BLI_linklist_prepend(&visited_edges, edge); - - /* get the next edge */ - edge2 = other_edge(face, vert, edge); - - /* record this face as visited */ - if(visited_faces) - BLI_linklist_prepend(visited_faces, face); - - /* search until we hit a loose edge or a sharp edge or an edge we've - * seen before - */ - while(face && !edge_is_sharp(edge2) - && !linklist_contains(visited_edges, edge2)) { -#ifdef EDGESPLIT_DEBUG_3 - printf("current face %4d; current edge %4d\n", face->newIndex, - edge2->newIndex); -#endif - /* get the next face */ - face = other_face(edge2, face); - - /* if face == NULL, edge2 is a loose edge */ - if(face) { - /* record this face as visited */ - if(visited_faces) - BLI_linklist_prepend(visited_faces, face); - - /* record this edge as visited */ - BLI_linklist_prepend(&visited_edges, edge2); - - /* get the next edge */ - edge2 = other_edge(face, vert, edge2); -#ifdef EDGESPLIT_DEBUG_3 - printf("next face %4d; next edge %4d\n", - face->newIndex, edge2->newIndex); - } else { - printf("loose edge: %4d\n", edge2->newIndex); -#endif - } - } - - /* either we came back to the start edge or we found a sharp/loose edge */ - if(linklist_contains(visited_edges, edge2)) - /* we came back to the start edge */ - edge2 = NULL; - - BLI_linklist_free(visited_edges, NULL); - -#ifdef EDGESPLIT_DEBUG_1 - printf("=== END === find_other_sharp_edge(edge = %4d, vert = %4d), " - "returning edge %d\n", - edge->newIndex, vert->newIndex, edge2 ? edge2->newIndex : -1); -#endif - return edge2; -} - -static void split_single_vert(SmoothVert *vert, SmoothFace *face, - SmoothMesh *mesh) -{ - SmoothVert *copy_vert; - ReplaceData repdata; - - copy_vert = smoothvert_copy(vert, mesh); - - if(copy_vert == NULL) { - /* bug [#26316], this prevents a segfault - * but this still needs fixing */ - return; - } - - repdata.find = vert; - repdata.replace = copy_vert; - face_replace_vert(face, &repdata); -} - -typedef struct PropagateEdge { - struct PropagateEdge *next, *prev; - SmoothEdge *edge; - SmoothVert *vert; -} PropagateEdge; - -static void push_propagate_stack(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh) -{ - PropagateEdge *pedge = mesh->reusestack.first; - - if(pedge) { - BLI_remlink(&mesh->reusestack, pedge); - } - else { - if(!mesh->arena) { - mesh->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "edgesplit arena"); - BLI_memarena_use_calloc(mesh->arena); - } - - pedge = BLI_memarena_alloc(mesh->arena, sizeof(PropagateEdge)); - } - - pedge->edge = edge; - pedge->vert = vert; - BLI_addhead(&mesh->propagatestack, pedge); -} - -static void pop_propagate_stack(SmoothEdge **edge, SmoothVert **vert, SmoothMesh *mesh) -{ - PropagateEdge *pedge = mesh->propagatestack.first; - - if(pedge) { - *edge = pedge->edge; - *vert = pedge->vert; - BLI_remlink(&mesh->propagatestack, pedge); - BLI_addhead(&mesh->reusestack, pedge); - } - else { - *edge = NULL; - *vert = NULL; - } -} - -static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh); - -static void propagate_split(SmoothEdge *edge, SmoothVert *vert, - SmoothMesh *mesh) -{ - SmoothEdge *edge2; - LinkNode *visited_faces = NULL; -#ifdef EDGESPLIT_DEBUG_1 - printf("=== START === propagate_split(edge = %4d, vert = %4d)\n", - edge->newIndex, vert->newIndex); -#endif - - edge2 = find_other_sharp_edge(vert, edge, &visited_faces); - - if(!edge2) { - /* didn't find a sharp or loose edge, so we've hit a dead end */ - } else if(!edge_is_loose(edge2)) { - /* edge2 is not loose, so it must be sharp */ - if(edge_is_loose(edge)) { - /* edge is loose, so we can split edge2 at this vert */ - split_edge(edge2, vert, mesh); - } else if(edge_is_sharp(edge)) { - /* both edges are sharp, so we can split the pair at vert */ - split_edge(edge, vert, mesh); - } else { - /* edge is not sharp, so try to split edge2 at its other vert */ - split_edge(edge2, other_vert(edge2, vert), mesh); - } - } else { /* edge2 is loose */ - if(edge_is_loose(edge)) { - SmoothVert *vert2; - ReplaceData repdata; - - /* can't split edge, what should we do with vert? */ - if(linklist_subset(vert->faces, visited_faces)) { - /* vert has only one fan of faces attached; don't split it */ ->>>>>>> .merge-right.r36153 - } else { - etags[ml->e].used = 1; - - if (vu->ov == etags[ml->e].v1) - medge[ml->e].v1 = vu->v; - else if (vu->ov == etags[ml->e].v2) - medge[ml->e].v2 = vu->v; - } -#endif } } @@ -544,7 +335,10 @@ static void propagate_split(SmoothEdge *edge, SmoothVert *vert, CDDM_set_mvert(cddm, mvert); CDDM_set_medge(cddm, medge); - + + CustomData_set_layer(&cddm->vertData, CD_MVERT, mvert); + CustomData_set_layer(&cddm->edgeData, CD_MEDGE, medge); + free_membase(membase); MEM_freeN(etags);