alt-ctrl leftmouse (e.g. current knife) now uses bmesh edge subdivide! wa-hoo! basically I had to add some slots to the subdivide operator so it could accept custom percentags for splitting edges. also put some commonly passed-around paramters into a struct, so i don't have to constantly keep changing a dozen function signatures
This commit is contained in:
@@ -62,6 +62,7 @@ void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, int
|
||||
void BMO_Set_Float(struct BMOperator *op, int slotcode, float f);
|
||||
void BMO_Set_Int(struct BMOperator *op, int slotcode, int i);
|
||||
void BMO_Set_PntBuf(struct BMOperator *op, int slotcode, void *p, int len);
|
||||
void BMO_Set_FltBuf(BMOperator *op, int slotcode, float *p, int len);
|
||||
void BMO_Set_Pnt(struct BMOperator *op, int slotcode, void *p);
|
||||
void BMO_Set_Vec(struct BMOperator *op, int slotcode, float *vec);
|
||||
void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
|
||||
@@ -161,7 +162,7 @@ enum {
|
||||
BMOP_ESUBDIVIDE_CUSTOMFILL_FACES,
|
||||
BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS,
|
||||
|
||||
BMOP_ESUBDIVIDE_PERCENT_VERTS,
|
||||
BMOP_ESUBDIVIDE_PERCENT_EDGES,
|
||||
BMOP_ESUBDIVIDE_PERCENT_VALUES,
|
||||
|
||||
BMOP_ESUBDIVIDE_TOTSLOT,
|
||||
|
||||
@@ -42,7 +42,7 @@ BMOpDefine def_subdop = {
|
||||
BMOP_OPSLOT_PNT_BUF,
|
||||
BMOP_OPSLOT_PNT_BUF,
|
||||
BMOP_OPSLOT_PNT_BUF,
|
||||
BMOP_OPSLOT_FLT},
|
||||
BMOP_OPSLOT_FLT_BUF},
|
||||
esubdivide_exec,
|
||||
BMOP_ESUBDIVIDE_TOTSLOT,
|
||||
0
|
||||
|
||||
@@ -212,6 +212,15 @@ void BMO_Set_PntBuf(BMOperator *op, int slotcode, void *p, int len)
|
||||
op->slots[slotcode].len = len;
|
||||
}
|
||||
|
||||
void BMO_Set_FltBuf(BMOperator *op, int slotcode, float *p, int len)
|
||||
{
|
||||
if( !(op->slots[slotcode].slottype == BMOP_OPSLOT_FLT_BUF) )
|
||||
return;
|
||||
|
||||
op->slots[slotcode].data.p = p;
|
||||
op->slots[slotcode].len = len;
|
||||
}
|
||||
|
||||
void BMO_Set_Pnt(BMOperator *op, int slotcode, void *p)
|
||||
{
|
||||
if( !(op->slots[slotcode].slottype == BMOP_OPSLOT_PNT) )
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#define SUBD_SPLIT 1
|
||||
|
||||
#define EDGE_PERCENT 2
|
||||
|
||||
/*I don't think new faces are flagged, currently, but
|
||||
better safe than sorry.*/
|
||||
#define FACE_NEW 2
|
||||
@@ -48,12 +50,12 @@ NOTE: beauty has been renamed to flag!
|
||||
*/
|
||||
|
||||
/* calculates offset for co, based on fractal, sphere or smooth settings */
|
||||
static void alter_co(float *co, BMEdge *edge, float rad, int flag, float perc,
|
||||
static void alter_co(float *co, BMEdge *edge, subdparams *params, float perc,
|
||||
BMVert *vsta, BMVert *vend)
|
||||
{
|
||||
float vec1[3], fac;
|
||||
|
||||
if(flag & B_SMOOTH) {
|
||||
if(params->flag & B_SMOOTH) {
|
||||
/* we calculate an offset vector vec1[], to be added to *co */
|
||||
float len, fac, nor[3], nor1[3], nor2[3];
|
||||
|
||||
@@ -77,23 +79,23 @@ static void alter_co(float *co, BMEdge *edge, float rad, int flag, float perc,
|
||||
vec1[1]+= fac*nor2[1];
|
||||
vec1[2]+= fac*nor2[2];
|
||||
|
||||
vec1[0]*= rad*len;
|
||||
vec1[1]*= rad*len;
|
||||
vec1[2]*= rad*len;
|
||||
vec1[0]*= params->rad*len;
|
||||
vec1[1]*= params->rad*len;
|
||||
vec1[2]*= params->rad*len;
|
||||
|
||||
co[0] += vec1[0];
|
||||
co[1] += vec1[1];
|
||||
co[2] += vec1[2];
|
||||
}
|
||||
else {
|
||||
if(rad > 0.0) { /* subdivide sphere */
|
||||
if(params->rad > 0.0) { /* subdivide sphere */
|
||||
Normalize(co);
|
||||
co[0]*= rad;
|
||||
co[1]*= rad;
|
||||
co[2]*= rad;
|
||||
co[0]*= params->rad;
|
||||
co[1]*= params->rad;
|
||||
co[2]*= params->rad;
|
||||
}
|
||||
else if(rad< 0.0) { /* fractal subdivide */
|
||||
fac= rad* VecLenf(vsta->co, vend->co);
|
||||
else if(params->rad< 0.0) { /* fractal subdivide */
|
||||
fac= params->rad* VecLenf(vsta->co, vend->co);
|
||||
vec1[0]= fac*(float)(0.5-BLI_drand());
|
||||
vec1[1]= fac*(float)(0.5-BLI_drand());
|
||||
vec1[2]= fac*(float)(0.5-BLI_drand());
|
||||
@@ -106,18 +108,18 @@ static void alter_co(float *co, BMEdge *edge, float rad, int flag, 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, float rad,
|
||||
int flag, float percent, BMEdge **out,
|
||||
BMVert *vsta, BMVert *vend)
|
||||
static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge,
|
||||
subdparams *params, float percent,
|
||||
BMEdge **out,BMVert *vsta,BMVert *vend)
|
||||
{
|
||||
BMVert *ev;
|
||||
// float co[3];
|
||||
|
||||
ev = BM_Split_Edge(bm, edge->v1, edge, out, percent, 1);
|
||||
if (flag & SELTYPE_INNER) BM_Select_Vert(bm, ev, 1);
|
||||
if (params->flag & SELTYPE_INNER) BM_Select_Vert(bm, ev, 1);
|
||||
|
||||
/* offset for smooth or sphere or fractal */
|
||||
alter_co(ev->co, edge, rad, flag, percent, vsta, vend);
|
||||
alter_co(ev->co, edge, params, percent, vsta, vend);
|
||||
|
||||
#if 0 //TODO
|
||||
/* clip if needed by mirror modifier */
|
||||
@@ -138,48 +140,33 @@ static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, float rad,
|
||||
}
|
||||
|
||||
static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge,
|
||||
int curpoint, int totpoint, float rad,
|
||||
int flag, BMEdge **newe,
|
||||
BMVert *vsta, BMVert *vend)
|
||||
int curpoint, int totpoint, subdparams *params,
|
||||
BMEdge **newe, BMVert *vsta, BMVert *vend)
|
||||
{
|
||||
BMVert *ev;
|
||||
float percent;
|
||||
|
||||
if (flag & (B_PERCENTSUBD) && totpoint == 1)
|
||||
/*I guess the idea is vertices store what
|
||||
percent to use?*/
|
||||
//percent=(float)(edge->tmp.l)/32768.0f;
|
||||
percent= 1.0; //edge->tmp.fp;
|
||||
if (BMO_TestFlag(bm, edge, EDGE_PERCENT) && totpoint == 1)
|
||||
percent= *((float*)BLI_ghash_lookup(params->percenthash,edge));
|
||||
else {
|
||||
percent= 1.0f/(float)(totpoint+1-curpoint);
|
||||
|
||||
}
|
||||
|
||||
/*{
|
||||
float co[3], co2[3];
|
||||
VecSubf(co, edge->v2->co, edge->v1->co);
|
||||
VecMulf(co, 1.0f/(float)(totpoint+1-curpoint));
|
||||
VecAddf(co2, edge->v1->co, co);
|
||||
*/
|
||||
ev= bm_subdivide_edge_addvert(bm, edge, rad, flag, percent,
|
||||
newe, vsta, vend);
|
||||
|
||||
/* VECCOPY(ev->co, co2);
|
||||
}
|
||||
*/
|
||||
ev= bm_subdivide_edge_addvert(bm, edge, params, percent,
|
||||
newe, vsta, vend);
|
||||
return ev;
|
||||
}
|
||||
|
||||
static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, float rad,
|
||||
int flag, int numcuts,
|
||||
static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, subdparams *params,
|
||||
BMVert *vsta, BMVert *vend) {
|
||||
BMEdge *eed = edge, *newe;
|
||||
BMVert *v;
|
||||
int i;
|
||||
int i, numcuts = params->numcuts;
|
||||
|
||||
for(i=0;i<numcuts;i++) {
|
||||
v = subdivideedgenum(bm, eed, i, numcuts, rad,
|
||||
flag, &newe, vsta, vend);
|
||||
v = subdivideedgenum(bm, eed, i, params->numcuts, params,
|
||||
&newe, vsta, vend);
|
||||
BMO_SetFlag(bm, v, SUBD_SPLIT);
|
||||
BMO_SetFlag(bm, eed, SUBD_SPLIT);
|
||||
}
|
||||
@@ -199,28 +186,28 @@ v3---------v2
|
||||
v4---v0---v1
|
||||
|
||||
*/
|
||||
static void q_1edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
|
||||
int flag, float rad) {
|
||||
static void q_1edge_split(BMesh *bm, BMFace *face,
|
||||
BMVert **verts, subdparams *params) {
|
||||
BMFace *nf;
|
||||
int i, add;
|
||||
int i, add, numcuts = params->numcuts;
|
||||
|
||||
/*if it's odd, the middle face is a quad, otherwise it's a triangle*/
|
||||
if (numcuts % 2==0) {
|
||||
add = 2;
|
||||
for (i=0; i<numcuts; i++) {
|
||||
if (i == numcuts/2) add -= 1;
|
||||
BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add],
|
||||
BM_Connect_Verts(bm, verts[i], verts[numcuts+add],
|
||||
&nf);
|
||||
}
|
||||
} else {
|
||||
add = 2;
|
||||
for (i=0; i<numcuts; i++) {
|
||||
BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add],
|
||||
BM_Connect_Verts(bm, verts[i], verts[numcuts+add],
|
||||
&nf);
|
||||
if (i == numcuts/2) {
|
||||
add -= 1;
|
||||
BM_Connect_Verts(bm, vlist[i],
|
||||
vlist[numcuts+add],
|
||||
BM_Connect_Verts(bm, verts[i],
|
||||
verts[numcuts+add],
|
||||
&nf);
|
||||
}
|
||||
}
|
||||
@@ -246,13 +233,14 @@ v5---v0---v1
|
||||
|
||||
*/
|
||||
|
||||
static void q_2edge_op_split(BMesh *bm, BMFace *face, BMVert **vlist,
|
||||
int numcuts, int flag, float rad) {
|
||||
static void q_2edge_op_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
int i;
|
||||
int i, numcuts = params->numcuts;
|
||||
|
||||
for (i=0; i<numcuts; i++) {
|
||||
BM_Connect_Verts(bm, vlist[i],vlist[(numcuts-i-1)+numcuts+2],
|
||||
BM_Connect_Verts(bm, verts[i],verts[(numcuts-i-1)+numcuts+2],
|
||||
&nf);
|
||||
}
|
||||
}
|
||||
@@ -272,16 +260,17 @@ v6--------v5
|
||||
v7-v0--v1-v2
|
||||
|
||||
*/
|
||||
static void q_2edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
|
||||
int numcuts, int flag, float rad) {
|
||||
static void q_2edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
int i;
|
||||
int i, numcuts = params->numcuts;
|
||||
|
||||
for (i=0; i<numcuts; i++) {
|
||||
BM_Connect_Verts(bm, vlist[i], vlist[numcuts+(numcuts-i)],
|
||||
BM_Connect_Verts(bm, verts[i], verts[numcuts+(numcuts-i)],
|
||||
&nf);
|
||||
}
|
||||
BM_Connect_Verts(bm, vlist[numcuts*2+3], vlist[numcuts*2+1], &nf);
|
||||
BM_Connect_Verts(bm, verts[numcuts*2+3], verts[numcuts*2+1], &nf);
|
||||
}
|
||||
|
||||
subdpattern q_2edge = {
|
||||
@@ -300,25 +289,26 @@ v8--v7--v6-v5
|
||||
v9-v0--v1-v2
|
||||
|
||||
*/
|
||||
static void q_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
|
||||
int numcuts, int flag, float rad) {
|
||||
static void q_3edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
int i, add=0;
|
||||
int i, add=0, numcuts = params->numcuts;
|
||||
|
||||
for (i=0; i<numcuts; i++) {
|
||||
if (i == numcuts/2) {
|
||||
if (numcuts % 2 != 0) {
|
||||
BM_Connect_Verts(bm, vlist[numcuts-i-1+add],
|
||||
vlist[i+numcuts+1], &nf);
|
||||
BM_Connect_Verts(bm, verts[numcuts-i-1+add],
|
||||
verts[i+numcuts+1], &nf);
|
||||
}
|
||||
add = numcuts*2+2;
|
||||
}
|
||||
BM_Connect_Verts(bm, vlist[numcuts-i-1+add],
|
||||
vlist[i+numcuts+1], &nf);
|
||||
BM_Connect_Verts(bm, verts[numcuts-i-1+add],
|
||||
verts[i+numcuts+1], &nf);
|
||||
}
|
||||
|
||||
for (i=0; i<numcuts/2+1; i++) {
|
||||
BM_Connect_Verts(bm, vlist[i],vlist[(numcuts-i)+numcuts*2+1],
|
||||
BM_Connect_Verts(bm, verts[i],verts[(numcuts-i)+numcuts*2+1],
|
||||
&nf);
|
||||
}
|
||||
}
|
||||
@@ -340,27 +330,30 @@ first line | | last line
|
||||
|
||||
it goes from bottom up
|
||||
*/
|
||||
static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
|
||||
int flag, float rad) {
|
||||
static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
BMVert *v, *v1, *v2;
|
||||
BMEdge *e, *ne;
|
||||
BMVert **lines = MEM_callocN(sizeof(BMVert*)*(numcuts+2)*(numcuts+2),
|
||||
"q_4edge_split");
|
||||
BMVert **lines;
|
||||
int numcuts = params->numcuts;
|
||||
int i, j, a, b, s=numcuts+2, totv=numcuts*4+4;
|
||||
|
||||
lines = MEM_callocN(sizeof(BMVert*)*(numcuts+2)*(numcuts+2),
|
||||
"q_4edge_split");
|
||||
/*build a 2-dimensional array of verts,
|
||||
containing every vert (and all new ones)
|
||||
in the face.*/
|
||||
|
||||
/*first line*/
|
||||
for (i=0; i<numcuts+2; i++) {
|
||||
lines[i] = vlist[numcuts*3+2+(numcuts-i+1)];
|
||||
lines[i] = verts[numcuts*3+2+(numcuts-i+1)];
|
||||
}
|
||||
|
||||
/*last line*/
|
||||
for (i=0; i<numcuts+2; i++) {
|
||||
lines[(s-1)*s+i] = vlist[numcuts+i];
|
||||
lines[(s-1)*s+i] = verts[numcuts+i];
|
||||
}
|
||||
|
||||
/*first and last members of middle lines*/
|
||||
@@ -368,19 +361,19 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
|
||||
a = i;
|
||||
b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
|
||||
|
||||
e = BM_Connect_Verts(bm, vlist[a], vlist[b], &nf);
|
||||
if (flag & SELTYPE_INNER) {
|
||||
e = BM_Connect_Verts(bm, verts[a], verts[b], &nf);
|
||||
if (params->flag & SELTYPE_INNER) {
|
||||
BM_Select_Edge(bm, e, 1);
|
||||
BM_Select_Face(bm, nf, 1);
|
||||
}
|
||||
|
||||
v1 = lines[(i+1)*s] = vlist[a];
|
||||
v2 = lines[(i+1)*s + s-1] = vlist[b];
|
||||
v1 = lines[(i+1)*s] = verts[a];
|
||||
v2 = lines[(i+1)*s + s-1] = verts[b];
|
||||
|
||||
for (a=0; a<numcuts; a++) {
|
||||
v = subdivideedgenum(bm, e, a, numcuts, rad, flag, &ne,
|
||||
v = subdivideedgenum(bm, e, a, numcuts, params, &ne,
|
||||
v1, v2);
|
||||
if (flag & SELTYPE_INNER) {
|
||||
if (params->flag & SELTYPE_INNER) {
|
||||
BM_Select_Edge(bm, ne, 1);
|
||||
}
|
||||
lines[(i+1)*s+a+1] = v;
|
||||
@@ -392,7 +385,7 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
|
||||
a = i*s + j;
|
||||
b = (i-1)*s + j;
|
||||
e = BM_Connect_Verts(bm, lines[a], lines[b], &nf);
|
||||
if (flag & SELTYPE_INNER) {
|
||||
if (params->flag & SELTYPE_INNER) {
|
||||
BM_Select_Edge(bm, e, 1);
|
||||
BM_Select_Face(bm, nf, 1);
|
||||
}
|
||||
@@ -411,13 +404,14 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
|
||||
v4--v0--v1--v2
|
||||
s s
|
||||
*/
|
||||
static void t_1edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
|
||||
int numcuts, int flag, float rad) {
|
||||
static void t_1edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
int i;
|
||||
int i, numcuts = params->numcuts;
|
||||
|
||||
for (i=0; i<numcuts; i++) {
|
||||
BM_Connect_Verts(bm, vlist[i], vlist[numcuts+1], &nf);
|
||||
BM_Connect_Verts(bm, verts[i], verts[numcuts+1], &nf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,13 +430,14 @@ subdpattern t_1edge = {
|
||||
v6--v0--v1--v2
|
||||
s s
|
||||
*/
|
||||
static void t_2edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
|
||||
int numcuts, int flag, float rad) {
|
||||
static void t_2edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
int i;
|
||||
int i, numcuts = params->numcuts;
|
||||
|
||||
for (i=0; i<numcuts; i++) {
|
||||
BM_Connect_Verts(bm, vlist[i], vlist[numcuts+numcuts-i], &nf);
|
||||
BM_Connect_Verts(bm, verts[i], verts[numcuts+numcuts-i], &nf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,49 +457,50 @@ sv7/---v---\ v3 s
|
||||
v8--v0--v1--v2
|
||||
s s
|
||||
*/
|
||||
static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
|
||||
int numcuts, int flag, float rad) {
|
||||
static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **verts,
|
||||
subdparams *params)
|
||||
{
|
||||
BMFace *nf;
|
||||
BMEdge *e, *ne;
|
||||
BMVert ***lines, *v;
|
||||
void *stackarr[1];
|
||||
int i, j, a, b;
|
||||
int i, j, a, b, numcuts = params->numcuts;
|
||||
|
||||
/*number of verts in each line*/
|
||||
lines = MEM_callocN(sizeof(void*)*(numcuts+2), "triangle vert table");
|
||||
|
||||
lines[0] = (BMVert**) stackarr;
|
||||
lines[0][0] = vlist[numcuts*2+1];
|
||||
lines[0][0] = verts[numcuts*2+1];
|
||||
|
||||
lines[1+numcuts] = MEM_callocN(sizeof(void*)*(numcuts+2),
|
||||
"triangle vert table 2");
|
||||
for (i=0; i<numcuts; i++) {
|
||||
lines[1+numcuts][1+i] = vlist[i];
|
||||
lines[1+numcuts][1+i] = verts[i];
|
||||
}
|
||||
lines[1+numcuts][0] = vlist[numcuts*3+2];
|
||||
lines[1+numcuts][1+numcuts] = vlist[numcuts];
|
||||
lines[1+numcuts][0] = verts[numcuts*3+2];
|
||||
lines[1+numcuts][1+numcuts] = verts[numcuts];
|
||||
|
||||
for (i=0; i<numcuts; i++) {
|
||||
lines[i+1] = MEM_callocN(sizeof(void*)*(2+i),
|
||||
"triangle vert table row");
|
||||
a = numcuts*2 + 2 + i;
|
||||
b = numcuts + numcuts - i;
|
||||
e = BM_Connect_Verts(bm, vlist[a], vlist[b], &nf);
|
||||
e = BM_Connect_Verts(bm, verts[a], verts[b], &nf);
|
||||
|
||||
if (flag & SELTYPE_INNER) {
|
||||
if (params->flag & SELTYPE_INNER) {
|
||||
BM_Select_Edge(bm, e, 1);
|
||||
BM_Select_Face(bm, nf, 1);
|
||||
}
|
||||
|
||||
lines[i+1][0] = vlist[a];
|
||||
lines[i+1][1+i] = vlist[b];
|
||||
lines[i+1][0] = verts[a];
|
||||
lines[i+1][1+i] = verts[b];
|
||||
|
||||
for (j=0; j<i; j++) {
|
||||
v = subdivideedgenum(bm, e, j, i, rad, flag, &ne,
|
||||
vlist[a], vlist[b]);
|
||||
v = subdivideedgenum(bm, e, j, i, params, &ne,
|
||||
verts[a], verts[b]);
|
||||
lines[i+1][j+1] = v;
|
||||
|
||||
if (flag & SELTYPE_INNER) {
|
||||
if (params->flag & SELTYPE_INNER) {
|
||||
BM_Select_Edge(bm, ne, 1);
|
||||
}
|
||||
}
|
||||
@@ -524,14 +520,14 @@ sv7/---v---\ v3 s
|
||||
for (j=0; j<i; j++) {
|
||||
e= BM_Connect_Verts(bm, lines[i][j], lines[i+1][j+1],
|
||||
&nf);
|
||||
if (flag & SELTYPE_INNER) {
|
||||
if (params->flag & SELTYPE_INNER) {
|
||||
BM_Select_Edge(bm, e, 1);
|
||||
BM_Select_Face(bm, nf, 1);
|
||||
}
|
||||
|
||||
e= BM_Connect_Verts(bm,lines[i][j+1],lines[i+1][j+1],
|
||||
&nf);
|
||||
if (flag & SELTYPE_INNER) {
|
||||
if (params->flag & SELTYPE_INNER) {
|
||||
BM_Select_Edge(bm, e, 1);
|
||||
BM_Select_Face(bm, nf, 1);
|
||||
}
|
||||
@@ -577,20 +573,21 @@ typedef struct subd_facedata {
|
||||
|
||||
void esubdivide_exec(BMesh *bmesh, BMOperator *op)
|
||||
{
|
||||
V_DECLARE(facedata);
|
||||
V_DECLARE(verts);
|
||||
V_DECLARE(edges);
|
||||
BMOpSlot *einput, *finput, *pinput;
|
||||
BMEdge *edge, **edges = NULL;
|
||||
V_DECLARE(edges);
|
||||
BMFace *face;
|
||||
BMLoop *nl;
|
||||
BMVert **verts = NULL;
|
||||
V_DECLARE(verts);
|
||||
BMIter fiter, liter;
|
||||
GHash *customfill_hash;
|
||||
GHash *customfill_hash, *percent_hash;
|
||||
subdpattern *pat;
|
||||
subdparams params;
|
||||
subd_facedata *facedata = NULL;
|
||||
V_DECLARE(facedata);
|
||||
float rad;
|
||||
int i, j, matched, a, b, numcuts, flag, selaction, fillindex;
|
||||
int i, j, matched, a, b, numcuts, flag, selaction;
|
||||
|
||||
BMO_Flag_Buffer(bmesh, op, BMOP_ESUBDIVIDE_EDGES, SUBD_SPLIT);
|
||||
|
||||
@@ -602,8 +599,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
|
||||
if (selaction == SUBDIV_SELECT_INNER) flag |= SELTYPE_INNER;
|
||||
|
||||
einput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
|
||||
|
||||
/*first go through and split edges*/
|
||||
/*first go through and tag edges*/
|
||||
for (i=0; i<einput->len; i++) {
|
||||
edge = ((BMEdge**)einput->data.p)[i];
|
||||
BMO_SetFlag(bmesh, edge, SUBD_SPLIT);
|
||||
@@ -611,7 +607,9 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
|
||||
|
||||
customfill_hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
|
||||
BLI_ghashutil_ptrcmp);
|
||||
|
||||
percent_hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
|
||||
BLI_ghashutil_ptrcmp);
|
||||
|
||||
/*process custom fill patterns*/
|
||||
finput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_FACES);
|
||||
pinput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS);
|
||||
@@ -622,6 +620,20 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
|
||||
((void**)pinput->data.p)[i]);
|
||||
}
|
||||
|
||||
einput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_PERCENT_EDGES);
|
||||
pinput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_PERCENT_VALUES);
|
||||
|
||||
for (i=0; i<einput->len; i++) {
|
||||
edge = ((BMEdge**)einput->data.p)[i];
|
||||
BMO_SetFlag(bmesh, edge, EDGE_PERCENT);
|
||||
BLI_ghash_insert(percent_hash, edge, ((float*)pinput->data.p)+i);
|
||||
}
|
||||
|
||||
params.flag = flag;
|
||||
params.numcuts = numcuts;
|
||||
params.percenthash = percent_hash;
|
||||
params.rad = rad;
|
||||
|
||||
for (face=BMIter_New(&fiter, bmesh, BM_FACES, NULL);
|
||||
face; face=BMIter_Step(&fiter)) {
|
||||
/*figure out which pattern to use*/
|
||||
@@ -694,11 +706,12 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
einput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
|
||||
|
||||
/*go through and split edges*/
|
||||
for (i=0; i<einput->len; i++) {
|
||||
edge = ((BMEdge**)einput->data.p)[i];
|
||||
bm_subdivide_multicut(bmesh, edge, rad, flag, numcuts,
|
||||
edge->v1, edge->v2);
|
||||
bm_subdivide_multicut(bmesh, edge,¶ms, edge->v1, edge->v2);
|
||||
//BM_Split_Edge_Multi(bmesh, edge, numcuts);
|
||||
}
|
||||
|
||||
@@ -737,7 +750,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
|
||||
j += 1;
|
||||
}
|
||||
|
||||
pat->connectexec(bmesh, face, verts, numcuts, flag, rad);
|
||||
pat->connectexec(bmesh, face, verts, ¶ms);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define EDGE_NEW 1
|
||||
#define FACE_NEW 1
|
||||
|
||||
void triangulate_exec(BMesh *bmesh, BMOperator *op)
|
||||
{
|
||||
BMOpSlot *finput;
|
||||
|
||||
@@ -76,6 +76,7 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "mesh_intern.h"
|
||||
#include "bmesh.h"
|
||||
|
||||
/* **** XXX ******** */
|
||||
static void BIF_undo_push() {}
|
||||
@@ -204,8 +205,8 @@ void CutEdgeloop(Object *obedit, EditMesh *em, int numcuts)
|
||||
EditEdge *nearest=NULL, *eed;
|
||||
float fac;
|
||||
int keys = 0, holdnum=0, selectmode, dist;
|
||||
short mvalo[2] = {0,0}, mval[2];
|
||||
short event, val, choosing=1, cancel=0, cuthalf = 0, smooth=0;
|
||||
short mvalo[2] = {0,0}, mval[2] = {0, 0};
|
||||
short event=0, val, choosing=1, cancel=0, cuthalf = 0, smooth=0;
|
||||
short hasHidden = 0;
|
||||
char msg[128];
|
||||
|
||||
@@ -473,7 +474,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
|
||||
float m1, b1, m2, b2, x21, x22, y21, y22, xi;
|
||||
float yi, x1min, x1max, y1max, y1min, perc=0;
|
||||
float *scr;
|
||||
float threshold;
|
||||
float threshold = 0.0;
|
||||
int i;
|
||||
|
||||
//threshold = 0.000001; /*tolerance for vertex intersection*/
|
||||
@@ -619,20 +620,181 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
|
||||
}
|
||||
|
||||
|
||||
static float bm_seg_intersect(BMEdge *e, CutCurve *c, int len, char mode,
|
||||
struct GHash *gh, int *isected)
|
||||
{
|
||||
#define MAXSLOPE 100000
|
||||
float x11, y11, x12=0, y12=0, x2max, x2min, y2max;
|
||||
float y2min, dist, lastdist=0, xdiff2, xdiff1;
|
||||
float m1, b1, m2, b2, x21, x22, y21, y22, xi;
|
||||
float yi, x1min, x1max, y1max, y1min, perc=0;
|
||||
float *scr;
|
||||
float threshold = 0.0;
|
||||
int i;
|
||||
|
||||
//threshold = 0.000001; /*tolerance for vertex intersection*/
|
||||
// XXX threshold = scene->toolsettings->select_thresh / 100;
|
||||
|
||||
/* Get screen coords of verts */
|
||||
scr = BLI_ghash_lookup(gh, e->v1);
|
||||
x21=scr[0];
|
||||
y21=scr[1];
|
||||
|
||||
scr = BLI_ghash_lookup(gh, e->v2);
|
||||
x22=scr[0];
|
||||
y22=scr[1];
|
||||
|
||||
xdiff2=(x22-x21);
|
||||
if (xdiff2) {
|
||||
m2=(y22-y21)/xdiff2;
|
||||
b2= ((x22*y21)-(x21*y22))/xdiff2;
|
||||
}
|
||||
else {
|
||||
m2=MAXSLOPE; /* Verticle slope */
|
||||
b2=x22;
|
||||
}
|
||||
|
||||
*isected = 0;
|
||||
|
||||
/*check for *exact* vertex intersection first*/
|
||||
if(mode!=KNIFE_MULTICUT){
|
||||
for (i=0; i<len; i++){
|
||||
if (i>0){
|
||||
x11=x12;
|
||||
y11=y12;
|
||||
}
|
||||
else {
|
||||
x11=c[i].x;
|
||||
y11=c[i].y;
|
||||
}
|
||||
x12=c[i].x;
|
||||
y12=c[i].y;
|
||||
|
||||
/*test e->v1*/
|
||||
if((x11 == x21 && y11 == y21) || (x12 == x21 && y12 == y21)){
|
||||
perc = 0;
|
||||
*isected = 1;
|
||||
return(perc);
|
||||
}
|
||||
/*test e->v2*/
|
||||
else if((x11 == x22 && y11 == y22) || (x12 == x22 && y12 == y22)){
|
||||
perc = 0;
|
||||
*isected = 2;
|
||||
return(perc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*now check for edge interesect (may produce vertex intersection as well)*/
|
||||
for (i=0; i<len; i++){
|
||||
if (i>0){
|
||||
x11=x12;
|
||||
y11=y12;
|
||||
}
|
||||
else {
|
||||
x11=c[i].x;
|
||||
y11=c[i].y;
|
||||
}
|
||||
x12=c[i].x;
|
||||
y12=c[i].y;
|
||||
|
||||
/* Perp. Distance from point to line */
|
||||
if (m2!=MAXSLOPE) dist=(y12-m2*x12-b2);/* /sqrt(m2*m2+1); Only looking for */
|
||||
/* change in sign. Skip extra math */
|
||||
else dist=x22-x12;
|
||||
|
||||
if (i==0) lastdist=dist;
|
||||
|
||||
/* if dist changes sign, and intersect point in edge's Bound Box*/
|
||||
if ((lastdist*dist)<=0){
|
||||
xdiff1=(x12-x11); /* Equation of line between last 2 points */
|
||||
if (xdiff1){
|
||||
m1=(y12-y11)/xdiff1;
|
||||
b1= ((x12*y11)-(x11*y12))/xdiff1;
|
||||
}
|
||||
else{
|
||||
m1=MAXSLOPE;
|
||||
b1=x12;
|
||||
}
|
||||
x2max=MAX2(x21,x22)+0.001; /* prevent missed edges */
|
||||
x2min=MIN2(x21,x22)-0.001; /* due to round off error */
|
||||
y2max=MAX2(y21,y22)+0.001;
|
||||
y2min=MIN2(y21,y22)-0.001;
|
||||
|
||||
/* Found an intersect, calc intersect point */
|
||||
if (m1==m2){ /* co-incident lines */
|
||||
/* cut at 50% of overlap area*/
|
||||
x1max=MAX2(x11, x12);
|
||||
x1min=MIN2(x11, x12);
|
||||
xi= (MIN2(x2max,x1max)+MAX2(x2min,x1min))/2.0;
|
||||
|
||||
y1max=MAX2(y11, y12);
|
||||
y1min=MIN2(y11, y12);
|
||||
yi= (MIN2(y2max,y1max)+MAX2(y2min,y1min))/2.0;
|
||||
}
|
||||
else if (m2==MAXSLOPE){
|
||||
xi=x22;
|
||||
yi=m1*x22+b1;
|
||||
}
|
||||
else if (m1==MAXSLOPE){
|
||||
xi=x12;
|
||||
yi=m2*x12+b2;
|
||||
}
|
||||
else {
|
||||
xi=(b1-b2)/(m2-m1);
|
||||
yi=(b1*m2-m1*b2)/(m2-m1);
|
||||
}
|
||||
|
||||
/* Intersect inside bounding box of edge?*/
|
||||
if ((xi>=x2min)&&(xi<=x2max)&&(yi<=y2max)&&(yi>=y2min)){
|
||||
/*test for vertex intersect that may be 'close enough'*/
|
||||
if(mode!=KNIFE_MULTICUT){
|
||||
if(xi <= (x21 + threshold) && xi >= (x21 - threshold)){
|
||||
if(yi <= (y21 + threshold) && yi >= (y21 - threshold)){
|
||||
*isected = 1;
|
||||
perc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(xi <= (x22 + threshold) && xi >= (x22 - threshold)){
|
||||
if(yi <= (y22 + threshold) && yi >= (y22 - threshold)){
|
||||
*isected = 2;
|
||||
perc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((m2<=1.0)&&(m2>=-1.0)) perc = (xi-x21)/(x22-x21);
|
||||
else perc=(yi-y21)/(y22-y21); /*lower slope more accurate*/
|
||||
//isect=32768.0*(perc+0.0000153); /* Percentage in 1/32768ths */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastdist=dist;
|
||||
}
|
||||
return(perc);
|
||||
}
|
||||
|
||||
#define MAX_CUTS 256
|
||||
|
||||
static int knife_cut_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
|
||||
EditMesh *em= ((Mesh *)obedit->data)->edit_mesh, *em2;
|
||||
BMesh *bm;
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
EditEdge *eed;
|
||||
EditVert *eve;
|
||||
BMVert *bv;
|
||||
BMIter iter;
|
||||
BMEdge **edges = NULL, *be;
|
||||
V_DECLARE(edges);
|
||||
BMOperator bmop;
|
||||
CutCurve curve[MAX_CUTS];
|
||||
struct GHash *gh;
|
||||
float isect=0.0;
|
||||
float *scr, co[4];
|
||||
int len=0;
|
||||
float *scr, co[4], *percents = NULL;
|
||||
V_DECLARE(percents);
|
||||
int len=0, isected, flag;
|
||||
short numcuts=1, mode= RNA_int_get(op->ptr, "type");
|
||||
|
||||
if (EM_nvertices_selected(em) < 2) {
|
||||
@@ -651,51 +813,67 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
|
||||
|
||||
if(len<2) return OPERATOR_CANCELLED;
|
||||
|
||||
/*store percentage of edge cut for KNIFE_EXACT here.*/
|
||||
for(eed=em->edges.first; eed; eed= eed->next)
|
||||
eed->tmp.fp = 0.0;
|
||||
|
||||
bm = editmesh_to_bmesh(em);
|
||||
|
||||
/*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
|
||||
gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
||||
for(eve=em->verts.first; eve; eve=eve->next){
|
||||
for(bv=BMIter_New(&iter, bm, BM_VERTS, NULL);bv;bv=BMIter_Step(&iter)){
|
||||
scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
|
||||
VECCOPY(co, eve->co);
|
||||
VECCOPY(co, bv->co);
|
||||
co[3]= 1.0;
|
||||
Mat4MulVec4fl(obedit->obmat, co);
|
||||
project_float(ar, co, scr);
|
||||
BLI_ghash_insert(gh, eve, scr);
|
||||
eve->f1 = 0; /*store vertex intersection flag here*/
|
||||
|
||||
BLI_ghash_insert(gh, bv, scr);
|
||||
}
|
||||
|
||||
eed= em->edges.first;
|
||||
while(eed) {
|
||||
if( eed->v1->f & eed->v2->f & SELECT ){ // NOTE: uses vertex select, subdiv doesnt do edges yet
|
||||
isect= seg_intersect(eed, curve, len, mode, gh);
|
||||
if (isect!=0.0f) eed->f2= 1;
|
||||
else eed->f2=0;
|
||||
eed->tmp.fp= isect;
|
||||
//printf("isect=%i\n", isect);
|
||||
/*store percentage of edge cut for KNIFE_EXACT here.*/
|
||||
for (be=BMIter_New(&iter, bm, BM_EDGES, NULL); be; be=BMIter_Step(&iter)) {
|
||||
if( BM_Is_Selected(bm, be) ) {
|
||||
isect= bm_seg_intersect(be, curve, len, mode, gh, &isected);
|
||||
|
||||
if (isect != 0.0f) {
|
||||
V_GROW(edges);
|
||||
V_GROW(percents);
|
||||
edges[V_COUNT(edges)-1] = be;
|
||||
percents[V_COUNT(percents)-1] = isect;
|
||||
}
|
||||
}
|
||||
else {
|
||||
eed->f2=0;
|
||||
eed->f1=0;
|
||||
}
|
||||
eed= eed->next;
|
||||
}
|
||||
|
||||
BMO_Init_Op(&bmop, BMOP_ESUBDIVIDE);
|
||||
|
||||
if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, 1, SUBDIV_SELECT_ORIG);
|
||||
else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, numcuts, SUBDIV_SELECT_ORIG);
|
||||
else esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD, 1, SUBDIV_SELECT_ORIG);
|
||||
BMO_Set_Int(&bmop, BMOP_ESUBDIVIDE_NUMCUTS, numcuts);
|
||||
flag = B_KNIFE;
|
||||
if (mode == KNIFE_MIDPOINT) numcuts = 1;
|
||||
else if (mode != KNIFE_MULTICUT) {
|
||||
BMO_Set_PntBuf(&bmop, BMOP_ESUBDIVIDE_PERCENT_EDGES, edges, V_COUNT(edges));
|
||||
BMO_Set_FltBuf(&bmop, BMOP_ESUBDIVIDE_PERCENT_VALUES, percents, V_COUNT(percents));
|
||||
}
|
||||
|
||||
eed=em->edges.first;
|
||||
while(eed){
|
||||
eed->f2=0;
|
||||
eed->f1=0;
|
||||
eed=eed->next;
|
||||
}
|
||||
BMO_Set_Int(&bmop, BMOP_ESUBDIVIDE_FLAG, flag);
|
||||
BMO_Set_Float(&bmop, BMOP_ESUBDIVIDE_RADIUS, 0);
|
||||
BMO_Set_Int(&bmop, BMOP_ESUBDIVIDE_SELACTION, SUBDIV_SELECT_ORIG);
|
||||
BMO_Set_PntBuf(&bmop, BMOP_ESUBDIVIDE_EDGES, edges, V_COUNT(edges));
|
||||
|
||||
BMO_Exec_Op(bm, &bmop);
|
||||
BMO_Finish_Op(bm, &bmop);
|
||||
|
||||
V_FREE(edges);
|
||||
V_FREE(percents);
|
||||
|
||||
//if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, 1, SUBDIV_SELECT_ORIG);
|
||||
//else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, numcuts, SUBDIV_SELECT_ORIG);
|
||||
//else esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD, 1, SUBDIV_SELECT_ORIG);
|
||||
|
||||
BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
|
||||
|
||||
free_editMesh(em);
|
||||
|
||||
em2 = bmesh_to_editmesh(bm);
|
||||
*em = *em2;
|
||||
|
||||
MEM_freeN(em2);
|
||||
BM_Free_Mesh(bm);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -176,6 +176,8 @@ void ED_operatortypes_mesh(void)
|
||||
WM_operatortype_append(MESH_OT_smooth_vertex);
|
||||
WM_operatortype_append(MESH_OT_flip_editnormals);
|
||||
WM_operatortype_append(MESH_OT_knife_cut);
|
||||
|
||||
WM_operatortype_append(MESH_OT_bmesh_test);
|
||||
|
||||
}
|
||||
|
||||
@@ -285,7 +287,7 @@ void ED_keymap_mesh(wmWindowManager *wm)
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
|
||||
|
||||
|
||||
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_bmesh_test", JKEY, KM_PRESS, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user