[Bf-blender-cvs] [aab947eb468] blender-v3.2-release: Fix T98349: Knife project resulting selection is wrong

Campbell Barton noreply at git.blender.org
Wed May 25 09:18:20 CEST 2022


Commit: aab947eb468c2e9ca068fabc9562562d3e0e739a
Author: Campbell Barton
Date:   Wed May 25 17:16:25 2022 +1000
Branches: blender-v3.2-release
https://developer.blender.org/rBaab947eb468c2e9ca068fabc9562562d3e0e739a

Fix T98349: Knife project resulting selection is wrong

Regression in [0] which removed the call to BVH-tree recalculation
before calculating the selection.

Instead of recalculating the BVH-tree, postpone recalculating mesh data
until after the selection has been calculated.

[0]: 6e77afe6ec7b6a73f218f1fef264758abcbc778a

===================================================================

M	source/blender/editors/mesh/editmesh_knife.c

===================================================================

diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 584642d12fc..01276d7640d 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1383,7 +1383,6 @@ static BMFace *knife_bvh_raycast(KnifeTool_OpData *kcd,
                                  uint *r_base_index)
 {
   BMFace *face;
-  BMLoop **ltri;
   BVHTreeRayHit hit;
   const float dist = r_dist ? *r_dist : FLT_MAX;
   hit.dist = dist;
@@ -1397,8 +1396,9 @@ static BMFace *knife_bvh_raycast(KnifeTool_OpData *kcd,
 
     /* Hits returned in world space. */
     if (r_hitout) {
-      ltri = kcd->bvh.looptris[hit.index];
-      interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, kcd->bvh.uv);
+      float tri_cos[3][3];
+      knife_bm_tri_cagecos_get_worldspace(kcd, kcd->bvh.base_index, hit.index, tri_cos);
+      interp_v3_v3v3v3_uv(r_hitout, UNPACK3(tri_cos), kcd->bvh.uv);
 
       if (r_cagehit) {
         copy_v3_v3(r_cagehit, hit.co);
@@ -1434,7 +1434,6 @@ static BMFace *knife_bvh_raycast_filter(KnifeTool_OpData *kcd,
   kcd->bvh.filter_data = filter_userdata;
 
   BMFace *face;
-  BMLoop **ltri;
   BVHTreeRayHit hit;
   const float dist = r_dist ? *r_dist : FLT_MAX;
   hit.dist = dist;
@@ -1451,8 +1450,9 @@ static BMFace *knife_bvh_raycast_filter(KnifeTool_OpData *kcd,
 
     /* Hits returned in world space. */
     if (r_hitout) {
-      ltri = kcd->bvh.looptris[hit.index];
-      interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, kcd->bvh.uv);
+      float tri_cos[3][3];
+      knife_bm_tri_cagecos_get_worldspace(kcd, kcd->bvh.base_index, hit.index, tri_cos);
+      interp_v3_v3v3v3_uv(r_hitout, UNPACK3(tri_cos), kcd->bvh.uv);
 
       if (r_cagehit) {
         copy_v3_v3(r_cagehit, hit.co);
@@ -4290,33 +4290,18 @@ static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
 /** \name Finalization
  * \{ */
 
-/* Called on tool confirmation. */
-static void knifetool_finish_ex(KnifeTool_OpData *kcd)
+static void knifetool_finish_single_pre(KnifeTool_OpData *kcd, Object *ob)
 {
-  Object *ob;
-  BMEditMesh *em;
-  for (uint b = 0; b < kcd->objects_len; b++) {
-    ob = kcd->objects[b];
-    em = BKE_editmesh_from_object(ob);
-
-    knife_make_cuts(kcd, ob);
-
-    EDBM_selectmode_flush(em);
-    EDBM_update(ob->data,
-                &(const struct EDBMUpdate_Params){
-                    .calc_looptri = true,
-                    .calc_normals = true,
-                    .is_destructive = true,
-                });
-  }
+  knife_make_cuts(kcd, ob);
 }
 
-static void knifetool_finish_single_ex(KnifeTool_OpData *kcd, Object *ob, uint UNUSED(base_index))
+/**
+ * A post version is needed to to delay recalculating tessellation after making cuts.
+ * Without this, knife-project can't use the BVH tree to select geometry after a cut, see: T98349.
+ */
+static void knifetool_finish_single_post(KnifeTool_OpData *UNUSED(kcd), Object *ob)
 {
-  knife_make_cuts(kcd, ob);
-
   BMEditMesh *em = BKE_editmesh_from_object(ob);
-
   EDBM_selectmode_flush(em);
   EDBM_update(ob->data,
               &(const struct EDBMUpdate_Params){
@@ -4326,6 +4311,16 @@ static void knifetool_finish_single_ex(KnifeTool_OpData *kcd, Object *ob, uint U
               });
 }
 
+/* Called on tool confirmation. */
+static void knifetool_finish_ex(KnifeTool_OpData *kcd)
+{
+  for (uint b = 0; b < kcd->objects_len; b++) {
+    Object *ob = kcd->objects[b];
+    knifetool_finish_single_pre(kcd, ob);
+    knifetool_finish_single_post(kcd, ob);
+  }
+}
+
 static void knifetool_finish(wmOperator *op)
 {
   KnifeTool_OpData *kcd = op->customdata;
@@ -5009,7 +5004,7 @@ void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_th
         BM_mesh_elem_hflag_enable_all(em->bm, BM_EDGE, BM_ELEM_TAG, false);
       }
 
-      knifetool_finish_single_ex(kcd, ob, b);
+      knifetool_finish_single_pre(kcd, ob);
 
       /* Tag faces inside! */
       if (use_tag) {
@@ -5098,6 +5093,10 @@ void EDBM_mesh_knife(ViewContext *vc, LinkNode *polys, bool use_tag, bool cut_th
 #undef F_ISECT_SET_UNKNOWN
 #undef F_ISECT_SET_OUTSIDE
       }
+
+      /* Defer freeing data until the BVH tree is finished with, see: #point_is_visible and
+       * the doc-string for #knifetool_finish_single_post. */
+      knifetool_finish_single_post(kcd, ob);
     }
 
     knifetool_exit_ex(kcd);



More information about the Bf-blender-cvs mailing list