Fix batch project bug and expose placemnt options

3.2.0

- added: UI settings to show GP tool settings placement and orientation
- fixed: Bug with reproject orientation settings
- added: show current orientation in batch reproject popup UI (if current is selected)
gpv2
pullusb 2024-06-04 14:33:31 +02:00
parent 01ce06201e
commit 19e26f8cee
5 changed files with 78 additions and 38 deletions

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
3.2.0
- added: UI settings to show GP tool settings placement and orientation
- fixed: Bug with reproject orientation settings
- added: show current orientation in batch reproject popup UI (if current is selected)
3.1.0 3.1.0
- added: Feature to move all strokes using active material to an existing or new layer (material dropdown menu > `Move Material To Layer`) - added: Feature to move all strokes using active material to an existing or new layer (material dropdown menu > `Move Material To Layer`)

View File

@ -15,6 +15,35 @@ def get_scale_matrix(scale):
matscale = matscale_x @ matscale_y @ matscale_z matscale = matscale_x @ matscale_y @ matscale_z
return matscale return matscale
'''
## Old reproject method using Operators:
omode = bpy.context.mode
if all_strokes:
layers_state = [[l, l.hide, l.lock, l.lock_frame] for l in obj.data.layers]
for l in obj.data.layers:
l.hide = False
l.lock = False
l.lock_frame = False
bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
for fnum in frame_list:
bpy.context.scene.frame_current = fnum
bpy.ops.gpencil.select_all(action='SELECT')
bpy.ops.gpencil.reproject(type=proj_type) # 'INVOKE_DEFAULT'
bpy.ops.gpencil.select_all(action='DESELECT')
# restore
if all_strokes:
for layer, hide, lock, lock_frame in layers_state:
layer.hide = hide
layer.lock = lock
layer.lock_frame = lock_frame
bpy.ops.object.mode_set(mode=omode)
'''
def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False): def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False):
'''Reproject - ops method '''Reproject - ops method
:all_stroke: affect hided, locked layers :all_stroke: affect hided, locked layers
@ -72,40 +101,13 @@ def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False
# new_local_coords = utils.matrix_transform(new_world_co_3d, matrix_inv).ravel() # new_local_coords = utils.matrix_transform(new_world_co_3d, matrix_inv).ravel()
s.points.foreach_set('co', new_local_coords) s.points.foreach_set('co', new_local_coords)
bpy.context.area.tag_redraw()
'''
## Old method using Operators:
omode = bpy.context.mode
if all_strokes:
layers_state = [[l, l.hide, l.lock, l.lock_frame] for l in obj.data.layers]
for l in obj.data.layers:
l.hide = False
l.lock = False
l.lock_frame = False
bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
for fnum in frame_list:
bpy.context.scene.frame_current = fnum
bpy.ops.gpencil.select_all(action='SELECT')
bpy.ops.gpencil.reproject(type=proj_type) # 'INVOKE_DEFAULT'
bpy.ops.gpencil.select_all(action='DESELECT')
# restore
if all_strokes:
for layer, hide, lock, lock_frame in layers_state:
layer.hide = hide
layer.lock = lock
layer.lock_frame = lock_frame
bpy.ops.object.mode_set(mode=omode)
'''
if restore_frame: if restore_frame:
bpy.context.scene.frame_current = oframe bpy.context.scene.frame_current = oframe
## Update the layer and redraw all viewports
obj.data.layers.update()
utils.refresh_areas()
def align_global(reproject=True, ref=None, all_strokes=True): def align_global(reproject=True, ref=None, all_strokes=True):
@ -369,14 +371,14 @@ class GPTB_OT_batch_reproject_all_frames(bpy.types.Operator):
name='All Strokes', default=True, name='All Strokes', default=True,
description='Hided and locked layer will also be reprojected') description='Hided and locked layer will also be reprojected')
type: bpy.props.EnumProperty(name='Type', type : bpy.props.EnumProperty(name='Type',
items=(('CURRENT', "Current", ""), items=(('CURRENT', "Current", ""),
('FRONT', "Front", ""), ('FRONT', "Front", ""),
('SIDE', "Side", ""), ('SIDE', "Side", ""),
('TOP', "Top", ""), ('TOP', "Top", ""),
('VIEW', "View", ""), ('VIEW', "View", ""),
('SURFACE', "Surface", ""),
('CURSOR', "Cursor", ""), ('CURSOR', "Cursor", ""),
# ('SURFACE', "Surface", ""),
), ),
default='CURRENT') default='CURRENT')
@ -390,9 +392,29 @@ class GPTB_OT_batch_reproject_all_frames(bpy.types.Operator):
layout = self.layout layout = self.layout
if not context.region_data.view_perspective == 'CAMERA': if not context.region_data.view_perspective == 'CAMERA':
# layout.label(text='Not in camera ! (reprojection is made from view)', icon='ERROR') # layout.label(text='Not in camera ! (reprojection is made from view)', icon='ERROR')
layout.label(text='Reprojection is made from camera, not current view', icon='ERROR') layout.label(text='Reprojection is made from camera', icon='ERROR')
layout.prop(self, "all_strokes") layout.prop(self, "all_strokes")
layout.prop(self, "type") layout.prop(self, "type", text='Project Axis')
## Hint show axis
if self.type == 'CURRENT':
## Show as prop
# row = layout.row()
# row.prop(context.scene.tool_settings.gpencil_sculpt, 'lock_axis', text='Current', icon='INFO')
# row.enabled = False
orient = {
'VIEW' : ['View', 'RESTRICT_VIEW_ON'],
'AXIS_Y': ['front (X-Z)', 'AXIS_FRONT'], # AXIS_Y
'AXIS_X': ['side (Y-Z)', 'AXIS_SIDE'], # AXIS_X
'AXIS_Z': ['top (X-Y)', 'AXIS_TOP'], # AXIS_Z
'CURSOR': ['Cursor', 'PIVOT_CURSOR'],
}
box = layout.box()
axis = context.scene.tool_settings.gpencil_sculpt.lock_axis
box.label(text=orient[axis][0], icon=orient[axis][1])
def execute(self, context): def execute(self, context):

