Add occlusion management in geometry mode Fixes #2
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…
Reference in New Issue