1 # SPDX-License-Identifier: GPL-2.0-or-later
4 from bpy
.types
import Menu
5 from . import utils_core
8 class DynTopoMenu(Menu
):
10 bl_idname
= "VIEW3D_MT_sv3_dyntopo"
13 def poll(self
, context
):
14 return utils_core
.get_mode() == 'SCULPT'
16 def draw(self
, context
):
19 if context
.object.use_dynamic_topology_sculpting
:
20 layout
.row().operator("sculpt.dynamic_topology_toggle",
21 text
="Disable Dynamic Topology")
23 layout
.row().separator()
25 layout
.row().menu(DynDetailMenu
.bl_idname
)
26 layout
.row().menu(DetailMethodMenu
.bl_idname
)
28 layout
.row().separator()
30 layout
.row().operator("sculpt.optimize")
31 if context
.tool_settings
.sculpt
.detail_type_method
== 'CONSTANT':
32 layout
.row().operator("sculpt.detail_flood_fill")
34 layout
.row().menu(SymmetrizeMenu
.bl_idname
)
35 layout
.row().prop(context
.tool_settings
.sculpt
,
36 "use_smooth_shading", toggle
=True)
40 row
.operator_context
= 'INVOKE_DEFAULT'
41 row
.operator("sculpt.dynamic_topology_toggle",
42 text
="Enable Dynamic Topology")
45 class DynDetailMenu(Menu
):
46 bl_label
= "Detail Size"
47 bl_idname
= "VIEW3D_MT_sv3_dyn_detail"
50 settings
= (("40", 40),
57 if bpy
.context
.tool_settings
.sculpt
.detail_type_method
== 'RELATIVE':
58 datapath
= "tool_settings.sculpt.detail_size"
59 slider_setting
= "detail_size"
61 elif bpy
.context
.tool_settings
.sculpt
.detail_type_method
== 'CONSTANT':
62 datapath
= "tool_settings.sculpt.constant_detail_resolution"
63 slider_setting
= "constant_detail_resolution"
65 datapath
= "tool_settings.sculpt.detail_percent"
66 slider_setting
= "detail_percent"
67 settings
= (("100", 100),
74 return settings
, datapath
, slider_setting
76 def draw(self
, context
):
77 settings
, datapath
, slider_setting
= self
.init()
81 layout
.row().prop(context
.tool_settings
.sculpt
,
82 slider_setting
, slider
=True)
83 layout
.row().separator()
85 # add the rest of the menu items
86 for i
in range(len(settings
)):
88 layout
.row(), settings
[i
][0], settings
[i
][1], datapath
,
89 icon
='RADIOBUT_OFF', disable
=True,
90 disable_icon
='RADIOBUT_ON'
94 class DetailMethodMenu(Menu
):
95 bl_label
= "Detail Method"
96 bl_idname
= "VIEW3D_MT_sv3_detail_method_menu"
98 def draw(self
, context
):
100 refine_path
= "tool_settings.sculpt.detail_refine_method"
101 type_path
= "tool_settings.sculpt.detail_type_method"
103 refine_items
= (("Subdivide Edges", 'SUBDIVIDE'),
104 ("Collapse Edges", 'COLLAPSE'),
105 ("Subdivide Collapse", 'SUBDIVIDE_COLLAPSE'))
107 type_items
= (("Relative Detail", 'RELATIVE'),
108 ("Constant Detail", 'CONSTANT'),
109 ("Brush Detail", 'BRUSH'))
111 layout
.row().label(text
="Refine")
112 layout
.row().separator()
114 # add the refine menu items
115 for item
in refine_items
:
117 layout
.row(), item
[0], item
[1],
118 refine_path
, disable
=True,
120 disable_icon
='RADIOBUT_ON'
123 layout
.row().label(text
="")
125 layout
.row().label(text
="Type")
126 layout
.row().separator()
128 # add the type menu items
129 for item
in type_items
:
131 layout
.row(), item
[0], item
[1],
132 type_path
, disable
=True,
133 icon
='RADIOBUT_OFF', disable_icon
='RADIOBUT_ON'
137 class SymmetrizeMenu(Menu
):
138 bl_label
= "Symmetrize"
139 bl_idname
= "VIEW3D_MT_sv3_symmetrize_menu"
141 def draw(self
, context
):
143 path
= "tool_settings.sculpt.symmetrize_direction"
145 # add the the symmetrize operator to the menu
146 layout
.row().operator("sculpt.symmetrize")
147 layout
.row().separator()
149 # add the rest of the menu items
150 for item
in context
.tool_settings
.sculpt
. \
151 bl_rna
.properties
['symmetrize_direction'].enum_items
:
153 layout
.row(), item
.name
, item
.identifier
,
155 icon
='RADIOBUT_OFF', disable_icon
='RADIOBUT_ON'
168 bpy
.utils
.register_class(cls
)
172 bpy
.utils
.unregister_class(cls
)