diff options
Diffstat (limited to 'source/blender/bmesh/operators/bmo_wireframe.c')
-rw-r--r-- | source/blender/bmesh/operators/bmo_wireframe.c | 87 |
1 files changed, 55 insertions, 32 deletions
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c index d572a1c5863..532145ab129 100644 --- a/source/blender/bmesh/operators/bmo_wireframe.c +++ b/source/blender/bmesh/operators/bmo_wireframe.c @@ -77,39 +77,60 @@ static void bm_vert_boundary_tangent(BMVert *v, float r_no[3], float r_no_face[3 } } - l_a = bm_edge_tag_faceloop(e_a); - l_b = bm_edge_tag_faceloop(e_b); + if (e_a && e_b) { + l_a = bm_edge_tag_faceloop(e_a); + l_b = bm_edge_tag_faceloop(e_b); + + /* average edge face normal */ + add_v3_v3v3(no_face, l_a->f->no, l_b->f->no); + + /* average edge direction */ + v_a = BM_edge_other_vert(e_a, v); + v_b = BM_edge_other_vert(e_b, v); + + sub_v3_v3v3(tvec_a, v->co, v_a->co); + sub_v3_v3v3(tvec_b, v_b->co, v->co); + normalize_v3(tvec_a); + normalize_v3(tvec_b); + add_v3_v3v3(no_edge, tvec_a, tvec_b); /* not unit length but this is ok */ + + /* check are we flipped the right way */ + BM_edge_calc_face_tangent(e_a, l_a, tvec_a); + BM_edge_calc_face_tangent(e_b, l_b, tvec_b); + add_v3_v3(tvec_a, tvec_b); + + *r_va_other = v_a; + *r_vb_other = v_b; + } + else { + /* degenerate case - vertex connects a boundary edged face to other faces, + * so we have only one boundary face - only use it for calculations */ + l_a = bm_edge_tag_faceloop(e_a); - /* average edge face normal */ - add_v3_v3v3(no_face, l_a->f->no, l_b->f->no); + copy_v3_v3(no_face, l_a->f->no); - /* average edge direction */ - v_a = BM_edge_other_vert(e_a, v); - v_b = BM_edge_other_vert(e_b, v); + /* edge direction */ + v_a = BM_edge_other_vert(e_a, v); + v_b = NULL; - sub_v3_v3v3(tvec_a, v->co, v_a->co); - sub_v3_v3v3(tvec_b, v_b->co, v->co); - normalize_v3(tvec_a); - normalize_v3(tvec_b); - add_v3_v3v3(no_edge, tvec_a, tvec_b); /* not unit length but this is ok */ + sub_v3_v3v3(no_edge, v->co, v_a->co); + /* check are we flipped the right way */ + BM_edge_calc_face_tangent(e_a, l_a, tvec_a); + + *r_va_other = NULL; + *r_vb_other = NULL; + } /* find the normal */ cross_v3_v3v3(r_no, no_edge, no_face); normalize_v3(r_no); - /* check are we flipped the right way */ - BM_edge_calc_face_tangent(e_a, l_a, tvec_a); - BM_edge_calc_face_tangent(e_b, l_b, tvec_b); - add_v3_v3(tvec_a, tvec_b); - if (dot_v3v3(r_no, tvec_a) > 0.0f) { negate_v3(r_no); } copy_v3_v3(r_no_face, no_face); - *r_va_other = v_a; - *r_vb_other = v_b; } /* check if we are the only tagged loop-face around this edge */ @@ -134,12 +155,12 @@ extern float BM_vert_calc_mean_tagged_edge_length(BMVert *v); void bmo_wireframe_exec(BMesh *bm, BMOperator *op) { - const int use_boundary = BMO_slot_bool_get(op, "use_boundary"); - const int use_even_offset = BMO_slot_bool_get(op, "use_even_offset"); - const int use_relative_offset = BMO_slot_bool_get(op, "use_relative_offset"); - const int use_crease = (BMO_slot_bool_get(op, "use_crease") && + const int use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary"); + const int use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset"); + const int use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset"); + const int use_crease = (BMO_slot_bool_get(op->slots_in, "use_crease") && CustomData_has_layer(&bm->edata, CD_CREASE)); - const float depth = BMO_slot_float_get(op, "thickness"); + const float depth = BMO_slot_float_get(op->slots_in, "thickness"); const float inset = depth; const int totvert_orig = bm->totvert; @@ -184,7 +205,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) /* setup tags, all faces and verts will be tagged which will be duplicated */ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, FALSE); - BMO_ITER (f_src, &oiter, bm, op, "faces", BM_FACE) { + BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) { verts_loop_tot += f_src->len; BM_elem_flag_enable(f_src, BM_ELEM_TAG); BM_ITER_ELEM (l, &itersub, f_src, BM_LOOPS_OF_FACE) { @@ -230,7 +251,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) verts_loop = MEM_mallocN(sizeof(BMVert **) * verts_loop_tot, __func__); verts_loop_tot = 0; /* count up again */ - BMO_ITER (f_src, &oiter, bm, op, "faces", BM_FACE) { + BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) { BM_ITER_ELEM (l, &itersub, f_src, BM_LOOPS_OF_FACE) { BM_elem_index_set(l, verts_loop_tot); /* set_loop */ @@ -269,10 +290,12 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) /* similar to code above but different angle calc */ fac = inset; if (use_even_offset) { - fac *= shell_angle_to_dist(((float)M_PI - angle_on_axis_v3v3v3_v3(va_other->co, - l_pair[i]->v->co, - vb_other->co, - no_face)) * 0.5f); + if (va_other) { /* for verts with only one boundary edge - this will be NULL */ + fac *= shell_angle_to_dist(((float)M_PI - angle_on_axis_v3v3v3_v3(va_other->co, + l_pair[i]->v->co, + vb_other->co, + no_face)) * 0.5f); + } } if (use_relative_offset) { fac *= verts_relfac[BM_elem_index_get(l_pair[i]->v)]; @@ -288,7 +311,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) } } - BMO_ITER (f_src, &oiter, bm, op, "faces", BM_FACE) { + BMO_ITER (f_src, &oiter, op->slots_in, "faces", BM_FACE) { BM_elem_flag_disable(f_src, BM_ELEM_TAG); BM_ITER_ELEM (l, &itersub, f_src, BM_LOOPS_OF_FACE) { BMFace *f_new; @@ -400,5 +423,5 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op) MEM_freeN(verts_pos); MEM_freeN(verts_loop); - BMO_slot_buffer_from_enabled_hflag(bm, op, "faceout", BM_FACE, BM_ELEM_TAG); + BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); } |