diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 52658411fb0..c494590d005 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -142,6 +142,14 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel): col.operator("mesh.spin") col.operator("mesh.screw") + row = col.row(align=True) + props = row.operator("mesh.knife_tool", text="Knife") + props.use_occlude_geometry = True + props.only_select = False + props = row.operator("mesh.knife_tool", text="Select") + props.use_occlude_geometry = False + props.only_select = True + col = layout.column(align=True) col.label(text="Remove:") col.menu("VIEW3D_MT_edit_mesh_delete") diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index 8be0cc0aa36..6155ad1be1c 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -104,8 +104,16 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit) tree->bm = em->bm; tree->epsilon = FLT_EPSILON * 2.0f; tree->flag = flag; - - if (flag & BMBVH_RESPECT_HIDDEN) { + + if (flag & (BMBVH_RESPECT_SELECT)) { + tottri = 0; + for (i = 0; i < em->tottri; i++) { + if (BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_SELECT)) { + tottri++; + } + } + } + else if (flag & (BMBVH_RESPECT_HIDDEN)) { tottri = 0; for (i = 0; i < em->tottri; i++) { if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) { @@ -146,7 +154,14 @@ BMBVHTree *BMBVH_NewBVH(BMEditMesh *em, int flag, Scene *scene, Object *obedit) for (i = 0; i < em->tottri; i++) { - if (flag & BMBVH_RESPECT_HIDDEN) { + + if (flag & BMBVH_RESPECT_SELECT) { + /* note, the arrays wont allign now! take care */ + if (!BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_SELECT)) { + continue; + } + } + else if (flag & BMBVH_RESPECT_HIDDEN) { /* note, the arrays wont allign now! take care */ if (BM_elem_flag_test(em->looptris[i][0]->f, BM_ELEM_HIDDEN)) { continue; diff --git a/source/blender/editors/mesh/editmesh_bvh.h b/source/blender/editors/mesh/editmesh_bvh.h index 2b0a7cc02dd..e2b45062e41 100644 --- a/source/blender/editors/mesh/editmesh_bvh.h +++ b/source/blender/editors/mesh/editmesh_bvh.h @@ -64,7 +64,8 @@ struct BMVert *BMBVH_FindClosestVert(struct BMBVHTree *tree, float *co, float ma enum { BMBVH_USE_CAGE = 1, /* project geometry onto modifier cage */ BMBVH_RETURN_ORIG = 2, /* use with BMBVH_USE_CAGE, returns hits in relation to original geometry */ - BMBVH_RESPECT_HIDDEN = 4 + BMBVH_RESPECT_SELECT = 4, /* restrict to hidden geometry (overrides BMBVH_RESPECT_HIDDEN) */ + BMBVH_RESPECT_HIDDEN = 8 /* omit hidden geometry */ }; #endif /* __EDITBMESH_BVH_H__ */ diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 1f272e83023..9134fe49837 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -71,8 +71,6 @@ #define KMAXDIST 10 /* max mouse distance from edge before not detecting it */ -#define USE_SELECTED_ONLY - /* knifetool operator */ typedef struct KnifeVert { BMVert *v; /* non-NULL if this is an original vert */ @@ -159,8 +157,13 @@ typedef struct knifetool_opdata { BLI_mempool *refs; float projmat[4][4]; - int is_ortho; - int cut_through; + + short is_ortho; + + /* operatpr options */ + char cut_through; /* preference, can be modified at runtime (that feature may go) */ + char only_select; /* set on initialization */ + float clipsta, clipend; enum { @@ -733,15 +736,6 @@ static void knife_add_cut(knifetool_opdata *kcd) if (len_v3v3(kcd->cur.cage, lh->realhit) < FLT_EPSILON * 80) continue; -#if 0 /* not working perfect, ignore for now */ -#ifdef USE_SELECTED_ONLY - /* don't mess up logic by skipping too early */ - if (lh->kfe->e && !BM_elem_flag_test(lh->kfe->e, BM_ELEM_SELECT)) { - continue; - } -#endif -#endif - if (kcd->prev.is_space) { kcd->prev.is_space = 0; copy_v3_v3(kcd->prev.co, lh->hit); @@ -976,13 +970,6 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) lh = kcd->linehits; for (i = 0; i < kcd->totlinehit; i++, lh++) { float sv1[3], sv2[3]; - int do_draw = TRUE; - -#ifdef USE_SELECTED_ONLY - if (!BM_elem_flag_test(lh->f, BM_ELEM_SELECT)) { - do_draw = FALSE; - } -#endif knife_project_v3(kcd, lh->kfe->v1->cageco, sv1); knife_project_v3(kcd, lh->kfe->v2->cageco, sv2); @@ -990,12 +977,12 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) if (len_v2v2(lh->schit, sv1) < kcd->vthresh / 4.0f) { copy_v3_v3(lh->cagehit, lh->kfe->v1->cageco); - if (do_draw) glVertex3fv(lh->cagehit); + glVertex3fv(lh->cagehit); lh->v = lh->kfe->v1; } else if (len_v2v2(lh->schit, sv2) < kcd->vthresh / 4.0f) { copy_v3_v3(lh->cagehit, lh->kfe->v2->cageco); - if (do_draw) glVertex3fv(lh->cagehit); + glVertex3fv(lh->cagehit); lh->v = lh->kfe->v2; } } @@ -1007,13 +994,6 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) glBegin(GL_POINTS); lh = kcd->linehits; for (i = 0; i < kcd->totlinehit; i++, lh++) { - -#ifdef USE_SELECTED_ONLY - if (!BM_elem_flag_test(lh->f, BM_ELEM_SELECT)) { - continue; - } -#endif - glVertex3fv(lh->cagehit); } glEnd(); @@ -2655,11 +2635,11 @@ static void knife_make_cuts(knifetool_opdata *kcd) for (lst = BLI_smallhash_iternew(ehash, &hiter, (uintptr_t *)&e); lst; lst = BLI_smallhash_iternext(&hiter, (uintptr_t *)&e)) { -#ifdef USE_SELECTED_ONLY - if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) { - continue; + if (kcd->only_select) { + if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) { + continue; + } } -#endif sort_by_frac_along(lst, e); for (ref = lst->first; ref; ref = ref->next) { @@ -2673,11 +2653,12 @@ static void knife_make_cuts(knifetool_opdata *kcd) for (lst = BLI_smallhash_iternew(fhash, &hiter, (uintptr_t *)&f); lst; lst = BLI_smallhash_iternext(&hiter, (uintptr_t *)&f)) { -#ifdef USE_SELECTED_ONLY - if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) { - continue; + + if (kcd->only_select) { + if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) { + continue; + } } -#endif knife_make_face_cuts(kcd, f, lst); } @@ -2802,6 +2783,7 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut)) DerivedMesh *cage, *final; SmallHash shash; void *data[3]; + const short only_select = RNA_boolean_get(op->ptr, "only_select"); /* alloc new customdata */ kcd = op->customdata = MEM_callocN(sizeof(knifetool_opdata), "knifetool Modal Op Data"); @@ -2827,7 +2809,11 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut)) cage->foreachMappedVert(cage, cage_mapped_verts_callback, data); BLI_smallhash_release(&shash); - kcd->bmbvh = BMBVH_NewBVH(kcd->em, BMBVH_USE_CAGE | BMBVH_RETURN_ORIG | BMBVH_RESPECT_HIDDEN, scene, obedit); + kcd->bmbvh = BMBVH_NewBVH(kcd->em, + (BMBVH_USE_CAGE | BMBVH_RETURN_ORIG) | + (only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN), + scene, obedit); + kcd->arena = BLI_memarena_new(1 << 15, "knife"); kcd->vthresh = KMAXDIST - 1; kcd->ethresh = KMAXDIST; @@ -2848,6 +2834,7 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut)) /* cut all the way through the mesh if use_occlude_geometry button not pushed */ kcd->cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry"); + kcd->only_select = only_select; knife_pos_data_clear(&kcd->cur); knife_pos_data_clear(&kcd->prev); @@ -2939,7 +2926,7 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, CKEY, KM_PRESS, 0, 0, KNF_MODAL_ANGLE_SNAP_TOGGLE); WM_modalkeymap_add_item(keymap, ZKEY, KM_PRESS, 0, 0, KNF_MODAL_CUT_THROUGH_TOGGLE); - WM_modalkeymap_assign(keymap, "MESH_OT_knifetool"); + WM_modalkeymap_assign(keymap, "MESH_OT_knife_tool"); return keymap; } @@ -3074,11 +3061,11 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } -void MESH_OT_knifetool(wmOperatorType *ot) +void MESH_OT_knife_tool(wmOperatorType *ot) { /* description */ ot->name = "Knife Topology Tool"; - ot->idname = "MESH_OT_knifetool"; + ot->idname = "MESH_OT_knife_tool"; ot->description = "Cut new topology"; /* callbacks */ @@ -3090,5 +3077,6 @@ void MESH_OT_knifetool(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; - RNA_def_boolean(ot->srna, "use_occlude_geometry", 0, "Occlude Geometry", "Only cut the front most geometry"); + RNA_def_boolean(ot->srna, "use_occlude_geometry", TRUE, "Occlude Geometry", "Only cut the front most geometry"); + RNA_def_boolean(ot->srna, "only_select", FALSE, "Only Selected", "Only cut selected geometry"); } diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 706192f882b..772e80fff69 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -209,7 +209,7 @@ void MESH_OT_extrude_faces_indiv(struct wmOperatorType *ot); void MESH_OT_edgering_select(struct wmOperatorType *ot); void MESH_OT_loopcut(struct wmOperatorType *ot); -void MESH_OT_knifetool(struct wmOperatorType *ot); +void MESH_OT_knife_tool(struct wmOperatorType *ot); void MESH_OT_bevel(struct wmOperatorType *ot); void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 145bef56285..7e8c38c9abc 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -156,7 +156,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_select_nth); WM_operatortype_append(MESH_OT_vert_connect); WM_operatortype_append(MESH_OT_vert_slide); - WM_operatortype_append(MESH_OT_knifetool); + WM_operatortype_append(MESH_OT_knife_tool); WM_operatortype_append(MESH_OT_bevel); @@ -347,8 +347,13 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_delete", DELKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "MESH_OT_knifetool", KKEY, KM_PRESS, 0, 0); - //RNA_enum_set(WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_SHIFT, KKEY)->ptr, "type", 2/*KNIFE_MIDPOINT*/); + kmi = WM_keymap_add_item(keymap, "MESH_OT_knife_tool", KKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "use_occlude_geometry", TRUE); + RNA_boolean_set(kmi->ptr, "only_select", FALSE); + + kmi = WM_keymap_add_item(keymap, "MESH_OT_knife_tool", KKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "use_occlude_geometry", FALSE); + RNA_boolean_set(kmi->ptr, "only_select", TRUE); WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);