View File

@ -58,6 +58,11 @@ class GPTB_PT_sidebar_panel(Panel):
## flip X cam ## flip X cam
# layout.label(text='! Flipped !') # layout.label(text='! Flipped !')
row = col.row(align=True)
row.prop(context.scene.tool_settings, 'gpencil_stroke_placement_view3d', text='')
row.prop(context.scene.tool_settings.gpencil_sculpt, 'lock_axis', text='')
row = col.row(align=True) row = col.row(align=True)
row.operator('view3d.camera_mirror_flipx', text = 'Mirror Flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT row.operator('view3d.camera_mirror_flipx', text = 'Mirror Flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT

View File

@ -4,7 +4,7 @@ bl_info = {
"name": "GP toolbox", "name": "GP toolbox",
"description": "Tool set for Grease Pencil in animation production", "description": "Tool set for Grease Pencil in animation production",
"author": "Samuel Bernou, Christophe Seux", "author": "Samuel Bernou, Christophe Seux",
"version": (3, 1, 0), "version": (3, 2, 0),
"blender": (4, 0, 0), "blender": (4, 0, 0),
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
"warning": "", "warning": "",

View File

@ -288,13 +288,13 @@ def get_gp_draw_plane(obj=None, orient=None):
plane_co = bpy.context.scene.cursor.location plane_co = bpy.context.scene.cursor.location
mat = bpy.context.scene.cursor.matrix mat = bpy.context.scene.cursor.matrix
elif orient == 'AXIS_Y':#front (X-Z) elif orient in ('AXIS_Y', 'FRONT'): # front (X-Z)
plane_no = Vector((0,1,0)) plane_no = Vector((0,1,0))
elif orient == 'AXIS_X':#side (Y-Z) elif orient in ('AXIS_X', 'SIDE'): # side (Y-Z)
plane_no = Vector((1,0,0)) plane_no = Vector((1,0,0))
elif orient == 'AXIS_Z':#top (X-Y) elif orient in ('AXIS_Z', 'TOP'): # top (X-Y)
plane_no = Vector((0,0,1)) plane_no = Vector((0,0,1))
plane_no.rotate(mat) plane_no.rotate(mat)
@ -853,6 +853,13 @@ def show_message_box(_message = "", _title = "Message Box", _icon = 'INFO'):
### UI utils ### UI utils
# ----------------- # -----------------
def refresh_areas():
for window in bpy.context.window_manager.windows:
for area in window.screen.areas:
area.tag_redraw()
# for area in bpy.context.screen.areas:
# area.tag_redraw()
## kmi draw for addon without delete button ## kmi draw for addon without delete button
def draw_kmi(km, kmi, layout): def draw_kmi(km, kmi, layout):
map_type = kmi.map_type map_type = kmi.map_type