2009-03-04 09:38:26 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
|
|
|
|
|
|
#include "bmesh.h"
|
|
|
|
|
#include "mesh_intern.h"
|
|
|
|
|
#include "bmesh_private.h"
|
2009-11-23 14:41:22 +00:00
|
|
|
#include "BLI_math.h"
|
2009-09-17 23:05:33 +00:00
|
|
|
#include "BLI_array.h"
|
2009-03-04 09:38:26 +00:00
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2009-03-14 13:16:35 +00:00
|
|
|
#include <string.h>
|
2009-03-04 09:38:26 +00:00
|
|
|
|
|
|
|
|
#define VERT_INPUT 1
|
|
|
|
|
#define EDGE_OUT 1
|
2009-03-14 13:16:35 +00:00
|
|
|
#define FACE_NEW 2
|
2011-08-15 23:38:51 +00:00
|
|
|
#define EDGE_MARK 4
|
|
|
|
|
#define EDGE_DONE 8
|
2009-03-04 09:38:26 +00:00
|
|
|
|
|
|
|
|
void connectverts_exec(BMesh *bm, BMOperator *op)
|
|
|
|
|
{
|
|
|
|
|
BMIter iter, liter;
|
|
|
|
|
BMFace *f, *nf;
|
2009-03-14 13:16:35 +00:00
|
|
|
BMLoop **loops = NULL, *lastl = NULL;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_declare(loops);
|
2009-03-13 13:11:50 +00:00
|
|
|
BMLoop *l, *nl;
|
2009-03-14 13:16:35 +00:00
|
|
|
BMVert *v1, *v2, **verts = NULL;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_declare(verts);
|
2009-03-14 13:16:35 +00:00
|
|
|
int i;
|
2009-03-04 09:38:26 +00:00
|
|
|
|
Brought Extrude all the way back. The contextual menu works,
as does only edges and individual faces extrude (individual vert
extrude already did).
Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.
I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator. I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).
The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well. To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
2009-08-11 07:49:35 +00:00
|
|
|
BMO_Flag_Buffer(bm, op, "verts", VERT_INPUT, BM_VERT);
|
2009-03-04 09:38:26 +00:00
|
|
|
|
2009-03-22 23:16:43 +00:00
|
|
|
for (f=BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL); f; f=BMIter_Step(&iter)){
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(loops);
|
|
|
|
|
BLI_array_empty(verts);
|
2009-03-14 13:16:35 +00:00
|
|
|
|
|
|
|
|
if (BMO_TestFlag(bm, f, FACE_NEW)) continue;
|
|
|
|
|
|
2009-03-04 09:38:26 +00:00
|
|
|
l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
|
|
|
|
|
v1 = v2 = NULL;
|
2009-03-14 13:16:35 +00:00
|
|
|
lastl = NULL;
|
2009-03-04 09:38:26 +00:00
|
|
|
for (; l; l=BMIter_Step(&liter)) {
|
|
|
|
|
if (BMO_TestFlag(bm, l->v, VERT_INPUT)) {
|
2009-03-14 13:16:35 +00:00
|
|
|
if (!lastl) {
|
|
|
|
|
lastl = l;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-14 22:06:10 +00:00
|
|
|
if (lastl != l->prev && lastl !=
|
|
|
|
|
l->next)
|
2009-03-14 13:16:35 +00:00
|
|
|
{
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(loops);
|
|
|
|
|
loops[BLI_array_count(loops)-1] = lastl;
|
2009-03-14 13:16:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(loops);
|
|
|
|
|
loops[BLI_array_count(loops)-1] = l;
|
2009-03-14 13:16:35 +00:00
|
|
|
|
|
|
|
|
}
|
2009-03-15 06:14:03 +00:00
|
|
|
lastl = l;
|
2009-03-04 09:38:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
if (BLI_array_count(loops) == 0) continue;
|
2009-03-14 13:16:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
if (BLI_array_count(loops) > 2) {
|
|
|
|
|
BLI_array_growone(loops);
|
|
|
|
|
loops[BLI_array_count(loops)-1] = loops[BLI_array_count(loops)-2];
|
2009-03-14 13:16:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(loops);
|
|
|
|
|
loops[BLI_array_count(loops)-1] = loops[0];
|
2009-03-14 13:16:35 +00:00
|
|
|
}
|
|
|
|
|
|
2011-05-10 23:48:09 +00:00
|
|
|
BM_LegalSplits(bm, f, (BMLoop *(*)[2])loops, BLI_array_count(loops)/2);
|
2009-03-14 13:16:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
for (i=0; i<BLI_array_count(loops)/2; i++) {
|
2009-03-14 13:16:35 +00:00
|
|
|
if (loops[i*2]==NULL) continue;
|
2009-03-13 13:11:50 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(verts);
|
|
|
|
|
verts[BLI_array_count(verts)-1] = loops[i*2]->v;
|
2009-03-14 13:16:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(verts);
|
|
|
|
|
verts[BLI_array_count(verts)-1] = loops[i*2+1]->v;
|
2009-03-14 13:16:35 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
for (i=0; i<BLI_array_count(verts)/2; i++) {
|
2009-03-14 13:16:35 +00:00
|
|
|
nf = BM_Split_Face(bm, f, verts[i*2],
|
|
|
|
|
verts[i*2+1], &nl, NULL);
|
|
|
|
|
f = nf;
|
2009-03-13 13:11:50 +00:00
|
|
|
|
|
|
|
|
if (!nl || !nf) {
|
2009-03-04 09:38:26 +00:00
|
|
|
BMO_RaiseError(bm, op,
|
|
|
|
|
BMERR_CONNECTVERT_FAILED, NULL);
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_free(loops);
|
2009-03-14 13:16:35 +00:00
|
|
|
return;;;
|
2009-03-04 09:38:26 +00:00
|
|
|
}
|
2009-03-14 13:16:35 +00:00
|
|
|
BMO_SetFlag(bm, nf, FACE_NEW);
|
2009-03-13 13:11:50 +00:00
|
|
|
BMO_SetFlag(bm, nl->e, EDGE_OUT);
|
2009-03-04 09:38:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-22 23:16:43 +00:00
|
|
|
BMO_Flag_To_Slot(bm, op, "edgeout", EDGE_OUT, BM_EDGE);
|
2009-03-14 13:16:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_free(loops);
|
|
|
|
|
BLI_array_free(verts);
|
2009-03-04 09:38:26 +00:00
|
|
|
}
|
2011-08-15 23:38:51 +00:00
|
|
|
|
|
|
|
|
static BMVert *get_outer_vert(BMesh *bm, BMEdge *e)
|
|
|
|
|
{
|
|
|
|
|
BMIter iter;
|
|
|
|
|
BMEdge *e2;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
i= 0;
|
|
|
|
|
BM_ITER(e2, &iter, bm, BM_EDGES_OF_VERT, e->v1) {
|
|
|
|
|
if (BMO_TestFlag(bm, e2, EDGE_MARK))
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i==2)
|
|
|
|
|
return e->v2;
|
|
|
|
|
else
|
|
|
|
|
return e->v1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void bmesh_bridge_loops_exec(BMesh *bm, BMOperator *op)
|
|
|
|
|
{
|
|
|
|
|
BMEdge **ee1 = NULL, **ee2 = NULL;
|
|
|
|
|
BMVert **vv1 = NULL, **vv2 = NULL;
|
|
|
|
|
BLI_array_declare(ee1);
|
|
|
|
|
BLI_array_declare(ee2);
|
|
|
|
|
BLI_array_declare(vv1);
|
|
|
|
|
BLI_array_declare(vv2);
|
|
|
|
|
BMOIter siter;
|
|
|
|
|
BMIter iter;
|
|
|
|
|
BMEdge *e;
|
|
|
|
|
int c=0, cl1=0, cl2=0;
|
|
|
|
|
|
|
|
|
|
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
|
|
|
|
BMO_SetFlag(bm, e, EDGE_MARK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
|
|
|
|
if (!BMO_TestFlag(bm, e, EDGE_DONE)) {
|
|
|
|
|
BMVert *v, *ov;
|
2011-08-28 21:20:10 +00:00
|
|
|
/* BMEdge *e2, *e3, *oe = e; */ /* UNUSED */
|
2011-08-25 16:47:47 +00:00
|
|
|
BMEdge *e2, *e3;
|
2011-08-15 23:38:51 +00:00
|
|
|
|
|
|
|
|
if (c > 2) {
|
|
|
|
|
printf("eek! more than two edge loops!\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
e2 = e;
|
|
|
|
|
v = e->v1;
|
|
|
|
|
do {
|
|
|
|
|
v = BM_OtherEdgeVert(e2, v);
|
|
|
|
|
BM_ITER(e3, &iter, bm, BM_EDGES_OF_VERT, v) {
|
|
|
|
|
if (e3 != e2 && BMO_TestFlag(bm, e3, EDGE_MARK)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-08-30 00:54:07 +00:00
|
|
|
|
|
|
|
|
if (e3)
|
|
|
|
|
e2 = e3;
|
|
|
|
|
} while (e3 && e2 != e);
|
2011-08-15 23:38:51 +00:00
|
|
|
|
|
|
|
|
if (!e2)
|
|
|
|
|
e2 = e;
|
|
|
|
|
|
|
|
|
|
e = e2;
|
|
|
|
|
ov = v;
|
|
|
|
|
do {
|
|
|
|
|
if (c==0) {
|
|
|
|
|
BLI_array_append(ee1, e2);
|
|
|
|
|
BLI_array_append(vv1, v);
|
|
|
|
|
} else {
|
|
|
|
|
BLI_array_append(ee2, e2);
|
|
|
|
|
BLI_array_append(vv2, v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BMO_SetFlag(bm, e2, EDGE_DONE);
|
|
|
|
|
|
|
|
|
|
v = BM_OtherEdgeVert(e2, v);
|
|
|
|
|
BM_ITER(e3, &iter, bm, BM_EDGES_OF_VERT, v) {
|
|
|
|
|
if (e3 != e2 && BMO_TestFlag(bm, e3, EDGE_MARK) && !BMO_TestFlag(bm, e3, EDGE_DONE)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-08-30 00:54:07 +00:00
|
|
|
if (e3)
|
|
|
|
|
e2 = e3;
|
|
|
|
|
} while (e3 && e2 != e);
|
2011-08-15 23:38:51 +00:00
|
|
|
|
2011-08-30 00:54:07 +00:00
|
|
|
if (v && !e3) {
|
2011-08-15 23:38:51 +00:00
|
|
|
if (c==0) {
|
2011-08-21 00:59:08 +00:00
|
|
|
if (BLI_array_count(vv1) && v == vv1[BLI_array_count(vv1)-1]) {
|
|
|
|
|
printf("eck!\n");
|
|
|
|
|
}
|
2011-08-15 23:38:51 +00:00
|
|
|
BLI_array_append(vv1, v);
|
|
|
|
|
} else {
|
|
|
|
|
BLI_array_append(vv2, v);
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-08-30 00:54:07 +00:00
|
|
|
|
|
|
|
|
/*test for connected loops, and set cl1 or cl2 if so*/
|
2011-08-15 23:38:51 +00:00
|
|
|
if (v == ov) {
|
|
|
|
|
if (c==0)
|
|
|
|
|
cl1 = 1;
|
|
|
|
|
else
|
|
|
|
|
cl2 = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ee1 && ee2) {
|
|
|
|
|
int i, j;
|
|
|
|
|
BMVert *v1, *v2, *v3, *v4;
|
2011-08-21 00:59:08 +00:00
|
|
|
int starti=0, lenv1=BLI_array_count(vv1), lenv2=BLI_array_count(vv1);
|
2011-08-15 23:38:51 +00:00
|
|
|
|
|
|
|
|
/*handle case of two unclosed loops*/
|
|
|
|
|
if (!cl1 && !cl2) {
|
|
|
|
|
v1 = get_outer_vert(bm, ee1[0]);
|
|
|
|
|
v2 = BLI_array_count(ee1) > 1 ? get_outer_vert(bm, ee1[1]) : v1;
|
|
|
|
|
v3 = get_outer_vert(bm, ee2[0]);
|
|
|
|
|
v4 = BLI_array_count(ee2) > 1 ? get_outer_vert(bm, ee2[1]) : v3;
|
2011-08-16 06:24:10 +00:00
|
|
|
|
2011-08-15 23:38:51 +00:00
|
|
|
if (len_v3v3(v1->co, v3->co) > len_v3v3(v1->co, v4->co)) {
|
|
|
|
|
for (i=0; i<BLI_array_count(ee1)/2; i++) {
|
|
|
|
|
SWAP(void*, ee1[i], ee1[BLI_array_count(ee1)-i-1]);
|
|
|
|
|
SWAP(void*, vv1[i], vv1[BLI_array_count(vv1)-i-1]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cl1) {
|
|
|
|
|
float min = 1e32;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<BLI_array_count(vv1); i++) {
|
|
|
|
|
if (len_v3v3(vv1[i]->co, vv2[0]->co) < min) {
|
|
|
|
|
min = len_v3v3(vv1[i]->co, vv2[0]->co);
|
|
|
|
|
starti = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
j = 0;
|
2011-08-21 00:59:08 +00:00
|
|
|
if (lenv1 && vv1[0] == vv1[lenv1-1]) {
|
|
|
|
|
lenv1--;
|
|
|
|
|
}
|
|
|
|
|
if (lenv2 && vv2[0] == vv2[lenv2-1]) {
|
|
|
|
|
lenv2--;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-30 00:54:07 +00:00
|
|
|
for (i=0; i<BLI_array_count(ee1) && lenv1; i++) {
|
2011-08-15 23:38:51 +00:00
|
|
|
BMFace *f;
|
|
|
|
|
|
|
|
|
|
if (j >= BLI_array_count(ee2))
|
|
|
|
|
break;
|
2011-08-21 00:59:08 +00:00
|
|
|
|
|
|
|
|
if (vv1[(i + starti)%lenv1] == vv1[(i + 1 + starti)%lenv1]) {
|
|
|
|
|
j++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f = BM_Make_QuadTri(bm, vv1[(i + starti)%lenv1], vv2[i], vv2[(i+1)%lenv2], vv1[(i+1 + starti)%lenv1], NULL, 1);
|
|
|
|
|
if (!f || f->len != 4) {
|
|
|
|
|
printf("eek in bridge!\n");
|
2011-08-15 23:38:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|