[Bf-blender-cvs] [9d435076746] soc-2021-knife-tools: Knife: Moved code to world space

Cian Jinks noreply at git.blender.org
Sat Sep 11 20:20:31 CEST 2021


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. @@



More information about the Bf-blender-cvs mailing list