struct BMVert *BM_Split_Edge(struct BMesh *bm, struct BMVert *v, struct BMEdge *e, struct BMEdge **ne, float percent, int calcnorm);
struct BMVert *BM_Split_Edge_Multi(struct BMesh *bm, struct BMEdge *e, int numcuts);
BMEdge *BM_Connect_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
-void BM_Dissolve_Disk(BMesh *bm, BMVert *v);
+
+/*dissolves vert surrounded by faces*/
+int BM_Dissolve_Disk(BMesh *bm, BMVert *v);
+
+/*dissolves vert, in more situations then BM_Dissolve_Disk.*/
+int BM_Dissolve_Vert(BMesh *bm, BMVert *v);
/*Interpolation*/
void BM_Data_Interp_From_Verts(struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac);
*
*/
#if 1
-void BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
- BMFace *f, *f2;
- BMEdge *e, *keepedge=NULL, *baseedge=NULL;
- BMLoop *loop;
- int done, len;
+int BM_Dissolve_Vert(BMesh *bm, BMVert *v) {
+ BMIter iter;
+ BMEdge *e;
+ int len=0;
+
+ if (!v) return 0;
+
+ e = BMIter_New(&iter, bm, BM_EDGES_OF_VERT, v);
+ for (; e; e=BMIter_Step(&iter)) {
+ len++;
+ }
+
+ if (len == 1) {
+ bmesh_ke(bm, v->edge);
+ bmesh_kv(bm, v);
+ return 1;
+ }
if(BM_Nonmanifold_Vert(bm, v)) {
if (!v->edge) bmesh_kv(bm, v);
else if (!v->edge->loop) {
bmesh_ke(bm, v->edge);
bmesh_kv(bm, v);
- }
- return;
+ } else return 0;
+
+ return 1;
+ }
+
+ return BM_Dissolve_Disk(bm, v);
+}
+
+int BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
+ BMFace *f, *f2;
+ BMEdge *e, *keepedge=NULL, *baseedge=NULL;
+ BMLoop *loop;
+ int done, len;
+
+ if(BM_Nonmanifold_Vert(bm, v)) {
+ return 0;
}
if(v->edge){
/*collapse the vertex*/
BM_Collapse_Vert(bm, v->edge, v, 1.0, 0);
BM_Join_Faces(bm, f, f2, NULL, 0, 0);
- } else if (len == 1) {
- bmesh_ke(bm, v->edge);
- bmesh_kv(bm, v);
}
if(keepedge){
/*return if couldn't join faces in manifold
conditions.*/
//!disabled for testing why bad things happen
- if (!f) return;
+ if (!f) return 0;
}
if(f){
/*join two remaining faces*/
BM_Join_Faces(bm, f, f2, NULL, 0, 0);
}
+
+ return 1;
}
#else
void BM_Dissolve_Disk(BMesh *bm, BMVert *v){
bmop_error *err = MEM_callocN(sizeof(bmop_error), "bmop_error");
err->errorcode = errcode;
+ if (!msg) msg = bmop_error_messages[errcode];
err->msg = msg;
err->op = owner;
if (errorcode) {
bmop_error *err = bm->errorstack.first;
- BLI_remlink(&bm->errorstack, &bm->errorstack.first);
+ BLI_remlink(&bm->errorstack, bm->errorstack.first);
MEM_freeN(err);
}
return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5;
}
-int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert)
+int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert, float *outv)
{
- /*the hardcoded stuff here, 200000, 0.999, and 1.0001 may be problems
+ /*the hardcoded stuff here, 0.999 and 1.0001, may be problems
in the future, not sure. - joeedh*/
- static float outv[3] = {2000.0f, 2000.0f, 0.0f};
float v1[3], v2[3], p[3], vv1[3], vv2[3], mid[3], a[3], b[3];
int i = 0, lcount=0;
*
*/
-static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert)
+static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert, float *outv)
{
BMVert *v1, *v2, *v3;
BMLoop *bestear = NULL, *l;
if (BM_Edge_Exist(v1, v3)) isear = 0;
- if (isear && !goodline(verts, v1->head.eflag2, v3->head.eflag2, nvert)) isear = 0;
+ if (isear && !goodline(verts, v1->head.eflag2, v3->head.eflag2,
+ nvert, outv)) isear = 0;
if(isear){
angle = VecAngle3(verts[v1->head.eflag2], verts[v2->head.eflag2], verts[v3->head.eflag2]);
- if(!bestear || ABS(angle-40.0) < bestangle){
+ if(!bestear || ABS(angle-40.0f) < bestangle){
bestear = l;
- bestangle = ABS(40.0-angle);
+ bestangle = ABS(40.0f-angle);
}
}
l = (BMLoop*)(l->head.next);
{
int i, done, nvert;
BMLoop *l, *newl, *nextloop;
+ float outv[3] = {-1.0e30f, -1.0e30f, -1.0e30f};
/*copy vertex coordinates to vertspace array*/
i = 0;
VECCOPY(projectverts[i], l->v->co);
l->v->head.eflag2 = i; /*warning, abuse! never duplicate in tools code! never you hear?*/ /*actually, get rid of this completely, use a new structure for this....*/
i++;
+
+ outv[0] = MAX2(outv[0], l->v->co[0])+1.0f;
+ outv[1] = MAX2(outv[1], l->v->co[1])+1.0f;
+ outv[2] = MAX2(outv[2], l->v->co[2])+1.0f;
+
l = (BMLoop*)(l->head.next);
}while(l != f->loopbase);
+
//bmesh_update_face_normal(bm, f, projectverts);
compute_poly_normal(f->no, projectverts, f->len);
done = 0;
while(!done && f->len > 3){
done = 1;
- l = find_ear(f, projectverts, nvert);
+ l = find_ear(f, projectverts, nvert, outv);
if(l) {
done = 0;
f = bmesh_sfme(bm, f, ((BMLoop*)(l->head.prev))->v, ((BMLoop*)(l->head.next))->v, &newl);
static BM_fgonconvert(BMesh *bm, EditMesh *em, int numCol, int numTex)
{
EditFace *efa;
+ BMFace *f;
+ BMIter iter;
struct fgonsort *sortblock, *sb, *sb1;
int a, b, amount=0;
+
+ /*
+ for (efa=em->faces.first; efa; efa=efa->next) {
+ f = editface_to_BMFace(bm, em, efa, numCol, numTex);
+ }
+
+ for (f=bm->polys.first; f; f=f->head.next) {
+ fuse_fgon(bm, f);
+ }
+
+ return;*/
+
+ EM_fgon_flags(em);
/*zero out efa->tmp, we store fgon index here*/
for(efa = em->faces.first; efa; efa = efa->next){
len = 0;
for (v=BMIter_New(&iter, bm, BM_VERTS, NULL); v; v=BMIter_Step(&iter)) {
if (BMO_TestFlag(bm, v, VERT_MARK)) {
- BM_Dissolve_Disk(bm, v);
+ if (!BM_Dissolve_Vert(bm, v)) {
+ BMO_RaiseError(bm, op,
+ BMERR_DISSOLVEDISK_FAILED, NULL);
+ return;
+ }
found = 1;
len++;
}
#if 1
for (e=BMIter_New(&iter, bm, BM_EDGES, NULL);e;e=BMIter_Step(&iter)) {
+ if (!BMO_TestFlag(bm, e, EXT_INPUT)) continue;
+
found = 0;
f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, e);
for (rlen=0; f; f=BMIter_Step(&fiter), rlen++) {
}
}
-void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
+/* Note, these values must match delete_mesh() event values */
+static EnumPropertyItem prop_mesh_delete_types[] = {
+ {10,"VERT", "Vertices", ""},
+ {1, "EDGE", "Edges", ""},
+ {2, "FACE", "Faces", ""},
+ {3, "ALL", "All", ""},
+ {4, "EDGE_FACE","Edges & Faces", ""},
+ {5, "ONLY_FACE","Only Faces", ""},
+ {6, "EDGE_LOOP","Edge Loop", ""},
+ {7, "COLLAPSE","Collapse", ""},
+ {0, NULL, NULL, NULL}
+};
+
+static int delete_mesh_exec(bContext *C, wmOperator *op)
{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
EditFace *efa, *nextvl;
EditVert *eve,*nextve;
EditEdge *eed,*nexted;
int count;
char *str="Erase";
+ int event = RNA_enum_get(op->ptr, "type");
-
if(event<1) return;
if(event==10 ) {
}
else if(event==7) {
BMesh *bm = editmesh_to_bmesh(em);
- BMOperator op;
+ BMOperator bmop;
EditMesh *em2;
+ char *errmsg;
- BMO_Init_Op(&op, BMOP_DISSOLVE_VERTS);
- BMO_HeaderFlag_To_Slot(bm, &op, BMOP_DISVERTS_VERTIN,
+ BMO_Init_Op(&bmop, BMOP_DISSOLVE_VERTS);
+ BMO_HeaderFlag_To_Slot(bm, &bmop, BMOP_DISVERTS_VERTIN,
BM_SELECT, BM_VERT);
- BMO_Exec_Op(bm, &op);
+ BMO_Exec_Op(bm, &bmop);
- BMO_Finish_Op(bm, &op);
+ BMO_Finish_Op(bm, &bmop);
+ if (BMO_GetError(bm, &errmsg, NULL)) {
+ BKE_report(op->reports, RPT_ERROR, errmsg);
+ BMO_ClearStack(bm);
+ return OPERATOR_CANCELLED;
+ }
+
em2 = bmesh_to_editmesh(bm);
set_editMesh(em, em2);
MEM_freeN(em2);
+ BM_Free_Mesh(bm);
}
else if(event==6) {
if(!EdgeLoopDelete(em, op))
EM_fgon_flags(em); // redo flags and indices for fgons
-// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-}
-
-/* Note, these values must match delete_mesh() event values */
-static EnumPropertyItem prop_mesh_delete_types[] = {
- {10,"VERT", "Vertices", ""},
- {1, "EDGE", "Edges", ""},
- {2, "FACE", "Faces", ""},
- {3, "ALL", "All", ""},
- {4, "EDGE_FACE","Edges & Faces", ""},
- {5, "ONLY_FACE","Only Faces", ""},
- {6, "EDGE_LOOP","Edge Loop", ""},
- {7, "COLLAPSE","Collapse", ""},
- {0, NULL, NULL, NULL}
-};
-
-static int delete_mesh_exec(bContext *C, wmOperator *op)
-{
- Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
-
- delete_mesh(obedit,em, op,RNA_enum_get(op->ptr, "type"));
-
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;