Preserve homestead context and garden-centred Blender design
This commit is contained in:
60
source/samford-retreat-garage/finish_and_render.py
Normal file
60
source/samford-retreat-garage/finish_and_render.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import bpy, bmesh, math, json, os
|
||||
from mathutils import Vector
|
||||
OUT=os.path.dirname(os.path.abspath(__file__)); s=bpy.context.scene
|
||||
# Clear grass from the new vehicle surfaces and garage interior.
|
||||
route=[(36,-40),(28,-33),(22,-27),(8,-26),(5,-22),(5,-13),(1,-12),(-3,-12)]
|
||||
segments=[]
|
||||
for a,b in zip(route,route[1:]):
|
||||
dx,dy=b[0]-a[0],b[1]-a[1]; segments.append((a[0],a[1],dx,dy,dx*dx+dy*dy))
|
||||
def clear(x,y):
|
||||
if -7.2<x<1.2 and -22.7<y<-15.3:return True
|
||||
if -7.05<x<5.05 and -15.55<y<-9.45:return True
|
||||
for ax,ay,dx,dy,l2 in segments:
|
||||
t=max(0,min(1,((x-ax)*dx+(y-ay)*dy)/l2))
|
||||
if (x-ax-t*dx)**2+(y-ay-t*dy)**2<2.08**2:return True
|
||||
return False
|
||||
removed=0
|
||||
for o in s.objects:
|
||||
if o.type=='MESH' and o.name.startswith('Native grasses'):
|
||||
bm=bmesh.new(); bm.from_mesh(o.data); faces=[]
|
||||
for f in bm.faces:
|
||||
p=o.matrix_world@f.calc_center_median()
|
||||
if clear(p.x,p.y):faces.append(f)
|
||||
removed+=len(faces); bmesh.ops.delete(bm,geom=faces,context='FACES'); bm.to_mesh(o.data); bm.free()
|
||||
# This broad panel is the vehicle entrance, not a permanent wall across the car bay.
|
||||
o=bpy.data.objects.get('Garage north front panel')
|
||||
if o:o.name='Garage 3.7m wide sectional vehicle door'; o['Operation']='Concept upward-opening vehicle door; transparent for presentation.'
|
||||
o=bpy.data.objects.get('Garage roller door concept')
|
||||
if o:o.name='Garage north service infill panel'
|
||||
# Distinct static overview for inspecting the driveway without changing the Play camera.
|
||||
camdata=bpy.data.cameras.new('VIEW - Road garage and retreat'); cam=bpy.data.objects.new(camdata.name,camdata); s.collection.objects.link(cam)
|
||||
cam.location=(47,40,47); cam.rotation_euler=(Vector((0,-7,1))-cam.location).to_track_quat('-Z','Y').to_euler(); camdata.lens=38; camdata.clip_end=450
|
||||
tour=bpy.data.objects['PLAY TOUR camera']; s.camera=tour; s.frame_set(1)
|
||||
report=json.load(open(os.path.join(OUT,'design-checks.json'))); report['grass_faces_cleared_from_vehicle_surfaces']=removed
|
||||
report['retained_child_beds']=sum(o.name.startswith('Child') and ('bed' in o.name or 'mattress' in o.name) for o in s.objects)
|
||||
report['transparent_buildings']=['Living pavilion','Parents bedroom wing','Short corridor','Meditation room','Sauna','Greenhouse','Garage']
|
||||
assert report['retained_child_beds']==0 and report['candles']==3
|
||||
chapters=json.load(open(os.path.join(OUT,'tour-chapters.json')))
|
||||
for ch in chapters:
|
||||
s.frame_set(ch['start']); a=tour.location.copy(); s.frame_set(ch['end']); b=tour.location.copy(); assert (b-a).length>.01
|
||||
report['all_23_chapters_animate']=True; json.dump(report,open(os.path.join(OUT,'design-checks.json'),'w'),indent=2)
|
||||
s.camera=tour; s.frame_set(1)
|
||||
for screen in bpy.data.screens:
|
||||
for area in screen.areas:
|
||||
if area.type=='VIEW_3D':
|
||||
area.spaces.active.region_3d.view_perspective='CAMERA'; area.spaces.active.shading.type='SOLID'; area.spaces.active.shading.color_type='MATERIAL'; area.spaces.active.overlay.show_overlays=False
|
||||
s.render.engine='CYCLES'; s.render.resolution_percentage=100; s.cycles.samples=48; s.cycles.use_denoising=True; s.cycles.adaptive_threshold=.035
|
||||
prefs=bpy.context.preferences.addons['cycles'].preferences; prefs.compute_device_type='METAL'; prefs.get_devices()
|
||||
for d in prefs.devices:d.use=d.type=='METAL'
|
||||
s.cycles.device='GPU'; s.render.filepath=os.path.join(OUT,'retreat-garage-overview.png')
|
||||
bpy.ops.wm.save_as_mainfile(filepath=os.path.join(OUT,'samford-retreat-garage-tour.blend'))
|
||||
# Captions are useful during playback, but photographs use clean architectural views.
|
||||
titles=[o for o in bpy.data.collections['22 PLAY - guided camera tour'].objects if o.type=='FONT']
|
||||
for o in titles:o.hide_render=True
|
||||
s.camera=cam; bpy.ops.render.render(write_still=True); print('OVERVIEW_RENDERED',flush=True)
|
||||
s.camera=tour; s.frame_set(2220); s.render.filepath=os.path.join(OUT,'meditation-room.png'); bpy.ops.render.render(write_still=True); print('MEDITATION_RENDERED',flush=True)
|
||||
s.frame_set(2460); s.render.filepath=os.path.join(OUT,'garage-workstation-bikes.png'); bpy.ops.render.render(write_still=True); print('GARAGE_RENDERED',flush=True)
|
||||
for o in titles:o.hide_render=False
|
||||
s.camera=tour; s.frame_set(1); s.render.filepath=os.path.join(OUT,'retreat-garage-overview.png')
|
||||
bpy.ops.wm.save_as_mainfile(filepath=os.path.join(OUT,'samford-retreat-garage-tour.blend'))
|
||||
print('FINAL_RETREAT_READY_TO_PLAY',flush=True)
|
||||
Reference in New Issue
Block a user