1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
22 "name": "Hotkey: 'Shift O'",
23 "description": "Proportional Object/Edit Tools",
24 "author": "pitiwazou, meta-androcto",
26 "blender": (2, 80, 0),
27 "location": "3D View Object & Edit modes",
30 "category": "Proportional Edit Pie"
34 from bpy
.types
import (
40 # Proportional Edit Object
41 class PIE_OT_ProportionalEditObj(Operator
):
42 bl_idname
= "proportional_obj.active"
43 bl_label
= "Proportional Edit Object"
44 bl_options
= {'REGISTER', 'UNDO'}
46 def execute(self
, context
):
47 ts
= context
.tool_settings
49 if ts
.use_proportional_edit_objects
is True:
50 ts
.use_proportional_edit_objects
= False
52 elif ts
.use_proportional_edit_objects
is False:
53 ts
.use_proportional_edit_objects
= True
58 class PIE_OT_ProportionalSmoothObj(Operator
):
59 bl_idname
= "proportional_obj.smooth"
60 bl_label
= "Proportional Smooth Object"
61 bl_options
= {'REGISTER', 'UNDO'}
63 def execute(self
, context
):
64 ts
= context
.tool_settings
65 if ts
.use_proportional_edit_objects
is False:
66 ts
.use_proportional_edit_objects
= True
67 ts
.proportional_edit_falloff
= 'SMOOTH'
69 if ts
.proportional_edit_falloff
!= 'SMOOTH':
70 ts
.proportional_edit_falloff
= 'SMOOTH'
74 class PIE_OT_ProportionalSphereObj(Operator
):
75 bl_idname
= "proportional_obj.sphere"
76 bl_label
= "Proportional Sphere Object"
77 bl_options
= {'REGISTER', 'UNDO'}
79 def execute(self
, context
):
80 ts
= context
.tool_settings
81 if ts
.use_proportional_edit_objects
is False:
82 ts
.use_proportional_edit_objects
= True
83 ts
.proportional_edit_falloff
= 'SPHERE'
85 if ts
.proportional_edit_falloff
!= 'SPHERE':
86 ts
.proportional_edit_falloff
= 'SPHERE'
90 class PIE_OT_ProportionalRootObj(Operator
):
91 bl_idname
= "proportional_obj.root"
92 bl_label
= "Proportional Root Object"
93 bl_options
= {'REGISTER', 'UNDO'}
95 def execute(self
, context
):
96 ts
= context
.tool_settings
97 if ts
.use_proportional_edit_objects
is False:
98 ts
.use_proportional_edit_objects
= True
99 ts
.proportional_edit_falloff
= 'ROOT'
101 if ts
.proportional_edit_falloff
!= 'ROOT':
102 ts
.proportional_edit_falloff
= 'ROOT'
106 class PIE_OT_ProportionalSharpObj(Operator
):
107 bl_idname
= "proportional_obj.sharp"
108 bl_label
= "Proportional Sharp Object"
109 bl_options
= {'REGISTER', 'UNDO'}
111 def execute(self
, context
):
112 ts
= context
.tool_settings
113 if ts
.use_proportional_edit_objects
is False:
114 ts
.use_proportional_edit_objects
= True
115 ts
.proportional_edit_falloff
= 'SHARP'
117 if ts
.proportional_edit_falloff
!= 'SHARP':
118 ts
.proportional_edit_falloff
= 'SHARP'
122 class PIE_OT_ProportionalLinearObj(Operator
):
123 bl_idname
= "proportional_obj.linear"
124 bl_label
= "Proportional Linear Object"
125 bl_options
= {'REGISTER', 'UNDO'}
127 def execute(self
, context
):
128 ts
= context
.tool_settings
129 if ts
.use_proportional_edit_objects
is False:
130 ts
.use_proportional_edit_objects
= True
131 ts
.proportional_edit_falloff
= 'LINEAR'
133 if ts
.proportional_edit_falloff
!= 'LINEAR':
134 ts
.proportional_edit_falloff
= 'LINEAR'
138 class PIE_OT_ProportionalConstantObj(Operator
):
139 bl_idname
= "proportional_obj.constant"
140 bl_label
= "Proportional Constant Object"
141 bl_options
= {'REGISTER', 'UNDO'}
143 def execute(self
, context
):
144 ts
= context
.tool_settings
145 if ts
.use_proportional_edit_objects
is False:
146 ts
.use_proportional_edit_objects
= True
147 ts
.proportional_edit_falloff
= 'CONSTANT'
149 if ts
.proportional_edit_falloff
!= 'CONSTANT':
150 ts
.proportional_edit_falloff
= 'CONSTANT'
154 class PIE_OT_ProportionalRandomObj(Operator
):
155 bl_idname
= "proportional_obj.random"
156 bl_label
= "Proportional Random Object"
157 bl_options
= {'REGISTER', 'UNDO'}
159 def execute(self
, context
):
160 ts
= context
.tool_settings
161 if ts
.use_proportional_edit_objects
is False:
162 ts
.use_proportional_edit_objects
= True
163 ts
.proportional_edit_falloff
= 'RANDOM'
165 if ts
.proportional_edit_falloff
!= 'RANDOM':
166 ts
.proportional_edit_falloff
= 'RANDOM'
169 class PIE_OT_ProportionalInverseSquareObj(Operator
):
170 bl_idname
= "proportional_obj.inversesquare"
171 bl_label
= "Proportional Random Object"
172 bl_options
= {'REGISTER', 'UNDO'}
174 def execute(self
, context
):
175 ts
= context
.tool_settings
176 if ts
.use_proportional_edit_objects
is False:
177 ts
.use_proportional_edit_objects
= True
178 ts
.proportional_edit_falloff
= 'INVERSE_SQUARE'
180 if ts
.proportional_edit_falloff
!= 'INVERSE_SQUARE':
181 ts
.proportional_edit_falloff
= 'INVERSE_SQUARE'
185 # Proportional Edit Edit Mode
186 class PIE_OT_ProportionalEditEdt(Operator
):
187 bl_idname
= "proportional_edt.active"
188 bl_label
= "Proportional Edit EditMode"
189 bl_options
= {'REGISTER', 'UNDO'}
191 def execute(self
, context
):
192 ts
= context
.tool_settings
193 ts
.use_proportional_edit ^
= 1
197 class PIE_OT_ProportionalConnectedEdt(Operator
):
198 bl_idname
= "proportional_edt.connected"
199 bl_label
= "Proportional Connected EditMode"
200 bl_options
= {'REGISTER', 'UNDO'}
202 def execute(self
, context
):
203 ts
= context
.tool_settings
204 ts
.use_proportional_connected ^
= 1
208 class PIE_OT_ProportionalProjectedEdt(Operator
):
209 bl_idname
= "proportional_edt.projected"
210 bl_label
= "Proportional projected EditMode"
211 bl_options
= {'REGISTER', 'UNDO'}
213 def execute(self
, context
):
214 ts
= context
.tool_settings
215 ts
.use_proportional_projected ^
= 1
219 class PIE_OT_ProportionalSmoothEdt(Operator
):
220 bl_idname
= "proportional_edt.smooth"
221 bl_label
= "Proportional Smooth EditMode"
222 bl_options
= {'REGISTER', 'UNDO'}
224 def execute(self
, context
):
225 ts
= context
.tool_settings
226 ts
.use_proportional_edit
= True
227 ts
.proportional_edit_falloff
= 'SMOOTH'
231 class PIE_OT_ProportionalSphereEdt(Operator
):
232 bl_idname
= "proportional_edt.sphere"
233 bl_label
= "Proportional Sphere EditMode"
234 bl_options
= {'REGISTER', 'UNDO'}
236 def execute(self
, context
):
237 ts
= context
.tool_settings
238 ts
.use_proportional_edit
= True
239 ts
.proportional_edit_falloff
= 'SPHERE'
243 class PIE_OT_ProportionalRootEdt(Operator
):
244 bl_idname
= "proportional_edt.root"
245 bl_label
= "Proportional Root EditMode"
246 bl_options
= {'REGISTER', 'UNDO'}
248 def execute(self
, context
):
249 ts
= context
.tool_settings
250 ts
.use_proportional_edit
= True
251 ts
.proportional_edit_falloff
= 'ROOT'
255 class PIE_OT_ProportionalSharpEdt(Operator
):
256 bl_idname
= "proportional_edt.sharp"
257 bl_label
= "Proportional Sharp EditMode"
258 bl_options
= {'REGISTER', 'UNDO'}
260 def execute(self
, context
):
261 ts
= context
.tool_settings
262 ts
.use_proportional_edit
= True
263 ts
.proportional_edit_falloff
= 'SHARP'
267 class PIE_OT_ProportionalLinearEdt(Operator
):
268 bl_idname
= "proportional_edt.linear"
269 bl_label
= "Proportional Linear EditMode"
270 bl_options
= {'REGISTER', 'UNDO'}
272 def execute(self
, context
):
273 ts
= context
.tool_settings
274 ts
.use_proportional_edit
= True
275 ts
.proportional_edit_falloff
= 'LINEAR'
279 class PIE_OT_ProportionalConstantEdt(Operator
):
280 bl_idname
= "proportional_edt.constant"
281 bl_label
= "Proportional Constant EditMode"
282 bl_options
= {'REGISTER', 'UNDO'}
284 def execute(self
, context
):
285 ts
= context
.tool_settings
286 ts
.use_proportional_edit
= True
287 ts
.proportional_edit_falloff
= 'CONSTANT'
291 class PIE_OT_ProportionalRandomEdt(Operator
):
292 bl_idname
= "proportional_edt.random"
293 bl_label
= "Proportional Random EditMode"
294 bl_options
= {'REGISTER', 'UNDO'}
296 def execute(self
, context
):
297 ts
= context
.tool_settings
298 ts
.use_proportional_edit
= True
299 ts
.proportional_edit_falloff
= 'RANDOM'
302 class PIE_OT_ProportionalInverseSquareEdt(Operator
):
303 bl_idname
= "proportional_edt.inversesquare"
304 bl_label
= "Proportional Inverese Square EditMode"
305 bl_options
= {'REGISTER', 'UNDO'}
307 def execute(self
, context
):
308 ts
= context
.tool_settings
309 ts
.use_proportional_edit
= True
310 ts
.proportional_edit_falloff
= 'INVERSE_SQUARE'
314 # Pie ProportionalEditObj - O
315 class PIE_MT_ProportionalObj(Menu
):
316 bl_idname
= "PIE_MT_proportional_obj"
317 bl_label
= "Pie Proportional Obj"
319 def draw(self
, context
):
321 pie
= layout
.menu_pie()
323 pie
.operator("proportional_obj.smooth", text
="Smooth", icon
='SMOOTHCURVE')
325 pie
.operator("proportional_obj.sphere", text
="Sphere", icon
='SPHERECURVE')
327 pie
.operator("proportional_obj.linear", text
="Linear", icon
='LINCURVE')
329 pie
.prop(context
.tool_settings
, "use_proportional_edit_objects", text
="Proportional On/Off")
331 pie
.operator("proportional_obj.root", text
="Root", icon
='ROOTCURVE')
333 pie
.operator("proportional_obj.inversesquare", text
="Inverse Square", icon
='INVERSESQUARECURVE')
335 pie
.operator("proportional_obj.sharp", text
="Sharp", icon
='SHARPCURVE')
337 pie
.menu("PIE_MT_proportional_moreob", text
="More", icon
='LINCURVE')
340 # Pie ProportionalEditEdt - O
341 class PIE_MT_ProportionalEdt(Menu
):
342 bl_idname
= "PIE_MT_proportional_edt"
343 bl_label
= "Pie Proportional Edit"
345 def draw(self
, context
):
347 pie
= layout
.menu_pie()
349 pie
.operator("proportional_edt.smooth", text
="Smooth", icon
='SMOOTHCURVE')
351 pie
.operator("proportional_edt.sphere", text
="Sphere", icon
='SPHERECURVE')
353 pie
.operator("proportional_edt.inversesquare", text
="Inverse Square", icon
='INVERSESQUARECURVE')
355 pie
.operator("proportional_edt.active", text
="Proportional On/Off", icon
='PROP_ON')
357 pie
.operator("proportional_edt.connected", text
="Connected", icon
='PROP_CON')
359 pie
.operator("proportional_edt.projected", text
="Projected", icon
='PROP_PROJECTED')
361 pie
.operator("proportional_edt.root", text
="Root", icon
='ROOTCURVE')
363 pie
.menu("PIE_MT_proportional_more", text
="More", icon
='LINCURVE')
366 # Pie ProportionalEditEdt - O
367 class PIE_MT_ProportionalMore(Menu
):
368 bl_idname
= "PIE_MT_proportional_more"
369 bl_label
= "Pie Proportional More"
371 def draw(self
, context
):
373 pie
= layout
.menu_pie()
374 box
= pie
.split().column()
375 box
.operator("proportional_edt.sharp", text
="Sharp", icon
='SHARPCURVE')
376 box
.operator("proportional_edt.linear", text
="Linear", icon
='LINCURVE')
377 box
.operator("proportional_edt.constant", text
="Constant", icon
='NOCURVE')
378 box
.operator("proportional_edt.random", text
="Random", icon
='RNDCURVE')
381 # Pie ProportionalEditEdt2
382 class PIE_MT_proportionalmoreob(Menu
):
383 bl_idname
= "PIE_MT_proportional_moreob"
384 bl_label
= "Pie Proportional More"
386 def draw(self
, context
):
388 pie
= layout
.menu_pie()
389 box
= pie
.split().column()
390 box
.operator("proportional_obj.constant", text
="Constant", icon
='NOCURVE')
391 box
.operator("proportional_obj.random", text
="Random", icon
='RNDCURVE')
396 PIE_OT_ProportionalEditObj
,
397 PIE_OT_ProportionalSmoothObj
,
398 PIE_OT_ProportionalSphereObj
,
399 PIE_OT_ProportionalRootObj
,
400 PIE_OT_ProportionalSharpObj
,
401 PIE_OT_ProportionalLinearObj
,
402 PIE_OT_ProportionalConstantObj
,
403 PIE_OT_ProportionalRandomObj
,
404 PIE_OT_ProportionalInverseSquareObj
,
405 PIE_OT_ProportionalEditEdt
,
406 PIE_OT_ProportionalConnectedEdt
,
407 PIE_OT_ProportionalProjectedEdt
,
408 PIE_OT_ProportionalSmoothEdt
,
409 PIE_OT_ProportionalSphereEdt
,
410 PIE_OT_ProportionalRootEdt
,
411 PIE_OT_ProportionalSharpEdt
,
412 PIE_OT_ProportionalLinearEdt
,
413 PIE_OT_ProportionalConstantEdt
,
414 PIE_OT_ProportionalRandomEdt
,
415 PIE_OT_ProportionalInverseSquareEdt
,
416 PIE_MT_ProportionalObj
,
417 PIE_MT_ProportionalEdt
,
418 PIE_MT_ProportionalMore
,
419 PIE_MT_proportionalmoreob
427 bpy
.utils
.register_class(cls
)
429 wm
= bpy
.context
.window_manager
430 if wm
.keyconfigs
.addon
:
431 # ProportionalEditObj
432 km
= wm
.keyconfigs
.addon
.keymaps
.new(name
='Object Mode')
433 kmi
= km
.keymap_items
.new('wm.call_menu_pie', 'O', 'PRESS', shift
=True)
434 kmi
.properties
.name
= "PIE_MT_proportional_obj"
435 addon_keymaps
.append((km
, kmi
))
437 # ProportionalEditEdt
438 km
= wm
.keyconfigs
.addon
.keymaps
.new(name
='Mesh')
439 kmi
= km
.keymap_items
.new('wm.call_menu_pie', 'O', 'PRESS', shift
=True)
440 kmi
.properties
.name
= "PIE_MT_proportional_edt"
441 addon_keymaps
.append((km
, kmi
))
446 bpy
.utils
.unregister_class(cls
)
448 wm
= bpy
.context
.window_manager
449 kc
= wm
.keyconfigs
.addon
451 for km
, kmi
in addon_keymaps
:
452 km
.keymap_items
.remove(kmi
)
453 addon_keymaps
.clear()
456 if __name__
== "__main__":