Add occlusion management in geometry mode Fixes #2
This commit is contained in:
		
							parent
							
								
									b8180ea84f
								
							
						
					
					
						commit
						5ca9c9707e
					
				| @ -1,7 +1,7 @@ | |||||||
| bl_info = { | bl_info = { | ||||||
|     "name": "gp interpolate", |     "name": "gp interpolate", | ||||||
|     "author": "Christophe Seux, Samuel Bernou", |     "author": "Christophe Seux, Samuel Bernou", | ||||||
|     "version": (0, 5, 0), |     "version": (0, 6, 0), | ||||||
|     "blender": (3, 6, 0), |     "blender": (3, 6, 0), | ||||||
|     "location": "Sidebar > Gpencil Tab > Interpolate", |     "location": "Sidebar > Gpencil Tab > Interpolate", | ||||||
|     "description": "Interpolate Grease pencil strokes over 3D", |     "description": "Interpolate Grease pencil strokes over 3D", | ||||||
|  | |||||||
| @ -24,7 +24,7 @@ from mathutils.geometry import (barycentric_transform, | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ## TODO: add bake animation to empty for later GP layer parenting | ## TODO: add bake animation to empty for later GP layer parenting | ||||||
| ## TODO: Occlusion management | ## TODO: Convert operator to Modal to Stop animation | ||||||
| 
 | 
 | ||||||
| class GP_OT_interpolate_stroke(bpy.types.Operator): | class GP_OT_interpolate_stroke(bpy.types.Operator): | ||||||
|     bl_idname = "gp.interpolate_stroke" |     bl_idname = "gp.interpolate_stroke" | ||||||
| @ -258,6 +258,7 @@ class GP_OT_interpolate_stroke(bpy.types.Operator): | |||||||
|                 matrix_inv = np.array(gp.matrix_world.inverted(), dtype='float64')#.inverted() |                 matrix_inv = np.array(gp.matrix_world.inverted(), dtype='float64')#.inverted() | ||||||
|                 new_strokes = gp.data.layers.active.active_frame.strokes[-len(strokes_data):] |                 new_strokes = gp.data.layers.active.active_frame.strokes[-len(strokes_data):] | ||||||
| 
 | 
 | ||||||
|  |                 # for new_stroke, stroke_data in zip(new_strokes, strokes_data): | ||||||
|                 for new_stroke, stroke_data in zip(reversed(new_strokes), reversed(strokes_data)): |                 for new_stroke, stroke_data in zip(reversed(new_strokes), reversed(strokes_data)): | ||||||
|                     world_co_3d = [] |                     world_co_3d = [] | ||||||
|                     for stroke, point_co, object_hit, hit_location, tri_a, tri_indices in stroke_data: |                     for stroke, point_co, object_hit, hit_location, tri_a, tri_indices in stroke_data: | ||||||
| @ -291,47 +292,43 @@ class GP_OT_interpolate_stroke(bpy.types.Operator): | |||||||
|                     new_stroke.points.update() |                     new_stroke.points.update() | ||||||
| 
 | 
 | ||||||
|                      |                      | ||||||
|                     ## TODO: Occlusion management |                     ## Occlusion management | ||||||
|                     ## Tag occlusion on points for removal (need to create all substrokes from existing strokes) |                     if settings.method == 'GEOMETRY' and settings.remove_occluded: | ||||||
|                     # if settings.method == 'GEOMETRY': |                         viz_list = [True]*len(world_co_3d) | ||||||
|                     #     ## WIP |                         for i, nco in enumerate(world_co_3d): | ||||||
|                     #     occlusion_list = [False]*len(world_co_3d) |                             vec_direction = nco - origin | ||||||
|                     #     for i, nco in enumerate(world_co_3d): |                             ## Reduced distance slightly to avoid occlusion on same source... | ||||||
|                     #         vec_direction = nco - origin |                             dist = vec_direction.length - 0.001 | ||||||
|                     #         ## Maybe distance need to be reduced by tiny segment... |                             n_hit, _hit_location, _normal, _n_face_index, n_object_hit, _matrix = scn.ray_cast(dg, origin, vec_direction, distance=dist) | ||||||
|                     #         n_hit, _hit_location, _normal, _n_face_index, n_object_hit, _matrix = scn.ray_cast(dg, origin, vec_direction, distance=vec_direction.length) |                             # if there is a hit, it's occluded | ||||||
|                     #         # if n_hit and n_object_hit != object_hit: # note: Arm could still hit from torso... |                             if n_hit: | ||||||
|                     #         if n_hit: |                                 viz_list[i] = False | ||||||
|                     #             # if there is a hit, it's occluded |  | ||||||
|                     #             # Occluded ! |  | ||||||
|                     #             occlusion_list[i] = True |  | ||||||
| 
 | 
 | ||||||
|                     #     if all(occlusion_list): |                         if all(viz_list): | ||||||
|                     #         # all occluded, Just remove stroke (! Safer to reverse both list in zip iteration !) |                             # All visible, do nothing (just keep previous stroke) | ||||||
|                     #         gp.data.layers.active.active_frame.strokes.remove(new_stroke) |                             continue | ||||||
| 
 | 
 | ||||||
|                     #     if any(occlusion_list): |                         if any(viz_list): | ||||||
|                     #         # Create substroke according to indices in original stroke |                             # Create sub-strokes according to indices in original stroke | ||||||
|                     #         for sublist in index_list_from_bools(occlusion_list): |                             for sublist in index_list_from_bools(viz_list): | ||||||
|                     #             ## Clear if only one isolated point ? |                                 ## Clear if only one isolated point ? | ||||||
|                     #             # if len(sublist) == 1: |                                 if len(sublist) == 1: | ||||||
|                     #             #     continue     |                                     continue | ||||||
|                     #             ns = gp.data.layers.active.active_frame.strokes.new() |  | ||||||
|                     #             for elem in ('hardness', 'material_index', 'line_width'): |  | ||||||
|                     #                 setattr(ns, elem, getattr(new_strokes, elem)) |  | ||||||
| 
 | 
 | ||||||
|                     #             ns.points.add(len(sublist)) |                                 ns = gp.data.layers.active.active_frame.strokes.new() | ||||||
|                     #             for i, point_index in enumerate(sublist): |                                 for elem in ('hardness', 'material_index', 'line_width'): | ||||||
|                     #                 for elem in ('uv_factor', 'uv_fill', 'uv_rotation', 'pressure', 'co', 'strength', 'vertex_color'): |                                     setattr(ns, elem, getattr(new_stroke, elem)) | ||||||
|                     #                     setattr(ns.points[i], elem, getattr(new_strokes.points[point_index], elem)) |  | ||||||
| 
 | 
 | ||||||
|                     #         ## Delete original stroke |                                 ns.points.add(len(sublist)) | ||||||
|                     #         gp.data.layers.active.active_frame.strokes.remove(new_stroke) |                                 for i, point_index in enumerate(sublist): | ||||||
|  |                                     for elem in ('uv_factor', 'uv_fill', 'uv_rotation', 'pressure', 'co', 'strength', 'vertex_color'): | ||||||
|  |                                         setattr(ns.points[i], elem, getattr(new_stroke.points[point_index], elem)) | ||||||
| 
 | 
 | ||||||
|  |                         ## Delete original stroke | ||||||
|  |                         gp.data.layers.active.active_frame.strokes.remove(new_stroke) | ||||||
| 
 | 
 | ||||||
|             wm.progress_end() # Pgs |             wm.progress_end() # Pgs | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         if debug: |         if debug: | ||||||
|             print(f"Paste'n'place time {time()-start - scan_time}s") |             print(f"Paste'n'place time {time()-start - scan_time}s") | ||||||
|         else: |         else: | ||||||
|  | |||||||
| @ -29,6 +29,10 @@ class GP_PG_interpolate_settings(PropertyGroup): | |||||||
|         default=False, |         default=False, | ||||||
|         description='Apply the interpolation on the all keys forward or backward') |         description='Apply the interpolation on the all keys forward or backward') | ||||||
| 
 | 
 | ||||||
|  |     remove_occluded : BoolProperty(name='Remove Occluded Points', | ||||||
|  |         default=False, | ||||||
|  |         description='Remove point when occluded by geometry (works best in animation mode)') | ||||||
|  | 
 | ||||||
|     search_range : FloatProperty( |     search_range : FloatProperty( | ||||||
|         name="Search Range", |         name="Search Range", | ||||||
|         description="Search range size when points are out of mesh\ |         description="Search range size when points are out of mesh\ | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								ui.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								ui.py
									
									
									
									
									
								
							| @ -38,10 +38,10 @@ class GP_PT_interpolate(bpy.types.Panel): | |||||||
|                 col.prop_search(settings, 'target_bone', settings.target_rig.pose, 'bones', text='Bone') |                 col.prop_search(settings, 'target_bone', settings.target_rig.pose, 'bones', text='Bone') | ||||||
|                 col.prop(settings, 'use_bone_rotation', text='Use Bone Rotation') |                 col.prop(settings, 'use_bone_rotation', text='Use Bone Rotation') | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|         elif settings.method == 'GEOMETRY': |         elif settings.method == 'GEOMETRY': | ||||||
|             col.prop(settings, 'target_collection', text='Collection') |             col.prop(settings, 'target_collection', text='Collection') | ||||||
|             col.prop(settings, 'search_range') |             col.prop(settings, 'search_range') | ||||||
|  |             col.prop(settings, 'remove_occluded') | ||||||
|          |          | ||||||
|         elif settings.method == 'OBJECT': |         elif settings.method == 'OBJECT': | ||||||
|             col.prop(settings, 'target_object', text='Object') |             col.prop(settings, 'target_object', text='Object') | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user