Merge branch 'master' into blender2.8
This commit is contained in:
@@ -1465,6 +1465,7 @@ static BMOpDefine bmo_spin_def = {
|
|||||||
{"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
|
{"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
|
||||||
{"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
|
{"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
|
||||||
{"steps", BMO_OP_SLOT_INT}, /* number of steps */
|
{"steps", BMO_OP_SLOT_INT}, /* number of steps */
|
||||||
|
{"use_merge", BMO_OP_SLOT_BOOL}, /* Merge first/last when the angle is a full revolution. */
|
||||||
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
|
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
|
||||||
{"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
|
{"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
|
||||||
{{'\0'}},
|
{{'\0'}},
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
* Duplicate, Split, Split operators.
|
* Duplicate, Split, Split operators.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_alloca.h"
|
#include "BLI_alloca.h"
|
||||||
|
|
||||||
@@ -486,10 +488,29 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
|
|||||||
steps = BMO_slot_int_get(op->slots_in, "steps");
|
steps = BMO_slot_int_get(op->slots_in, "steps");
|
||||||
phi = BMO_slot_float_get(op->slots_in, "angle") / steps;
|
phi = BMO_slot_float_get(op->slots_in, "angle") / steps;
|
||||||
do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate");
|
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");
|
const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
|
||||||
|
/* Caller needs to perform other sanity checks (such as the spin being 360d). */
|
||||||
|
const bool use_merge = BMO_slot_bool_get(op->slots_in, "use_merge") && steps >= 3;
|
||||||
|
|
||||||
axis_angle_normalized_to_mat3(rmat, axis, phi);
|
axis_angle_normalized_to_mat3(rmat, axis, phi);
|
||||||
|
|
||||||
|
BMVert **vtable = NULL;
|
||||||
|
if (use_merge) {
|
||||||
|
vtable = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__);
|
||||||
|
int i = 0;
|
||||||
|
BMIter iter;
|
||||||
|
BMVert *v;
|
||||||
|
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||||
|
vtable[i] = v;
|
||||||
|
/* Evil! store original index in normal,
|
||||||
|
* this is duplicated into every other vertex.
|
||||||
|
* So we can read the original from the final.
|
||||||
|
*
|
||||||
|
* The normals must be recalculated anyway. */
|
||||||
|
*((int *)&v->no[0]) = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BMO_slot_copy(op, slots_in, "geom",
|
BMO_slot_copy(op, slots_in, "geom",
|
||||||
op, slots_out, "geom_last.out");
|
op, slots_out, "geom_last.out");
|
||||||
for (a = 0; a < steps; a++) {
|
for (a = 0; a < steps; a++) {
|
||||||
@@ -507,11 +528,44 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
|
|||||||
BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S use_normal_flip=%b",
|
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));
|
op, "geom_last.out", use_normal_flip && (a == 0));
|
||||||
BMO_op_exec(bm, &extop);
|
BMO_op_exec(bm, &extop);
|
||||||
BMO_op_callf(bm, op->flag,
|
if ((use_merge && (a == steps - 1)) == false) {
|
||||||
"rotate cent=%v matrix=%m3 space=%s verts=%S",
|
BMO_op_callf(bm, op->flag,
|
||||||
cent, rmat, op, "space", &extop, "geom.out");
|
"rotate cent=%v matrix=%m3 space=%s verts=%S",
|
||||||
BMO_slot_copy(&extop, slots_out, "geom.out",
|
cent, rmat, op, "space", &extop, "geom.out");
|
||||||
op, slots_out, "geom_last.out");
|
BMO_slot_copy(&extop, slots_out, "geom.out",
|
||||||
|
op, slots_out, "geom_last.out");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Merge first/last vertices and edges (maintaining 'geom.out' state). */
|
||||||
|
BMOpSlot *slot_geom_out = BMO_slot_get(extop.slots_out, "geom.out");
|
||||||
|
BMElem **elem_array = (BMElem **)slot_geom_out->data.buf;
|
||||||
|
int elem_array_len = slot_geom_out->len;
|
||||||
|
for (int i = 0; i < elem_array_len; ) {
|
||||||
|
if (elem_array[i]->head.htype == BM_VERT) {
|
||||||
|
BMVert *v_src = (BMVert *)elem_array[i];
|
||||||
|
BMVert *v_dst = vtable[*((const int *)&v_src->no[0])];
|
||||||
|
BM_vert_splice(bm, v_dst, v_src);
|
||||||
|
elem_array_len--;
|
||||||
|
elem_array[i] = elem_array[elem_array_len];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < elem_array_len; ) {
|
||||||
|
if (elem_array[i]->head.htype == BM_EDGE) {
|
||||||
|
BMEdge *e_src = (BMEdge *)elem_array[i];
|
||||||
|
BMEdge *e_dst = BM_edge_find_double(e_src);
|
||||||
|
BM_edge_splice(bm, e_dst, e_src);
|
||||||
|
elem_array_len--;
|
||||||
|
elem_array[i] = elem_array[elem_array_len];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slot_geom_out->len = elem_array_len;
|
||||||
|
}
|
||||||
BMO_op_finish(bm, &extop);
|
BMO_op_finish(bm, &extop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,4 +576,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
|
|||||||
dvec, op, "space", op, "geom_last.out");
|
dvec, op, "space", op, "geom_last.out");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vtable) {
|
||||||
|
MEM_freeN(vtable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
|
|||||||
const float angle = RNA_float_get(op->ptr, "angle");
|
const float angle = RNA_float_get(op->ptr, "angle");
|
||||||
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip") ^ (angle < 0.0f);
|
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip") ^ (angle < 0.0f);
|
||||||
const bool dupli = RNA_boolean_get(op->ptr, "dupli");
|
const bool dupli = RNA_boolean_get(op->ptr, "dupli");
|
||||||
|
const bool use_auto_merge = (
|
||||||
|
RNA_boolean_get(op->ptr, "use_auto_merge") &&
|
||||||
|
(dupli == false) &&
|
||||||
|
(steps >= 3) &&
|
||||||
|
fabsf((fabsf(angle) - (M_PI * 2))) <= 1e-6f);
|
||||||
|
|
||||||
if (is_zero_v3(axis)) {
|
if (is_zero_v3(axis)) {
|
||||||
BKE_report(op->reports, RPT_ERROR, "Invalid/unset axis");
|
BKE_report(op->reports, RPT_ERROR, "Invalid/unset axis");
|
||||||
@@ -92,14 +97,17 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
|
|||||||
if (!EDBM_op_init(
|
if (!EDBM_op_init(
|
||||||
em, &spinop, op,
|
em, &spinop, op,
|
||||||
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 "
|
"spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 "
|
||||||
"use_normal_flip=%b use_duplicate=%b",
|
"use_normal_flip=%b use_duplicate=%b use_merge=%b",
|
||||||
BM_ELEM_SELECT, cent, axis, d, steps, -angle, obedit->obmat, use_normal_flip, dupli))
|
BM_ELEM_SELECT, cent, axis, d, steps, -angle, obedit->obmat,
|
||||||
|
use_normal_flip, dupli, use_auto_merge))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BMO_op_exec(bm, &spinop);
|
BMO_op_exec(bm, &spinop);
|
||||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
if (use_auto_merge == false) {
|
||||||
BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
|
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||||
|
BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
|
||||||
|
}
|
||||||
if (!EDBM_op_finish(em, &spinop, op, true)) {
|
if (!EDBM_op_finish(em, &spinop, op, true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -181,6 +189,7 @@ void MESH_OT_spin(wmOperatorType *ot)
|
|||||||
prop = RNA_def_float(ot->srna, "angle", DEG2RADF(90.0f), -1e12f, 1e12f, "Angle", "Rotation for each step",
|
prop = RNA_def_float(ot->srna, "angle", DEG2RADF(90.0f), -1e12f, 1e12f, "Angle", "Rotation for each step",
|
||||||
DEG2RADF(-360.0f), DEG2RADF(360.0f));
|
DEG2RADF(-360.0f), DEG2RADF(360.0f));
|
||||||
RNA_def_property_subtype(prop, PROP_ANGLE);
|
RNA_def_property_subtype(prop, PROP_ANGLE);
|
||||||
|
RNA_def_boolean(ot->srna, "use_auto_merge", true, "Auto Merge", "Merge first/last when the angle is a full revolution");
|
||||||
RNA_def_boolean(ot->srna, "use_normal_flip", 0, "Flip Normals", "");
|
RNA_def_boolean(ot->srna, "use_normal_flip", 0, "Flip Normals", "");
|
||||||
|
|
||||||
RNA_def_float_vector(ot->srna, "center", 3, NULL, -1e12f, 1e12f,
|
RNA_def_float_vector(ot->srna, "center", 3, NULL, -1e12f, 1e12f,
|
||||||
|
|||||||
Reference in New Issue
Block a user