simplify occlusion removal code uing native operators

Better UI
This commit is contained in:
pullusb
2024-07-24 11:59:35 +02:00
parent cb0ea42e19
commit 071f4fd13b
3 changed files with 40 additions and 42 deletions
+27 -37
View File
@@ -158,7 +158,6 @@ class GP_OT_interpolate_stroke(GP_OT_interpolate_stroke_base):
if obj:
object_hit, hit_location, tri, tri_indices = obj_ray_cast(obj, square_co, origin, dg)
else:
# scene raycast
object_hit, hit_location, tri, tri_indices = ray_cast_point(square_co, origin, dg)
if object_hit:
@@ -228,7 +227,6 @@ class GP_OT_interpolate_stroke(GP_OT_interpolate_stroke_base):
elif self.settings.method == 'GEOMETRY':
if col != context.scene.collection:
included_cols.append(col.name)
## Maybe include a plane just behind geo ? probably bad idea
elif self.settings.method == 'OBJECT':
if not self.settings.target_object:
@@ -263,7 +261,7 @@ class GP_OT_interpolate_stroke(GP_OT_interpolate_stroke_base):
vl_col = bpy.context.view_layer.layer_collection.children.get(intercol.name)
intercol.hide_viewport = vl_col.exclude = vl_col.hide_viewport = False
# Override collection
## Override collection
col = intercol
dg = bpy.context.evaluated_depsgraph_get()
@@ -275,9 +273,10 @@ class GP_OT_interpolate_stroke(GP_OT_interpolate_stroke_base):
point_co_world = self.gp.matrix_world @ point.co
if target_obj:
## Object raycast
object_hit, hit_location, tri, tri_indices = obj_ray_cast(target_obj, point_co_world, origin, dg)
else:
# scene raycast
## Scene raycast
object_hit, hit_location, tri, tri_indices = ray_cast_point(point_co_world, origin, dg)
## Iterative increasing search range when no surface hit
@@ -342,10 +341,13 @@ class GP_OT_interpolate_stroke(GP_OT_interpolate_stroke_base):
mesh=True)
dg = bpy.context.evaluated_depsgraph_get()
# Get only just pasted strokes
## Get pasted stroke
new_strokes = [s for s in self.gp.data.layers.active.active_frame.strokes if s.select]
# new_strokes = self.gp.data.layers.active.active_frame.strokes[-len(self.strokes_data):]
## Keep reference to all accessible other strokes (in all accessible layer)
other_strokes = [s for l in self.gp.data.layers if l.active_frame and not l.lock for s in l.active_frame.strokes if not s.select]
occluded_points = []
# For new_stroke, stroke_data in zip(new_strokes, self.strokes_data):
for new_stroke, stroke_data in zip(list(new_strokes), list(self.strokes_data)):
world_co_3d = []
@@ -364,39 +366,27 @@ class GP_OT_interpolate_stroke(GP_OT_interpolate_stroke_base):
## Occlusion management
if self.settings.method == 'GEOMETRY' and self.settings.remove_occluded:
viz_list = [True]*len(world_co_3d)
for i, nco in enumerate(world_co_3d):
vec_direction = nco - origin
## Reduced distance slightly to avoid occlusion on same source...
dist = vec_direction.length - 0.001
n_hit, _, _, _, _, _ = scn.ray_cast(dg, origin, vec_direction, distance=dist)
# If there is a hit, it's occluded
for i, point in enumerate(new_stroke.points):
point_co = world_co_3d[i]
vec_direction = point_co - origin
## Raycast with slightly reduced distance (avoid occlusion on same source)
n_hit, _, _, _, _, _ = scn.ray_cast(dg, origin, vec_direction, distance=vec_direction.length - 0.001)
if n_hit:
viz_list[i] = False
occluded_points.append(point)
if all(viz_list):
# All visible, do nothing (just keep previous stroke)
continue
if any(viz_list):
# Create sub-strokes according to indices in original stroke
for sublist in index_list_from_bools(viz_list):
## Clear if only one isolated point ?
if len(sublist) == 1:
continue
ns = self.gp.data.layers.active.active_frame.strokes.new()
for elem in ('hardness', 'material_index', 'line_width'):
setattr(ns, elem, getattr(new_stroke, elem))
ns.points.add(len(sublist))
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
self.gp.data.layers.active.active_frame.strokes.remove(new_stroke)
if occluded_points:
## Select only occluded point
bpy.ops.gpencil.select_all(action='DESELECT')
for point in occluded_points:
point.select = True
## remove points
bpy.ops.gpencil.delete(type='POINTS')
## restore selection (keep new strokes selected)
bpy.ops.gpencil.select_all(action='SELECT')
for stroke in other_strokes:
stroke.select = False
self.loop_count += 1
if self.loop_count >= len(self.frames_to_jump):
self.exit_modal(context)