Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'greasepencil_tools/box_deform.py')
-rw-r--r--greasepencil_tools/box_deform.py131
1 files changed, 98 insertions, 33 deletions
diff --git a/greasepencil_tools/box_deform.py b/greasepencil_tools/box_deform.py
index 0ac08987..a9a47ce2 100644
--- a/greasepencil_tools/box_deform.py
+++ b/greasepencil_tools/box_deform.py
@@ -31,6 +31,31 @@ def region_to_location(viewcoords, depthcoords):
from bpy_extras import view3d_utils
return view3d_utils.region_2d_to_location_3d(bpy.context.region, bpy.context.space_data.region_3d, viewcoords, depthcoords)
+def store_cage(self, vg_name):
+ import time
+ unique_id = time.strftime(r'%y%m%d%H%M%S') # ex: 20210711111117
+ # name = f'gp_lattice_{unique_id}'
+ name = f'{self.gp_obj.name}_lat{unique_id}'
+ vg = self.gp_obj.vertex_groups.get(vg_name)
+ if vg:
+ vg.name = name
+ for o in self.other_gp:
+ vg = o.vertex_groups.get(vg_name)
+ if vg:
+ vg.name = name
+
+ self.cage.name = name
+ self.cage.data.name = name
+ mod = self.gp_obj.grease_pencil_modifiers.get('tmp_lattice')
+ if mod:
+ mod.name = name #f'Lattice_{unique_id}'
+ mod.vertex_group = name
+ for o in self.other_gp:
+ mod = o.grease_pencil_modifiers.get('tmp_lattice')
+ if mod:
+ mod.name = name
+ mod.vertex_group = name
+
def assign_vg(obj, vg_name, delete=False):
## create vertex group
vg = obj.vertex_groups.get(vg_name)
@@ -51,6 +76,10 @@ def view_cage(obj):
gp = obj.data
gpl = gp.layers
+ from_obj = bpy.context.mode == 'OBJECT'
+ all_gps = [o for o in bpy.context.selected_objects if o.type == 'GPENCIL']
+ other_gp = [o for o in all_gps if o is not obj]
+
coords = []
initial_mode = bpy.context.mode
@@ -73,13 +102,14 @@ def view_cage(obj):
# get real location
coords.append(obj.matrix_world @ p.co)
- elif bpy.context.mode == 'OBJECT':#object mode -> all points
- for l in gpl:# if l.hide:continue# only visible ? (might break things)
- if not len(l.frames):
- continue#skip frameless layer
- for s in l.active_frame.strokes:
- for p in s.points:
- coords.append(obj.matrix_world @ p.co)
+ elif bpy.context.mode == 'OBJECT': # object mode -> all points of all selected gp objects
+ for gpo in all_gps:
+ for l in gpo.data.layers:# if l.hide:continue# only visible ? (might break things)
+ if not len(l.frames):
+ continue # skip frameless layer
+ for s in l.active_frame.strokes:
+ for p in s.points:
+ coords.append(gpo.matrix_world @ p.co)
elif bpy.context.mode == 'PAINT_GPENCIL':
# get last stroke points coordinated
@@ -189,7 +219,7 @@ def view_cage(obj):
## Master (root) collection
bpy.context.scene.collection.objects.link(cage)
- # spawn cage and align it to view (Again ! align something to a vector !!! argg)
+ # spawn cage and align it to view
r3d = bpy.context.space_data.region_3d
viewmat = r3d.view_matrix
@@ -205,17 +235,28 @@ def view_cage(obj):
lattice.points_v = 2
lattice.points_w = 1
- lattice.interpolation_type_u = lattice_interp#'KEY_LINEAR'-'KEY_BSPLINE'
- lattice.interpolation_type_v = lattice_interp#'KEY_LINEAR'-'KEY_BSPLINE'
- lattice.interpolation_type_w = lattice_interp#'KEY_LINEAR'-'KEY_BSPLINE'
+ lattice.interpolation_type_u = lattice_interp #'KEY_LINEAR'-'KEY_BSPLINE'
+ lattice.interpolation_type_v = lattice_interp
+ lattice.interpolation_type_w = lattice_interp
mod = obj.grease_pencil_modifiers.new('tmp_lattice', 'GP_LATTICE')
+ if from_obj:
+ mods = []
+ for o in other_gp:
+ mods.append( o.grease_pencil_modifiers.new('tmp_lattice', 'GP_LATTICE') )
# move to top if modifiers exists
for _ in range(len(obj.grease_pencil_modifiers)):
bpy.ops.object.gpencil_modifier_move_up(modifier='tmp_lattice')
+ if from_obj:
+ for o in other_gp:
+ for _ in range(len(o.grease_pencil_modifiers)):
+ bpy.ops.object.gpencil_modifier_move_up({'object':o}, modifier='tmp_lattice')
mod.object = cage
+ if from_obj:
+ for m in mods:
+ m.object = cage
if initial_mode == 'PAINT_GPENCIL':
mod.layer = gpl.active.info
@@ -225,29 +266,32 @@ def view_cage(obj):
if bpy.context.mode == 'EDIT_GPENCIL':
mod.vertex_group = vg.name
- #Go in object mode if not already
+ # Go in object mode if not already
if bpy.context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode='OBJECT')
# Store name of deformed object in case of 'revive modal'
cage.vertex_groups.new(name=obj.name)
+ if from_obj:
+ for o in other_gp:
+ cage.vertex_groups.new(name=o.name)
## select and make cage active
# cage.select_set(True)
bpy.context.view_layer.objects.active = cage
- obj.select_set(False)#deselect GP object
- bpy.ops.object.mode_set(mode='EDIT')# go in lattice edit mode
- bpy.ops.lattice.select_all(action='SELECT')# select all points
+ obj.select_set(False) # deselect GP object
+ bpy.ops.object.mode_set(mode='EDIT') # go in lattice edit mode
+ bpy.ops.lattice.select_all(action='SELECT') # select all points
if prefs.use_clic_drag:
## Eventually change tool mode to tweak for direct point editing (reset after before leaving)
- bpy.ops.wm.tool_set_by_id(name="builtin.select")# Tweaktoolcode
+ bpy.ops.wm.tool_set_by_id(name="builtin.select") # Tweaktoolcode
return cage
def back_to_obj(obj, gp_mode, org_lattice_toolset, context):
- if context.mode == 'EDIT_LATTICE' and org_lattice_toolset:# Tweaktoolcode - restore the active tool used by lattice edit..
- bpy.ops.wm.tool_set_by_id(name = org_lattice_toolset)# Tweaktoolcode
+ if context.mode == 'EDIT_LATTICE' and org_lattice_toolset: # Tweaktoolcode - restore the active tool used by lattice edit..
+ bpy.ops.wm.tool_set_by_id(name = org_lattice_toolset) # Tweaktoolcode
# gp object active and selected
bpy.ops.object.mode_set(mode='OBJECT')
@@ -260,7 +304,7 @@ def delete_cage(cage):
bpy.data.objects.remove(cage)
bpy.data.lattices.remove(lattice)
-def apply_cage(gp_obj, cage):
+def apply_cage(gp_obj):
mod = gp_obj.grease_pencil_modifiers.get('tmp_lattice')
multi_user = None
if mod:
@@ -270,7 +314,8 @@ def apply_cage(gp_obj, cage):
other_user = [o for o in bpy.data.objects if o is not gp_obj and o.data is old]
gp_obj.data = gp_obj.data.copy()
- bpy.ops.object.gpencil_modifier_apply(apply_as='DATA', modifier=mod.name)
+ # bpy.ops.object.gpencil_modifier_apply(apply_as='DATA', modifier=mod.name)
+ bpy.ops.object.gpencil_modifier_apply({'object': gp_obj}, apply_as='DATA', modifier=mod.name)
if multi_user:
for o in other_user: # relink
@@ -281,17 +326,22 @@ def apply_cage(gp_obj, cage):
else:
print('tmp_lattice modifier not found to apply...')
- delete_cage(cage)
-
-def cancel_cage(gp_obj, cage):
+def cancel_cage(self):
#remove modifier
- mod = gp_obj.grease_pencil_modifiers.get('tmp_lattice')
+ mod = self.gp_obj.grease_pencil_modifiers.get('tmp_lattice')
if mod:
- gp_obj.grease_pencil_modifiers.remove(mod)
+ self.gp_obj.grease_pencil_modifiers.remove(mod)
else:
- print('tmp_lattice modifier not found to remove...')
+ print(f'tmp_lattice modifier not found to remove on {self.gp_obj.name}')
+
+ for ob in self.other_gp:
+ mod = ob.grease_pencil_modifiers.get('tmp_lattice')
+ if mod:
+ ob.grease_pencil_modifiers.remove(mod)
+ else:
+ print(f'tmp_lattice modifier not found to remove on {ob.name}')
- delete_cage(cage)
+ delete_cage(self.cage)
class GP_OT_latticeGpDeform(bpy.types.Operator):
@@ -413,8 +463,16 @@ valid:Spacebar/Enter, cancel:Del/Backspace/Tab/Ctrl+T"
context.window_manager.boxdeform_running = False
self.restore_prefs(context)
back_to_obj(self.gp_obj, self.gp_mode, self.org_lattice_toolset, context)
- apply_cage(self.gp_obj, self.cage)#must be in object mode
- assign_vg(self.gp_obj, 'lattice_cage_deform_group', delete=True)
+ if event.shift:
+ # Let the cage as is with a unique ID
+ store_cage(self, 'lattice_cage_deform_group')
+ else:
+ apply_cage(self.gp_obj) # must be in object mode
+ assign_vg(self.gp_obj, 'lattice_cage_deform_group', delete=True)
+ for o in self.other_gp:
+ apply_cage(o)
+ assign_vg(o, 'lattice_cage_deform_group', delete=True)
+ delete_cage(self.cage)
# back to original mode
if self.gp_mode != 'OBJECT':
@@ -448,7 +506,7 @@ valid:Spacebar/Enter, cancel:Del/Backspace/Tab/Ctrl+T"
context.window_manager.boxdeform_running = False
self.restore_prefs(context)
back_to_obj(self.gp_obj, self.gp_mode, self.org_lattice_toolset, context)
- cancel_cage(self.gp_obj, self.cage)
+ cancel_cage(self)
assign_vg(self.gp_obj, 'lattice_cage_deform_group', delete=True)
context.area.header_text_set(None)
if self.gp_mode != 'OBJECT':
@@ -523,16 +581,23 @@ valid:Spacebar/Enter, cancel:Del/Backspace/Tab/Ctrl+T"
## silent return
return {'CANCELLED'}
- #paint need VG workaround. object need good shortcut
if context.mode not in ('EDIT_GPENCIL', 'OBJECT', 'PAINT_GPENCIL'):
- # self.report({'WARNING'}, "Works only in following GPencil modes: edit")# ERROR
+ # self.report({'WARNING'}, "Works only in following GPencil modes: object / edit/ paint")# ERROR
## silent return
return {'CANCELLED'}
+
# bpy.ops.ed.undo_push(message="Box deform step")#don't work as expected (+ might be obsolete)
# https://developer.blender.org/D6147 <- undo forget
self.gp_obj = context.object
+
+ self.from_object = context.mode == 'OBJECT'
+ self.all_gps = self.other_gp = []
+ if self.from_object:
+ self.all_gps = [o for o in bpy.context.selected_objects if o.type == 'GPENCIL']
+ self.other_gp = [o for o in self.all_gps if o is not self.gp_obj]
+
# Clean potential failed previous job (delete tmp lattice)
mod = self.gp_obj.grease_pencil_modifiers.get('tmp_lattice')
if mod:
@@ -549,7 +614,7 @@ valid:Spacebar/Enter, cancel:Del/Backspace/Tab/Ctrl+T"
self.report({'ERROR'}, "Grease pencil object already has a lattice modifier (multi-lattices are enabled in blender 2.93+)")
return {'CANCELLED'}
- self.gp_mode = context.mode#store mode for restore
+ self.gp_mode = context.mode # store mode for restore
# All good, create lattice and start modal