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:
authorCampbell Barton <ideasman42@gmail.com>2014-12-15 16:17:28 +0300
committerCampbell Barton <ideasman42@gmail.com>2014-12-15 17:10:49 +0300
commitdb0e2e7347db73786b38c0cbace60741ddd28b7e (patch)
tree2ac0fae98625095f248156f583bedd7b47254de0
parent2329b58fd3d978752d200952591fd4e7db7d0fca (diff)
Fix T42864 (partial): knife-project included uncut backfaces
When knife-project ran with cut-through disabled, it would still try to select faces behind the cut. Now check if the faces are obscured.
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c78
1 files changed, 37 insertions, 41 deletions
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index c94e4ca2c95..c2aafba9249 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -3168,16 +3168,14 @@ void MESH_OT_knife_tool(wmOperatorType *ot)
* tessellation here seems way overkill,
* but without this its very hard to know of a point is inside the face
*/
-static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
+static void edbm_mesh_knife_face_point(BMFace *f, float r_cent[3])
{
const int tottri = f->len - 2;
BMLoop **loops = BLI_array_alloca(loops, f->len);
unsigned int (*index)[3] = BLI_array_alloca(index, tottri);
int j;
-
- const float *best_co[3] = {NULL};
- float best_area = -1.0f;
- bool ok = false;
+ int j_best = 0; /* use as fallback when unset */
+ float area_best = -1.0f;
BM_face_calc_tessellation(f, loops, index);
@@ -3190,49 +3188,34 @@ static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
float cross[3];
cross_v3_v3v3(cross, p2, p3);
area = fabsf(dot_v3v3(p1, cross));
- if (area > best_area) {
- best_co[0] = p1;
- best_co[1] = p2;
- best_co[2] = p3;
- best_area = area;
- ok = true;
+ if (area > area_best) {
+ j_best = j;
+ area_best = area;
}
}
- if (ok) {
- mid_v3_v3v3v3(r_cent, best_co[0], best_co[1], best_co[2]);
- }
- else {
- mid_v3_v3v3v3(r_cent, loops[0]->v->co, loops[1]->v->co, loops[2]->v->co);
- }
+ mid_v3_v3v3v3(
+ r_cent,
+ loops[index[j_best][0]]->v->co,
+ loops[index[j_best][1]]->v->co,
+ loops[index[j_best][2]]->v->co);
}
-static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, float projmat[4][4])
+static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
{
- float cent_ss[2];
- float cent[3];
-
- edvm_mesh_knife_face_point(f, cent);
-
- ED_view3d_project_float_v2_m4(ar, cent, cent_ss, projmat);
-
- /* check */
- {
- LinkNode *p = polys;
- int isect = 0;
-
- while (p) {
- const float (*mval_fl)[2] = p->link;
- const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
- isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
- p = p->next;
- }
+ LinkNode *p = polys;
+ int isect = 0;
- if (isect % 2) {
- return true;
- }
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
+ p = p->next;
}
+ if (isect % 2) {
+ return true;
+ }
return false;
}
@@ -3242,6 +3225,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f,
void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through)
{
KnifeTool_OpData *kcd;
+ bglMats mats;
view3d_operator_needs_opengl(C);
@@ -3260,6 +3244,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
if (use_tag) {
BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
}
+
+ if (kcd->cut_through == false) {
+ bgl_get_mats(&mats);
+ }
}
/* execute */
@@ -3324,7 +3312,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
BMFace *f;
BMIter fiter;
BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
- if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ float cent[3], cent_ss[2];
+ edbm_mesh_knife_face_point(f, cent);
+ knife_project_v2(kcd, cent, cent_ss);
+ if (edbm_mesh_knife_point_isect(polys, cent_ss)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
}
}
@@ -3357,7 +3348,12 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
} while ((l_iter = l_iter->next) != l_first && (found == false));
if (found) {
- if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ float cent[3], cent_ss[2];
+ edbm_mesh_knife_face_point(f, cent);
+ knife_project_v2(kcd, cent, cent_ss);
+ if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats)) &&
+ edbm_mesh_knife_point_isect(polys, cent_ss))
+ {
BM_elem_flag_enable(f, BM_ELEM_TAG);
keep_search = true;
}