forked from bartvdbraak/blender
=bmesh= fixed edge split modifier, and a bug in knifetool reported by letterrip. also brought back beautify-fill.
This commit is contained in:
parent
2a24370bab
commit
133a1c2699
@ -46,6 +46,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
|
||||
# ...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()
|
||||
|
||||
|
@ -2749,6 +2749,9 @@ 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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*));
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -805,8 +805,9 @@ BMEdgeHit *knife_edge_tri_isect(knifetool_opdata *kcd, BMBVHTree *bmtree, float
|
||||
|
||||
for (j=0; j<3; 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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -545,6 +336,9 @@ 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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user