Preserve homestead context and garden-centred Blender design
This commit is contained in:
65
source/samford-modular/refine_scene.py
Normal file
65
source/samford-modular/refine_scene.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import bpy, random, math, os
|
||||
from mathutils import Vector
|
||||
random.seed(119)
|
||||
OUT=os.path.dirname(os.path.abspath(__file__))
|
||||
s=bpy.context.scene
|
||||
# Layer individual leaves into substantial evergreen canopies instead of sparse twigs.
|
||||
for ob in list(bpy.data.objects):
|
||||
if 'individual canopy leaves' not in ob.name: continue
|
||||
old=ob.data
|
||||
verts=[tuple(v.co) for v in old.vertices]; faces=[tuple(p.vertices) for p in old.polygons]; inds=[p.material_index for p in old.polygons]
|
||||
original=list(verts)
|
||||
for k in range(0,len(original),5):
|
||||
center=Vector(original[k+4]); index=inds[(k//5)*4]
|
||||
for repeat in range(6):
|
||||
offset=Vector((random.uniform(-.36,.36),random.uniform(-.36,.36),random.uniform(-.23,.23)))
|
||||
a=random.uniform(-1,1); scale=random.uniform(.95,1.35); j=len(verts)
|
||||
for v in original[k:k+5]:
|
||||
d=(Vector(v)-center)*scale
|
||||
d=Vector((d.x*math.cos(a)-d.y*math.sin(a),d.x*math.sin(a)+d.y*math.cos(a),d.z))
|
||||
verts.append(tuple(center+offset+d))
|
||||
faces.extend([(j,j+1,j+4),(j+1,j+2,j+4),(j+2,j+3,j+4),(j+3,j,j+4)]); inds.extend([index]*4)
|
||||
me=bpy.data.meshes.new(ob.name+' full layered foliage'); me.from_pydata(verts,[],faces); me.update()
|
||||
for m in old.materials: me.materials.append(m)
|
||||
for p,mi in zip(me.polygons,inds): p.material_index=mi
|
||||
ob.data=me; bpy.data.meshes.remove(old)
|
||||
print('CANOPY',ob.name,len(verts),flush=True)
|
||||
# Move two foreground eucalyptus trees aside to leave greenhouse and beds visible.
|
||||
for ob in bpy.data.collections['09 Eucalyptus and fruit trees'].objects:
|
||||
if not ob.data or ob.type!='MESH': continue
|
||||
center=sum((Vector(b) for b in ob.bound_box),Vector())/8
|
||||
center=ob.matrix_world@center
|
||||
if center.x>26 and center.y>5: ob.location.x+=17
|
||||
# Soft blue ambient sky with a warm north-east morning sun.
|
||||
world=s.world; nodes=world.node_tree.nodes; bg=nodes.get('Background')
|
||||
for link in list(bg.inputs['Color'].links): world.node_tree.links.remove(link)
|
||||
bg.inputs['Color'].default_value=(.38,.49,.64,1); bg.inputs['Strength'].default_value=.45
|
||||
s.view_settings.exposure=0
|
||||
sun=bpy.data.objects['Warm early morning sun from north-east']; sun.data.energy=2.3; sun.data.color=(1,.78,.53)
|
||||
sun.location=(35,40,23); sun.rotation_euler=(Vector((-15,-20,0))-sun.location).to_track_quat('-Z','Y').to_euler()
|
||||
# Broad overlapping, wooded ridgelines complete the landscape beyond the site.
|
||||
collection=bpy.data.collections['07 Terrain and paths']
|
||||
for row,(y,base,color) in enumerate([(-58,9,(.13,.21,.16)),(-87,17,(.20,.29,.26)),(-125,23,(.29,.37,.36))]):
|
||||
mat=bpy.data.materials.new('Distant wooded ridge '+str(row)); mat.diffuse_color=(*color,1); mat.use_nodes=True; p=mat.node_tree.nodes.get('Principled BSDF'); p.inputs['Base Color'].default_value=(*color,1); p.inputs['Roughness'].default_value=1
|
||||
vs=[]; fs=[]
|
||||
for j in range(9):
|
||||
yy=y+(j-4)*7
|
||||
for i in range(81):
|
||||
x=-180+i*4.5; crest=base+4*math.sin(x*.048+row)+2.2*math.sin(x*.105+row*2)
|
||||
z=crest*max(0,1-((j-4)/4.5)**2)-2
|
||||
vs.append((x,yy,z))
|
||||
for j in range(8):
|
||||
for i in range(80):
|
||||
k=j*81+i; fs.append((k,k+1,k+82,k+81))
|
||||
me=bpy.data.meshes.new('Ridgeline terrain'); me.from_pydata(vs,[],fs); me.materials.append(mat); ob=bpy.data.objects.new('Layered subtropical ridgeline',me); collection.objects.link(ob)
|
||||
for p in me.polygons: p.use_smooth=True
|
||||
# Tone down new timber and roof glare; retain warm structure and silver-grey cladding.
|
||||
for name in ['Silvered hardwood weatherboard - X grain','Silvered hardwood weatherboard - Y grain']:
|
||||
m=bpy.data.materials[name]; ramp=next(n for n in m.node_tree.nodes if n.type=='VALTORGB')
|
||||
ramp.color_ramp.elements[0].color=(.115,.12,.105,1); ramp.color_ramp.elements[1].color=(.30,.30,.26,1)
|
||||
bpy.data.objects['NE aerial - complete adaptable compound'].data.lens=48
|
||||
s.render.resolution_x=2560; s.render.resolution_y=1440; s.render.resolution_percentage=100; s.render.filepath=os.path.join(OUT,'samford-modular-final.png'); s.cycles.samples=96
|
||||
bpy.ops.wm.save_as_mainfile(filepath=os.path.join(OUT,'samford-modular-home.blend'))
|
||||
s.cycles.device='CPU'; s.cycles.samples=12; s.render.resolution_percentage=40; s.render.filepath=os.path.join(OUT,'samford-modular-refined-draft.png')
|
||||
bpy.ops.render.render(write_still=True)
|
||||
print('REFINED_DRAFT_COMPLETE',flush=True)
|
||||
Reference in New Issue
Block a user