import bpy, math, os, json, random, bmesh from mathutils import Vector from math import sin,cos,pi OUT=os.path.dirname(os.path.abspath(__file__)); s=bpy.context.scene def center(o): return o.matrix_world@(sum((Vector(v) for v in o.bound_box),Vector())/8) def ground(x,y): return -.024*y+.004*x+.12*sin(x*.19)*cos(y*.14)+.055*sin(x*.72+y*.32) def move(o,delta): o.location+=Vector(delta) def shift_collection(name,d): for o in bpy.data.collections[name].objects: move(o,d) sleep=(-5,-7,0); sauna=(-5,-2,0); tanks=(-5,-4,0); garden=(6,1,0) shift_collection('02 Sleeping pavilion 8 x 5 m',sleep) shift_collection('16 Oval Finnish sauna',sauna) shift_collection('17 Outdoor shower and stone terrace',sauna) shift_collection('06 Kitchen garden',garden) for o in bpy.data.collections['05 Water and services'].objects: p=center(o); n=o.name if n.startswith(('2000 mm','Poly tank','Tank service lid','Accessible tank outlet','Gravel tank pad')): move(o,tanks) elif n.startswith('Exposed rainwater downpipe') and p.x<-10: move(o,sleep) elif p.y<-8 and ('PV ' in n or 'Photovoltaic' in n or 'Ground array' in n): move(o,(3,-6,0)) for o in bpy.data.collections['18 Starlink and single-server homelab'].objects: if o.name.startswith('Starlink'): move(o,sleep) if o.name=='Overview sauna label': o.hide_render=True; o.hide_set(True) for o in bpy.data.collections['19 Clay finishes and hemp wall infill'].objects: if o.name.startswith('Sleeping'): move(o,sleep) for o in list(bpy.data.collections['12 Natural materials and reversible connections'].objects): p=center(o) if o.name.startswith('Sleeping west expansion'): move(o,sleep) elif o.name.startswith('Stone facing bed joint'): if p.x<-12 and p.y<-5: move(o,sleep) elif p.x<-6: bpy.data.objects.remove(o,do_unlink=True) # Guest and office are optional attached rooms; short connecting frames will be rebuilt. for o in list(bpy.data.collections['13 NEXT - optional attached room modules'].objects): if o.name.startswith('02A'): move(o,(5,0,0)) elif o.name.startswith('02B'): move(o,(-7,-7,0)) else: bpy.data.objects.remove(o,do_unlink=True) for o in list(bpy.data.collections['14 LATER - independent dwelling and workshop'].objects): if o.name.startswith('03A'): move(o,(0,9,0)) elif o.name.startswith('03B'): move(o,(0,-8,0)) else: bpy.data.objects.remove(o,do_unlink=True) for o in bpy.data.collections['15 Expansion labels - toggle to hide'].objects: o.hide_set(True); o.hide_render=True # Move the tree whose former location is inside the newly separated guest reservation. tree_delta=(0,0,0) for o in bpy.data.collections['09 Eucalyptus and fruit trees'].objects: if 'trunk' in o.name: p=center(o); tree_delta=(-7,0,0) if -35