[Bf-blender-cvs] [bd6587cb524] soc-2021-knife-tools: Knife: Added support for multi-object edit mode

Cian Jinks noreply at git.blender.org
Sat Jul 24 22:18:47 CEST 2021


Commit: bd6587cb524b24f3f43c4dde2a5eab845f54d82c
Author: Cian Jinks
Date:   Sat Jul 24 21:09:15 2021 +0100
Branches: soc-2021-knife-tools
https://developer.blender.org/rBbd6587cb524b24f3f43c4dde2a5eab845f54d82c

Knife: Added support for multi-object edit mode

Now you can create cuts on all objects in multi object edit mode.
 - If a cut is started on a given object it can interact with that same object.
 - The current object to be cut is switched based on the nearest edge to the mouse cursor, only when the tool mode is idle.
 - When a cut is started in empty space it will interact with the last object the mouse was nearest before the cut was started.

Further improvements could include starting a cut in empty space interacting with the current object the mouse is nearest and allocating BMBVH's for each object on tool init instead of every time an object switch occurs.

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

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 2cd83c8e214..86cc779ec3e 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -47,6 +47,7 @@
 #include "BKE_context.h"
 #include "BKE_editmesh.h"
 #include "BKE_editmesh_bvh.h"
+#include "BKE_layer.h"
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_unit.h"
@@ -109,11 +110,13 @@ typedef struct KnifeColors {
 
 /* Knifetool Operator. */
 typedef struct KnifeVert {
+  Object *ob;
   BMVert *v; /* Non-NULL if this is an original vert. */
   ListBase edges;
   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;
@@ -126,6 +129,7 @@ typedef struct Ref {
 } Ref;
 
 typedef struct KnifeEdge {
+  Object *ob;
   KnifeVert *v1, *v2;
   BMFace *basef; /* Face to restrict face fill to. */
   ListBase faces;
@@ -154,6 +158,7 @@ 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.
@@ -192,9 +197,14 @@ typedef struct KnifeTool_OpData {
   float mval[2];     /* Mouse value with snapping applied. */
 
   Scene *scene;
+
   Object *ob;
   BMEditMesh *em;
 
+  /* Used for swapping current object when in multi-object edit mode. */
+  Base **bases;
+  uint bases_len;
+
   MemArena *arena;
 
   /* Reused for edge-net filling. */
@@ -593,6 +603,8 @@ static void knifetool_draw_angle(const KnifeTool_OpData *kcd,
     copy_v3_v3(dir_tmp, dir_a);
 
     immUniformThemeColor3(TH_WIRE);
+    GPU_line_width(1.0);
+
     immBegin(GPU_PRIM_LINE_STRIP, arc_steps + 1);
     for (int j = 0; j <= arc_steps; j++) {
       madd_v3_v3v3fl(ar_coord, mid, dir_tmp, px_scale);
@@ -865,16 +877,6 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
   GPU_polygon_offset(1.0f, 1.0f);
 
   GPU_matrix_push();
-  GPU_matrix_mul(kcd->ob->obmat);
-
-  if (kcd->mode == MODE_DRAGGING) {
-    if (kcd->is_angle_snapping) {
-      knifetool_draw_angle_snapping(kcd);
-    }
-    else if (kcd->axis_constrained) {
-      knifetool_draw_orientation_locking(kcd);
-    }
-  }
 
   GPUVertFormat *format = immVertexFormat();
   uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -886,8 +888,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.cage);
-    immVertex3fv(pos, kcd->curr.cage);
+    immVertex3fv(pos, kcd->prev.wcage);
+    immVertex3fv(pos, kcd->curr.wcage);
     immEnd();
   }
 
@@ -896,7 +898,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.cage);
+    immVertex3fv(pos, kcd->prev.wcage);
     immEnd();
   }
 
@@ -905,7 +907,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.cage);
+    immVertex3fv(pos, kcd->prev.wcage);
     immEnd();
   }
 
@@ -914,7 +916,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.cage);
+    immVertex3fv(pos, kcd->curr.wcage);
     immEnd();
   }
   else if (kcd->curr.edge) {
@@ -922,8 +924,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->cageco);
-    immVertex3fv(pos, kcd->curr.edge->v2->cageco);
+    immVertex3fv(pos, kcd->curr.edge->v1->wcageco);
+    immVertex3fv(pos, kcd->curr.edge->v2->wcageco);
     immEnd();
   }
 
@@ -932,7 +934,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.cage);
+    immVertex3fv(pos, kcd->curr.wcage);
     immEnd();
   }
 
@@ -940,50 +942,6 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
     GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
   }
 
-  if (kcd->totlinehit > 0) {
-    KnifeLineHit *lh;
-    int i, snapped_verts_count, other_verts_count;
-    float fcol[4];
-
-    GPU_blend(GPU_BLEND_ALPHA);
-
-    GPUVertBuf *vert = GPU_vertbuf_create_with_format(format);
-    GPU_vertbuf_data_alloc(vert, kcd->totlinehit);
-
-    lh = kcd->linehits;
-    for (i = 0, snapped_verts_count = 0, other_verts_count = 0; i < kcd->totlinehit; i++, lh++) {
-      if (lh->v) {
-        GPU_vertbuf_attr_set(vert, pos, snapped_verts_count++, lh->cagehit);
-      }
-      else {
-        GPU_vertbuf_attr_set(vert, pos, kcd->totlinehit - 1 - other_verts_count++, lh->cagehit);
-      }
-    }
-
-    GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO);
-    GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
-
-    /* Draw any snapped verts first. */
-    rgba_uchar_to_float(fcol, kcd->colors.point_a);
-    GPU_batch_uniform_4fv(batch, "color", fcol);
-    GPU_point_size(11 * UI_DPI_FAC);
-    if (snapped_verts_count > 0) {
-      GPU_batch_draw_range(batch, 0, snapped_verts_count);
-    }
-
-    /* Now draw the rest. */
-    rgba_uchar_to_float(fcol, kcd->colors.curpoint_a);
-    GPU_batch_uniform_4fv(batch, "color", fcol);
-    GPU_point_size(7 * UI_DPI_FAC);
-    if (other_verts_count > 0) {
-      GPU_batch_draw_range(batch, snapped_verts_count, other_verts_count);
-    }
-
-    GPU_batch_discard(batch);
-
-    GPU_blend(GPU_BLEND_NONE);
-  }
-
   if (kcd->totkedge > 0) {
     BLI_mempool_iter iter;
     KnifeEdge *kfe;
@@ -999,8 +957,8 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
         continue;
       }
 
