make spin into a bmop, use it in screw
This commit is contained in:
@@ -695,6 +695,28 @@ static BMOpDefine def_splitop = {
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
Spin
|
||||
|
||||
Extrude or duplicate geometry a number of times,
|
||||
rotating and possibly translating after each step
|
||||
*/
|
||||
static BMOpDefine def_spinop = {
|
||||
"spin",
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "lastout"}, /* result of last step */
|
||||
{BMOP_OPSLOT_VEC, "cent"}, /* rotation center */
|
||||
{BMOP_OPSLOT_VEC, "axis"}, /* rotation axis */
|
||||
{BMOP_OPSLOT_VEC, "dvec"}, /* translation delta per step */
|
||||
{BMOP_OPSLOT_FLT, "ang"}, /* total rotation angle (degrees) */
|
||||
{BMOP_OPSLOT_INT, "steps"}, /* number of steps */
|
||||
{BMOP_OPSLOT_INT, "dupli"}, /* duplicate or extrude? */
|
||||
{0} /*null-terminating sentinel*/},
|
||||
spinop_exec,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Similar faces search
|
||||
|
||||
@@ -988,6 +1010,7 @@ static BMOpDefine def_triangle_fill = {
|
||||
|
||||
BMOpDefine *opdefines[] = {
|
||||
&def_splitop,
|
||||
&def_spinop,
|
||||
&def_dupeop,
|
||||
&def_delop,
|
||||
&def_subdop,
|
||||
|
||||
@@ -8,6 +8,7 @@ void BMO_push(BMesh *bm, BMOperator *op);
|
||||
void BMO_pop(BMesh *bm);
|
||||
|
||||
void splitop_exec(BMesh *bm, BMOperator *op);
|
||||
void spinop_exec(BMesh *bm, BMOperator *op);
|
||||
void dupeop_exec(BMesh *bm, BMOperator *op);
|
||||
void delop_exec(BMesh *bm, BMOperator *op);
|
||||
void esubdivide_exec(BMesh *bmesh, BMOperator *op);
|
||||
|
||||
@@ -543,3 +543,60 @@ static void delete_context(BMesh *bm, int type){
|
||||
BM_remove_tagged_verts(bm, DEL_INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Spin Operator
|
||||
*
|
||||
* Extrude or duplicate geometry a number of times,
|
||||
* rotating and possibly translating after each step
|
||||
*/
|
||||
|
||||
void spinop_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOperator dupop, extop;
|
||||
float cent[3], dvec[3];
|
||||
float axis[3] = {0.0f, 0.0f, 1.0f};
|
||||
float q[4];
|
||||
float rmat[3][3];
|
||||
float phi, si;
|
||||
int steps, dupli, a, usedvec;
|
||||
|
||||
BMO_Get_Vec(op, "cent", cent);
|
||||
BMO_Get_Vec(op, "axis", axis);
|
||||
normalize_v3(axis);
|
||||
BMO_Get_Vec(op, "dvec", dvec);
|
||||
usedvec = !is_zero_v3(dvec);
|
||||
steps = BMO_Get_Int(op, "steps");
|
||||
phi = BMO_Get_Float(op, "ang")*M_PI/(360.0*steps);
|
||||
dupli = BMO_Get_Int(op, "dupli");
|
||||
|
||||
si = (float)sin(phi);
|
||||
q[0] = (float)cos(phi);
|
||||
q[1] = axis[0]*si;
|
||||
q[2] = axis[1]*si;
|
||||
q[3] = axis[2]*si;
|
||||
quat_to_mat3(rmat, q);
|
||||
|
||||
BMO_CopySlot(op, op, "geom", "lastout");
|
||||
for(a=0; a<steps; a++) {
|
||||
if(dupli) {
|
||||
BMO_InitOpf(bm, &dupop, "dupe geom=%s", op, "lastout");
|
||||
BMO_Exec_Op(bm, &dupop);
|
||||
BMO_CallOpf(bm, "rotate cent=%v mat=%m3 verts=%s",
|
||||
cent, rmat, &dupop, "newout");
|
||||
BMO_CopySlot(&dupop, op, "newout", "lastout");
|
||||
BMO_Finish_Op(bm, &dupop);
|
||||
} else {
|
||||
BMO_InitOpf(bm, &extop, "extrudefaceregion edgefacein=%s",
|
||||
op, "lastout");
|
||||
BMO_Exec_Op(bm, &extop);
|
||||
BMO_CallOpf(bm, "rotate cent=%v mat=%m3 verts=%s",
|
||||
cent, rmat, &extop, "geomout");
|
||||
BMO_CopySlot(&extop, op, "geomout", "lastout");
|
||||
BMO_Finish_Op(bm, &extop);
|
||||
}
|
||||
|
||||
if(usedvec)
|
||||
BMO_CallOpf(bm, "translate vec=%v verts=%s", dvec, op, "lastout");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3821,84 +3821,38 @@ void MESH_OT_split(wmOperatorType *ot)
|
||||
}
|
||||
|
||||
|
||||
static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float degr, int dupli)
|
||||
static int spin_mesh_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
ToolSettings *ts= CTX_data_tool_settings(C);
|
||||
BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
|
||||
float nor[3]= {0.0f, 0.0f, 0.0f};
|
||||
float si, n[3], q[4], cmat[3][3], imat[3][3], tmat[3][3];
|
||||
float cent[3], bmat[3][3], rmat[4][4];
|
||||
float phi;
|
||||
short a, ok= 1;
|
||||
BMOperator bmop;
|
||||
|
||||
BMesh *bm= em->bm;
|
||||
BMOperator spinop;
|
||||
float cent[3], axis[3], imat[3][3];
|
||||
float d[3] = {0.0f, 0.0f, 0.0f};
|
||||
int steps, dupli;
|
||||
float degr;
|
||||
|
||||
RNA_float_get_array(op->ptr, "center", cent);
|
||||
|
||||
/* imat and center and size */
|
||||
copy_m3_m4(bmat, obedit->obmat);
|
||||
invert_m3_m3(imat,bmat);
|
||||
|
||||
cent[0]-= obedit->obmat[3][0];
|
||||
cent[1]-= obedit->obmat[3][1];
|
||||
cent[2]-= obedit->obmat[3][2];
|
||||
RNA_float_get_array(op->ptr, "axis", axis);
|
||||
steps = RNA_int_get(op->ptr, "steps");
|
||||
degr = RNA_float_get(op->ptr, "degrees");
|
||||
if(ts->editbutflag & B_CLOCKWISE) degr= -degr;
|
||||
dupli = RNA_boolean_get(op->ptr, "dupli");
|
||||
|
||||
/* undo object transformation */
|
||||
copy_m3_m4(imat, obedit->imat);
|
||||
sub_v3_v3(cent, obedit->obmat[3]);
|
||||
mul_m3_v3(imat, cent);
|
||||
mul_m3_v3(imat, axis);
|
||||
|
||||
phi= degr*M_PI/360.0;
|
||||
phi/= steps;
|
||||
if(ts->editbutflag & B_CLOCKWISE) phi= -phi;
|
||||
|
||||
RNA_float_get_array(op->ptr, "axis", n);
|
||||
normalize_v3(n);
|
||||
|
||||
q[0]= (float)cos(phi);
|
||||
si= (float)sin(phi);
|
||||
q[1]= n[0]*si;
|
||||
q[2]= n[1]*si;
|
||||
q[3]= n[2]*si;
|
||||
quat_to_mat3( cmat,q);
|
||||
|
||||
mul_m3_m3m3(tmat,cmat,bmat);
|
||||
mul_m3_m3m3(bmat,imat,tmat);
|
||||
copy_m4_m3(rmat, bmat);
|
||||
|
||||
for(a=0; a<steps; a++) {
|
||||
if(dupli==0) {
|
||||
EDBM_Extrude_edge(obedit, em, BM_SELECT, nor);
|
||||
BMO_CallOpf(em->bm, "rotate cent=%v mat=%m4 verts=%hv", cent, rmat, BM_SELECT);
|
||||
ok = 1;
|
||||
} else {
|
||||
EDBM_InitOpf(em, &bmop, op, "dupe geom=%hvef", BM_SELECT);
|
||||
BMO_Exec_Op(em->bm, &bmop);
|
||||
BMO_CallOpf(em->bm, "rotate cent=%v mat=%m4 verts=%s", cent, rmat, &bmop, "newout");
|
||||
EDBM_clear_flag_all(em, BM_SELECT);
|
||||
BMO_HeaderFlag_Buffer(em->bm, &bmop, "newout", BM_SELECT, BM_ALL);
|
||||
ok = EDBM_FinishOp(em, &bmop, op, 1);
|
||||
}
|
||||
|
||||
if(!ok)
|
||||
break;
|
||||
|
||||
if(dvec) {
|
||||
mul_m3_v3(bmat, dvec);
|
||||
BMO_CallOpf(em->bm, "translate vec=%v verts=%hv", (float*)dvec, BM_SELECT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int spin_mesh_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
int ok;
|
||||
|
||||
ok= spin_mesh(C, op, NULL, RNA_int_get(op->ptr,"steps"), RNA_float_get(op->ptr,"degrees"), RNA_boolean_get(op->ptr,"dupli"));
|
||||
if(ok==0) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No valid vertices are selected");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
BMO_InitOpf(bm, &spinop,
|
||||
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%d ang=%f dupli=%d",
|
||||
BM_SELECT, cent, axis, d, steps, degr, dupli);
|
||||
BMO_Exec_Op(bm, &spinop);
|
||||
EDBM_clear_flag_all(em, BM_SELECT);
|
||||
BMO_HeaderFlag_Buffer(bm, &spinop, "lastout", BM_SELECT, BM_ALL);
|
||||
BMO_Finish_Op(bm, &spinop);
|
||||
|
||||
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
|
||||
@@ -3947,16 +3901,27 @@ static int screw_mesh_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
|
||||
BMesh *bm= em->bm;
|
||||
BMEdge *eed;
|
||||
BMVert *eve, *v1, *v2;
|
||||
BMIter iter, eiter;
|
||||
float dvec[3], nor[3];
|
||||
BMOperator spinop;
|
||||
float dvec[3], nor[3], cent[3], axis[3];
|
||||
float imat[3][3];
|
||||
int steps, turns;
|
||||
int valence;
|
||||
|
||||
|
||||
turns= RNA_int_get(op->ptr, "turns");
|
||||
steps= RNA_int_get(op->ptr, "steps");
|
||||
RNA_float_get_array(op->ptr, "center", cent);
|
||||
RNA_float_get_array(op->ptr, "axis", axis);
|
||||
|
||||
/* undo object transformation */
|
||||
copy_m3_m4(imat, obedit->imat);
|
||||
sub_v3_v3(cent, obedit->obmat[3]);
|
||||
mul_m3_v3(imat, cent);
|
||||
mul_m3_v3(imat, axis);
|
||||
|
||||
|
||||
/* find two vertices with valence count==1, more or less is wrong */
|
||||
@@ -3992,28 +3957,22 @@ static int screw_mesh_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
/* calculate dvec */
|
||||
dvec[0]= ( v1->co[0]- v2->co[0] )/steps;
|
||||
dvec[1]= ( v1->co[1]- v2->co[1] )/steps;
|
||||
dvec[2]= ( v1->co[2]- v2->co[2] )/steps;
|
||||
sub_v3_v3v3(dvec, v1->co, v2->co);
|
||||
mul_v3_fl(dvec, 1.0f/steps);
|
||||
|
||||
VECCOPY(nor, obedit->obmat[2]);
|
||||
if(dot_v3v3(nor, dvec)>0.000)
|
||||
negate_v3(dvec);
|
||||
|
||||
if(nor[0]*dvec[0]+nor[1]*dvec[1]+nor[2]*dvec[2]>0.000) {
|
||||
dvec[0]= -dvec[0];
|
||||
dvec[1]= -dvec[1];
|
||||
dvec[2]= -dvec[2];
|
||||
}
|
||||
BMO_InitOpf(bm, &spinop,
|
||||
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%d ang=%f dupli=0",
|
||||
BM_SELECT, cent, axis, dvec, turns*steps, 360.0f*turns);
|
||||
BMO_Exec_Op(bm, &spinop);
|
||||
EDBM_clear_flag_all(em, BM_SELECT);
|
||||
BMO_HeaderFlag_Buffer(bm, &spinop, "lastout", BM_SELECT, BM_ALL);
|
||||
BMO_Finish_Op(bm, &spinop);
|
||||
|
||||
if(spin_mesh(C, op, dvec, turns*steps, 360.0f*turns, 0)) {
|
||||
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
else {
|
||||
BKE_report(op->reports, RPT_ERROR, "No valid vertices are selected");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user