Object: new add object tool, currently for primitive types

- Interactively adding primitives with two clicks.
- Scene orientation used for new objects.
- Depth [view-plane, axis-plane, surface]
- Origin [base, center]
- Primitive types [cube, cylinder, cone, uv-sphere, ico-sphere ]
- Settings for object types in the top-bar.

Shortcuts:

- Snapping (Ctrl).
- Constrain 1:1 aspect (Shift).
- Toggle center (Alt).

Part of T57210 design task.
This commit is contained in:
Campbell Barton 2020-05-28 14:34:17 +10:00
parent 16943c0146
commit 122cb1aea8
Notes: blender-bot 2023-02-14 06:27:47 +01:00
Referenced by issue #78425, New Add Object tool: Size parameter in the Redo panel does not match the real size of the object
Referenced by issue #57210, Add Object Tools Todo
9 changed files with 1365 additions and 24 deletions

View File

@ -4945,6 +4945,32 @@ def km_transform_modal_map(_params):
return keymap
def km_view3d_interactive_add_tool_modal_map(_params):
items = []
keymap = (
"View3D Placement Modal Map",
{"space_type": 'EMPTY', "region_type": 'WINDOW', "modal": True},
{"items": items},
)
items.extend([
("FIXED_ASPECT_ON", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None),
("FIXED_ASPECT_OFF", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None),
("FIXED_ASPECT_ON", {"type": 'RIGHT_ALT', "value": 'PRESS', "any": True}, None),
("FIXED_ASPECT_OFF", {"type": 'RIGHT_ALT', "value": 'RELEASE', "any": True}, None),
("PIVOT_CENTER_ON", {"type": 'LEFT_SHIFT', "value": 'PRESS', "any": True}, None),
("PIVOT_CENTER_OFF", {"type": 'LEFT_SHIFT', "value": 'RELEASE', "any": True}, None),
("PIVOT_CENTER_ON", {"type": 'RIGHT_SHIFT', "value": 'PRESS', "any": True}, None),
("PIVOT_CENTER_OFF", {"type": 'RIGHT_SHIFT', "value": 'RELEASE', "any": True}, None),
("SNAP_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None),
("SNAP_OFF", {"type": 'LEFT_CTRL', "value": 'RELEASE', "any": True}, None),
("SNAP_ON", {"type": 'RIGHT_CTRL', "value": 'PRESS', "any": True}, None),
("SNAP_OFF", {"type": 'RIGHT_CTRL', "value": 'RELEASE', "any": True}, None),
])
return keymap
def km_view3d_gesture_circle(_params):
items = []
keymap = (
@ -5855,13 +5881,14 @@ def km_3d_view_tool_edit_armature_extrude_to_cursor(params):
)
def km_3d_view_tool_edit_mesh_add_cube(params):
def km_3d_view_tool_interactive_add(params):
return (
"3D View Tool: Edit Mesh, Add Cube",
"3D View Tool: Object, Add Primitive",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
("view3d.cursor3d", {"type": params.tool_mouse, "value": 'CLICK'}, None),
("mesh.primitive_cube_add_gizmo", {"type": params.tool_tweak, "value": 'ANY'}, None),
("view3d.interactive_add", {"type": params.tool_tweak, "value": 'ANY', "any": True},
{"properties": [("wait_for_input", False)]}),
]},
)
@ -6674,6 +6701,7 @@ def generate_keymaps(params=None):
km_eyedropper_modal_map(params),
km_eyedropper_colorramp_pointsampling_map(params),
km_transform_modal_map(params),
km_view3d_interactive_add_tool_modal_map(params),
km_view3d_gesture_circle(params),
km_gesture_border(params),
km_gesture_zoom_border(params),
@ -6733,6 +6761,7 @@ def generate_keymaps(params=None):
km_3d_view_tool_scale(params),
km_3d_view_tool_shear(params),
km_3d_view_tool_measure(params),
km_3d_view_tool_interactive_add(params),
km_3d_view_tool_pose_breakdowner(params),
km_3d_view_tool_pose_push(params),
km_3d_view_tool_pose_relax(params),
@ -6741,7 +6770,6 @@ def generate_keymaps(params=None):
km_3d_view_tool_edit_armature_bone_envelope(params),
km_3d_view_tool_edit_armature_extrude(params),
km_3d_view_tool_edit_armature_extrude_to_cursor(params),
km_3d_view_tool_edit_mesh_add_cube(params),
km_3d_view_tool_edit_mesh_extrude_region(params),
km_3d_view_tool_edit_mesh_extrude_dissolve_and_intersect(params),
km_3d_view_tool_edit_mesh_extrude_along_normals(params),

