[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49616] trunk/blender/source/blender/ editors/mesh/editmesh_knife.c: Fix to knife: would sometimes miss cuts on non-planar faces.
Howard Trickey
howard.trickey at gmail.com
Mon Aug 6 15:37:25 CEST 2012
Revision: 49616
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49616
Author: howardt
Date: 2012-08-06 13:37:25 +0000 (Mon, 06 Aug 2012)
Log Message:
-----------
Fix to knife: would sometimes miss cuts on non-planar faces.
Also, there was a needless loop through all three loops of
a tesselation triangle, which all share the same original face.
Also, made an early out for case where an edge cut had already
been discovered on a Knife edge.
Modified Paths:
--------------
trunk/blender/source/blender/editors/mesh/editmesh_knife.c
Modified: trunk/blender/source/blender/editors/mesh/editmesh_knife.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_knife.c 2012-08-06 13:31:28 UTC (rev 49615)
+++ trunk/blender/source/blender/editors/mesh/editmesh_knife.c 2012-08-06 13:37:25 UTC (rev 49616)
@@ -1092,9 +1092,9 @@
BLI_array_declare(edges);
BVHTreeOverlap *results, *result;
BMLoop **ls;
- float cos[9], uv[3], lambda;
+ float cos[9], lambda;
unsigned int tot = 0;
- int i, j;
+ int i;
/* for comparing distances, error of intersection depends on triangle scale.
* need to scale down before squaring for accurate comparison */
@@ -1112,105 +1112,107 @@
for (i = 0; i < tot; i++, result++) {
float p[3];
+ BMLoop *l1;
+ BMFace *hitf;
+ ListBase *lst;
+ Ref *ref;
ls = (BMLoop **)kcd->em->looptris[result->indexA];
- for (j = 0; j < 3; j++) {
- BMLoop *l1 = ls[j];
- BMFace *hitf;
- ListBase *lst = knife_get_face_kedges(kcd, l1->f);
- Ref *ref;
+ l1 = ls[0];
+ lst = knife_get_face_kedges(kcd, l1->f);
- for (ref = lst->first; ref; ref = ref->next) {
- KnifeEdge *kfe = ref->ref;
+ for (ref = lst->first; ref; ref = ref->next) {
+ KnifeEdge *kfe = ref->ref;
- //if (kfe == kcd->cur.edge || kfe == kcd->prev.edge)
- // continue;
+ if (BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
+ continue; // We already found a hit on this knife edge
+ }
- if (isect_line_tri_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, &lambda, uv)) {
- float no[3], view[3], sp[3];
+ if (isect_line_tri_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, &lambda, NULL)) {
+ float no[3], view[3], sp[3];
- interp_v3_v3v3(p, kfe->v1->cageco, kfe->v2->cageco, lambda);
+ interp_v3_v3v3(p, kfe->v1->cageco, kfe->v2->cageco, lambda);
- if (kcd->cur.vert && len_squared_v3v3(kcd->cur.vert->cageco, p) < depsilon_squared)
- continue;
- if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_squared)
- continue;
- if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_squared ||
- len_squared_v3v3(kcd->cur.cage, p) < depsilon_squared)
- {
- continue;
- }
+ if (kcd->cur.vert && len_squared_v3v3(kcd->cur.vert->cageco, p) < depsilon_squared)
+ continue;
+ if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_squared)
+ continue;
+ if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_squared ||
+ len_squared_v3v3(kcd->cur.cage, p) < depsilon_squared)
+ continue;
- knife_project_v3(kcd, p, sp);
- view3d_unproject(mats, view, sp[0], sp[1], 0.0f);
- mul_m4_v3(kcd->ob->imat, view);
+ knife_project_v3(kcd, p, sp);
+ view3d_unproject(mats, view, sp[0], sp[1], 0.0f);
+ mul_m4_v3(kcd->ob->imat, view);
- if (kcd->cut_through) {
- hitf = FALSE;
+ if (kcd->cut_through) {
+ hitf = FALSE;
+ } else {
+ /* check if this point is visible in the viewport */
+ float p1[3], lambda1;
+
+ /* if face isn't planer, p may be behind the current tesselated tri,
+ so move it onto that and then a little towards eye */
+ if (isect_line_tri_v3(p, view, ls[0]->v->co, ls[1]->v->co, ls[2]->v->co, &lambda1, NULL)) {
+ interp_v3_v3v3(p1, p, view, lambda1);
+ } else {
+ copy_v3_v3(p1, p);
}
- else {
- /* check if this point is visible in the viewport */
- sub_v3_v3(view, p);
- normalize_v3(view);
+ sub_v3_v3(view, p1);
+ normalize_v3(view);
- copy_v3_v3(no, view);
- mul_v3_fl(no, 0.003);
+ copy_v3_v3(no, view);
+ mul_v3_fl(no, 0.003);
- /* go towards view a bit */
- add_v3_v3(p, no);
-
- /* ray cast */
- hitf = BMBVH_RayCast(bmtree, p, no, NULL, NULL);
- }
-
- /* ok, if visible add the new point */
- if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
- BMEdgeHit hit;
+ /* go towards view a bit */
+ add_v3_v3(p1, no);
- if (len_squared_v3v3(p, kcd->cur.co) < depsilon_squared ||
- len_squared_v3v3(p, kcd->prev.co) < depsilon_squared)
- {
- continue;
- }
+ /* ray cast */
+ hitf = BMBVH_RayCast(bmtree, p1, no, NULL, NULL);
+ }
- hit.kfe = kfe;
- hit.v = NULL;
+ /* ok, if visible add the new point */
+ if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
+ BMEdgeHit hit;
+
+ if (len_squared_v3v3(p, kcd->cur.co) < depsilon_squared ||
+ len_squared_v3v3(p, kcd->prev.co) < depsilon_squared)
+ continue;
- knife_find_basef(kfe);
- hit.f = kfe->basef;
- hit.perc = len_v3v3(p, kfe->v1->cageco) / len_v3v3(kfe->v1->cageco, kfe->v2->cageco);
- copy_v3_v3(hit.cagehit, p);
+ hit.kfe = kfe;
+ hit.v = NULL;
- interp_v3_v3v3(p, kfe->v1->co, kfe->v2->co, hit.perc);
- copy_v3_v3(hit.realhit, p);
+ knife_find_basef(kfe);
+ hit.f = kfe->basef;
+ hit.perc = len_v3v3(p, kfe->v1->cageco) / len_v3v3(kfe->v1->cageco, kfe->v2->cageco);
+ copy_v3_v3(hit.cagehit, p);
- /* BMESH_TODO: should also snap to vertices */
- if (kcd->snap_midpoints) {
- float perc = hit.perc;
+ interp_v3_v3v3(p, kfe->v1->co, kfe->v2->co, hit.perc);
+ copy_v3_v3(hit.realhit, p);
- /* select the closest from the edge endpoints or the midpoint */
- if (perc < 0.25f) {
- perc = 0.0f;
- }
- else if (perc < 0.75f) {
- perc = 0.5f;
- }
- else {
- perc = 1.0f;
- }
+ /* BMESH_TODO: should also snap to vertices */
+ if (kcd->snap_midpoints) {
+ float perc = hit.perc;
- interp_v3_v3v3(hit.hit, kfe->v1->co, kfe->v2->co, perc);
- interp_v3_v3v3(hit.cagehit, kfe->v1->cageco, kfe->v2->cageco, perc);
+ /* select the closest from the edge endpoints or the midpoint */
+ if (perc < 0.25f) {
+ perc = 0.0f;
+ } else if (perc < 0.75f) {
+ perc = 0.5f;
+ } else {
+ perc = 1.0f;
}
- else {
- copy_v3_v3(hit.hit, p);
- }
- knife_project_v3(kcd, hit.cagehit, hit.schit);
- BLI_array_append(edges, hit);
- BLI_smallhash_insert(ehash, (intptr_t)kfe, NULL);
+ interp_v3_v3v3(hit.hit, kfe->v1->co, kfe->v2->co, perc);
+ interp_v3_v3v3(hit.cagehit, kfe->v1->cageco, kfe->v2->cageco, perc);
+ } else {
+ copy_v3_v3(hit.hit, p);
}
+ knife_project_v3(kcd, hit.cagehit, hit.schit);
+
+ BLI_array_append(edges, hit);
+ BLI_smallhash_insert(ehash, (intptr_t)kfe, NULL);
}
}
}
More information about the Bf-blender-cvs
mailing list