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 #####
21 from bpy
.props
import (
30 from .ui_panels
import GP_PT_sidebarPanel
32 def get_addon_prefs():
34 addon_name
= os
.path
.splitext(__name__
)[0]
35 addon_prefs
= bpy
.context
.preferences
.addons
[addon_name
].preferences
38 from .timeline_scrub
import GPTS_timeline_settings
, draw_ts_pref
40 ## Addons Preferences Update Panel
41 def update_panel(self
, context
):
43 bpy
.utils
.unregister_class(GP_PT_sidebarPanel
)
46 GP_PT_sidebarPanel
.bl_category
= get_addon_prefs().category
47 bpy
.utils
.register_class(GP_PT_sidebarPanel
)
49 ## keymap binder for rotate canvas
50 def auto_rebind(self
, context
):
54 class GreasePencilAddonPrefs(bpy
.types
.AddonPreferences
):
55 bl_idname
= os
.path
.splitext(__name__
)[0] #'greasepencil-addon' ... __package__ ?
56 # bl_idname = __name__
58 ts
: PointerProperty(type=GPTS_timeline_settings
)
60 category
: StringProperty(
62 description
="Choose a name for the category of the panel",
63 default
="Grease Pencil",
67 use_clic_drag
: BoolProperty(
68 name
='Use click drag directly on points',
69 description
="Change the active tool to 'tweak' during modal, Allow to direct clic-drag points of the box",
72 default_deform_type
: EnumProperty(
73 items
=(('KEY_LINEAR', "Linear (perspective mode)", "Linear interpolation, like corner deform / perspective tools of classic 2D", 'IPO_LINEAR',0),
74 ('KEY_BSPLINE', "Spline (smooth deform)", "Spline interpolation transformation\nBest when lattice is subdivided", 'IPO_CIRC',1),
76 name
='Starting Interpolation', default
='KEY_LINEAR', description
='Choose default interpolation when entering mode')
78 # About interpolation : https://docs.blender.org/manual/en/2.83/animation/shape_keys/shape_keys_panel.html#fig-interpolation-type
80 auto_swap_deform_type
: BoolProperty(
81 name
='Auto swap interpolation mode',
82 description
="Automatically set interpolation to 'spline' when subdividing lattice\n Back to 'linear' when",
85 ## rotate canvas variables
88 canvas_use_hud
: BoolProperty(
90 description
= "Display angle lines and angle value as text on viewport",
94 canvas_use_shortcut
: BoolProperty(
95 name
= "Use Default Shortcut",
96 description
= "Use default shortcut: mouse double-click + modifier",
100 mouse_click
: EnumProperty(
101 name
="Mouse button", description
="click on right/left/middle mouse button in combination with a modifier to trigger alignement",
102 default
='MIDDLEMOUSE',
104 ('RIGHTMOUSE', 'Right click', 'Use click on Right mouse button', 'MOUSE_RMB', 0),
105 ('LEFTMOUSE', 'Left click', 'Use click on Left mouse button', 'MOUSE_LMB', 1),
106 ('MIDDLEMOUSE', 'Mid click', 'Use click on Mid mouse button', 'MOUSE_MMB', 2),
110 use_shift
: BoolProperty(
111 name
= "combine with shift",
112 description
= "add shift",
116 use_alt
: BoolProperty(
117 name
= "combine with alt",
118 description
= "add alt",
122 use_ctrl
: BoolProperty(
123 name
= "combine with ctrl",
124 description
= "add ctrl",
128 rc_angle_step
: FloatProperty(
130 description
="Step the rotation using this angle when using rotate canvas step modifier",
131 default
=0.2617993877991494, # 15
132 min=0.01745329238474369, # 1
133 max=3.1415927410125732, # 180
134 soft_min
=0.01745329238474369, # 1
135 soft_max
=1.5707963705062866, # 90
136 step
=10, precision
=1, subtype
='ANGLE', unit
='ROTATION')
138 def draw(self
, context
):
139 prefs
= get_addon_prefs()
141 # layout.use_property_split = True
142 row
= layout
.row(align
=True)
146 row
= box
.row(align
=True)
147 row
.label(text
="Panel Category:")
148 row
.prop(self
, "category", text
="")
152 row
= box
.row(align
=True)
153 row
.label(text
='Box Deform:')
154 row
.operator("wm.call_menu", text
="", icon
='QUESTION').name
= "GPT_MT_box_deform_doc"
155 box
.prop(self
, "use_clic_drag")
157 box
.prop(self
, "default_deform_type")
158 box
.label(text
="Deformer type can be changed during modal with 'M' key, this is for default behavior", icon
='INFO')
160 box
.prop(self
, "auto_swap_deform_type")
161 box
.label(text
="Once 'M' is hit, auto swap is desactivated to stay in your chosen mode", icon
='INFO')
165 box
.label(text
='Rotate canvas:')
167 box
.prop(self
, "canvas_use_shortcut", text
='Bind Shortcuts')
169 if self
.canvas_use_shortcut
:
172 row
.label(text
="(Auto rebind when changing shortcut)")#icon=""
173 # row.operator("prefs.rebind_shortcut", text='Bind/Rebind shortcuts', icon='FILE_REFRESH')#EVENT_SPACEKEY
174 row
= box
.row(align
= True)
175 row
.prop(self
, "use_ctrl", text
='Ctrl')#, expand=True
176 row
.prop(self
, "use_alt", text
='Alt')#, expand=True
177 row
.prop(self
, "use_shift", text
='Shift')#, expand=True
178 row
.prop(self
, "mouse_click",text
='')#expand=True
180 if not self
.use_ctrl
and not self
.use_alt
and not self
.use_shift
:
181 box
.label(text
="Choose at least one modifier to combine with click (default: Ctrl+Alt)", icon
="ERROR")# INFO
183 if not all((self
.use_ctrl
, self
.use_alt
, self
.use_shift
)):
184 row
= box
.row(align
= True)
186 if not self
.use_ctrl
:
187 snap_key_list
.append('Ctrl')
188 if not self
.use_shift
:
189 snap_key_list
.append('Shift')
191 snap_key_list
.append('Alt')
193 row
.label(text
=f
"Step rotation with: {' or '.join(snap_key_list)}", icon
='DRIVER_ROTATIONAL_DIFFERENCE')
194 row
.prop(self
, "rc_angle_step", text
='Angle Steps')
198 box
.label(text
="No hotkey has been set automatically. Following operators needs to be set manually:", icon
="ERROR")
199 box
.label(text
="view3d.rotate_canvas")
200 box
.prop(self
, 'canvas_use_hud')
204 draw_ts_pref(prefs
.ts
, box
)
208 class GPT_MT_box_deform_doc(bpy
.types
.Menu
):
209 # bl_idname = "OBJECT_MT_custom_menu"
210 bl_label
= "Box Deform Infos Sheet"
212 def draw(self
, context
):
215 #layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
216 #**Behavior from context mode**
217 col
= layout
.column()
218 col
.label(text
='Box Deform Tool')
219 col
.label(text
="Usage:", icon
='MOD_LATTICE')
220 col
.label(text
="Use the shortcut 'Ctrl+T' in available modes (listed below)")
221 col
.label(text
="The lattice box is generated facing your view (be sure to face canvas if you want to stay on it)")
222 col
.label(text
="Use shortcuts below to deform (a help will be displayed in the topbar)")
225 col
.label(text
="Shortcuts:", icon
='HAND')
226 col
.label(text
="Spacebar / Enter : Confirm")
227 col
.label(text
="Delete / Backspace / Tab(twice) / Ctrl+T : Cancel")
228 col
.label(text
="M : Toggle between Linear and Spline mode at any moment")
229 col
.label(text
="1-9 top row number : Subdivide the box")
230 col
.label(text
="Ctrl + arrows-keys : Subdivide the box incrementally in individual X/Y axis")
233 col
.label(text
="Modes and deformation target:", icon
='PIVOT_BOUNDBOX')
234 col
.label(text
="- Object mode : The whole GP object is deformed (including all frames)")
235 col
.label(text
="- GPencil Edit mode : Deform Selected points")
236 col
.label(text
="- Gpencil Paint : Deform last Strokes")
237 # col.label(text="- Lattice edit : Revive the modal after a ctrl+Z")
240 col
.label(text
="Notes:", icon
='TEXT')
241 col
.label(text
="- If you return in box deform after applying (with a ctrl+Z), you need to hit 'Ctrl+T' again to revive the modal.")
242 col
.label(text
="- A cancel warning will be displayed the first time you hit Tab")
244 ### rotate canvas keymap
247 def register_keymaps():
248 pref
= get_addon_prefs()
249 if not pref
.canvas_use_shortcut
:
251 addon
= bpy
.context
.window_manager
.keyconfigs
.addon
253 km
= addon
.keymaps
.new(name
= "3D View", space_type
= "VIEW_3D")
255 if 'view3d.rotate_canvas' not in km
.keymap_items
:
256 km
= addon
.keymaps
.new(name
='3D View', space_type
='VIEW_3D')
257 kmi
= km
.keymap_items
.new('view3d.rotate_canvas',
258 type=pref
.mouse_click
, value
="PRESS", alt
=pref
.use_alt
, ctrl
=pref
.use_ctrl
, shift
=pref
.use_shift
, any
=False)
260 addon_keymaps
.append((km
, kmi
))
262 def unregister_keymaps():
263 for km
, kmi
in addon_keymaps
:
264 km
.keymap_items
.remove(kmi
)
265 addon_keymaps
.clear()
271 GPTS_timeline_settings
,
272 GPT_MT_box_deform_doc
,
273 GreasePencilAddonPrefs
,
278 bpy
.utils
.register_class(cls
)
279 # Force box deform running to false
280 bpy
.context
.preferences
.addons
[os
.path
.splitext(__name__
)[0]].preferences
.boxdeform_running
= False
285 for cls
in reversed(classes
):
286 bpy
.utils
.unregister_class(cls
)