View File

@ -436,10 +436,124 @@ class _defs_view3d_select:
)
class _defs_view3d_add:
# Layout tweaks here would be good to avoid,
# this shows limits in layout engine, as buttons are using a lot of space.
@staticmethod
def draw_settings_interactive_add(layout, tool):
props = tool.operator_properties("view3d.interactive_add")
row = layout.row()
row.scale_x = 0.8
row.label(text="Depth:")
row = layout.row()
row.scale_x = 0.9
row.prop(props, "plane_depth", text="")
row = layout.row()
row.prop(props, "plane_axis", text="")
row = layout.row()
row.scale_x = 0.7
row.prop(props, "plane_origin")
@ToolDef.from_fn
def cube_add():
def draw_settings(_context, layout, tool):
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
return dict(
idname="builtin.primitive_cube_add",
label="Add Cube",
icon="ops.mesh.primitive_cube_add_gizmo",
description=(
"Add cube to mesh interactively"
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def cone_add():
def draw_settings(_context, layout, tool):
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
props = tool.operator_properties("mesh.primitive_cone_add")
layout.prop(props, "vertices")
layout.prop(props, "end_fill_type")
return dict(
idname="builtin.primitive_cone_add",
label="Add Cone",
icon="ops.mesh.primitive_cube_add_gizmo",
description=(
"Add cone to mesh interactively"
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def cylinder_add():
def draw_settings(_context, layout, tool):
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
props = tool.operator_properties("mesh.primitive_cylinder_add")
layout.prop(props, "vertices")
layout.prop(props, "end_fill_type")
return dict(
idname="builtin.primitive_cylinder_add",
label="Add Cylinder",
icon="ops.mesh.primitive_cylinder_add_gizmo",
description=(
"Add cylinder to mesh interactively"
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def uv_sphere_add():
def draw_settings(_context, layout, tool):
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
props = tool.operator_properties("mesh.primitive_uv_sphere_add")
layout.prop(props, "segments")
layout.prop(props, "ring_count")
return dict(
idname="builtin.primitive_uv_sphere_add",
label="Add UV Sphere",
icon="ops.mesh.primitive_sphere_add_gizmo",
description=(
"Add cylinder to mesh interactively"
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
@ToolDef.from_fn
def ico_sphere_add():
def draw_settings(_context, layout, tool):
_defs_view3d_add.draw_settings_interactive_add(layout, tool)
props = tool.operator_properties("mesh.primitive_ico_sphere_add")
layout.prop(props, "subdivisions")
return dict(
idname="builtin.primitive_ico_sphere_add",
label="Add Ico Sphere",
icon="ops.mesh.primitive_sphere_add_gizmo",
description=(
"Add cylinder to mesh interactively"
),
widget="VIEW3D_GGT_placement",
keymap="3D View Tool: Object, Add Primitive",
draw_settings=draw_settings,
)
# -----------------------------------------------------------------------------
# Object Modes (named based on context.mode)
class _defs_edit_armature:
@ToolDef.from_fn
@ -497,19 +611,6 @@ class _defs_edit_armature:
class _defs_edit_mesh:
@ToolDef.from_fn
def cube_add():
return dict(
idname="builtin.add_cube",
label="Add Cube",
icon="ops.mesh.primitive_cube_add_gizmo",
description=(
"Add cube to mesh interactively"
),
widget=None,
keymap=(),
)
@ToolDef.from_fn
def rip_region():
def draw_settings(_context, layout, tool):
@ -2147,6 +2248,14 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
),
)
_tools_view3d_add = (
_defs_view3d_add.cube_add,
_defs_view3d_add.cone_add,
_defs_view3d_add.cylinder_add,
_defs_view3d_add.uv_sphere_add,
_defs_view3d_add.ico_sphere_add,
)
_tools_default = (
*_tools_select,
_defs_view3d_generic.cursor,
@ -2165,6 +2274,9 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
],
'OBJECT': [
*_tools_default,
None,
_tools_view3d_add,
],
'POSE': [
*_tools_default,
@ -2193,6 +2305,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
'EDIT_MESH': [
*_tools_default,
None,
_tools_view3d_add,
None,
(
_defs_edit_mesh.extrude,
_defs_edit_mesh.extrude_dissolve_and_intersect,

View File

@ -74,6 +74,7 @@ typedef struct SnapGizmo3D {
int snap_on;
bool invert_snap;
#endif
int use_snap_override;
} SnapGizmo3D;
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
@ -211,6 +212,23 @@ SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(Scene *scene,
return gizmo_snap->snap_context_v3d;
}
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz)
{
SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
return gizmo_snap->invert_snap;
}
void ED_gizmotypes_snap_3d_toggle_set(wmGizmo *gz, bool enable)
{
SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
gizmo_snap->use_snap_override = (int)enable;
}
void ED_gizmotypes_snap_3d_toggle_clear(wmGizmo *gz)
{
SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
gizmo_snap->use_snap_override = -1;
}
short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
struct Depsgraph *depsgraph,
const ARegion *region,
@ -221,21 +239,30 @@ short ED_gizmotypes_snap_3d_update(wmGizmo *gz,
float r_nor[3])
{
SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
Scene *scene = DEG_get_input_scene(depsgraph);
float co[3], no[3];
short snap_elem = 0;
int snap_elem_index[3] = {-1, -1, -1};
int index = -1;
if (gizmo_snap->use_snap_override != -1) {
if (gizmo_snap->use_snap_override == false) {
gizmo_snap->snap_elem = 0;
return 0;
}
}
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
if (wm) {
gizmo_snap->invert_snap = invert_snap(gz, wm, wm->winactive->eventstate);
}
Scene *scene = DEG_get_input_scene(depsgraph);
const ToolSettings *ts = scene->toolsettings;
if (gizmo_snap->invert_snap != !(ts->snap_flag & SCE_SNAP)) {
gizmo_snap->snap_elem = 0;
return 0;
if (gizmo_snap->use_snap_override == -1) {
const ToolSettings *ts = scene->toolsettings;
if (gizmo_snap->invert_snap != !(ts->snap_flag & SCE_SNAP)) {
gizmo_snap->snap_elem = 0;
return 0;
}
}
#else
UNUSED_VARS(wm);
@ -328,6 +355,8 @@ static void gizmo_snap_setup(wmGizmo *gz)
gizmo_snap->prop_elem_index = RNA_struct_find_property(gz->ptr, "snap_elem_index");
gizmo_snap->prop_snap_force = RNA_struct_find_property(gz->ptr, "snap_elements_force");
gizmo_snap->use_snap_override = -1;
/* Prop fallback. */
WM_gizmo_target_property_def_rna(gz, "snap_elements", gz->ptr, "snap_elements_force", -1);
@ -381,7 +410,7 @@ static int gizmo_snap_test_select(bContext *C, wmGizmo *gz, const int mval[2])
SnapGizmo3D *gizmo_snap = (SnapGizmo3D *)gz;
#ifdef USE_SNAP_DETECT_FROM_KEYMAP_HACK
wmWindowManager *wm = CTX_wm_manager(C);
bool invert = invert_snap(gz, wm, wm->winactive->eventstate);
const bool invert = invert_snap(gz, wm, wm->winactive->eventstate);
if (gizmo_snap->invert_snap == invert && gizmo_snap->mval[0] == mval[0] &&
gizmo_snap->mval[1] == mval[1]) {
/* Performance, do not update. */

View File

@ -261,6 +261,11 @@ struct SnapObjectContext *ED_gizmotypes_snap_3d_context_ensure(struct Scene *sce
const struct ARegion *region,
const struct View3D *v3d,
struct wmGizmo *gz);
bool ED_gizmotypes_snap_3d_invert_snap_get(struct wmGizmo *gz);
void ED_gizmotypes_snap_3d_toggle_set(struct wmGizmo *gz, bool enable);
void ED_gizmotypes_snap_3d_toggle_clear(struct wmGizmo *gz);
short ED_gizmotypes_snap_3d_update(struct wmGizmo *gz,
struct Depsgraph *depsgraph,
const struct ARegion *region,

View File

@ -64,6 +64,7 @@ set(SRC
view3d_header.c
view3d_iterators.c
view3d_ops.c
view3d_placement.c
view3d_project.c
view3d_select.c
view3d_snap.c

View File

@ -675,6 +675,8 @@ static void view3d_widgets(void)
WM_gizmogrouptype_append(VIEW3D_GGT_ruler);
WM_gizmotype_append(VIEW3D_GT_ruler_item);
WM_gizmogrouptype_append(VIEW3D_GGT_placement);
WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_navigate);
WM_gizmotype_append(VIEW3D_GT_navigate_rotate);
}

View File

@ -213,6 +213,7 @@ void viewrotate_modal_keymap(struct wmKeyConfig *keyconf);
void viewmove_modal_keymap(struct wmKeyConfig *keyconf);
void viewzoom_modal_keymap(struct wmKeyConfig *keyconf);
void viewdolly_modal_keymap(struct wmKeyConfig *keyconf);
void viewplace_modal_keymap(struct wmKeyConfig *keyconf);
/* view3d_buttons.c */
void VIEW3D_OT_object_mode_pie_or_toggle(struct wmOperatorType *ot);
@ -243,6 +244,9 @@ void VIEW3D_OT_snap_cursor_to_center(struct wmOperatorType *ot);
void VIEW3D_OT_snap_cursor_to_selected(struct wmOperatorType *ot);
void VIEW3D_OT_snap_cursor_to_active(struct wmOperatorType *ot);
/* view3d_placement.c */
void VIEW3D_OT_interactive_add(struct wmOperatorType *ot);
/* space_view3d.c */
extern const char *view3d_context_dir[]; /* doc access */
@ -268,6 +272,8 @@ void VIEW3D_OT_ruler_remove(struct wmOperatorType *ot);
void VIEW3D_GT_navigate_rotate(struct wmGizmoType *gzt);
void VIEW3D_GGT_placement(struct wmGizmoGroupType *gzgt);
/* workaround for trivial but noticeable camera bug caused by imprecision
* between view border calculation in 2D/3D space, workaround for bug [#28037].
* without this define we get the old behavior which is to try and align them

View File

@ -211,6 +211,8 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_snap_cursor_to_selected);
WM_operatortype_append(VIEW3D_OT_snap_cursor_to_active);
WM_operatortype_append(VIEW3D_OT_interactive_add);
WM_operatortype_append(VIEW3D_OT_toggle_shading);
WM_operatortype_append(VIEW3D_OT_toggle_xray);
WM_operatortype_append(VIEW3D_OT_toggle_matcap_flip);
@ -234,4 +236,5 @@ void view3d_keymap(wmKeyConfig *keyconf)
viewmove_modal_keymap(keyconf);
viewzoom_modal_keymap(keyconf);
viewdolly_modal_keymap(keyconf);
viewplace_modal_keymap(keyconf);
}

File diff suppressed because it is too large Load Diff