83
float bm_vert_avg_tag_dist(BMVert *v)
90
BM_ITER_ELEM_INDEX (e, &iter, v, BM_EDGES_OF_VERT, tot) {
91
BMVert *v_other = BM_edge_other_vert(e, v);
92
if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
93
length += BM_edge_calc_length(e);
97
return length / (float)tot;
101
84
* implementation is as follows...
110
93
void bmo_inset_exec(BMesh *bm, BMOperator *op)
112
const int use_outset = BMO_slot_bool_get(op, "use_outset");
113
const int use_boundary = BMO_slot_bool_get(op, "use_boundary") && (use_outset == FALSE);
114
const int use_even_offset = BMO_slot_bool_get(op, "use_even_offset");
115
const int use_even_boundry = use_even_offset; /* could make own option */
116
const int use_relative_offset = BMO_slot_bool_get(op, "use_relative_offset");
117
const float thickness = BMO_slot_float_get(op, "thickness");
118
const float depth = BMO_slot_float_get(op, "depth");
95
const bool use_outset = BMO_slot_bool_get(op->slots_in, "use_outset");
96
const bool use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary") && (use_outset == false);
97
const bool use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
98
const bool use_even_boundry = use_even_offset; /* could make own option */
99
const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
100
const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
101
const float depth = BMO_slot_float_get(op->slots_in, "depth");
120
103
int edge_info_len = 0;
131
if (use_outset == FALSE) {
132
BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
133
BMO_slot_buffer_hflag_enable(bm, op, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
114
if (use_outset == false) {
115
BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
116
BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
136
BM_mesh_elem_hflag_enable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE);
137
BMO_slot_buffer_hflag_disable(bm, op, "faces", BM_FACE, BM_ELEM_TAG, FALSE);
119
BM_mesh_elem_hflag_enable_all(bm, BM_FACE, BM_ELEM_TAG, false);
120
BMO_slot_buffer_hflag_disable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
140
123
/* first count all inset edges we will split */
199
182
if (es->e_new == es->e_old) { /* happens on boundary edges */
200
183
/* take care here, we're creating this double edge which _must_ have its verts replaced later on */
201
es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, FALSE);
184
es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, 0);
204
187
/* store index back to original in 'edge_info' */
222
205
v1 = BM_vert_create(bm, tvec, NULL);
223
206
v2 = BM_vert_create(bm, tvec, NULL);
224
207
madd_v3_v3fl(v2->co, es->no, 0.1f);
225
BM_edge_create(bm, v1, v2, NULL, FALSE);
208
BM_edge_create(bm, v1, v2, NULL, 0);
297
280
BMFace *f_b = e_info_b->l->f;
299
282
/* we use this as either the normal OR to find the right direction for the
300
* crpss product between both face normals */
283
* cross product between both face normals */
301
284
add_v3_v3v3(tvec, e_info_a->no, e_info_b->no);
303
if ((f_a == f_b) || compare_v3v3(f_a->no, f_b->no, 0.00001f)) {
286
/* epsilon increased to fix [#32329] */
287
if ((f_a == f_b) || compare_v3v3(f_a->no, f_b->no, 0.001f)) {
304
288
normalize_v3(tvec);
487
472
/* no need to check doubles, we KNOW there won't be any */
488
473
/* yes - reverse face is correct in this case */
489
f = BM_face_create_quad_tri_v(bm, varr, j, es->l->f, FALSE);
474
f = BM_face_create_quad_tri_v(bm, varr, j, es->l->f, false);
490
475
BMO_elem_flag_enable(bm, f, ELE_NEW);
492
477
/* copy for loop data, otherwise UV's and vcols are no good.
493
478
* tiny speedup here we could be more clever and copy from known adjacent data
494
479
* also - we could attempt to interpolate the loop data, this would be much slower but more useful too */
481
/* don't use this because face boundaries have no adjacent loops and won't be filled in.
482
* instead copy from the opposite side with the code below */
495
483
BM_face_copy_shared(bm, f);
486
/* 2 inner loops on the edge between the new face and the original */
492
l_a = BM_FACE_FIRST_LOOP(f);
495
/* we know this side has a radial_next because of the order of created verts in the quad */
496
l_a_other = BM_edge_other_loop(l_a->e, l_a);
497
l_b_other = BM_edge_other_loop(l_a->e, l_b);
498
BM_elem_attrs_copy(bm, bm, l_a_other, l_a);
499
BM_elem_attrs_copy(bm, bm, l_b_other, l_b);
501
/* step around to the opposite side of the quad - warning, this may have no other edges! */
502
l_a = l_a->next->next;
504
if (!BM_edge_is_boundary(l_a->e)) {
506
l_a_other = BM_edge_other_loop(l_a->e, l_a);
507
l_b_other = BM_edge_other_loop(l_a->e, l_b);
508
BM_elem_attrs_copy(bm, bm, l_a_other, l_a);
509
BM_elem_attrs_copy(bm, bm, l_b_other, l_b);
511
else { /* boundary edges have no useful data to copy from, use opposite side of face */
512
/* swap a<->b intentionally */
513
BM_elem_attrs_copy(bm, bm, l_a_other, l_b);
514
BM_elem_attrs_copy(bm, bm, l_b_other, l_a);
498
520
/* we could flag new edges/verts too, is it useful? */
499
BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, ELE_NEW);
521
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_NEW);
501
523
/* cheap feature to add depth to the inset */
502
524
if (depth != 0.0f) {
526
548
/* done correcting edge verts normals */
528
550
/* untag verts */
529
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, FALSE);
551
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
531
553
/* tag face verts */
532
BMO_ITER (f, &oiter, bm, op, "faces", BM_FACE) {
554
BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
533
555
BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
534
556
BM_elem_flag_enable(v, BM_ELEM_TAG);
544
566
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
545
567
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
546
568
const float fac = (depth *
547
(use_relative_offset ? bm_vert_avg_tag_dist(v) : 1.0f) *
569
(use_relative_offset ? BM_vert_calc_mean_tagged_edge_length(v) : 1.0f) *
548
570
(use_even_boundry ? BM_vert_calc_shell_factor(v) : 1.0f));
549
571
madd_v3_v3v3fl(varr_co[i], v->co, v->no, fac);