bmesh inset: add depth option (make use of relative and even offset options)
This commit is contained in:
parent
c7f8af329b
commit
e387ccdb42
|
@ -1099,6 +1099,7 @@ static BMOpDefine bmo_inset_def = {
|
|||
{BMO_OP_SLOT_BOOL, "use_even_offset"},
|
||||
{BMO_OP_SLOT_BOOL, "use_relative_offset"},
|
||||
{BMO_OP_SLOT_FLT, "thickness"},
|
||||
{BMO_OP_SLOT_FLT, "depth"},
|
||||
{BMO_OP_SLOT_BOOL, "use_outset"},
|
||||
{0} /* null-terminating sentinel */},
|
||||
bmo_inset_exec,
|
||||
|
|
|
@ -866,6 +866,26 @@ float BM_vert_edge_angle(BMVert *v)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \note this isn't optimal to run on an array of verts,
|
||||
* see 'solidify_add_thickness' for a function which runs on an array.
|
||||
*/
|
||||
float BM_vert_shell_factor(BMVert *v)
|
||||
{
|
||||
BMIter iter;
|
||||
BMLoop *l;
|
||||
float accum_shell = 0.0f;
|
||||
float accum_angle = 0.0f;
|
||||
|
||||
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
|
||||
const float face_angle = BM_loop_face_angle(l);
|
||||
accum_shell += shell_angle_to_dist(angle_normalized_v3v3(v->no, l->f->no)) * face_angle;
|
||||
accum_angle += face_angle;
|
||||
}
|
||||
|
||||
return accum_shell / accum_angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the edge existing between v1 and v2, or NULL if there isn't one.
|
||||
*
|
||||
|
|
|
@ -65,6 +65,7 @@ float BM_edge_face_angle(BMEdge *e);
|
|||
void BM_edge_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]);
|
||||
|
||||
float BM_vert_edge_angle(BMVert *v);
|
||||
float BM_vert_shell_factor(BMVert *v);
|
||||
|
||||
BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2);
|
||||
|
||||
|
|
|
@ -80,6 +80,22 @@ static BMLoop *bm_edge_is_mixed_face_tag(BMLoop *l)
|
|||
}
|
||||
}
|
||||
|
||||
float bm_vert_avg_tag_dist(BMVert *v)
|
||||
{
|
||||
BMIter iter;
|
||||
BMEdge *e;
|
||||
int tot;
|
||||
float length = 0.0f;
|
||||
|
||||
BM_ITER_ELEM_INDEX (e, &iter, v, BM_EDGES_OF_VERT, tot) {
|
||||
BMVert *v_other = BM_edge_other_vert(e, v);
|
||||
if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
|
||||
length += BM_edge_length_calc(e);
|
||||
}
|
||||
}
|
||||
|
||||
return length / (float)tot;
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation is as follows...
|
||||
|
@ -98,7 +114,8 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
|
|||
const int use_even_offset = BMO_slot_bool_get(op, "use_even_offset");
|
||||
const int use_even_boundry = use_even_offset; /* could make own option */
|
||||
const int use_relative_offset = BMO_slot_bool_get(op, "use_relative_offset");
|
||||
const float thickness = BMO_slot_float_get(op, "thickness");
|
||||
const float thickness = BMO_slot_float_get(op, "thickness");
|
||||
const float depth = BMO_slot_float_get(op, "depth");
|
||||
|
||||
int edge_info_len = 0;
|
||||
|
||||
|
@ -482,4 +499,42 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
|
|||
|
||||
/* we could flag new edges/verts too, is it useful? */
|
||||
BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, ELE_NEW);
|
||||
|
||||
/* cheap feature to add depth to the inset */
|
||||
if (depth != 0.0f) {
|
||||
float (*varr_co)[3];
|
||||
BMOIter oiter;
|
||||
|
||||
/* untag verts */
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
|
||||
|
||||
/* tag face verts */
|
||||
BMO_ITER (f, &oiter, bm, op, "faces", BM_FACE) {
|
||||
BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
|
||||
BM_elem_flag_enable(v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
/* do in 2 passes so moving the verts doesn't feed back into face angle checks
|
||||
* which BM_vert_shell_factor uses. */
|
||||
|
||||
/* over allocate */
|
||||
varr_co = MEM_callocN(sizeof(*varr_co) * bm->totvert, __func__);
|
||||
|
||||
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||
const float fac = (depth *
|
||||
(use_relative_offset ? bm_vert_avg_tag_dist(v) : 1.0f) *
|
||||
(use_even_boundry ? BM_vert_shell_factor(v) : 1.0f));
|
||||
madd_v3_v3v3fl(varr_co[i], v->co, v->no, fac);
|
||||
}
|
||||
}
|
||||
|
||||
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||
copy_v3_v3(v->co, varr_co[i]);
|
||||
}
|
||||
}
|
||||
MEM_freeN(varr_co);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4200,13 +4200,16 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
|
|||
const int use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
|
||||
const int use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset");
|
||||
const int use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset");
|
||||
const float thickness = RNA_float_get(op->ptr, "thickness");
|
||||
const float thickness = RNA_float_get(op->ptr, "thickness");
|
||||
const float depth = RNA_float_get(op->ptr, "depth");
|
||||
const int use_outset = RNA_boolean_get(op->ptr, "use_outset");
|
||||
const int use_select_inset = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */
|
||||
|
||||
EDBM_op_init(em, &bmop, op,
|
||||
"inset faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b thickness=%f use_outset=%b",
|
||||
BM_ELEM_SELECT, use_boundary, use_even_offset, use_relative_offset, thickness, use_outset);
|
||||
"inset faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b "
|
||||
"thickness=%f depth=%f use_outset=%b",
|
||||
BM_ELEM_SELECT, use_boundary, use_even_offset, use_relative_offset,
|
||||
thickness, depth, use_outset);
|
||||
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
|
||||
|
@ -4252,9 +4255,11 @@ void MESH_OT_inset(wmOperatorType *ot)
|
|||
RNA_def_boolean(ot->srna, "use_even_offset", TRUE, "Offset Even", "Scale the offset to give more even thickness");
|
||||
RNA_def_boolean(ot->srna, "use_relative_offset", FALSE, "Offset Relative", "Scale the offset by surrounding geometry");
|
||||
|
||||
prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "thickness", "", 0.0f, 10.0f);
|
||||
prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "Thickness", "", 0.0f, 10.0f);
|
||||
/* use 1 rather then 10 for max else dragging the button moves too far */
|
||||
RNA_def_property_ui_range(prop, 0.0, 1.0, 0.01, 4);
|
||||
prop = RNA_def_float(ot->srna, "depth", 0.0f, -FLT_MAX, FLT_MAX, "Depth", "", -10.0f, 10.0f);
|
||||
RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.01, 4);
|
||||
|
||||
RNA_def_boolean(ot->srna, "use_outset", FALSE, "Outset", "Outset rather than inset");
|
||||
RNA_def_boolean(ot->srna, "use_select_inset", TRUE, "Select Outer", "Select the new inset faces");
|
||||
|
|
Loading…
Reference in New Issue