This commit is contained in:
Zack Buhman 2025-05-26 17:53:27 -05:00
parent b39abc0b85
commit d61f533e2a

90
blender_shadow_volume2.py Normal file
View File

@ -0,0 +1,90 @@
import bpy
import bmesh
from mathutils import Vector
from collections import defaultdict
from dataclasses import dataclass
def sprint(*text):
screen = bpy.data.screens['Scripting']
for area in screen.areas:
if area.type != "CONSOLE":
continue
override = {'screen': screen, 'area': area}
with bpy.context.temp_override(**override):
bpy.ops.console.scrollback_append(text=" ".join(map(str, text)))
print = sprint
def face_indicators(light: Vector,
position: list[Vector],
polygon_normal: list[Vector],
mesh: bpy.types.Mesh,
# outputs
indicators: list[float]):
for i in range(len(mesh.polygons)):
n = polygon_normal[i]
p = position[mesh.polygons[i].a]
indicator = dot(n, (light - p))
indicators[i] = indicator
@dataclass
class Edge:
a: int # vertex index
b: int # vertex index
@dataclass
class PolygonIndex:
a: int
b: int
@dataclass
class EdgePolygon:
edge: Edge
polygon_index: PolygonIndex
def build_edge_polygons(mesh: bpy.types.Mesh):
by_edge = defaultdict(list)
for i, polygon in enumerate(mesh.polygons):
for edge in polygon.edge_keys:
by_edge[frozenset(edge)].append(i)
assert all(len(p) == 2 for p in by_edge.values())
return [
EdgePolygon(Edge(*edge), PolygonIndex(*polygons))
for edge, polygons in by_edge.items()
]
def object_silhouette(indicators: list[float],
mesh: bpy.types.Mesh,
# outputs
edge_indices: list[int]):
ix = 0
edge_polygons = build_edge_polygons(mesh)
for i in range(len(edge_polygons)):
ep = edge_polygons[i]
if (indicators[ep.polygon_index.a] > 0) != (indicators[ep.polygon_index.b]):
edge_indices[ix] = i
ix += 1
return ix
def select_edge(bm, edge):
for e in bm.edges:
if frozenset((e.verts[0].index, e.verts[1].index)) == frozenset(edge):
e.select = True
def select():
light = bpy.data.objects['Light']
torus = bpy.data.objects['Torus']
position = [0] * len(
obj = bpy.context.edit_object
bm = bmesh.from_edit_mesh(obj.data)
bmesh.update_edit_mesh(obj.data)