Files
sunrise/scripts/sculpt-photo-rock-joints.py

34 lines
1.6 KiB
Python

"""Finishing pass for the photo study, executed once in Blender through MCP."""
import bpy, bmesh, math
from mathutils import Vector, noise
ns=bpy.app.driver_namespace['photo_rocks']
for obj in ns['rocks'].objects:
if obj.get('joint_pass'): continue
bm=bmesh.new();bm.from_mesh(obj.data)
bmesh.ops.remove_doubles(bm,verts=list(bm.verts),dist=.001)
# Sample the joints closely enough to avoid a texture-only crack on a flat wall.
for _ in range(3):
long=[edge for edge in bm.edges if edge.calc_length()>.7]
if not long:break
bmesh.ops.subdivide_edges(bm,edges=long,cuts=1,use_grid_fill=True)
bm.normal_update()
for v in bm.verts:
p=v.co.copy()
if p.z < -28:continue
bedding=min(abs(p.z+.13*p.x-h) for h in [-22,-15,-9,-3,3])
vertical=min(abs(p.x+.16*p.y+.09*p.z-h) for h in [-24,-20,-16,-12,-5,1,6])
cut=.42*math.exp(-(bedding/.23)**2)+.29*math.exp(-(vertical/.2)**2)
weather=.065*noise.noise_vector(p*2.1).x
v.co+=v.normal*(weather-cut)
bmesh.ops.recalc_face_normals(bm,faces=list(bm.faces))
bm.to_mesh(obj.data);bm.free();obj.data.update()
# Restore projected UVs after subdivisions; color layers interpolate in bmesh.
uv=obj.data.uv_layers.active
for face in obj.data.polygons:
axis=max(range(3),key=lambda a:abs(face.normal[a]))
for li in face.loop_indices:
p=obj.data.vertices[obj.data.loops[li].vertex_index].co
uv.data[li].uv=Vector((p.y,p.z) if axis==0 else (p.x,p.z) if axis==1 else (p.x,p.y))/3
obj['joint_pass']=True
print('Finished joints:',sum(len(o.data.polygons) for o in ns['rocks'].objects),'faces')