Commit: 9d435076746ee147953b457cda0c84ee849565d0
Author: Cian Jinks
Date:   Sat Sep 11 19:16:24 2021 +0100
Branches: soc-2021-knife-tools
https://developer.blender.org/rB9d435076746ee147953b457cda0c84ee849565d0

Knife: Moved code to world space

This patch migrates the knife tool code to use world space coordinates instead 
of object space.
This is required to implement the ability to cut across multiple objects at 
once and the ability to use the geometry of other objects as a cutting 
reference.

This introduces precision errors for objects with very large scale or location, 
however it may be possible to add a switch between world space and object space 
coordinates depending on whether the user is in multi-object edit mode or not.

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

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 e0540e8c1e8..7081346de06 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -121,7 +121,6 @@ typedef struct KnifeVert {
   ListBase faces;
 
   float co[3], cageco[3];
-  float wcageco[3];
   bool is_face, in_space;
   bool is_cut; /* Along a cut created by user input (will draw too). */
   bool is_invalid;
@@ -163,7 +162,6 @@ typedef struct KnifeLineHit {
 typedef struct KnifePosData {
   float co[3];
   float cage[3];
-  float wcage[3];
 
   /* At most one of vert, edge, or bmface should be non-NULL,
    * saying whether the point is snapped to a vertex, edge, or in a face.
@@ -318,7 +316,6 @@ typedef struct KnifeTool_OpData {
   short constrain_axis;
   short constrain_axis_mode;
   bool axis_constrained;
-  float curr_cage_adjusted[3];
   char axis_string[2];
 
   short dist_angle_mode;
@@ -383,13 +380,17 @@ enum {
 static void knifetool_raycast_planes(const KnifeTool_OpData *kcd, float 
r_v1[3], float r_v2[3])
 {
   float planes[4][4];
-
   planes_from_projmat(kcd->projmat, planes[2], planes[0], planes[1], 
planes[3], NULL, NULL);
 
+  float curr_os[3];
+  float prev_os[3];
+  mul_v3_m4v3(curr_os, kcd->ob_imat, kcd->curr.cage);
+  mul_v3_m4v3(prev_os, kcd->ob_imat, kcd->prev.cage);
+
   /* Ray-cast all planes. */
   {
     float ray_dir[3];
-    float ray_hit_best[2][3] = {{UNPACK3(kcd->prev.cage)}, 
{UNPACK3(kcd->curr.cage)}};
+    float ray_hit_best[2][3] = {{UNPACK3(prev_os)}, {UNPACK3(curr_os)}};
     float lambda_best[2] = {-FLT_MAX, FLT_MAX};
     int i;
 
@@ -401,20 +402,20 @@ static void knifetool_raycast_planes(const 
KnifeTool_OpData *kcd, float r_v1[3],
       float curr_cage_adjust[3];
       float co_depth[3];
 
-      copy_v3_v3(co_depth, kcd->prev.cage);
+      copy_v3_v3(co_depth, prev_os);
       mul_m4_v3(kcd->ob->obmat, co_depth);
       ED_view3d_win_to_3d(kcd->vc.v3d, kcd->region, co_depth, kcd->curr.mval, 
curr_cage_adjust);
       mul_m4_v3(kcd->ob_imat, curr_cage_adjust);
 
-      sub_v3_v3v3(ray_dir, curr_cage_adjust, kcd->prev.cage);
+      sub_v3_v3v3(ray_dir, curr_cage_adjust, prev_os);
     }
 #endif
 
     for (i = 0; i < 4; i++) {
       float ray_hit[3];
       float lambda_test;
-      if (isect_ray_plane_v3(kcd->prev.cage, ray_dir, planes[i], &lambda_test, 
false)) {
-        madd_v3_v3v3fl(ray_hit, kcd->prev.cage, ray_dir, lambda_test);
+      if (isect_ray_plane_v3(prev_os, ray_dir, planes[i], &lambda_test, 
false)) {
+        madd_v3_v3v3fl(ray_hit, prev_os, ray_dir, lambda_test);
         if (lambda_test < 0.0f) {
           if (lambda_test > lambda_best[0]) {
             copy_v3_v3(ray_hit_best[0], ray_hit);
@@ -432,6 +433,8 @@ static void knifetool_raycast_planes(const KnifeTool_OpData 
*kcd, float r_v1[3],
 
     copy_v3_v3(r_v1, ray_hit_best[0]);
     copy_v3_v3(r_v2, ray_hit_best[1]);
+    mul_m4_v3(kcd->ob->obmat, r_v1);
+    mul_m4_v3(kcd->ob->obmat, r_v2);
   }
 }
 
@@ -514,13 +517,7 @@ static void knifetool_draw_visible_distances(const 
KnifeTool_OpData *kcd)
   const int distance_precision = 4;
 
   /* Calculate distance and convert to string. */
-  float prev_cage_world[3];
-  float curr_cage_world[3];
-  copy_v3_v3(prev_cage_world, kcd->mdata.corr_prev_cage);
-  copy_v3_v3(curr_cage_world, kcd->curr.cage);
-  mul_m4_v3(kcd->ob->obmat, prev_cage_world);
-  mul_m4_v3(kcd->ob->obmat, curr_cage_world);
-  const float cut_len = len_v3v3(prev_cage_world, curr_cage_world);
+  const float cut_len = len_v3v3(kcd->mdata.corr_prev_cage, kcd->curr.cage);
 
   UnitSettings *unit = &kcd->scene->unit;
   if (unit->system == USER_UNIT_NONE) {
@@ -736,7 +733,7 @@ static void knifetool_draw_visible_angles(const 
KnifeTool_OpData *kcd)
     if (min_angle > KNIFE_FLT_EPSBIG) {
       /* Last vertex in screen space. */
       float end_ss[2];
-      ED_view3d_project_float_v2_m4(kcd->region, end, end_ss, 
(float(*)[4])kcd->projmat);
+      ED_view3d_project_float_global(kcd->region, end, end_ss, 
V3D_PROJ_TEST_NOP);
 
       knifetool_draw_angle(kcd,
                            kcd->mdata.corr_prev_cage,
@@ -771,7 +768,7 @@ static void knifetool_draw_visible_angles(const 
KnifeTool_OpData *kcd)
 
       /* Last vertex in screen space. */
       float end_ss[2];
-      ED_view3d_project_float_v2_m4(kcd->region, end, end_ss, 
(float(*)[4])kcd->projmat);
+      ED_view3d_project_float_global(kcd->region, end, end_ss, 
V3D_PROJ_TEST_NOP);
 
       knifetool_draw_angle(kcd,
                            kcd->mdata.corr_prev_cage,
@@ -825,7 +822,7 @@ static void knifetool_draw_visible_angles(const 
KnifeTool_OpData *kcd)
     if (min_angle > KNIFE_FLT_EPSBIG) {
       /* Last vertex in screen space. */
       float end_ss[2];
-      ED_view3d_project_float_v2_m4(kcd->region, end, end_ss, 
(float(*)[4])kcd->projmat);
+      ED_view3d_project_float_global(kcd->region, end, end_ss, 
V3D_PROJ_TEST_NOP);
 
       knifetool_draw_angle(kcd,
                            kcd->curr.cage,
@@ -868,7 +865,7 @@ static void knifetool_draw_visible_angles(const 
KnifeTool_OpData *kcd)
 
     /* Last vertex in screen space. */
     float end_ss[2];
-    ED_view3d_project_float_v2_m4(kcd->region, end, end_ss, 
(float(*)[4])kcd->projmat);
+    ED_view3d_project_float_global(kcd->region, end, end_ss, 
V3D_PROJ_TEST_NOP);
 
     knifetool_draw_angle(
         kcd, kcd->curr.cage, kcd->prev.cage, end, kcd->curr.mval, 
kcd->prev.mval, end_ss, angle);
@@ -914,8 +911,6 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
   GPU_matrix_push_projection();
   GPU_polygon_offset(1.0f, 1.0f);
 
-  GPU_matrix_push();
-
   GPUVertFormat *format = immVertexFormat();
   uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, 
GPU_FETCH_FLOAT);
 
@@ -926,8 +921,8 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     GPU_line_width(2.0);
 
     immBegin(GPU_PRIM_LINES, 2);
-    immVertex3fv(pos, kcd->prev.wcage);
-    immVertex3fv(pos, kcd->curr.wcage);
+    immVertex3fv(pos, kcd->prev.cage);
+    immVertex3fv(pos, kcd->curr.cage);
     immEnd();
   }
 
@@ -936,7 +931,7 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     GPU_point_size(11 * UI_DPI_FAC);
 
     immBegin(GPU_PRIM_POINTS, 1);
-    immVertex3fv(pos, kcd->prev.wcage);
+    immVertex3fv(pos, kcd->prev.cage);
     immEnd();
   }
 
@@ -945,7 +940,7 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     GPU_point_size(9 * UI_DPI_FAC);
 
     immBegin(GPU_PRIM_POINTS, 1);
-    immVertex3fv(pos, kcd->prev.wcage);
+    immVertex3fv(pos, kcd->prev.cage);
     immEnd();
   }
 
@@ -954,7 +949,7 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     GPU_point_size(11 * UI_DPI_FAC);
 
     immBegin(GPU_PRIM_POINTS, 1);
-    immVertex3fv(pos, kcd->curr.wcage);
+    immVertex3fv(pos, kcd->curr.cage);
     immEnd();
   }
   else if (kcd->curr.edge) {
@@ -962,8 +957,8 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     GPU_line_width(2.0);
 
     immBegin(GPU_PRIM_LINES, 2);
-    immVertex3fv(pos, kcd->curr.edge->v1->wcageco);
-    immVertex3fv(pos, kcd->curr.edge->v2->wcageco);
+    immVertex3fv(pos, kcd->curr.edge->v1->cageco);
+    immVertex3fv(pos, kcd->curr.edge->v2->cageco);
     immEnd();
   }
 
@@ -972,7 +967,7 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     GPU_point_size(9 * UI_DPI_FAC);
 
     immBegin(GPU_PRIM_POINTS, 1);
-    immVertex3fv(pos, kcd->curr.wcage);
+    immVertex3fv(pos, kcd->curr.cage);
     immEnd();
   }
 
@@ -995,8 +990,8 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
         continue;
       }
 
-      immVertex3fv(pos, kfe->v1->wcageco);
-      immVertex3fv(pos, kfe->v2->wcageco);
+      immVertex3fv(pos, kfe->v1->cageco);
+      immVertex3fv(pos, kfe->v2->cageco);
     }
 
     immEnd();
@@ -1020,7 +1015,7 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
         continue;
       }
 
-      immVertex3fv(pos, kfv->wcageco);
+      immVertex3fv(pos, kfv->cageco);
     }
 
     immEnd();
@@ -1035,13 +1030,11 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     GPU_line_width(2.0);
 
     immBegin(GPU_PRIM_LINES, 2);
-    immVertex3fv(pos, kcd->snap_ref_edge->v1->wcageco);
-    immVertex3fv(pos, kcd->snap_ref_edge->v2->wcageco);
+    immVertex3fv(pos, kcd->snap_ref_edge->v1->cageco);
+    immVertex3fv(pos, kcd->snap_ref_edge->v2->cageco);
     immEnd();
   }
 
-  GPU_matrix_mul(kcd->ob->obmat);
-
   if (kcd->totlinehit > 0) {
     KnifeLineHit *lh;
     int i, snapped_verts_count, other_verts_count;
@@ -1103,7 +1096,6 @@ static void knifetool_draw(const bContext *UNUSED(C), 
ARegion *UNUSED(region), v
     }
   }
 
-  GPU_matrix_pop();
   GPU_matrix_pop_projection();
 
   /* Reset default. */
@@ -1363,10 +1355,6 @@ static void knife_bvh_raycast_cb(void *userdata,
 
       madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist);
 
-      /* TODO: Remove when converting tool code to world space. */
-      invert_m4_m4_safe_ortho(ob_imat, ob->obmat);
-      mul_m4_v3(ob_imat, hit->co);
-
       kcd->bvh.looptris = em->looptris;
       copy_v2_v2(kcd->bvh.uv, uv);
       kcd->bvh.base_index = b;
@@ -1404,7 +1392,7 @@ static BMFace *knife_bvh_raycast(KnifeTool_OpData *kcd,
 
     face = kcd->bvh.looptris[hit.index][0]->f;
 
-    /* Hits returned in object space. */
+    /* 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);
@@ -1466,7 +1454,7 @@ static BMFace *knife_bvh_raycast_filter(
 
     face = kcd->bvh.looptris[hit.index][0]->f;
 
-    /* Hits returned in object space. */
+    /* 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);
@@ -1490,7 +1478,7 @@ static BMFace *knife_bvh_raycast_

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to