BMesh: option to flip normals for extrude/spin
This commit is contained in:
parent
10fbea8845
commit
06d4fad313
|
@ -881,6 +881,7 @@ static BMOpDefine bmo_extrude_discrete_faces_def = {
|
|||
"extrude_discrete_faces",
|
||||
/* slots_in */
|
||||
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
|
||||
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
|
||||
{"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
|
||||
{{'\0'}},
|
||||
},
|
||||
|
@ -902,6 +903,7 @@ static BMOpDefine bmo_extrude_edge_only_def = {
|
|||
"extrude_edge_only",
|
||||
/* slots_in */
|
||||
{{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
|
||||
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
|
||||
{"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
|
||||
{{'\0'}},
|
||||
},
|
||||
|
@ -1037,6 +1039,7 @@ static BMOpDefine bmo_extrude_face_region_def = {
|
|||
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */
|
||||
{"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
|
||||
{"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry (requires ``geom`` to include edges). */
|
||||
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
|
||||
{"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
|
||||
{{'\0'}},
|
||||
},
|
||||
|
@ -1386,6 +1389,7 @@ static BMOpDefine bmo_spin_def = {
|
|||
{"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
|
||||
{"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
|
||||
{"steps", BMO_OP_SLOT_INT}, /* number of steps */
|
||||
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
|
||||
{"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
|
||||
{{'\0'}},
|
||||
},
|
||||
|
|
|
@ -486,6 +486,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
|
|||
steps = BMO_slot_int_get(op->slots_in, "steps");
|
||||
phi = BMO_slot_float_get(op->slots_in, "angle") / steps;
|
||||
do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate");
|
||||
const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
|
||||
|
||||
axis_angle_normalized_to_mat3(rmat, axis, phi);
|
||||
|
||||
|
@ -503,8 +504,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
|
|||
BMO_op_finish(bm, &dupop);
|
||||
}
|
||||
else {
|
||||
BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S",
|
||||
op, "geom_last.out");
|
||||
BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S use_normal_flip=%b",
|
||||
op, "geom_last.out", use_normal_flip && (a == 0));
|
||||
BMO_op_exec(bm, &extop);
|
||||
BMO_op_callf(bm, op->flag,
|
||||
"rotate cent=%v matrix=%m3 space=%s verts=%S",
|
||||
|
|
|
@ -186,6 +186,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
|
|||
BMOperator dupeop;
|
||||
BMFace *f;
|
||||
BMEdge *e, *e_new;
|
||||
const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
|
||||
|
||||
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
|
||||
BMO_edge_flag_enable(bm, e, EXT_INPUT);
|
||||
|
@ -212,7 +213,9 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
|
|||
BMVert *f_verts[4];
|
||||
e_new = BMO_iter_map_value_ptr(&siter);
|
||||
|
||||
if (e->l && e->v1 != e->l->v) {
|
||||
|
||||
const bool edge_normal_flip = !(e->l && e->v1 != e->l->v);
|
||||
if (edge_normal_flip == use_normal_flip) {
|
||||
f_verts[0] = e->v1;
|
||||
f_verts[1] = e->v2;
|
||||
f_verts[2] = e_new->v2;
|
||||
|
@ -332,9 +335,10 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
|||
BMEdge *e, *e_new;
|
||||
BMVert *v;
|
||||
BMFace *f;
|
||||
bool found, fwd, delorig = false;
|
||||
bool found, delorig = false;
|
||||
BMOpSlot *slot_facemap_out;
|
||||
BMOpSlot *slot_edges_exclude;
|
||||
const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
|
||||
|
||||
/* initialize our sub-operators */
|
||||
BMO_op_initf(
|
||||
|
@ -488,13 +492,11 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
|
|||
/* orient loop to give same normal as a loop of newedge
|
||||
* if it exists (will be an extruded face),
|
||||
* else same normal as a loop of e, if it exists */
|
||||
if (!e_new->l)
|
||||
fwd = !e->l || !(e->l->v == e->v1);
|
||||
else
|
||||
fwd = (e_new->l->v == e_new->v1);
|
||||
|
||||
|
||||
if (fwd) {
|
||||
const bool edge_normal_flip = !(
|
||||
e_new->l ?
|
||||
(e_new->l->v == e_new->v1) :
|
||||
(!e->l || !(e->l->v == e->v1)));
|
||||
if (edge_normal_flip == use_normal_flip) {
|
||||
f_verts[0] = e->v1;
|
||||
f_verts[1] = e->v2;
|
||||
f_verts[2] = e_new->v2;
|
||||
|
|
|
@ -161,15 +161,15 @@ static bool edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const ch
|
|||
}
|
||||
|
||||
/* extrudes individual edges */
|
||||
static bool edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag)
|
||||
static bool edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, const bool use_normal_flip)
|
||||
{
|
||||
BMesh *bm = em->bm;
|
||||
BMOperator bmop;
|
||||
|
||||
EDBM_op_init(
|
||||
em, &bmop, op,
|
||||
"extrude_edge_only edges=%he use_select_history=%b",
|
||||
hflag, true);
|
||||
"extrude_edge_only edges=%he use_normal_flip=%b use_select_history=%b",
|
||||
hflag, use_normal_flip, true);
|
||||
|
||||
/* deselect original verts */
|
||||
BM_SELECT_HISTORY_BACKUP(bm);
|
||||
|
@ -236,6 +236,7 @@ static char edbm_extrude_htype_from_em_select(BMEditMesh *em)
|
|||
static bool edbm_extrude_ex(
|
||||
Object *obedit, BMEditMesh *em,
|
||||
char htype, const char hflag,
|
||||
const bool use_normal_flip,
|
||||
const bool use_mirror,
|
||||
const bool use_select_history)
|
||||
{
|
||||
|
@ -250,6 +251,7 @@ static bool edbm_extrude_ex(
|
|||
}
|
||||
|
||||
BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
|
||||
BMO_slot_bool_set(extop.slots_in, "use_normal_flip", use_normal_flip);
|
||||
BMO_slot_bool_set(extop.slots_in, "use_select_history", use_select_history);
|
||||
BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", htype, hflag);
|
||||
|
||||
|
@ -302,7 +304,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
|
|||
mul_m3_v3(tmat, dvec);
|
||||
|
||||
for (a = 0; a < steps; a++) {
|
||||
edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false);
|
||||
edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false, false);
|
||||
|
||||
BMO_op_callf(
|
||||
em->bm, BMO_FLAG_DEFAULTS,
|
||||
|
@ -345,9 +347,10 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
|
|||
/* generic extern called extruder */
|
||||
static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
|
||||
{
|
||||
bool changed = false;
|
||||
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip");
|
||||
const char htype = edbm_extrude_htype_from_em_select(em);
|
||||
enum {NONE = 0, ELEM_FLAG, VERT_ONLY, EDGE_ONLY} nr;
|
||||
bool changed = false;
|
||||
|
||||
if (em->selectmode & SCE_SELECT_VERTEX) {
|
||||
if (em->bm->totvertsel == 0) nr = NONE;
|
||||
|
@ -369,13 +372,13 @@ static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
|
|||
case NONE:
|
||||
return false;
|
||||
case ELEM_FLAG:
|
||||
changed = edbm_extrude_ex(obedit, em, htype, BM_ELEM_SELECT, true, true);
|
||||
changed = edbm_extrude_ex(obedit, em, htype, BM_ELEM_SELECT, use_normal_flip, true, true);
|
||||
break;
|
||||
case VERT_ONLY:
|
||||
changed = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT);
|
||||
break;
|
||||
case EDGE_ONLY:
|
||||
changed = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT);
|
||||
changed = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, use_normal_flip);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -421,6 +424,7 @@ void MESH_OT_extrude_region(wmOperatorType *ot)
|
|||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(ot->srna, "use_normal_flip", false, "Flip Normals", "");
|
||||
Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
|
||||
}
|
||||
|
||||
|
@ -471,7 +475,7 @@ static int edbm_extrude_edges_exec(bContext *C, wmOperator *op)
|
|||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT);
|
||||
edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, false);
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
|
||||
|
@ -493,6 +497,7 @@ void MESH_OT_extrude_edges_indiv(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* to give to transform */
|
||||
RNA_def_boolean(ot->srna, "use_normal_flip", false, "Flip Normals", "");
|
||||
Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
|
||||
}
|
||||
|
||||
|
@ -664,7 +669,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
|
|||
EDBM_project_snap_verts(C, vc.ar, vc.em);
|
||||
}
|
||||
|
||||
edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, true, true);
|
||||
edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, false, true, true);
|
||||
EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3",
|
||||
BM_ELEM_SELECT, center, mat);
|
||||
EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v",
|
||||
|
|
|
@ -61,16 +61,13 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
|
|||
BMOperator spinop;
|
||||
float cent[3], axis[3];
|
||||
float d[3] = {0.0f, 0.0f, 0.0f};
|
||||
int steps, dupli;
|
||||
float angle;
|
||||
|
||||
RNA_float_get_array(op->ptr, "center", cent);
|
||||
RNA_float_get_array(op->ptr, "axis", axis);
|
||||
steps = RNA_int_get(op->ptr, "steps");
|
||||
angle = RNA_float_get(op->ptr, "angle");
|
||||
//if (ts->editbutflag & B_CLOCKWISE)
|
||||
angle = -angle;
|
||||
dupli = RNA_boolean_get(op->ptr, "dupli");
|
||||
const int steps = RNA_int_get(op->ptr, "steps");
|
||||
const float angle = -RNA_float_get(op->ptr, "angle");
|
||||
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip");
|
||||
const bool dupli = RNA_boolean_get(op->ptr, "dupli");
|
||||
|
||||
if (is_zero_v3(axis)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Invalid/unset axis");
|
||||
|
@ -78,9 +75,11 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* keep the values in worldspace since we're passing the obmat */
|
||||
if (!EDBM_op_init(em, &spinop, op,
|
||||
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b",
|
||||
BM_ELEM_SELECT, cent, axis, d, steps, angle, obedit->obmat, dupli))
|
||||
if (!EDBM_op_init(
|
||||
em, &spinop, op,
|
||||
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 "
|
||||
"use_normal_flip=%b use_duplicate=%b",
|
||||
BM_ELEM_SELECT, cent, axis, d, steps, angle, obedit->obmat, use_normal_flip, dupli))
|
||||
{
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@ -141,6 +140,7 @@ void MESH_OT_spin(wmOperatorType *ot)
|
|||
prop = RNA_def_float(ot->srna, "angle", DEG2RADF(90.0f), -1e12f, 1e12f, "Angle", "Rotation for each step",
|
||||
DEG2RADF(-360.0f), DEG2RADF(360.0f));
|
||||
RNA_def_property_subtype(prop, PROP_ANGLE);
|
||||
RNA_def_boolean(ot->srna, "use_normal_flip", 0, "Flip Normals", "");
|
||||
|
||||
RNA_def_float_vector(ot->srna, "center", 3, NULL, -1e12f, 1e12f,
|
||||
"Center", "Center in global view space", -1e4f, 1e4f);
|
||||
|
|
Loading…
Reference in New Issue