Fix for join faces ignoring angle limit

Angle limit for join-faces was more advice then actual limit.
Now joining entire selection, gives assurance that no faces above the limit will be merged.

The purpose of this was to allow users to isolate 2 faces and always join them.
Instead, support this by bypassing limit only when its not set and 2 faces are selected.
This commit is contained in:
Campbell Barton 2015-05-22 18:12:54 +10:00
parent 476feb622c
commit ed2cb8de2f
2 changed files with 22 additions and 37 deletions

@ -47,7 +47,8 @@
/* assumes edges are validated before reaching this poin */ /* assumes edges are validated before reaching this poin */
static float measure_facepair( static float measure_facepair(
const float v1[3], const float v2[3], const float v1[3], const float v2[3],
const float v3[3], const float v4[3], float limit) const float v3[3], const float v4[3],
const float limit)
{ {
/* gives a 'weight' to a pair of triangles that join an edge to decide how good a join they would make */ /* gives a 'weight' to a pair of triangles that join an edge to decide how good a join they would make */
/* Note: this is more complicated than it needs to be and should be cleaned up.. */ /* Note: this is more complicated than it needs to be and should be cleaned up.. */
@ -199,7 +200,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
const bool do_tf = do_uv; /* texture face, make make its own option eventually */ const bool do_tf = do_uv; /* texture face, make make its own option eventually */
const bool do_vcol = BMO_slot_bool_get(op->slots_in, "cmp_vcols"); const bool do_vcol = BMO_slot_bool_get(op->slots_in, "cmp_vcols");
const bool do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials"); const bool do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials");
const float limit = BMO_slot_float_get(op->slots_in, "limit"); float limit;
BMIter iter; BMIter iter;
BMOIter siter; BMOIter siter;
@ -210,6 +211,11 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
unsigned i, totedge; unsigned i, totedge;
unsigned int totedge_tag = 0; unsigned int totedge_tag = 0;
limit = BMO_slot_float_get(op->slots_in, "limit");
if (limit == DEG2RADF(180.0f)) {
limit = FLT_MAX;
}
/* flag all edges of all input face */ /* flag all edges of all input face */
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) { BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
if (f->len == 3) { if (f->len == 3) {
@ -308,39 +314,5 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
} }
} }
/* join 2-tri islands */
BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
if (BMO_elem_flag_test(bm, e, EDGE_MARK)) {
BMLoop *l_a, *l_b;
BMFace *f_a, *f_b;
/* ok, this edge wasn't merged, check if it's
* in a 2-tri-pair island, and if so merge */
l_a = e->l;
l_b = e->l->radial_next;
f_a = l_a->f;
f_b = l_b->f;
/* check the other 2 edges in both tris are untagged */
if ((f_a->len == 3 && f_b->len == 3) &&
(BMO_elem_flag_test(bm, l_a->next->e, EDGE_MARK) == false) &&
(BMO_elem_flag_test(bm, l_a->prev->e, EDGE_MARK) == false) &&
(BMO_elem_flag_test(bm, l_b->next->e, EDGE_MARK) == false) &&
(BMO_elem_flag_test(bm, l_b->prev->e, EDGE_MARK) == false) &&
/* check for faces that use same verts, this is supported but raises an error
* and cancels the operation when performed from editmode, since this is only
* two triangles we only need to compare a single vertex */
(LIKELY(l_a->prev->v != l_b->prev->v)))
{
BMFace *f_new;
f_new = BM_faces_join_pair(bm, f_a, f_b, e, true);
if (f_new) {
BMO_elem_flag_enable(bm, f_new, FACE_OUT);
}
}
}
}
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT); BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT);
} }

@ -3760,7 +3760,20 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C); Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit); BMEditMesh *em = BKE_editmesh_from_object(obedit);
int dosharp, douvs, dovcols, domaterials; int dosharp, douvs, dovcols, domaterials;
const float limit = RNA_float_get(op->ptr, "limit"); float limit;
PropertyRNA *prop;
/* When joining exactly 2 faces, no limit.
* this is useful for one off joins while editing. */
prop = RNA_struct_find_property(op->ptr, "limit");
if ((em->bm->totfacesel == 2) &&
(RNA_property_is_set(op->ptr, prop) == false))
{
limit = DEG2RADF(180.0f);
}
else {
limit = RNA_property_float_get(op->ptr, prop);
}
dosharp = RNA_boolean_get(op->ptr, "sharp"); dosharp = RNA_boolean_get(op->ptr, "sharp");
douvs = RNA_boolean_get(op->ptr, "uvs"); douvs = RNA_boolean_get(op->ptr, "uvs");