-      immVertex3fv(pos, kfe->v1->cageco);
-      immVertex3fv(pos, kfe->v2->cageco);
+      immVertex3fv(pos, kfe->v1->wcageco);
+      immVertex3fv(pos, kfe->v2->wcageco);
     }
 
     immEnd();
@@ -1024,7 +982,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
         continue;
       }
 
-      immVertex3fv(pos, kfv->cageco);
+      immVertex3fv(pos, kfv->wcageco);
     }
 
     immEnd();
@@ -1033,11 +991,64 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
     GPU_batch_discard(batch);
   }
 
+  GPU_matrix_mul(kcd->ob->obmat);
+
+  if (kcd->totlinehit > 0) {
+    KnifeLineHit *lh;
+    int i, snapped_verts_count, other_verts_count;
+    float fcol[4];
+
+    GPU_blend(GPU_BLEND_ALPHA);
+
+    GPUVertBuf *vert = GPU_vertbuf_create_with_format(format);
+    GPU_vertbuf_data_alloc(vert, kcd->totlinehit);
+
+    lh = kcd->linehits;
+    for (i = 0, snapped_verts_count = 0, other_verts_count = 0; i < kcd->totlinehit; i++, lh++) {
+      if (lh->v) {
+        GPU_vertbuf_attr_set(vert, pos, snapped_verts_count++, lh->cagehit);
+      }
+      else {
+        GPU_vertbuf_attr_set(vert, pos, kcd->totlinehit - 1 - other_verts_count++, lh->cagehit);
+      }
+    }
+
+    GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO);
+    GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+
+    /* Draw any snapped verts first. */
+    rgba_uchar_to_float(fcol, kcd->colors.point_a);
+    GPU_batch_uniform_4fv(batch, "color", fcol);
+    GPU_point_size(11 * UI_DPI_FAC);
+    if (snapped_verts_count > 0) {
+      GPU_batch_draw_range(batch, 0, snapped_verts_count);
+    }
+
+    /* Now draw the rest. */
+    rgba_uchar_to_float(fcol, kcd->colors.curpoint_a);
+    GPU_batch_uniform_4fv(batch, "color", fcol);
+    GPU_point_size(7 * UI_DPI_FAC);
+    if (other_verts_count > 0) {
+      GPU_batch_draw_range(batch, snapped_verts_count, other_verts_count);
+    }
+
+    GPU_batch_discard(batch);
+
+    GPU_blend(GPU_BLEND_NONE);
+  }
+
   immUnbindProgram();
 
   GPU_depth_test(GPU_DEPTH_NONE);
 
   if (kcd->mode == MODE_DRAGGING) {
+    if (kcd->is_angle_snapping) {
+      knifetool_draw_angle_snapping(kcd);
+    }
+    else if (kcd->axis_constrained) {
+      knifetool_draw_orientation_locking(kcd);
+    }
+
     if (kcd->show_dist_angle) {
       knifetool_draw_dist_angle(kcd);
     }
@@ -1355,17 +1366,24 @@ static KnifeVert *new_knife_vert(KnifeTool_OpData *kcd, const float co[3], const
   KnifeVert *kfv = BLI_mempool_calloc(kcd->kverts);
 
   kcd->totkvert++;
+  kfv->ob = kcd->ob;
 
   copy_v3_v3(kfv->co, co);
   copy_v3_v3(kfv->cageco, cageco);
+  copy_v3_v3(kfv->wcageco, cageco);
+  mul_m4_v3(kcd->ob->obmat, kfv->wcageco);
 
   return kfv;
 }
 
 static KnifeEdge *new_knife_edge(KnifeTool_OpData *kcd)
 {
+  KnifeEdge *kfe = BLI_mempool_calloc(kcd->kedges);
+
   kcd->totkedge++;
-  return BLI_mempool_calloc(kcd->kedges);
+  kfe->ob = kcd->ob;
+
+  return kfe;
 }
 
 /* Get a KnifeVert wrapper for an existing BMVert. */
@@ -1958,7 +1976,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
   /* Put list of cutting edges for a face into fhash, keyed by face. */
   BLI_mempool_iternew(kcd->kedges, &iter);
   for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
-    if (kfe->is_invalid) {
+    if (kfe->is_invalid || kfe->ob != kcd->ob) {
       continue;
     }
 
@@ -1984,7 +2002,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
   /* Put list of splitting vertices for an edge into ehash, keyed by edge. */
   BLI_mempool_iternew(kcd->kverts, &iter);
   for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) {
-    if (kfv->v || kfv->is_invalid) {
+    if (kfv->v || kfv->is_invalid || kfv->ob != kcd->ob) {
       continue; /* Already have a BMVert. */
     }
     for (ref = kfv->edges.first; ref; ref = ref->next) {
@@ -3423,7 +3441,8 @@ static bool knife_snap_update_from_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list