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)
This commit is contained in:
		
							parent
							
								
									01ce06201e
								
							
						
					
					
						commit
						19e26f8cee
					
				| @ -1,5 +1,11 @@ | ||||
| # 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 | ||||
| 
 | ||||
| - added: Feature to move all strokes using active material to an existing or new layer (material dropdown menu > `Move Material To Layer`) | ||||
|  | ||||
| @ -15,6 +15,35 @@ def get_scale_matrix(scale): | ||||
|     matscale = matscale_x @ matscale_y @ matscale_z | ||||
|     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): | ||||
|     '''Reproject - ops method | ||||
|     :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() | ||||
|                 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: | ||||
|         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): | ||||
| 
 | ||||
| @ -369,14 +371,14 @@ class GPTB_OT_batch_reproject_all_frames(bpy.types.Operator): | ||||
|         name='All Strokes', default=True, | ||||
|         description='Hided and locked layer will also be reprojected') | ||||
|   | ||||
|     type: bpy.props.EnumProperty(name='Type', | ||||
|     type : bpy.props.EnumProperty(name='Type', | ||||
|         items=(('CURRENT', "Current", ""), | ||||
|                ('FRONT', "Front", ""), | ||||
|                ('SIDE', "Side", ""), | ||||
|                ('TOP', "Top", ""), | ||||
|                ('VIEW', "View", ""), | ||||
|                ('SURFACE', "Surface", ""), | ||||
|                ('CURSOR', "Cursor", ""), | ||||
|                # ('SURFACE', "Surface", ""), | ||||
|                ), | ||||
|         default='CURRENT') | ||||
| 
 | ||||
| @ -390,9 +392,29 @@ class GPTB_OT_batch_reproject_all_frames(bpy.types.Operator): | ||||
|         layout = self.layout | ||||
|         if not context.region_data.view_perspective == 'CAMERA': | ||||
|             # 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, "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): | ||||
|  | ||||
| @ -58,6 +58,11 @@ class GPTB_PT_sidebar_panel(Panel): | ||||
|          | ||||
|         ## flip X cam | ||||
|         # 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.operator('view3d.camera_mirror_flipx', text = 'Mirror Flip', icon = 'MOD_MIRROR')# ARROW_LEFTRIGHT | ||||
|  | ||||
| @ -4,7 +4,7 @@ bl_info = { | ||||
| "name": "GP toolbox", | ||||
| "description": "Tool set for Grease Pencil in animation production", | ||||
| "author": "Samuel Bernou, Christophe Seux", | ||||
| "version": (3, 1, 0), | ||||
| "version": (3, 2, 0), | ||||
| "blender": (4, 0, 0), | ||||
| "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", | ||||
| "warning": "", | ||||
|  | ||||
							
								
								
									
										13
									
								
								utils.py
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								utils.py
									
									
									
									
									
								
							| @ -288,13 +288,13 @@ def get_gp_draw_plane(obj=None, orient=None): | ||||
|         plane_co = bpy.context.scene.cursor.location | ||||
|         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)) | ||||
| 
 | ||||
|     elif orient == 'AXIS_X':#side (Y-Z) | ||||
|     elif orient in ('AXIS_X', 'SIDE'): # side (Y-Z) | ||||
|         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.rotate(mat) | ||||
| @ -853,6 +853,13 @@ def show_message_box(_message = "", _title = "Message Box", _icon = 'INFO'): | ||||
| ### 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 | ||||
| def draw_kmi(km, kmi, layout): | ||||
|     map_type = kmi.map_type | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user