edge subdivide ops now use bmesh code, rather then just the test bmesh op. also, got bmesh edge subdivide's smooth subdivide mode to work (fractal already worked I think, not sure).
This commit is contained in:
@@ -119,6 +119,11 @@ enum {
|
||||
BMOP_TRIANG_FACEIN, /*faces*/
|
||||
BMOP_TRIANG_NEW_EDGES, /*edgeout*/
|
||||
BMOP_TRIANG_NEW_FACES, /*faceout*/
|
||||
|
||||
/*facemap, maps new faces to old one. since triangulator
|
||||
uses only split face, the original ngon face is still there,
|
||||
though it's just another triangle now.*/
|
||||
BMOP_TRIANG_FACEMAP,
|
||||
BMOP_TRIANG_TOTSLOT,
|
||||
};
|
||||
|
||||
@@ -187,6 +192,9 @@ struct EditMesh;
|
||||
void BMOP_DupeFromFlag(struct BMesh *bm, int etypeflag, int flag);
|
||||
void BM_esubdivideflag(struct Object *obedit, struct BMesh *bm, int selflag, float rad,
|
||||
int flag, int numcuts, int seltype);
|
||||
void BM_esubdivideflag_conv(struct Object *obedit, struct EditMesh *em,
|
||||
int selflag, float rad, int flag, int numcuts,
|
||||
int seltype);
|
||||
void BM_extrudefaceflag(BMesh *bm, int flag);
|
||||
|
||||
/*this next one return 1 if they did anything, or zero otherwise.
|
||||
|
||||
@@ -52,7 +52,8 @@ BMOpDefine def_triangop = {
|
||||
"triangulate",
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "faceout"}},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
|
||||
{BMOP_OPSLOT_MAPPING, "facemap"}},
|
||||
triangulate_exec,
|
||||
BMOP_TRIANG_TOTSLOT,
|
||||
0
|
||||
|
||||
@@ -351,17 +351,18 @@ void BM_Vert_UpdateNormal(BMesh *bm, BMVert *v)
|
||||
{
|
||||
BMIter iter;
|
||||
BMFace *f;
|
||||
float norm[3] = {0.0f, 0.0f, 0.0f};
|
||||
int len=0;
|
||||
|
||||
v->no[0] = v->no[1] = v->no[2] = 0.0f;
|
||||
|
||||
f = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v);
|
||||
for (; f; f=BMIter_Step(&iter), len++) {
|
||||
VecAddf(norm, f->no, norm);
|
||||
VecAddf(v->no, f->no, v->no);
|
||||
}
|
||||
|
||||
if (!len) return;
|
||||
|
||||
VecMulf(norm, 1.0f/(int)len);
|
||||
VecMulf(v->no, 1.0f/(int)len);
|
||||
}
|
||||
|
||||
void bmesh_update_face_normal(BMesh *bm, BMFace *f, float (*projectverts)[3])
|
||||
@@ -429,11 +430,11 @@ int linecrosses(double *v1, double *v2, double *v3, double *v4)
|
||||
|
||||
return (w1 == w2) && (w3 == w4);*/
|
||||
|
||||
w1 = testedgesidef(v1, v3, v2);
|
||||
w2 = testedgesidef(v2, v4, v1);
|
||||
w3 = !testedgesidef(v1, v2, v3);
|
||||
w4 = testedgesidef(v3, v2, v4);
|
||||
w5 = !testedgesidef(v3, v1, v4);
|
||||
w1 = testedgeside(v1, v3, v2);
|
||||
w2 = testedgeside(v2, v4, v1);
|
||||
w3 = !testedgeside(v1, v2, v3);
|
||||
w4 = testedgeside(v3, v2, v4);
|
||||
w5 = !testedgeside(v3, v1, v4);
|
||||
return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5;
|
||||
}
|
||||
|
||||
@@ -552,17 +553,17 @@ static BMLoop *find_ear(BMesh *bm, BMFace *f, float (*verts)[3],
|
||||
* triangles (angles less than
|
||||
* 90 degrees). If the triangulator
|
||||
* has bits left over (or cannot
|
||||
* triangulate at all) it uses an
|
||||
* arbitrary triangulation.
|
||||
*
|
||||
* TODO:
|
||||
* -Modify this to try and find ears that will not create a non-manifold face after conversion back to editmesh
|
||||
* triangulate at all) it uses a
|
||||
* simple fan triangulation
|
||||
*
|
||||
* newfaces, if non-null, must be an array of BMFace pointers,
|
||||
* with a length equal to f->len. it will be filled with the new
|
||||
* triangles, and will be NULL-terminated.
|
||||
*/
|
||||
void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3],
|
||||
int newedgeflag, int newfaceflag)
|
||||
int newedgeflag, int newfaceflag, BMFace **newfaces)
|
||||
{
|
||||
int i, done, nvert;
|
||||
int i, done, nvert, nf_i = 0;
|
||||
BMLoop *l, *newl, *nextloop;
|
||||
BMVert *v;
|
||||
|
||||
@@ -607,6 +608,8 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3],
|
||||
|
||||
BMO_SetFlag(bm, newl->e, newedgeflag);
|
||||
BMO_SetFlag(bm, f, newfaceflag);
|
||||
|
||||
if (newfaces) newfaces[nf_i++] = f;
|
||||
|
||||
/*l = f->loopbase;
|
||||
do {
|
||||
@@ -627,14 +630,22 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3],
|
||||
&newl, NULL);
|
||||
if (!f) {
|
||||
printf("triangle fan step of triangulator failed.\n");
|
||||
|
||||
/*NULL-terminate*/
|
||||
if (newfaces) newfaces[nf_i] = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newfaces) newfaces[nf_i++] = f;
|
||||
|
||||
BMO_SetFlag(bm, newl->e, newedgeflag);
|
||||
BMO_SetFlag(bm, f, newfaceflag);
|
||||
l = nextloop;
|
||||
}
|
||||
}
|
||||
|
||||
/*NULL-terminate*/
|
||||
if (newfaces) newfaces[nf_i] = NULL;
|
||||
}
|
||||
|
||||
/*each pair of loops defines a new edge, a split. this function goes
|
||||
|
||||
@@ -66,8 +66,10 @@ int bmesh_test_sysflag(struct BMHeader *element, int flag);
|
||||
|
||||
/*Polygon Utilities ? FIXME... where do these each go?*/
|
||||
/*newedgeflag sets a flag layer flag, obviously not the header flag.*/
|
||||
void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], int newedgeflag, int newfaceflag);
|
||||
void bmesh_update_face_normal(struct BMesh *bm, struct BMFace *f, float (*projectverts)[3]);
|
||||
void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3],
|
||||
int newedgeflag, int newfaceflag, BMFace **newfaces);
|
||||
void bmesh_update_face_normal(struct BMesh *bm, struct BMFace *f,
|
||||
float (*projectverts)[3]);
|
||||
void compute_poly_plane(float (*verts)[3], int nverts);
|
||||
void poly_rotate_plane(float normal[3], float (*verts)[3], int nverts);
|
||||
void bmesh_flip_normal(struct BMesh *bm, struct BMFace *f);
|
||||
|
||||
@@ -140,18 +140,21 @@ static void alter_co(float *co, BMEdge *edge, subdparams *params, float perc,
|
||||
/* assumes in the edge is the correct interpolated vertices already */
|
||||
/* percent defines the interpolation, rad and flag are for special options */
|
||||
/* results in new vertex with correct coordinate, vertex normal and weight group info */
|
||||
static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge,
|
||||
subdparams *params, float percent,
|
||||
static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge,BMEdge *oedge,
|
||||
subdparams *params, float percent,
|
||||
float percent2,
|
||||
BMEdge **out,BMVert *vsta,BMVert *vend)
|
||||
{
|
||||
BMVert *ev;
|
||||
// float co[3];
|
||||
|
||||
ev = BM_Split_Edge(bm, edge->v1, edge, out, percent);
|
||||
BM_Vert_UpdateNormal(bm, ev);
|
||||
|
||||
BMO_SetFlag(bm, ev, ELE_INNER);
|
||||
|
||||
/* offset for smooth or sphere or fractal */
|
||||
alter_co(ev->co, edge, params, percent, vsta, vend);
|
||||
alter_co(ev->co, oedge, params, percent2, vsta, vend);
|
||||
|
||||
#if 0 //TODO
|
||||
/* clip if needed by mirror modifier */
|
||||
@@ -171,34 +174,35 @@ static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge,
|
||||
return ev;
|
||||
}
|
||||
|
||||
static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge,
|
||||
static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
|
||||
int curpoint, int totpoint, subdparams *params,
|
||||
BMEdge **newe, BMVert *vsta, BMVert *vend)
|
||||
{
|
||||
BMVert *ev;
|
||||
float percent;
|
||||
float percent, percent2 = 0.0f;
|
||||
|
||||
if (BMO_TestFlag(bm, edge, EDGE_PERCENT) && totpoint == 1)
|
||||
percent = BMO_Get_MapFloat(bm, params->op,
|
||||
BMOP_ESUBDIVIDE_PERCENT_EDGEMAP, edge);
|
||||
else {
|
||||
percent= 1.0f/(float)(totpoint+1-curpoint);
|
||||
percent2 = (float)curpoint / (float)(totpoint + 1);
|
||||
|
||||
}
|
||||
|
||||
ev= bm_subdivide_edge_addvert(bm, edge, params, percent,
|
||||
newe, vsta, vend);
|
||||
ev= bm_subdivide_edge_addvert(bm, edge, oedge, params, percent,
|
||||
percent2, newe, vsta, vend);
|
||||
return ev;
|
||||
}
|
||||
|
||||
static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, subdparams *params,
|
||||
BMVert *vsta, BMVert *vend) {
|
||||
BMEdge *eed = edge, *newe;
|
||||
BMEdge *eed = edge, *newe, temp = *edge;
|
||||
BMVert *v;
|
||||
int i, numcuts = params->numcuts;
|
||||
|
||||
for(i=0;i<numcuts;i++) {
|
||||
v = subdivideedgenum(bm, eed, i, params->numcuts, params,
|
||||
v = subdivideedgenum(bm, eed, &temp, i, params->numcuts, params,
|
||||
&newe, vsta, vend);
|
||||
BMO_SetFlag(bm, v, SUBD_SPLIT);
|
||||
BMO_SetFlag(bm, eed, SUBD_SPLIT);
|
||||
@@ -371,7 +375,7 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
{
|
||||
BMFace *nf;
|
||||
BMVert *v, *v1, *v2;
|
||||
BMEdge *e, *ne;
|
||||
BMEdge *e, *ne, temp;
|
||||
BMVert **lines;
|
||||
int numcuts = params->numcuts;
|
||||
int i, j, a, b, s=numcuts+2, totv=numcuts*4+4;
|
||||
@@ -406,9 +410,10 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
|
||||
v1 = lines[(i+1)*s] = verts[a];
|
||||
v2 = lines[(i+1)*s + s-1] = verts[b];
|
||||
|
||||
|
||||
temp = *e;
|
||||
for (a=0; a<numcuts; a++) {
|
||||
v = subdivideedgenum(bm, e, a, numcuts, params, &ne,
|
||||
v = subdivideedgenum(bm, e, &temp, a, numcuts, params, &ne,
|
||||
v1, v2);
|
||||
BMO_SetFlag(bm, ne, ELE_INNER);
|
||||
lines[(i+1)*s+a+1] = v;
|
||||
@@ -496,7 +501,7 @@ static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
BMEdge *e, *ne;
|
||||
BMEdge *e, *ne, temp;
|
||||
BMVert ***lines, *v;
|
||||
void *stackarr[1];
|
||||
int i, j, a, b, numcuts = params->numcuts;
|
||||
@@ -528,9 +533,10 @@ static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
|
||||
lines[i+1][0] = verts[a];
|
||||
lines[i+1][1+i] = verts[b];
|
||||
|
||||
|
||||
temp = *e;
|
||||
for (j=0; j<i; j++) {
|
||||
v = subdivideedgenum(bm, e, j, i, params, &ne,
|
||||
v = subdivideedgenum(bm, e, &temp, j, i, params, &ne,
|
||||
verts[a], verts[b]);
|
||||
lines[i+1][j+1] = v;
|
||||
|
||||
|
||||
@@ -13,33 +13,42 @@
|
||||
#define EDGE_NEW 1
|
||||
#define FACE_NEW 1
|
||||
|
||||
void triangulate_exec(BMesh *bmesh, BMOperator *op)
|
||||
void triangulate_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOpSlot *finput;
|
||||
BMFace *face;
|
||||
BMOIter siter;
|
||||
BMFace *face, **newfaces = NULL;
|
||||
V_DECLARE(newfaces);
|
||||
float (*projectverts)[3] = NULL;
|
||||
V_DECLARE(projectverts);
|
||||
int i, lastlen=0, count = 0;
|
||||
|
||||
finput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
|
||||
|
||||
for (i=0; i<finput->len; i++) {
|
||||
face = ((BMFace**)finput->data.p)[i];
|
||||
|
||||
face = BMO_IterNew(&siter, bm, op, BMOP_TRIANG_FACEIN);
|
||||
for (; face; face=BMO_IterStep(&siter)) {
|
||||
if (lastlen < face->len) {
|
||||
V_RESET(projectverts);
|
||||
V_RESET(newfaces);
|
||||
for (lastlen=0; lastlen<face->len; lastlen++) {
|
||||
V_GROW(projectverts);
|
||||
V_GROW(projectverts);
|
||||
V_GROW(projectverts);
|
||||
V_GROW(newfaces);
|
||||
}
|
||||
}
|
||||
|
||||
BM_Triangulate_Face(bmesh, face, projectverts, EDGE_NEW, FACE_NEW);
|
||||
BM_Triangulate_Face(bm, face, projectverts, EDGE_NEW,
|
||||
FACE_NEW, newfaces);
|
||||
|
||||
BMO_Insert_MapPointer(bm, op, BMOP_TRIANG_FACEMAP,
|
||||
face, face);
|
||||
for (i=0; newfaces[i]; i++) {
|
||||
BMO_Insert_MapPointer(bm, op, BMOP_TRIANG_FACEMAP,
|
||||
newfaces[i], face);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BMO_Flag_To_Slot(bmesh, op, BMOP_TRIANG_NEW_EDGES, EDGE_NEW, BM_EDGE);
|
||||
BMO_Flag_To_Slot(bmesh, op, BMOP_TRIANG_NEW_FACES, FACE_NEW, BM_FACE);
|
||||
BMO_Flag_To_Slot(bm, op, BMOP_TRIANG_NEW_EDGES, EDGE_NEW, BM_EDGE);
|
||||
BMO_Flag_To_Slot(bm, op, BMOP_TRIANG_NEW_FACES, FACE_NEW, BM_FACE);
|
||||
|
||||
V_FREE(projectverts);
|
||||
}
|
||||
@@ -1675,6 +1675,7 @@ typedef struct UndoMesh {
|
||||
EditVertC *verts;
|
||||
EditEdgeC *edges;
|
||||
EditFaceC *faces;
|
||||
EditFaceC *act_face;
|
||||
EditSelectionC *selected;
|
||||
int totvert, totedge, totface, totsel;
|
||||
short selectmode;
|
||||
@@ -1785,6 +1786,8 @@ static void *editMesh_to_undoMesh(void *emv)
|
||||
CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
|
||||
}
|
||||
|
||||
if (em->act_face) um->act_face = um->faces + em->act_face->tmp.l;
|
||||
|
||||
a = 0;
|
||||
for(ese=em->selected.first; ese; ese=ese->next, esec++){
|
||||
esec->type = ese->type;
|
||||
@@ -1872,7 +1875,9 @@ static void undoMesh_to_editMesh(void *umv, void *emv)
|
||||
efa->f= efac->f;
|
||||
efa->h= efac->h;
|
||||
efa->fgonf= efac->fgonf;
|
||||
|
||||
|
||||
if (efac == um->act_face) em->act_face = efa;
|
||||
|
||||
CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
|
||||
}
|
||||
|
||||
@@ -1896,6 +1901,10 @@ static void undoMesh_to_editMesh(void *umv, void *emv)
|
||||
EM_free_index_arrays();
|
||||
}
|
||||
|
||||
EM_nvertices_selected(em);
|
||||
EM_nedges_selected(em);
|
||||
EM_nfaces_selected(em);
|
||||
|
||||
// XXX retopo_free_paint();
|
||||
// em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
|
||||
// scene->toolsettings->retopo_mode= um->retopo_mode;
|
||||
|
||||
@@ -3257,8 +3257,10 @@ static int bmesh_test_exec(bContext *C, wmOperator *op)
|
||||
bm = editmesh_to_bmesh(em);
|
||||
|
||||
#if 1 /*edge subdivide test*/
|
||||
//BM_esubdivideflag(obedit, bm, SELECT, 0.292f*5.0, B_SMOOTH, G.rt==0?1:G.rt, 0);
|
||||
BM_esubdivideflag(obedit, bm, SELECT, 0, 0, G.rt==0?1:G.rt, SUBDIV_SELECT_INNER);
|
||||
//esubdivideflag(obedit, em, 1, -(RNA_float_get(op->ptr, "random_factor")/100), scene->toolsettings->editbutflag, RNA_int_get(op->ptr, "number_cuts"), 0);
|
||||
|
||||
BM_esubdivideflag(obedit, bm, SELECT, -0.05f, 0, G.rt==0?1:G.rt, 0);
|
||||
//BM_esubdivideflag(obedit, bm, SELECT, 0, 0, G.rt==0?1:G.rt, SUBDIV_SELECT_INNER);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2188,7 +2188,7 @@ static void fill_quad_quadruple(EditMesh *em, EditFace *efa, struct GHash *gh, i
|
||||
|
||||
for(i=1;i<=numcuts;i++) {
|
||||
/* we create a fake edge for the next loop */
|
||||
temp.v2 = innerverts[i][0] = verts[1][i];
|
||||
temp.v2 = innerverts[i][0] = verts[1][i];
|
||||
temp.v1 = innerverts[i][numcuts+1] = verts[3][i];
|
||||
|
||||
for(j=1;j<=numcuts;j++) {
|
||||
@@ -6439,7 +6439,7 @@ static int subdivide_exec(bContext *C, wmOperator *op)
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
|
||||
|
||||
esubdivideflag(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, 1, 0);
|
||||
BM_esubdivideflag_conv(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, 1, 0);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
|
||||
|
||||
@@ -6466,7 +6466,7 @@ static int subdivide_multi_exec(bContext *C, wmOperator *op)
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
|
||||
|
||||
esubdivideflag(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, RNA_int_get(op->ptr,"number_cuts"), 0);
|
||||
BM_esubdivideflag_conv(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, RNA_int_get(op->ptr,"number_cuts"), 0);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
|
||||
|
||||
@@ -6496,7 +6496,7 @@ static int subdivide_multi_fractal_exec(bContext *C, wmOperator *op)
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
|
||||
|
||||
esubdivideflag(obedit, em, 1, -(RNA_float_get(op->ptr, "random_factor")/100), scene->toolsettings->editbutflag, RNA_int_get(op->ptr, "number_cuts"), 0);
|
||||
BM_esubdivideflag_conv(obedit, em, 1, -(RNA_float_get(op->ptr, "random_factor")/100), scene->toolsettings->editbutflag, RNA_int_get(op->ptr, "number_cuts"), 0);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
|
||||
|
||||
@@ -6527,7 +6527,7 @@ static int subdivide_smooth_exec(bContext *C, wmOperator *op)
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
|
||||
|
||||
esubdivideflag(obedit, em, 1, 0.292f*RNA_float_get(op->ptr, "smoothness"), scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
|
||||
BM_esubdivideflag_conv(obedit, em, 1, 0.292f*RNA_float_get(op->ptr, "smoothness"), scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
|
||||
|
||||
|
||||
@@ -1569,7 +1569,7 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *dra
|
||||
unsigned char *col;
|
||||
|
||||
if (efa->h==0) {
|
||||
if (efa == data->efa_act) {
|
||||
if (efa == data->efa_act || efa->flag & ME_DRAW_ACT) {
|
||||
glColor4ubv(data->cols[2]);
|
||||
return 2; /* stipple */
|
||||
} else {
|
||||
|
||||
@@ -216,7 +216,9 @@ typedef struct PartialVisibility {
|
||||
/* flag (mface) */
|
||||
#define ME_SMOOTH 1
|
||||
#define ME_FACE_SEL 2
|
||||
/* flag ME_HIDE==16 is used here too */
|
||||
/* flag ME_HIDE==16 is used here too */
|
||||
#define ME_DRAW_ACT 4
|
||||
|
||||
/* mselect->type */
|
||||
#define ME_VSEl 0
|
||||
#define ME_ESEl 1
|
||||
|
||||
Reference in New Issue
Block a user