Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-05-06 16:31:57 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-05-06 16:31:57 +0300
commitf26b373cb922e79bce34eed7bdb7a8ee29a3dab4 (patch)
treee1b2aad3353a3a7bced978eb74f78eb13a8cee3a /source/blender/editors/mesh
parentebcb8223bd886fd327cddae1394436e10f1f7a73 (diff)
parent5ffd10a6da956210062f5cd18c61de348f379849 (diff)
Merge branch 'master' into gooseberry
Conflicts: source/blender/editors/object/object_shapekey.c
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c164
1 files changed, 82 insertions, 82 deletions
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index abd88ae65aa..2a0bdfc45f0 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -63,9 +63,10 @@
* point and would result in the same distance.
*/
#define INSET_DEFAULT 0.00001f
-static float edbm_rip_edgedist_squared(ARegion *ar, float mat[4][4],
- const float co1[3], const float co2[3], const float mvalf[2],
- const float inset)
+static float edbm_rip_edgedist_squared(
+ ARegion *ar, float mat[4][4],
+ const float co1[3], const float co2[3], const float mvalf[2],
+ const float inset)
{
float vec1[2], vec2[2], dist_sq;
@@ -89,8 +90,9 @@ static float edbm_rip_edgedist_squared(ARegion *ar, float mat[4][4],
}
#if 0
-static float edbm_rip_linedist(ARegion *ar, float mat[4][4],
- const float co1[3], const float co2[3], const float mvalf[2])
+static float edbm_rip_linedist(
+ ARegion *ar, float mat[4][4],
+ const float co1[3], const float co2[3], const float mvalf[2])
{
float vec1[2], vec2[2];
@@ -114,9 +116,10 @@ static void edbm_calc_loop_co(BMLoop *l, float l_mid_co[3])
}
-static float edbm_rip_edge_side_measure(BMEdge *e, BMLoop *e_l,
- ARegion *ar,
- float projectMat[4][4], const float fmval[2])
+static float edbm_rip_edge_side_measure(
+ BMEdge *e, BMLoop *e_l,
+ ARegion *ar,
+ float projectMat[4][4], const float fmval[2])
{
float cent[3] = {0, 0, 0}, mid[3];
@@ -532,14 +535,14 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
BMesh *bm = em->bm;
BMIter iter, liter;
BMLoop *l;
- BMEdge *e, *e2;
+ BMEdge *e_best;
BMVert *v;
const int totvert_orig = bm->totvert;
int i;
float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
float dist_sq = FLT_MAX;
float d;
- bool is_wire;
+ bool is_wire, is_manifold_region;
BMEditSelection ese;
int totboundary_edge = 0;
@@ -565,86 +568,81 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
}
is_wire = BM_vert_is_wire(v);
+ is_manifold_region = BM_vert_is_manifold_region(v);
- e2 = NULL;
+ e_best = NULL;
- if (v->e) {
+ {
+ BMEdge *e;
/* find closest edge to mouse cursor */
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
/* consider wire as boundary for this purpose,
* otherwise we can't a face away from a wire edge */
totboundary_edge += (BM_edge_is_boundary(e) || BM_edge_is_wire(e));
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- if (BM_edge_is_manifold(e)) {
+ if ((is_manifold_region == false) || BM_edge_is_manifold(e)) {
d = edbm_rip_edgedist_squared(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT);
- if ((e2 == NULL) || (d < dist_sq)) {
+ if ((e_best == NULL) || (d < dist_sq)) {
dist_sq = d;
- e2 = e;
- }
- }
- }
- }
-
- /* if we are ripping a single vertex from 3 faces,
- * then measure the distance to the face corner as well as the edge */
- if (BM_vert_face_count_is_equal(v, 3) &&
- BM_vert_edge_count_is_equal(v, 3))
- {
- BMEdge *e_all[3];
- BMLoop *l_all[3];
- int i1, i2;
-
- BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3);
- BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3);
-
- /* not do a loop similar to the one above, but test against loops */
- for (i1 = 0; i1 < 3; i1++) {
- /* consider wire as boundary for this purpose,
- * otherwise we can't a face away from a wire edge */
- float l_mid_co[3];
- l = l_all[i1];
- edbm_calc_loop_co(l, l_mid_co);
- d = edbm_rip_edgedist_squared(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT);
- if ((e2 == NULL) || (d < dist_sq)) {
- dist_sq = d;
-
- /* find the edge that is not in this loop */
- e2 = NULL;
- for (i2 = 0; i2 < 3; i2++) {
- if (!BM_edge_in_loop(e_all[i2], l)) {
- e2 = e_all[i2];
- break;
- }
+ e_best = e;
}
- BLI_assert(e2 != NULL);
}
}
}
}
- if (e2) {
+ if (e_best && (is_manifold_region == false)) {
/* Try to split off a non-manifold fan (when we have multiple disconnected fans) */
-
- /* note: we're lazy here and first split then check there are any faces remaining,
- * this isn't good practice, however its less hassle then checking for multiple-disconnected regions */
- BMLoop *l_sep = e2->l->v == v ? e2->l : e2->l->next;
+ BMLoop *l_sep = e_best->l->v == v ? e_best->l : e_best->l->next;
BMVert *v_new;
+
BLI_assert(l_sep->v == v);
v_new = bmesh_urmv_loop_region(bm, l_sep);
- if (BM_vert_find_first_loop(v)) {
- BM_vert_select_set(bm, v, false);
- BM_select_history_remove(bm, v);
+ BLI_assert(BM_vert_find_first_loop(v));
- BM_vert_select_set(bm, v_new, true);
- if (ese.ele) {
- BM_select_history_store(bm, v_new);
- }
+ BM_vert_select_set(bm, v, false);
+ BM_select_history_remove(bm, v);
- return OPERATOR_FINISHED;
+ BM_vert_select_set(bm, v_new, true);
+ if (ese.ele) {
+ BM_select_history_store(bm, v_new);
}
- else {
- /* rewind */
- BM_vert_splice(bm, v, v_new);
+ return OPERATOR_FINISHED;
+ }
+
+ /* if we are ripping a single vertex from 3 faces,
+ * then measure the distance to the face corner as well as the edge */
+ if (BM_vert_face_count_is_equal(v, 3) &&
+ BM_vert_edge_count_is_equal(v, 3))
+ {
+ BMEdge *e_all[3];
+ BMLoop *l_all[3];
+ int i1, i2;
+
+ BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3);
+ BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3);
+
+ /* not do a loop similar to the one above, but test against loops */
+ for (i1 = 0; i1 < 3; i1++) {
+ /* consider wire as boundary for this purpose,
+ * otherwise we can't a face away from a wire edge */
+ float l_mid_co[3];
+ l = l_all[i1];
+ edbm_calc_loop_co(l, l_mid_co);
+ d = edbm_rip_edgedist_squared(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT);
+ if ((e_best == NULL) || (d < dist_sq)) {
+ dist_sq = d;
+
+ /* find the edge that is not in this loop */
+ e_best = NULL;
+ for (i2 = 0; i2 < 3; i2++) {
+ if (!BM_edge_in_loop(e_all[i2], l)) {
+ e_best = e_all[i2];
+ break;
+ }
+ }
+ BLI_assert(e_best != NULL);
+ }
}
}
@@ -703,6 +701,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
}
}
else {
+ BMEdge *e;
/* a wire vert, find the best edge */
BM_ITER_ELEM (e, &iter, vout[i], BM_EDGES_OF_VERT) {
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
@@ -751,7 +750,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
}
}
- if (!e2) {
+ if (!e_best) {
BKE_report(op->reports, RPT_ERROR, "Selected vertex has no edge/face pairs attached");
return OPERATOR_CANCELLED;
}
@@ -766,16 +765,16 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
int larr_len = 0;
/* rip two adjacent edges */
- if (BM_edge_is_boundary(e2) || BM_vert_face_count_is_equal(v, 2)) {
+ if (BM_edge_is_boundary(e_best) || BM_vert_face_count_is_equal(v, 2)) {
/* Don't run the edge split operator in this case */
- l = BM_edge_vert_share_loop(e2->l, v);
+ l = BM_edge_vert_share_loop(e_best->l, v);
larr[larr_len] = l;
larr_len++;
/* only tag for face-fill (we don't call the operator) */
- if (BM_edge_is_boundary(e2)) {
- BM_elem_flag_enable(e2, BM_ELEM_TAG);
+ if (BM_edge_is_boundary(e_best)) {
+ BM_elem_flag_enable(e_best, BM_ELEM_TAG);
}
else {
BM_elem_flag_enable(l->e, BM_ELEM_TAG);
@@ -783,10 +782,10 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *eve
}
}
else {
- if (BM_edge_is_manifold(e2)) {
+ if (BM_edge_is_manifold(e_best)) {
BMLoop *l_iter, *l_first;
- l_iter = l_first = e2->l;
+ l_iter = l_first = e_best->l;
do {
larr[larr_len] = BM_edge_vert_share_loop(l_iter, v);
BM_elem_flag_enable(larr[larr_len]->e, BM_ELEM_TAG);
@@ -880,7 +879,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
BMesh *bm = em->bm;
BMIter iter, eiter;
BMLoop *l;
- BMEdge *e, *e2;
+ BMEdge *e_best;
BMVert *v;
const int totedge_orig = bm->totedge;
float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]};
@@ -894,11 +893,12 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
/* expand edge selection */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BMEdge *e;
bool all_manifold;
int totedge_manifold; /* manifold, visible edges */
int i;
- e2 = NULL;
+ e_best = NULL;
i = 0;
totedge_manifold = 0;
all_manifold = true;
@@ -910,7 +910,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
/* important to check selection rather then tag here
* else we get feedback loop */
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- e2 = e;
+ e_best = e;
i++;
}
totedge_manifold++;
@@ -923,18 +923,18 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
}
/* single edge, extend */
- if (i == 1 && e2->l) {
+ if (i == 1 && e_best->l) {
/* note: if the case of 3 edges has one change in loop stepping,
* if this becomes more involved we may be better off splitting
* the 3 edge case into its own else-if branch */
if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == false)) {
- BMLoop *l_a = e2->l;
+ BMLoop *l_a = e_best->l;
BMLoop *l_b = l_a->radial_next;
/* find the best face to follow, this way the edge won't point away from
* the mouse when there are more than 4 (takes the shortest face fan around) */
- l = (edbm_rip_edge_side_measure(e2, l_a, ar, projectMat, fmval) <
- edbm_rip_edge_side_measure(e2, l_b, ar, projectMat, fmval)) ? l_a : l_b;
+ l = (edbm_rip_edge_side_measure(e_best, l_a, ar, projectMat, fmval) <
+ edbm_rip_edge_side_measure(e_best, l_b, ar, projectMat, fmval)) ? l_a : l_b;
l = BM_loop_other_edge_loop(l, v);
/* important edge is manifold else we can be attempting to split off a fan that don't budge,
@@ -952,7 +952,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *eve
}
}
else {
- e = BM_vert_other_disk_edge(v, e2);
+ e = BM_vert_other_disk_edge(v, e_best);
if (e) {
BLI_assert(!BM_elem_flag_test(e, BM_ELEM_TAG));