[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