1 # SPDX-FileCopyrightText: 2017-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 from bpy
.types
import Menu
7 from . import utils_core
10 class DynTopoMenu(Menu
):
12 bl_idname
= "VIEW3D_MT_sv3_dyntopo"
15 def poll(self
, context
):
16 return utils_core
.get_mode() == 'SCULPT'
18 def draw(self
, context
):
21 if context
.object.use_dynamic_topology_sculpting
:
22 layout
.row().operator("sculpt.dynamic_topology_toggle",
23 text
="Disable Dynamic Topology")
25 layout
.row().separator()
27 layout
.row().menu(DynDetailMenu
.bl_idname
)
28 layout
.row().menu(DetailMethodMenu
.bl_idname
)
30 layout
.row().separator()
32 layout
.row().operator("sculpt.optimize")
33 if context
.tool_settings
.sculpt
.detail_type_method
== 'CONSTANT':
34 layout
.row().operator("sculpt.detail_flood_fill")
36 layout
.row().menu(SymmetrizeMenu
.bl_idname
)
37 layout
.row().prop(context
.tool_settings
.sculpt
,
38 "use_smooth_shading", toggle
=True)
42 row
.operator_context
= 'INVOKE_DEFAULT'
43 row
.operator("sculpt.dynamic_topology_toggle",
44 text
="Enable Dynamic Topology")
47 class DynDetailMenu(Menu
):
48 bl_label
= "Detail Size"
49 bl_idname
= "VIEW3D_MT_sv3_dyn_detail"
52 settings
= (("40", 40),
59 if bpy
.context
.tool_settings
.sculpt
.detail_type_method
== 'RELATIVE':
60 datapath
= "tool_settings.sculpt.detail_size"
61 slider_setting
= "detail_size"
63 elif bpy
.context
.tool_settings
.sculpt
.detail_type_method
== 'CONSTANT':
64 datapath
= "tool_settings.sculpt.constant_detail_resolution"
65 slider_setting
= "constant_detail_resolution"
67 datapath
= "tool_settings.sculpt.detail_percent"
68 slider_setting
= "detail_percent"
69 settings
= (("100", 100),
76 return settings
, datapath
, slider_setting
78 def draw(self
, context
):
79 settings
, datapath
, slider_setting
= self
.init()
83 layout
.row().prop(context
.tool_settings
.sculpt
,
84 slider_setting
, slider
=True)
85 layout
.row().separator()
87 # add the rest of the menu items
88 for i
in range(len(settings
)):
90 layout
.row(), settings
[i
][0], settings
[i
][1], datapath
,
91 icon
='RADIOBUT_OFF', disable
=True,
92 disable_icon
='RADIOBUT_ON'
96 class DetailMethodMenu(Menu
):
97 bl_label
= "Detail Method"
98 bl_idname
= "VIEW3D_MT_sv3_detail_method_menu"
100 def draw(self
, context
):
102 refine_path
= "tool_settings.sculpt.detail_refine_method"
103 type_path
= "tool_settings.sculpt.detail_type_method"
105 refine_items
= (("Subdivide Edges", 'SUBDIVIDE'),
106 ("Collapse Edges", 'COLLAPSE'),
107 ("Subdivide Collapse", 'SUBDIVIDE_COLLAPSE'))
109 type_items
= (("Relative Detail", 'RELATIVE'),
110 ("Constant Detail", 'CONSTANT'),
111 ("Brush Detail", 'BRUSH'))
113 layout
.row().label(text
="Refine")
114 layout
.row().separator()
116 # add the refine menu items
117 for item
in refine_items
:
119 layout
.row(), item
[0], item
[1],
120 refine_path
, disable
=True,
122 disable_icon
='RADIOBUT_ON'
125 layout
.row().label(text
="")
127 layout
.row().label(text
="Type")
128 layout
.row().separator()
130 # add the type menu items
131 for item
in type_items
:
133 layout
.row(), item
[0], item
[1],
134 type_path
, disable
=True,
135 icon
='RADIOBUT_OFF', disable_icon
='RADIOBUT_ON'
139 class SymmetrizeMenu(Menu
):
140 bl_label
= "Symmetrize"
141 bl_idname
= "VIEW3D_MT_sv3_symmetrize_menu"
143 def draw(self
, context
):
145 path
= "tool_settings.sculpt.symmetrize_direction"
147 # add the the symmetrize operator to the menu
148 layout
.row().operator("sculpt.symmetrize")
149 layout
.row().separator()
151 # add the rest of the menu items
152 for item
in context
.tool_settings
.sculpt
. \
153 bl_rna
.properties
['symmetrize_direction'].enum_items
:
155 layout
.row(), item
.name
, item
.identifier
,
157 icon
='RADIOBUT_OFF', disable_icon
='RADIOBUT_ON'
170 bpy
.utils
.register_class(cls
)
174 bpy
.utils
.unregister_class(cls
)