remap relative off, realign obj
1.1.0: - Important change : Remap relative is now disabled by default in addon preferences - feat: Add realign operator in sidebar with reproject as true by default - UI: Batch reproject all frames is now in menus. Same places as native reprojectgpv2
parent
492095d333
commit
bf85582f28
|
@ -5,6 +5,15 @@ from math import pi
|
|||
import numpy as np
|
||||
from time import time
|
||||
|
||||
|
||||
def get_scale_matrix(scale):
|
||||
# recreate a neutral mat scale
|
||||
matscale_x = Matrix.Scale(scale[0], 4,(1,0,0))
|
||||
matscale_y = Matrix.Scale(scale[1], 4,(0,1,0))
|
||||
matscale_z = Matrix.Scale(scale[2], 4,(0,0,1))
|
||||
matscale = matscale_x @ matscale_y @ matscale_z
|
||||
return matscale
|
||||
|
||||
def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False):
|
||||
'''Reproject - ops method
|
||||
:all_stroke: affect hided, locked layers
|
||||
|
@ -23,11 +32,13 @@ def batch_reproject(obj, proj_type='VIEW', all_strokes=True, restore_frame=False
|
|||
l.lock_frame = False
|
||||
|
||||
bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
|
||||
# TODO : need to toggle visible and unlock all layers before attacking, and store restore.
|
||||
|
||||
for l in obj.data.layers:
|
||||
for f in l.frames:
|
||||
if not len(f.strokes):
|
||||
continue
|
||||
bpy.context.scene.frame_set(f.frame_number)
|
||||
|
||||
# switch to edit to reproject through ops
|
||||
bpy.ops.gpencil.select_all(action='SELECT')
|
||||
bpy.ops.gpencil.reproject(type=proj_type) # default is VIEW
|
||||
|
@ -211,7 +222,7 @@ class GPTB_OT_realign(bpy.types.Operator):
|
|||
description='Reproject stroke on the new alignment')
|
||||
|
||||
all_strokes : bpy.props.BoolProperty(
|
||||
name='All Strokes', default=False,
|
||||
name='All Strokes', default=True,
|
||||
description='Hided and locked layer will also be reprojected')
|
||||
|
||||
## add option to bake strokes if rotation anim is not constant ? might generate too many Keyframes
|
||||
|
@ -237,13 +248,14 @@ class GPTB_OT_realign(bpy.types.Operator):
|
|||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text='Realign the GP : Front axis facing active camera')
|
||||
if self.alert:
|
||||
layout.label(text=self.alert, icon='INFO')
|
||||
layout.label(text=self.alert, icon='ERROR')
|
||||
layout.label(text='(rotations key will be overwritten to face camera)')
|
||||
|
||||
layout.separator()
|
||||
layout.prop(self, "reproject")
|
||||
layout.label(text='Realign the GP front axis with active camera')
|
||||
if self.reproject:
|
||||
layout.label(text='After Realigning, reproject each frames on front axis')
|
||||
if not context.region_data.view_perspective == 'CAMERA':
|
||||
layout.label(text='Not in camera ! (reprojection is made from view)', icon='ERROR')
|
||||
layout.prop(self, "all_strokes")
|
||||
|
@ -256,7 +268,7 @@ class GPTB_OT_realign(bpy.types.Operator):
|
|||
if o.animation_data and o.animation_data.action:
|
||||
if o.animation_data.action.fcurves.find('rotation_euler') or o.animation_data.action.fcurves.find('rotation_quaternion'):
|
||||
align_all_frames(reproject=self.reproject)
|
||||
|
||||
|
||||
bpy.context.scene.frame_current = oframe
|
||||
print(f'\nAnim realign ({time()-t0:.2f}s)')
|
||||
return
|
||||
|
@ -279,11 +291,9 @@ class GPTB_OT_batch_reproject_all_frames(bpy.types.Operator):
|
|||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.object and context.object.type == 'GPENCIL'
|
||||
|
||||
# reproject : bpy.props.BoolProperty(name='Reproject', default=True)
|
||||
|
||||
all_strokes : bpy.props.BoolProperty(
|
||||
name='All Strokes', default=False,
|
||||
name='All Strokes', default=True,
|
||||
description='Hided and locked layer will also be reprojected')
|
||||
|
||||
type: bpy.props.EnumProperty(name='Type',
|
||||
|
@ -319,9 +329,18 @@ class GPTB_OT_batch_reproject_all_frames(bpy.types.Operator):
|
|||
|
||||
return {"FINISHED"}
|
||||
|
||||
### -- MENU ENTRY --
|
||||
|
||||
def reproject_clean_menu(self, context):
|
||||
if context.mode == 'EDIT_GPENCIL':
|
||||
self.layout.operator('gp.batch_reproject_all_frames', icon='SMALL_TRI_RIGHT_VEC') # KEYTYPE_JITTER_VEC
|
||||
|
||||
def reproject_context_menu(self, context):
|
||||
if context.mode == 'EDIT_GPENCIL' and context.scene.tool_settings.gpencil_selectmode_edit == 'STROKE':
|
||||
self.layout.operator('gp.batch_reproject_all_frames', icon='SMALL_TRI_RIGHT_VEC') # KEYTYPE_JITTER_VEC
|
||||
|
||||
classes = (
|
||||
# GPTB_OT_realign,
|
||||
GPTB_OT_realign,
|
||||
GPTB_OT_batch_reproject_all_frames,
|
||||
)
|
||||
|
||||
|
@ -329,6 +348,12 @@ def register():
|
|||
for cl in classes:
|
||||
bpy.utils.register_class(cl)
|
||||
|
||||
bpy.types.VIEW3D_MT_gpencil_edit_context_menu.append(reproject_context_menu)
|
||||
bpy.types.GPENCIL_MT_cleanup.append(reproject_clean_menu)
|
||||
|
||||
def unregister():
|
||||
bpy.types.GPENCIL_MT_cleanup.remove(reproject_clean_menu)
|
||||
bpy.types.VIEW3D_MT_gpencil_edit_context_menu.remove(reproject_context_menu)
|
||||
|
||||
for cl in reversed(classes):
|
||||
bpy.utils.unregister_class(cl)
|
|
@ -112,6 +112,12 @@ Panel in sidebar : 3D view > sidebar 'N' > Gpencil
|
|||
|
||||
## Changelog:
|
||||
|
||||
1.1.0:
|
||||
|
||||
- Important change : Remap relative is now disabled by default in addon preferences
|
||||
- feat: Add realign operator in sidebar with reproject as true by default
|
||||
- UI: Batch reproject all frames is now in menus. Same places as native reproject
|
||||
|
||||
1.0.9:
|
||||
|
||||
- feat: Reproject all frames operator
|
||||
|
|
|
@ -167,8 +167,9 @@ class GPTB_PT_sidebar_panel(bpy.types.Panel):
|
|||
|
||||
layout.prop(context.scene.gptoolprops, 'edit_lines_opacity')
|
||||
|
||||
# layout.operator('gp.realign')
|
||||
layout.operator('gp.batch_reproject_all_frames') # text=Batch Reproject
|
||||
## realign / reproject
|
||||
layout.operator('gp.realign')
|
||||
# layout.operator('gp.batch_reproject_all_frames') # text=Batch Reproject
|
||||
## Create empty frame on layer (ops stored under GP_colorize... might be best to separate in another panel )
|
||||
layout.operator('gp.create_empty_frames', icon='DECORATE_KEYFRAME')
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ bl_info = {
|
|||
"name": "GP toolbox",
|
||||
"description": "Set of tools for Grease Pencil in animation production",
|
||||
"author": "Samuel Bernou",
|
||||
"version": (1, 0, 9),
|
||||
"version": (1, 1, 0),
|
||||
"blender": (2, 91, 0),
|
||||
"location": "sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||
"warning": "",
|
||||
|
@ -74,11 +74,14 @@ from pathlib import Path
|
|||
|
||||
@persistent
|
||||
def remap_relative(dummy):
|
||||
# try:
|
||||
all_path = [lib for lib in bpy.utils.blend_paths(local=True)]
|
||||
bpy.ops.file.make_paths_relative()
|
||||
for i, lib in enumerate(bpy.utils.blend_paths(local=True)):
|
||||
if all_path[i] != lib:
|
||||
print('Remapped:', all_path[i], '\n>> ', lib)
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
|
||||
def remap_on_save_update(self, context):
|
||||
pref = get_addon_prefs()
|
||||
|
@ -150,7 +153,7 @@ class GPTB_prefs(bpy.types.AddonPreferences):
|
|||
use_relative_remap_on_save : BoolProperty(
|
||||
name="Relative Remap On Save",
|
||||
description="Always remap all external path to relative when saving\nNeed blender restart if changed",
|
||||
default=True,
|
||||
default=False,
|
||||
update=remap_on_save_update
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue