3 Commits

28 changed files with 11731 additions and 21 deletions

View File

@@ -2,7 +2,7 @@
Read README.md, docs/PROJECT-CONTEXT.md, docs/REQUEST-HISTORY.md and the latest decision record before editing. Read README.md, docs/PROJECT-CONTEXT.md, docs/REQUEST-HISTORY.md and the latest decision record before editing.
- Current model: blender/samford-solarpunk-garden-flow-tour.blend, version 004. - Current model: blender/samford-solarpunk-buddha-garden-tour.blend, version 006.
- The table-tennis deck was explicitly removed. Do not restore it from older scenes. - The table-tennis deck was explicitly removed. Do not restore it from older scenes.
- Future child/dwelling pavilions remain ghost outlines. The one built small pavilion is a meditation room. - Future child/dwelling pavilions remain ghost outlines. The one built small pavilion is a meditation room.
- Preserve the detailed kitchen, reading library, bedroom sleep setup, sauna, shower, solar, tanks, Starlink, homelab, Tesla garage, training and food-growing features. - Preserve the detailed kitchen, reading library, bedroom sleep setup, sauna, shower, solar, tanks, Starlink, homelab, Tesla garage, training and food-growing features.
@@ -11,6 +11,10 @@ Read README.md, docs/PROJECT-CONTEXT.md, docs/REQUEST-HISTORY.md and the latest
- Incremental source scripts depend on particular prior models. Do not run the whole script history against the current scene; it would duplicate or misplace geometry. Read each script and choose its expected starting model first. - Incremental source scripts depend on particular prior models. Do not run the whole script history against the current scene; it would duplicate or misplace geometry. Read each script and choose its expected starting model first.
- Validate saved .blend content and inspect actual renders before claiming a scene edit is finished. - Validate saved .blend content and inspect actual renders before claiming a scene edit is finished.
- Store a dated decision and a Git commit for intentional revisions. Preserve earlier model versions unless a cleanup is explicitly requested. - Store a dated decision and a Git commit for intentional revisions. Preserve earlier model versions unless a cleanup is explicitly requested.
- Working files and context stay in the private repository. The public website contains selected images and concept notes. - Marcus authorised making the repository, working files and design context public. The separate website gallery contains selected images and concept notes.
- This is an illustrative, unsurveyed concept. Do not label materials, engineering, equipment loads, costs or property compliance as verified when they are not. - This is an illustrative, unsurveyed concept. Do not label materials, engineering, equipment loads, costs or property compliance as verified when they are not.
- No need to create Linear issues unless Marcus explicitly asks. - No need to create Linear issues unless Marcus explicitly asks.
- Current water storage is a container-style enclosure with two sealed internal tanks. Do not restore the old exposed cylinders from earlier scene files.
- Preserve the garden Buddha north of the meditation room and its chapter 31 tour stop. Latest scene is version 006.

View File

@@ -4,7 +4,7 @@ A long-term working project for a modest, extendible family homestead in Samford
## Repository and context ## Repository and context
Private Git repository: https://git.rehbock.xyz/marcus/samford-valley-home Public Git repository: https://git.rehbock.xyz/marcus/samford-valley-home
Read [Project context](docs/PROJECT-CONTEXT.md), [Request history](docs/REQUEST-HISTORY.md) and [Agent notes](AGENTS.md) for the full brief, decisions, rejected ideas and current state. Git contains the actual Blender binaries, not download placeholders. The server working copy is `/home/marcus/projects/samford-valley-home`. Compressed snapshots are kept alongside it but excluded from Git. Read [Project context](docs/PROJECT-CONTEXT.md), [Request history](docs/REQUEST-HISTORY.md) and [Agent notes](AGENTS.md) for the full brief, decisions, rejected ideas and current state. Git contains the actual Blender binaries, not download placeholders. The server working copy is `/home/marcus/projects/samford-valley-home`. Compressed snapshots are kept alongside it but excluded from Git.
@@ -12,10 +12,10 @@ Clone using `git clone ssh://git@git.rehbock.xyz:2222/marcus/samford-valley-home
## Open the current work ## Open the current work
- **Blender 5.2.1:** `blender/samford-solarpunk-garden-flow-tour.blend`. Includes the entire homestead, reading chair and 163 books. Its camera tour has 30 chapters and lasts 2 minutes 30 seconds. Hover over the 3D view and press Space to play; Shift + Left Arrow returns to the start. It opens at the overview of the revised garden layout. Earlier bedroom and reading-tour files remain as previous versions. - **Blender 5.2.1:** `blender/samford-solarpunk-buddha-garden-tour.blend`. Includes the entire homestead, reading chair and 163 books. Its camera tour has 31 chapters and lasts 2 minutes 35 seconds. Hover over the 3D view and press Space to play; Shift + Left Arrow returns to the start. It opens at the garden Buddha chapter. Earlier bedroom and reading-tour files remain as previous versions.
- **Unreal Engine 5.8.2:** `unreal/SamfordMeditation/SamfordMeditation.uproject`. The saved meditation room includes 152 meshes, 14 materials, lighting and a camera. The Unreal work currently covers this room only; an interactive whole-home walkthrough is future work. - **Unreal Engine 5.8.2:** `unreal/SamfordMeditation/SamfordMeditation.uproject`. The saved meditation room includes 152 meshes, 14 materials, lighting and a camera. The Unreal work currently covers this room only; an interactive whole-home walkthrough is future work.
- **Images:** `renders/` contains the latest compound, detailed kitchen, training terrace and outdoor dining, plus earlier bedroom, reading corner, garage and actual Unreal room studies. - **Images:** `renders/` contains the latest compound, detailed kitchen, training terrace and outdoor dining, plus earlier bedroom, reading corner, garage and actual Unreal room studies.
- **Concept layout:** `plans/concept/garden-flow-plan.svg`. Current version 004 replaces the table-tennis deck with flowers, aligns the pavilions and adds curved paths and a central garden court. - **Concept layout:** `plans/concept/buddha-garden-plan.svg`. Current version 006 includes the container water-storage module and replaces the table-tennis deck with flowers, aligns the pavilions and adds curved paths and a central garden court.
- **Animation instructions:** `walkthroughs/UNREAL-CAMERA-ANIMATION.md`. - **Animation instructions:** `walkthroughs/UNREAL-CAMERA-ANIMATION.md`.
## Working in Blender ## Working in Blender
@@ -74,3 +74,11 @@ The saved camera tour includes all additions. Full Cycles scene settings are 256
Removed the table-tennis deck and all equipment. Aligned the garage with the main pavilion and the meditation room with the parents’ wing. The future east pavilion balances the meditation room; a second future footprint continues the central axis north. Added an oval garden court, curved covered timber breezeway, smooth gravel walks and driveway, 13 flowering beds and eight flowering shrubs. The former play area is now a flower garden. Two concept eucalyptus trees were moved clear of the solar array and vehicle route. The future basketball area remains unbuilt. Updated the 30-chapter tour and refreshed the overview, courtyard, flowers, dining and training renders. Removed the table-tennis deck and all equipment. Aligned the garage with the main pavilion and the meditation room with the parents’ wing. The future east pavilion balances the meditation room; a second future footprint continues the central axis north. Added an oval garden court, curved covered timber breezeway, smooth gravel walks and driveway, 13 flowering beds and eight flowering shrubs. The former play area is now a flower garden. Two concept eucalyptus trees were moved clear of the solar array and vehicle route. The future basketball area remains unbuilt. Updated the 30-chapter tour and refreshed the overview, courtyard, flowers, dining and training renders.
The full conversation context and decision history are now preserved in docs/. Source scripts are retained under source/ for future editing; they are incremental historical tools and must be run against their correct starting model. Survey and LiDAR folders remain reserved for future real-site work. The full conversation context and decision history are now preserved in docs/. Source scripts are retained under source/ for future editing; they are incremental historical tools and must be run against their correct starting model. Survey and LiDAR folders remain reserved for future real-site work.
## Container water-storage revision — 10 September 2026, v005
Marcus asked to make the water tanks a shipping container. Replaced the exposed cylinders with a dark-green 20-foot container-style module (approximately 6.06 × 2.44 × 2.59 m), retaining two sealed water tanks inside. Added corrugated walls, cargo doors and locking bars, corner castings, inlet/outlet manifolds, pump and a first-flush component concept. The container enclosure is not itself the water-retaining vessel. The west end is a transparent inspection cutaway. The garden service path reaches the east cargo doors. Updated tour chapter 13, the plan and exterior/cutaway/overview renders. Product selection, structural/loading checks and hydraulic sizing remain future design work.
## Garden Buddha — version 006, 10 September 2026
Added a seated weathered-limestone Buddha on a low stone plinth north of the meditation pavilion, facing east into the shared garden court. The statue has a draped robe, folded hands, lowered eyes, elongated earlobes and a carved topknot. Position (-12.4, 15.35), clear of both the room and curved walking route. Added a lightweight viewport proxy and chapter 31 to the Play tour (2 min 35 sec total). The scene opens on the statue. Existing house, container water module, future shadows and landscaping remain intact.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
{
"buddha_collection_objects": 281,
"viewport_proxy": true,
"tour_chapters": 31,
"caption_issues": [],
"path_clearance_m": 0.165,
"statue_outside_room": true,
"internal_water_tanks": 2,
"kitchen_preserved": true,
"no_table_tennis": true,
"render_size": [
2560,
1440,
100
]
}

View File

@@ -0,0 +1,12 @@
{
"container_dimensions_m": [
6.06,
2.44,
2.59
],
"internal_tanks": 2,
"old_exposed_tanks_removed": true,
"west_inspection_cutaway": true,
"tour_chapters": 30,
"removed_old_objects": 34
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
{
"internal_tanks": 2,
"old_exposed_tanks_removed": true,
"container": true,
"tour_chapters": 30,
"caption_issues": [],
"render_size": [
2560,
1440,
100
],
"kitchen_preserved": true,
"no_table_tennis": true
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,188 @@
[
{
"title": "01 / ONE CONNECTED GARDEN HOMESTEAD",
"start": 1,
"end": 120,
"seconds": 5
},
{
"title": "02 / LIVING PAVILION & VERANDA",
"start": 121,
"end": 240,
"seconds": 5
},
{
"title": "03 / KITCHEN & EXPOSED STRUCTURE",
"start": 241,
"end": 360,
"seconds": 5
},
{
"title": "04 / DINING & OPEN LIVING",
"start": 361,
"end": 480,
"seconds": 5
},
{
"title": "05 / ONE SERVER - LOCAL AI",
"start": 481,
"end": 600,
"seconds": 5
},
{
"title": "06 / SHORT CORRIDOR TO PRIVATE ROOMS",
"start": 601,
"end": 720,
"seconds": 5
},
{
"title": "07 / ADJACENT BEDROOM WING",
"start": 721,
"end": 840,
"seconds": 5
},
{
"title": "08 / ENCLOSED BEDROOM",
"start": 841,
"end": 960,
"seconds": 5
},
{
"title": "09 / BATHROOM - SEPARATE LOBBY DOOR",
"start": 961,
"end": 1080,
"seconds": 5
},
{
"title": "10 / FINNISH SAUNA & OUTDOOR SHOWER",
"start": 1081,
"end": 1200,
"seconds": 5
},
{
"title": "11 / SAUNA BENCHES & STONE HEATER",
"start": 1201,
"end": 1320,
"seconds": 5
},
{
"title": "12 / OUTDOOR SHOWER",
"start": 1321,
"end": 1440,
"seconds": 5
},
{
"title": "13 / CONTAINER RAINWATER STORAGE",
"start": 1441,
"end": 1560,
"seconds": 5
},
{
"title": "14 / ROOFTOP SOLAR & STARLINK",
"start": 1561,
"end": 1680,
"seconds": 5
},
{
"title": "15 / SOLAR ARRAY & ENERGY STORAGE",
"start": 1681,
"end": 1800,
"seconds": 5
},
{
"title": "16 / FOOD GARDEN & GREENHOUSE",
"start": 1801,
"end": 1920,
"seconds": 5
},
{
"title": "17 / INSIDE THE GREENHOUSE",
"start": 1921,
"end": 2040,
"seconds": 5
},
{
"title": "18 / QUIET MEDITATION ROOM",
"start": 2041,
"end": 2160,
"seconds": 5
},
{
"title": "19 / CUSHION, CANDLES & STILLNESS",
"start": 2161,
"end": 2280,
"seconds": 5
},
{
"title": "20 / GRAVEL ROAD & GARAGE",
"start": 2281,
"end": 2400,
"seconds": 5
},
{
"title": "21 / TESLA, SOLAR CHARGING & WORKSHOP",
"start": 2401,
"end": 2520,
"seconds": 5
},
{
"title": "22 / BALANCED FUTURE PAVILIONS",
"start": 2521,
"end": 2640,
"seconds": 5
},
{
"title": "23 / RECTANGLES AND GARDEN CURVES",
"start": 2641,
"end": 2760,
"seconds": 5
},
{
"title": "24 / BOOKS & A QUIET READING CORNER",
"start": 2761,
"end": 2880,
"seconds": 5
},
{
"title": "25 / TRAINING & STRENGTH",
"start": 2881,
"end": 3000,
"seconds": 5
},
{
"title": "26 / OUTDOOR TABLE & MATCHA",
"start": 3001,
"end": 3120,
"seconds": 5
},
{
"title": "27 / FLOWERING GARDEN - ROOM TO BREATHE",
"start": 3121,
"end": 3240,
"seconds": 5
},
{
"title": "28 / FLOWING WALKS AND GARDEN COURT",
"start": 3241,
"end": 3360,
"seconds": 5
},
{
"title": "29 / EASY EVERYDAY FOOD",
"start": 3361,
"end": 3480,
"seconds": 5
},
{
"title": "30 / COPPER & MARBLE KITCHEN",
"start": 3481,
"end": 3600,
"seconds": 5
},
{
"title": "31 / QUIET GARDEN BUDDHA",
"start": 3601,
"end": 3720,
"seconds": 5
}
]

View File

@@ -0,0 +1,182 @@
[
{
"title": "01 / ONE CONNECTED GARDEN HOMESTEAD",
"start": 1,
"end": 120,
"seconds": 5
},
{
"title": "02 / LIVING PAVILION & VERANDA",
"start": 121,
"end": 240,
"seconds": 5
},
{
"title": "03 / KITCHEN & EXPOSED STRUCTURE",
"start": 241,
"end": 360,
"seconds": 5
},
{
"title": "04 / DINING & OPEN LIVING",
"start": 361,
"end": 480,
"seconds": 5
},
{
"title": "05 / ONE SERVER - LOCAL AI",
"start": 481,
"end": 600,
"seconds": 5
},
{
"title": "06 / SHORT CORRIDOR TO PRIVATE ROOMS",
"start": 601,
"end": 720,
"seconds": 5
},
{
"title": "07 / ADJACENT BEDROOM WING",
"start": 721,
"end": 840,
"seconds": 5
},
{
"title": "08 / ENCLOSED BEDROOM",
"start": 841,
"end": 960,
"seconds": 5
},
{
"title": "09 / BATHROOM - SEPARATE LOBBY DOOR",
"start": 961,
"end": 1080,
"seconds": 5
},
{
"title": "10 / FINNISH SAUNA & OUTDOOR SHOWER",
"start": 1081,
"end": 1200,
"seconds": 5
},
{
"title": "11 / SAUNA BENCHES & STONE HEATER",
"start": 1201,
"end": 1320,
"seconds": 5
},
{
"title": "12 / OUTDOOR SHOWER",
"start": 1321,
"end": 1440,
"seconds": 5
},
{
"title": "13 / CONTAINER RAINWATER STORAGE",
"start": 1441,
"end": 1560,
"seconds": 5
},
{
"title": "14 / ROOFTOP SOLAR & STARLINK",
"start": 1561,
"end": 1680,
"seconds": 5
},
{
"title": "15 / SOLAR ARRAY & ENERGY STORAGE",
"start": 1681,
"end": 1800,
"seconds": 5
},
{
"title": "16 / FOOD GARDEN & GREENHOUSE",
"start": 1801,
"end": 1920,
"seconds": 5
},
{
"title": "17 / INSIDE THE GREENHOUSE",
"start": 1921,
"end": 2040,
"seconds": 5
},
{
"title": "18 / QUIET MEDITATION ROOM",
"start": 2041,
"end": 2160,
"seconds": 5
},
{
"title": "19 / CUSHION, CANDLES & STILLNESS",
"start": 2161,
"end": 2280,
"seconds": 5
},
{
"title": "20 / GRAVEL ROAD & GARAGE",
"start": 2281,
"end": 2400,
"seconds": 5
},
{
"title": "21 / TESLA, SOLAR CHARGING & WORKSHOP",
"start": 2401,
"end": 2520,
"seconds": 5
},
{
"title": "22 / BALANCED FUTURE PAVILIONS",
"start": 2521,
"end": 2640,
"seconds": 5
},
{
"title": "23 / RECTANGLES AND GARDEN CURVES",
"start": 2641,
"end": 2760,
"seconds": 5
},
{
"title": "24 / BOOKS & A QUIET READING CORNER",
"start": 2761,
"end": 2880,
"seconds": 5
},
{
"title": "25 / TRAINING & STRENGTH",
"start": 2881,
"end": 3000,
"seconds": 5
},
{
"title": "26 / OUTDOOR TABLE & MATCHA",
"start": 3001,
"end": 3120,
"seconds": 5
},
{
"title": "27 / FLOWERING GARDEN - ROOM TO BREATHE",
"start": 3121,
"end": 3240,
"seconds": 5
},
{
"title": "28 / FLOWING WALKS AND GARDEN COURT",
"start": 3241,
"end": 3360,
"seconds": 5
},
{
"title": "29 / EASY EVERYDAY FOOD",
"start": 3361,
"end": 3480,
"seconds": 5
},
{
"title": "30 / COPPER & MARBLE KITCHEN",
"start": 3481,
"end": 3600,
"seconds": 5
}
]

View File

@@ -0,0 +1,3 @@
# Public project repository
Marcus explicitly requested that the existing Samford Valley home repository be made public. Retain the models, project context and revision history, and change the repository visibility to public.

View File

@@ -0,0 +1,5 @@
# Container rainwater storage
Replaced the exposed rainwater cylinders with a dark-green 20-foot container-style enclosure at the existing water-service area. Water is stored in two separate sealed internal tanks; the steel container shell is not used as the water-retaining vessel. Added cargo door hardware, corrugations, support piers, manifold/plumbing concepts, pump and first-flush component, and a west inspection cutaway. Kept the east cargo-door approach clear. Updated chapter 13 while preserving the 30-chapter tour and all other approved features.
Verified both tanks fit inside the container bounds, old exposed-tank objects are absent, all captions match, the kitchen and no-table-tennis decision remain intact, and full render settings remain 2560 × 1440. Inspected actual Cycles exterior and cutaway renders.

View File

@@ -0,0 +1,5 @@
# Garden Buddha
Added a seated weathered-limestone Buddha on a low stone plinth north of the meditation pavilion, facing east into the shared garden court. The statue has a draped robe, folded hands, lowered eyes, elongated earlobes and a carved topknot. Position (-12.4, 15.35), clear of both the room and curved walking route. Added a lightweight viewport proxy and chapter 31 to the Play tour (2 min 35 sec total). The scene opens on the statue. Existing house, container water module, future shadows and landscaping remain intact.
Verified the saved Blender file, all 31 captions, full 2560 × 1440 render settings, path clearance and retained kitchen/container features. Inspected a Cycles preview of the finished sculpture.

View File

@@ -2,11 +2,11 @@
This is Marcus Rehbock's long-term personal homestead design project. The aim is to refine the design over several years, choose a real site, add survey and LiDAR information, coordinate construction plans, and eventually create a full Unreal Engine 5 walkthrough. The design is a working concept, not an approved or engineered building proposal. This is Marcus Rehbock's long-term personal homestead design project. The aim is to refine the design over several years, choose a real site, add survey and LiDAR information, coordinate construction plans, and eventually create a full Unreal Engine 5 walkthrough. The design is a working concept, not an approved or engineered building proposal.
## Current state: version 004, 10 September 2026 ## Current state: version 006, 10 September 2026
Open `blender/samford-solarpunk-garden-flow-tour.blend` in Blender 5.2.1. This is the current model. It includes the detailed kitchen and bedroom upgrades, a garden-centred arrangement, 13 flowering beds, and a 30-chapter camera tour lasting 2 minutes 30 seconds at 24 fps. The former table-tennis platform and its equipment have been removed. Earlier dated scene files are historical versions. Open `blender/samford-solarpunk-buddha-garden-tour.blend` in Blender 5.2.1. This is the current model. It includes the detailed kitchen and bedroom upgrades, a garden-centred arrangement, 13 flowering beds, and a 31-chapter camera tour lasting 2 minutes 35 seconds at 24 fps. The former table-tennis platform and its equipment have been removed. Earlier dated scene files are historical versions.
The latest plan is `plans/concept/garden-flow-plan.svg`. It is generated from the same `garden-flow-layout.json` coordinates used by the Blender revision. Current images are `renders/garden-flow-overview.png`, `garden-court.png`, `flowering-kitchen-garden.png`, `garden-flow-dining.png` and `garden-flow-training.png`. The latest plan is `plans/concept/buddha-garden-plan.svg`. It is generated from the same `buddha-garden-layout.json` coordinates used by the Blender revision. The Buddha close-up is `renders/buddha-garden.png`. Other current images are `renders/container-water-overview.png`, `container-water.png` and `container-water-cutaway.png`. The preceding garden revision also has courtyard, planting, dining and training detail renders.
## Philosophy and values ## Philosophy and values
@@ -58,20 +58,28 @@ Marcus prefers “warm timber, soft clay walls, selective hemp insulation, stone
## Energy and homesteading ## Energy and homesteading
Keep rooftop solar, a separate ground array (current conceptual footprint centred at 9.4, -19), off-grid energy storage, two dark-green cylindrical rainwater tanks, greenhouse, six raised vegetable beds, fruit trees and garden harvest bench. Product capacities, structural design, solar yield, battery autonomy, water balance, wastewater treatment and food-production targets have not been engineered. Keep rooftop solar, a separate ground array (current conceptual footprint centred at 9.4, -19), off-grid energy storage, two sealed rainwater tanks inside a dark-green container-style enclosure, greenhouse, six raised vegetable beds, fruit trees and garden harvest bench. Product capacities, structural design, solar yield, battery autonomy, water balance, wastewater treatment and food-production targets have not been engineered.
## Blender and Unreal state ## Blender and Unreal state
Blender has full editable geometry and Cycles materials. Saved render settings are 2560 × 1440 at 100%; web preview renders are made at 60% (1536 × 864). The user previously reported low playback FPS. `00 FAST TOUR - lightweight viewport` is a static simplified display; `DETAIL - full geometry for renders` is disabled only in the viewport. Cycles renders exclude FAST and use DETAIL automatically. For detailed editing, enable DETAIL and disable FAST. After moving or removing geometry, refresh the affected fast copies as well. Blender has full editable geometry and Cycles materials. Saved render settings are 2560 × 1440 at 100%; web preview renders are made at 60% (1536 × 864). The user previously reported low playback FPS. `00 FAST TOUR - lightweight viewport` is a static simplified display; `DETAIL - full geometry for renders` is disabled only in the viewport. Cycles renders exclude FAST and use DETAIL automatically. For detailed editing, enable DETAIL and disable FAST. After moving or removing geometry, refresh the affected fast copies as well.
The tour contains 30 five-second chapters. Space plays/pauses with the pointer over the 3D view; Shift+Left Arrow returns to frame 1. The current scene opens at the overview. Update camera positions and captions whenever a subject moves. The tour contains 31 five-second chapters. Space plays/pauses with the pointer over the 3D view; Shift+Left Arrow returns to frame 1. The current scene opens at chapter 31, the garden Buddha. Update camera positions and captions whenever a subject moves.
The **actual Unreal work covers only the meditation room**. `unreal/SamfordMeditation/SamfordMeditation.uproject` is the UE 5.8.2 project, with room geometry, materials, light and camera. It is not a complete Unreal homestead. FBX/GLB exports and textures are retained. Camera animation instructions are in `walkthroughs/UNREAL-CAMERA-ANIMATION.md`. A complete interactive home/site walkthrough remains future work. The **actual Unreal work covers only the meditation room**. `unreal/SamfordMeditation/SamfordMeditation.uproject` is the UE 5.8.2 project, with room geometry, materials, light and camera. It is not a complete Unreal homestead. FBX/GLB exports and textures are retained. Camera animation instructions are in `walkthroughs/UNREAL-CAMERA-ANIMATION.md`. A complete interactive home/site walkthrough remains future work.
## Storage and continuation ## Storage and continuation
Private repository: https://git.rehbock.xyz/marcus/samford-valley-home . Server working archive/repository: `/home/marcus/projects/samford-valley-home`. Public gallery: https://rehbock.xyz/projects/samford-valley-home/ . Only selected images, public descriptions and a concept SVG are in the public website; working assets belong in the private project. Public repository: https://git.rehbock.xyz/marcus/samford-valley-home . Server working archive/repository: `/home/marcus/projects/samford-valley-home`. Public gallery: https://rehbock.xyz/projects/samford-valley-home/ . The gallery contains selected images, descriptions and a concept SVG. Marcus subsequently authorised making this repository, its working assets and design context public.
The repository includes Blender models, renders, plans, design context, revision records, source scripts, Unreal assets and reserved folders for survey/LiDAR/construction information. Dated compressed snapshots remain in the server archive and are excluded from Git to avoid duplicating the entire repository in each commit. Git LFS is disabled on the existing Gitea installation; current assets are stored as ordinary Git binaries. Plan large-file/object storage before adding multi-gigabyte LiDAR or video datasets. No new off-site backup service has been configured. The repository includes Blender models, renders, plans, design context, revision records, source scripts, Unreal assets and reserved folders for survey/LiDAR/construction information. Dated compressed snapshots remain in the server archive and are excluded from Git to avoid duplicating the entire repository in each commit. Git LFS is disabled on the existing Gitea installation; current assets are stored as ordinary Git binaries. Plan large-file/object storage before adding multi-gigabyte LiDAR or video datasets. No new off-site backup service has been configured.
Read `REQUEST-HISTORY.md`, the decisions folder and `AGENTS.md` before making further changes. Do not mistake historical renders or earlier briefs for the current approved layout. Read `REQUEST-HISTORY.md`, the decisions folder and `AGENTS.md` before making further changes. Do not mistake historical renders or earlier briefs for the current approved layout.
## Version 005 water module
Marcus requested that the water tanks become a shipping container. The visible module is a roughly 20-foot corrugated-steel container at (-25, -8), 6.06 × 2.44 × 2.59 m. Two separate sealed tanks fit inside; the steel shell is an enclosure, not the water-retaining vessel. The cargo doors are at the east end and the west end is a transparent inspection cutaway. Plumbing is kept off the door faces, and the service path approaches the east end. Current renders: container-water.png, container-water-overview.png and container-water-cutaway.png. Exact tank products/capacities, water quality treatment, hydraulic sizing and container support design are not resolved by the concept model.
## Garden Buddha — version 006, 10 September 2026
Added a seated weathered-limestone Buddha on a low stone plinth north of the meditation pavilion, facing east into the shared garden court. The statue has a draped robe, folded hands, lowered eyes, elongated earlobes and a carved topknot. Position (-12.4, 15.35), clear of both the room and curved walking route. Added a lightweight viewport proxy and chapter 31 to the Play tour (2 min 35 sec total). The scene opens on the statue. Existing house, container water module, future shadows and landscaping remain intact.

View File

@@ -36,3 +36,15 @@ This records the supplied conversation's substantive requests in order. It is a
## Still to decide ## Still to decide
Actual property and required area; surveyed levels/boundaries; planning approvals and bushfire/flood response; engineering and detailed accessible circulation; quantities/budget; product selections and energy/water balances; server hardware; final botanical planting plan; large LiDAR storage and independent backups; full Unreal conversion and interactive walkthrough. Preserve these as future work rather than assuming they are completed. Actual property and required area; surveyed levels/boundaries; planning approvals and bushfire/flood response; engineering and detailed accessible circulation; quantities/budget; product selections and energy/water balances; server hardware; final botanical planting plan; large LiDAR storage and independent backups; full Unreal conversion and interactive walkthrough. Preserve these as future work rather than assuming they are completed.
## Subsequent visibility decision
Marcus explicitly authorised making the repository public: “You can make it public.” The repository contents and design context are therefore publicly accessible. This supersedes the earlier private-visibility choice.
## Version 005 request
Marcus asked: “Can you make my water tanks a shipping container?” Implemented as a container-style enclosure with two separate sealed tanks inside, with updated plumbing, service access, plan, camera chapter and rendered views.
## Version 006 request
Marcus asked: “Ok nice, can you also put a statue of hte buddha somewhere and open in blender”. Added a seated weathered-limestone Buddha on a low stone plinth north of the meditation pavilion, facing east into the shared garden court. The statue has a draped robe, folded hands, lowered eyes, elongated earlobes and a carved topknot. Position (-12.4, 15.35), clear of both the room and curved walking route. Added a lightweight viewport proxy and chapter 31 to the Play tour (2 min 35 sec total). The scene opens on the statue. Existing house, container water module, future shadows and landscaping remain intact.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

BIN
renders/buddha-garden.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
renders/container-water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -1,11 +1,16 @@
{ {
"milestone": "2026-09-10-v004-garden-flow", "milestone": "2026-09-10-v006-buddha-garden",
"files": { "files": {
".gitattributes": "d4f9cc15aed223cff7a906452370117fc93992272828cb1efbdd94c61422ad19", ".gitattributes": "d4f9cc15aed223cff7a906452370117fc93992272828cb1efbdd94c61422ad19",
".gitignore": "d38c3a1d58416906185c4c7695ea24f9401be3b610fcce0e624f41dff9fe1675", ".gitignore": "d38c3a1d58416906185c4c7695ea24f9401be3b610fcce0e624f41dff9fe1675",
"AGENTS.md": "233d2be130f8de20a4d17c9c5713462c97ed716be8682191db8dfcc646992999", "AGENTS.md": "8dbbdcbbddb316d81e86d2a7ea65e35d8ab1283a79734d6ef747d96e04af1cac",
"README.md": "44086788e8fe8428b3e103744162b6a82625991902cf2b0ef159be1fb3c4298c", "README.md": "977bd1623e2ebc4884c66a9a3b134c2621d6fc88ecaf94333f849adefa9456d1",
"blender/bedroom-sleep-checks.json": "4f28426b4c23e55c956a4c5bc94947706da63e35de455cfaedd8e90e330f1114", "blender/bedroom-sleep-checks.json": "4f28426b4c23e55c956a4c5bc94947706da63e35de455cfaedd8e90e330f1114",
"blender/buddha-garden-layout.json": "c24aabd04146d6e30c6d855ca43dc668881e65df2e2aab4af5b15668337bfe50",
"blender/buddha-garden-verification.json": "f030aa32bf883cd85d2c820846d78ad84e3ff0a6f8623878a6e0bda641712fcd",
"blender/container-water-checks.json": "59f1a2c3cdf921de280cb8931e26511c6502fb3618b9bad10021619863c0ae37",
"blender/container-water-layout.json": "d13666a791378cf826b56d69f2dc48cbbdf33ac0db339b944f69c45b8dcb7c50",
"blender/container-water-verification.json": "04aa76751f9310ffb2bfda90742e5907bcb09d2159003d837fbbaf7b439344e9",
"blender/daily-life-checks.json": "22cf10e5f3acb11e92ed4780b08eb7c23bef1132b16a631e29cd895e81f068ec", "blender/daily-life-checks.json": "22cf10e5f3acb11e92ed4780b08eb7c23bef1132b16a631e29cd895e81f068ec",
"blender/daily-life-layout.json": "a908d84f38a8ab035958b197c31037ea71e0e7efa5ed20da0bbf7867c5a85a1d", "blender/daily-life-layout.json": "a908d84f38a8ab035958b197c31037ea71e0e7efa5ed20da0bbf7867c5a85a1d",
"blender/daily-life-verification.json": "cc21f366de7c6133b7891c4fab23f075115fc96402aeaf27272280e9b7c5af55", "blender/daily-life-verification.json": "cc21f366de7c6133b7891c4fab23f075115fc96402aeaf27272280e9b7c5af55",
@@ -14,6 +19,8 @@
"blender/garden-flow-verification.json": "7f35c643afbc61152eb211a6c34a29b4edb98aefa261426ed0d5e99e9f296c70", "blender/garden-flow-verification.json": "7f35c643afbc61152eb211a6c34a29b4edb98aefa261426ed0d5e99e9f296c70",
"blender/reading-corner-checks.json": "e6cf3b9b895888b4c20c95a9612070064067100d881da7e26b4d5f69bf4db50a", "blender/reading-corner-checks.json": "e6cf3b9b895888b4c20c95a9612070064067100d881da7e26b4d5f69bf4db50a",
"blender/samford-solarpunk-bedroom-tour.blend": "5c967f65d9e3f680bcf9e1da3f2d3d82bd4ab313fe030c0b0a284c2aca5d58b7", "blender/samford-solarpunk-bedroom-tour.blend": "5c967f65d9e3f680bcf9e1da3f2d3d82bd4ab313fe030c0b0a284c2aca5d58b7",
"blender/samford-solarpunk-buddha-garden-tour.blend": "ac72bd7588c1802cd5029b93eab456c80887de3d4020ffd628b9074e6bb456a3",
"blender/samford-solarpunk-container-water-tour.blend": "bbf12b85e7d5373bbebfba7eeb30f5fc2a5fc06a339f314676c74d2ceea1dd33",
"blender/samford-solarpunk-daily-life-tour.blend": "445db0cc7b4647dd45ae899632e3de5a2aaf1bfabdc2aa8ffc77d11c6a70ad74", "blender/samford-solarpunk-daily-life-tour.blend": "445db0cc7b4647dd45ae899632e3de5a2aaf1bfabdc2aa8ffc77d11c6a70ad74",
"blender/samford-solarpunk-garden-flow-tour.blend": "b2bf1e7556f75b3ad3d96dbf340feac0fecfaf0865fcbeb838b1c417bb62ae2b", "blender/samford-solarpunk-garden-flow-tour.blend": "b2bf1e7556f75b3ad3d96dbf340feac0fecfaf0865fcbeb838b1c417bb62ae2b",
"blender/samford-solarpunk-reading-tour.blend": "f47296df39f3eaa381ec1b60615dec77f1ff5e2b5f3c645deea2e5b3af4e6d83", "blender/samford-solarpunk-reading-tour.blend": "f47296df39f3eaa381ec1b60615dec77f1ff5e2b5f3c645deea2e5b3af4e6d83",
@@ -21,21 +28,32 @@
"blender/scripts/create_site_plan.py": "7e7c566e960e37b5a8225157750ba11c06afe72d86fdceea7d73b2e6e0b03a24", "blender/scripts/create_site_plan.py": "7e7c566e960e37b5a8225157750ba11c06afe72d86fdceea7d73b2e6e0b03a24",
"blender/scripts/enhance_kitchen.py": "2ac50b24427210f00f6bd4ba492ddaffef22ee3835c20f3ec72d41b97081f1f3", "blender/scripts/enhance_kitchen.py": "2ac50b24427210f00f6bd4ba492ddaffef22ee3835c20f3ec72d41b97081f1f3",
"blender/scripts/verify_daily_life.py": "7241568d786cd9d78fad97af24b14fd487cad1357bfac19fc1c800cbafeef8fb", "blender/scripts/verify_daily_life.py": "7241568d786cd9d78fad97af24b14fd487cad1357bfac19fc1c800cbafeef8fb",
"blender/tour-chapters-buddha-garden.json": "f695157b58947bc494bddc4689365f784c8d825e8e263ed89dbfd7877c06d3aa",
"blender/tour-chapters-container-water.json": "acd9bfcb805fa6bc22a8521e5c0d3fe06bd32b1f947dbff0cd43b521568fcef5",
"blender/tour-chapters-daily-life.json": "d6eb5ff0406a5e3b54fd088ef3e050f876a0b922c2b94350770900bca3d6a587", "blender/tour-chapters-daily-life.json": "d6eb5ff0406a5e3b54fd088ef3e050f876a0b922c2b94350770900bca3d6a587",
"blender/tour-chapters-garden-flow.json": "7a6807925630812188acad57afab5c46671b0d0c4fe6c8b90763f5f80353cea6", "blender/tour-chapters-garden-flow.json": "7a6807925630812188acad57afab5c46671b0d0c4fe6c8b90763f5f80353cea6",
"blender/tour-chapters-reading.json": "53d17d81ab55528240e6453c19fc7e45721c1ecfcf610e90e21644da509d42ab", "blender/tour-chapters-reading.json": "53d17d81ab55528240e6453c19fc7e45721c1ecfcf610e90e21644da509d42ab",
"decisions/2026-09-10-repository-public.md": "3ded28ebf5fde19aeed74caac9308260602551651fdaebf58494fe625d0d27ad",
"decisions/2026-09-10-v001.md": "8c30365df61ef50a9bc06391e01eccc6e72c7bddd3d368defc34b720fcd90431", "decisions/2026-09-10-v001.md": "8c30365df61ef50a9bc06391e01eccc6e72c7bddd3d368defc34b720fcd90431",
"decisions/2026-09-10-v002-bedroom.md": "36d0a4a398b3fa8ca354e0f560c4cec4c96e788fa8789de41c11dad32d65c90e", "decisions/2026-09-10-v002-bedroom.md": "36d0a4a398b3fa8ca354e0f560c4cec4c96e788fa8789de41c11dad32d65c90e",
"decisions/2026-09-10-v003-daily-life-kitchen.md": "396ad405df9e7c10d1c71753ecc76cc9889c661e352533d601c666213f065c98", "decisions/2026-09-10-v003-daily-life-kitchen.md": "396ad405df9e7c10d1c71753ecc76cc9889c661e352533d601c666213f065c98",
"decisions/2026-09-10-v004-garden-flow.md": "55ed1e2e222941a9ab9dde5d0d18f6f979528d15e0e3fe988a340744f459b9bc", "decisions/2026-09-10-v004-garden-flow.md": "55ed1e2e222941a9ab9dde5d0d18f6f979528d15e0e3fe988a340744f459b9bc",
"docs/PROJECT-CONTEXT.md": "0c03434255f9b7764cccb4551b792564295f8e476154a2172b905b999ef4bc4f", "decisions/2026-09-10-v005-container-water.md": "5fc937e7231a6b3d1856a0f7db2a998c81e4b51afb31fa4222a8d3e931de53fc",
"docs/REQUEST-HISTORY.md": "279c1f8b4c8f6a0c6b85754ffdd6aeb8b2d3980ba26ec852768d07dbe3e86e88", "decisions/2026-09-10-v006-buddha-garden.md": "aa14fcca78e225563b19ed4a98e335b2f465ed27e12904665c3c654de77b950c",
"docs/PROJECT-CONTEXT.md": "80b4ae47ac54712241070f53ed80d5f96ecc78a7fa4e18fc806d64724afe5020",
"docs/REQUEST-HISTORY.md": "f5e4bf3f1194efdac3390f4822ab8ebf2cb7f6743b25358de780c11993b82b42",
"plans/architectural/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "plans/architectural/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"plans/concept/buddha-garden-plan.svg": "62f622647732bf9556e7d351c06c9dc8576f68e8e0044f91232401972e43e466",
"plans/concept/container-water-plan.svg": "5cf52ea84ae8e222f64881b46807ca869728845c9e1a5b5c80ecfdbfbc3d5fe3",
"plans/concept/garden-flow-plan.svg": "95c7309d44143ebb3f11a7e0f6b4cee8b076c17a423ab14c8288f450b54ae4db", "plans/concept/garden-flow-plan.svg": "95c7309d44143ebb3f11a7e0f6b4cee8b076c17a423ab14c8288f450b54ae4db",
"plans/concept/retreat-garage-plan.svg": "225985399ed62625b0280ef9e6a802e276e3c6aad6c35e47c744628868c8022e", "plans/concept/retreat-garage-plan.svg": "225985399ed62625b0280ef9e6a802e276e3c6aad6c35e47c744628868c8022e",
"plans/engineering/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "plans/engineering/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"references/UNREAL-PROJECT-SCOPE.md": "9727e4447a772756fae2456465f4677d63772858d3433e68c901adbd3a2a5632", "references/UNREAL-PROJECT-SCOPE.md": "9727e4447a772756fae2456465f4677d63772858d3433e68c901adbd3a2a5632",
"renders/bedroom-sleep-setup.png": "5e12a5303615695093b61ef70111ee3d75c41ebe119c9efe0645f70725fbb707", "renders/bedroom-sleep-setup.png": "5e12a5303615695093b61ef70111ee3d75c41ebe119c9efe0645f70725fbb707",
"renders/buddha-garden.png": "8b6f6658e17aac9f681191be2d02a1acb9387b0f94695489250d8ebf05acdb63",
"renders/container-water-cutaway.png": "720e0d03c6839e54b181edfe63515d0e11179d9f2767ea3ac41f3b1ebaafa447",
"renders/container-water-overview.png": "5c03c9e7d447a4847b227be4e76ce5fc03328b6635b840e5927f3404805d9323",
"renders/container-water.png": "279e52861b2557e79eeaed6dbbe5f96e4d81aaa273494bd4b6a6f6903a405c8f",
"renders/daily-life-overview.png": "fb7341ad4549c30b07696568616ae3304772307aea234d80214bfeeb79ffc834", "renders/daily-life-overview.png": "fb7341ad4549c30b07696568616ae3304772307aea234d80214bfeeb79ffc834",
"renders/flowering-kitchen-garden.png": "22f9fa70bfa9a9c2f1f2e77efb97744d47dbfacbd9b0dd9b723a365cada974ec", "renders/flowering-kitchen-garden.png": "22f9fa70bfa9a9c2f1f2e77efb97744d47dbfacbd9b0dd9b723a365cada974ec",
"renders/garden-court.png": "70c8bef1ae7b3c79be9fa914ca0e2edce7d097656957959fede9f7c1c48bc8de", "renders/garden-court.png": "70c8bef1ae7b3c79be9fa914ca0e2edce7d097656957959fede9f7c1c48bc8de",
@@ -65,10 +83,12 @@
"source/samford-retreat-garage/README.md": "ea463e21ea71158e75a17eea6ee0c4e666663ef18dd58ae74d64c2b09f201a0f", "source/samford-retreat-garage/README.md": "ea463e21ea71158e75a17eea6ee0c4e666663ef18dd58ae74d64c2b09f201a0f",
"source/samford-retreat-garage/UNREAL-PROJECT-SCOPE.md": "9727e4447a772756fae2456465f4677d63772858d3433e68c901adbd3a2a5632", "source/samford-retreat-garage/UNREAL-PROJECT-SCOPE.md": "9727e4447a772756fae2456465f4677d63772858d3433e68c901adbd3a2a5632",
"source/samford-retreat-garage/add_daily_life.py": "701f246fe963124b04ef86512ff1465dd51bec335ca0059d6b966b653563be47", "source/samford-retreat-garage/add_daily_life.py": "701f246fe963124b04ef86512ff1465dd51bec335ca0059d6b966b653563be47",
"source/samford-retreat-garage/add_garden_buddha.py": "6606a677bf529565fd3fa206bcd48657bb4a25982d2f5a6b63f0c4935f1a99ff",
"source/samford-retreat-garage/add_reading_corner.py": "95a5223670ae53343f6fe7e435c0955dcb0c7d05dea3804b2b3cca356c02feb9", "source/samford-retreat-garage/add_reading_corner.py": "95a5223670ae53343f6fe7e435c0955dcb0c7d05dea3804b2b3cca356c02feb9",
"source/samford-retreat-garage/bedroom-sleep-checks.json": "4f28426b4c23e55c956a4c5bc94947706da63e35de455cfaedd8e90e330f1114", "source/samford-retreat-garage/bedroom-sleep-checks.json": "4f28426b4c23e55c956a4c5bc94947706da63e35de455cfaedd8e90e330f1114",
"source/samford-retreat-garage/bedroom_sleep_setup.py": "584ea23c5fc9e7b1651025776d25c9ba18fe4b8482a539f9e84cde397cdc2e08", "source/samford-retreat-garage/bedroom_sleep_setup.py": "584ea23c5fc9e7b1651025776d25c9ba18fe4b8482a539f9e84cde397cdc2e08",
"source/samford-retreat-garage/create_garden_plan.py": "1bc15d6e847af799755ae6dcc857f096d8194c0f47db79527a7eade53a4d725c", "source/samford-retreat-garage/container_water.py": "e125514fda2f6d5b91d597d6d237e17ba5c7304f0f1890bf8603a6d7aedbae45",
"source/samford-retreat-garage/create_garden_plan.py": "10e36fc08ff8484f4d98832a794a0214489a1526c3c29d1147dc2122492739a6",
"source/samford-retreat-garage/create_site_plan.py": "7e7c566e960e37b5a8225157750ba11c06afe72d86fdceea7d73b2e6e0b03a24", "source/samford-retreat-garage/create_site_plan.py": "7e7c566e960e37b5a8225157750ba11c06afe72d86fdceea7d73b2e6e0b03a24",
"source/samford-retreat-garage/daily-life-checks.json": "22cf10e5f3acb11e92ed4780b08eb7c23bef1132b16a631e29cd895e81f068ec", "source/samford-retreat-garage/daily-life-checks.json": "22cf10e5f3acb11e92ed4780b08eb7c23bef1132b16a631e29cd895e81f068ec",
"source/samford-retreat-garage/daily-life-layout.json": "a908d84f38a8ab035958b197c31037ea71e0e7efa5ed20da0bbf7867c5a85a1d", "source/samford-retreat-garage/daily-life-layout.json": "a908d84f38a8ab035958b197c31037ea71e0e7efa5ed20da0bbf7867c5a85a1d",
@@ -91,6 +111,8 @@
"source/samford-retreat-garage/tour-chapters-garden-flow.json": "7a6807925630812188acad57afab5c46671b0d0c4fe6c8b90763f5f80353cea6", "source/samford-retreat-garage/tour-chapters-garden-flow.json": "7a6807925630812188acad57afab5c46671b0d0c4fe6c8b90763f5f80353cea6",
"source/samford-retreat-garage/tour-chapters-reading.json": "53d17d81ab55528240e6453c19fc7e45721c1ecfcf610e90e21644da509d42ab", "source/samford-retreat-garage/tour-chapters-reading.json": "53d17d81ab55528240e6453c19fc7e45721c1ecfcf610e90e21644da509d42ab",
"source/samford-retreat-garage/tour-chapters.json": "7ba0647e7c9102e1f9cf87ed35979b1a110f335ab0439bfbac9280d1d826de49", "source/samford-retreat-garage/tour-chapters.json": "7ba0647e7c9102e1f9cf87ed35979b1a110f335ab0439bfbac9280d1d826de49",
"source/samford-retreat-garage/verify_buddha_garden.py": "6869e5e386b160cd6b48ebce230715957581c755d057b59be1a66b8edeab7f51",
"source/samford-retreat-garage/verify_container_water.py": "74ac1a851660bde1c098b10dfbed1f92a1d5251c6b1a3303d7d506f6f344fa8a",
"source/samford-retreat-garage/verify_daily_life.py": "7241568d786cd9d78fad97af24b14fd487cad1357bfac19fc1c800cbafeef8fb", "source/samford-retreat-garage/verify_daily_life.py": "7241568d786cd9d78fad97af24b14fd487cad1357bfac19fc1c800cbafeef8fb",
"source/samford-retreat-garage/verify_garden_flow.py": "b48c25116eb7f3cd56914a4f53601427207c387dd59d48fbd3b8cb692a9e46c0", "source/samford-retreat-garage/verify_garden_flow.py": "b48c25116eb7f3cd56914a4f53601427207c387dd59d48fbd3b8cb692a9e46c0",
"source/samford-spacious-tour/README.md": "346f05b5f2aafc8b9f846f55da19ad33ae6a3ef917dc6f95902c78954791319d", "source/samford-spacious-tour/README.md": "346f05b5f2aafc8b9f846f55da19ad33ae6a3ef917dc6f95902c78954791319d",

View File

@@ -0,0 +1,154 @@
import bpy,math,os,json
from mathutils import Vector,Matrix
from math import sin,cos,pi
O=os.path.dirname(__file__);s=bpy.context.scene
c=bpy.data.collections.new('36 Buddha - meditation garden');bpy.data.collections['DETAIL - full geometry for renders'].children.link(c);COL={'new':c};active='new'
src=open(O+'/../samford-modular/build_scene.py').read();exec(src[src.index('def mesh('):src.index('timber=textured(')])
cubefs=[tuple(reversed(f)) for f in cubefs]
stone=textured('Buddha - warm weathered limestone',(.31,.285,.235),(.49,.46,.38),(42,42,42),.83,.0018)
shade=mat('Buddha - fine carved recess',(.18,.16,.125),.94)
def ell(n,p,sz,ma=stone,rot=0,nu=40,nv=24):
vs=[];fs=[]
for j in range(nv+1):
a=pi*j/nv
for i in range(nu):
b=2*pi*i/nu;x=sz[0]*sin(a)*cos(b);y=sz[1]*sin(a)*sin(b)
vs.append((p[0]+x*cos(rot)-y*sin(rot),p[1]+x*sin(rot)+y*cos(rot),p[2]+sz[2]*cos(a)))
for j in range(nv):
for i in range(nu):k=j*nu+i;l=j*nu+(i+1)%nu;fs.append((k,l,l+nu,k+nu))
ob=mesh('BUDDHA - '+n,vs,[tuple(reversed(f)) for f in fs],ma)
for f in ob.data.polygons:f.use_smooth=True
return ob
def tube(n,points,r,ma=stone):
# Catmull-Rom smooth carved lines / rounded limbs.
pts=[];p=[Vector(q) for q in points]
for i in range(len(p)-1):
a=p[max(0,i-1)];b=p[i];cc=p[i+1];d=p[min(i+2,len(p)-1)]
for j in range(8):
t=j/8;pts.append(.5*(2*b+(-a+cc)*t+(2*a-5*b+4*cc-d)*t*t+(-a+3*b-3*cc+d)*t*t*t))
pts.append(p[-1]);vs=[];fs=[]
for i,v in enumerate(pts):
q=(pts[min(i+1,len(pts)-1)]-pts[max(0,i-1)]).to_track_quat('Z','Y')
rr=r*(.65+.35*sin(pi*i/(len(pts)-1)))
for j in range(10):vs.append(tuple(v+q@Vector((rr*cos(j*2*pi/10),rr*sin(j*2*pi/10),0))))
for i in range(len(pts)-1):
for j in range(10):k=i*10+j;l=i*10+(j+1)%10;fs.append((k,l,l+10,k+10))
fs.extend([tuple(reversed(range(10))),tuple(range(len(vs)-10,len(vs)))])
ob=mesh('BUDDHA - '+n,vs,fs,ma)
for f in ob.data.polygons:f.use_smooth=True
return ob
box('BUDDHA - low stone plinth',(0,0,.13),(1.5,1.12,.26),stone,.04)
box('BUDDHA - plinth cap',(0,0,.285),(1.56,1.18,.075),stone,.025)
ell('oval seat',(0,0,.37),(.65,.43,.075))
ell('left folded robe knee',(-.30,-.075,.52),(.39,.32,.16),rot=-.22)
ell('right folded robe knee',(.30,-.075,.52),(.39,.32,.16),rot=.22)
ell('crossed shin left',(-.13,-.25,.555),(.40,.145,.13),rot=.23)
ell('crossed shin right',(.15,-.22,.585),(.39,.14,.12),rot=-.24)
ell('left resting foot',(.30,-.25,.655),(.19,.09,.075),rot=.25)
ell('right resting foot',(-.29,-.28,.64),(.18,.09,.072),rot=-.20)
# Sculpted torso profile narrows at waist and neck, rounded shoulders.
vs=[];fs=[];profiles=[(.53,.26,.18),(.68,.235,.185),(.86,.24,.175),(1.05,.30,.16),(1.16,.30,.14),(1.23,.20,.12),(1.25,.105,.095)]
for z,rx,ry in profiles:
for i in range(48):a=i*2*pi/48;vs.append((rx*cos(a),.02+ry*sin(a),z))
for j in range(len(profiles)-1):
for i in range(48):k=j*48+i;l=j*48+(i+1)%48;fs.append((k,l,l+48,k+48))
fs.extend([tuple(reversed(range(48))),tuple(range(len(vs)-48,len(vs)))])
ob=mesh('BUDDHA - draped torso',vs,fs,stone)
for f in ob.data.polygons:f.use_smooth=True
mod=ob.modifiers.new('Soft carved robe','SUBSURF');mod.levels=2;mod.render_levels=2
ell('neck',(0,.015,1.265),(.10,.10,.13))
for sign in [-1,1]:
ell('rounded robe shoulder',(sign*.265,0,1.135),(.095,.091,.107))
tube('relaxed arm',[(sign*.265,0,1.15),(sign*.32,-.015,.99),(sign*.34,-.08,.80),(sign*.22,-.255,.725),(sign*.085,-.30,.715)],.075)
ell('hand in meditation',(sign*.052,-.325,.73+sign*.012),(.13,.073,.037),rot=sign*.08)
for i in range(3):tube('finger crease',[(sign*.015,-.375-i*.008,.734+sign*.012),(sign*.11,-.365-i*.008,.728+sign*.012)],.0014,shade)
tube('touching thumbs',[(-.09,-.30,.755),(-.035,-.29,.79),(0,-.30,.785),(.035,-.29,.79),(.09,-.30,.755)],.014)
# A serene face, lowered eyelids, elongated earlobes and ushnisha.
ell('head',(0,0,1.48),(.157,.136,.21))
ell('chin',(0,-.033,1.355),(.100,.088,.067))
for sign in [-1,1]:
ell('ear',(sign*.157,.002,1.46),(.037,.050,.104))
ell('elongated earlobe',(sign*.158,-.002,1.365),(.026,.028,.055))
tube('ear carving',[(sign*.168,-.036,1.52),(sign*.181,-.042,1.47),(sign*.171,-.037,1.40)],.004,shade)
tube('gentle brow',[(sign*.022,-.127,1.527),(sign*.068,-.127,1.545),(sign*.113,-.105,1.53)],.009)
tube('lowered eyelid',[(sign*.026,-.131,1.497),(sign*.061,-.133,1.486),(sign*.102,-.112,1.493)],.0035,shade)
ell('nose bridge',(0,-.133,1.46),(.024,.029,.064))
ell('nose tip',(0,-.155,1.423),(.029,.024,.017))
tube('calm closed mouth',[(-.047,-.116,1.387),(-.022,-.130,1.392),(0,-.133,1.389),(.022,-.130,1.392),(.047,-.116,1.387)],.0028,shade)
ell('lower lip',(0,-.123,1.378),(.037,.010,.009))
ell('ushnisha topknot',(0,.022,1.723),(.087,.086,.092))
for j in range(7):
a=.16+j*.14;num=max(9,int(36*sin(a)))
for i in range(num):
b=2*pi*(i+.5*(j%2))/num
ell('carved hair curl',(.161*sin(a)*cos(b),.143*sin(a)*sin(b),1.48+.214*cos(a)),(.018,.018,.015),nu=10,nv=6)
for j in range(6):
a=.20+j*.29;num=max(6,int(24*sin(a)))
for i in range(num):
b=2*pi*(i+.5*(j%2))/num
ell('topknot carving',(.087*sin(a)*cos(b),.022+.086*sin(a)*sin(b),1.723+.092*cos(a)),(.013,.013,.011),nu=8,nv=6)
# Robe seam and restrained shallow folds.
tube('robe diagonal edge',[(-.18,-.095,1.20),(-.11,-.16,1.10),(.02,-.174,.97),(.15,-.15,.86),(.20,-.13,.77)],.013)
for j in range(5):
z=.61+j*.075;tube('robe fold',[(-.18,-.13,z+.04),(-.05,-.173,z),(.11,-.155,z-.008)],.0045)
for sign in [-1,1]:
for j in range(3):tube('knee robe fold',[(sign*.22,-.37,.57+j*.022),(sign*.42,-.30,.57+j*.025),(sign*.55,-.17,.55+j*.027)],.005)
# Fuse the neck, shoulders and arms into one continuous stone carving.
detail=bpy.data.collections['DETAIL - full geometry for renders'];was_hidden=detail.hide_viewport;detail.hide_viewport=False;bpy.context.view_layer.update()
parts=[ob for ob in c.objects if any(k in ob.name for k in ['draped torso','rounded robe shoulder','relaxed arm',' - neck'])]
vs=[];fs=[];dg=bpy.context.evaluated_depsgraph_get()
for ob in parts:
ev=ob.evaluated_get(dg);me=ev.to_mesh();off=len(vs);vs.extend(tuple(v.co) for v in me.vertices);fs.extend(tuple(off+i for i in p.vertices) for p in me.polygons);ev.to_mesh_clear()
body=mesh('BUDDHA - continuous carved upper body',vs,fs,stone)
bpy.context.view_layer.objects.active=body
rem=body.modifiers.new('Joined limestone carving','REMESH');rem.mode='VOXEL';rem.voxel_size=.007;rem.use_smooth_shade=True
bpy.ops.object.modifier_apply(modifier=rem.name)
sm=body.modifiers.new('Stone carving finish','SMOOTH');sm.factor=.65;sm.iterations=5;bpy.ops.object.modifier_apply(modifier=sm.name)
for ob in parts:bpy.data.objects.remove(ob,do_unlink=True)
detail.hide_viewport=was_hidden
# Rotate east to look toward shared court; north of meditation room, south of garden path.
cx,cy=-12.4,15.35
def ground(x,y):return -.024*y+.004*x+.12*sin(x*.19)*cos(y*.14)+.055*sin(x*.72+y*.32)
zbase=max(ground(cx+x,cy+y) for x in [-.6,.6] for y in [-.8,.8])+.025
T=Matrix.Translation((cx,cy,zbase))@Matrix.Rotation(pi/2,4,'Z')
for ob in c.objects:ob.matrix_world=T@Matrix.LocRotScale(ob.location,ob.rotation_euler.to_quaternion(),ob.scale)
# Single smooth lightweight viewport proxy, no object overhead from small carving details.
vs=[];fs=[];inds=[];smooth=[];mats=[]
for ob in c.objects:
mw=Matrix.LocRotScale(ob.location,ob.rotation_euler.to_quaternion(),ob.scale);off=len(vs);vs.extend(tuple(mw@v.co) for v in ob.data.vertices)
for m in ob.data.materials:
if m not in mats:mats.append(m)
for p in ob.data.polygons:fs.append(tuple(off+i for i in p.vertices));inds.append(mats.index(ob.data.materials[p.material_index]));smooth.append(p.use_smooth)
me=bpy.data.meshes.new('Buddha garden viewport');me.from_pydata(vs,[],fs);me.update()
for m in mats:me.materials.append(m)
me.polygons.foreach_set('material_index',inds);me.polygons.foreach_set('use_smooth',smooth)
proxy=bpy.data.objects.new('FAST | Garden Buddha statue',me);bpy.data.collections['00 FAST TOUR - lightweight viewport'].objects.link(proxy)
chapters=json.load(open(O+'/tour-chapters-container-water.json'));title='31 / QUIET GARDEN BUDDHA';chapters.append(dict(title=title,start=3601,end=3720,seconds=5))
cam=bpy.data.objects['PLAY TOUR camera'];s.frame_end=3720
for f,p in [(3601,(-7.5,18.2,2.6)),(3720,(-7.8,17.7,2.35))]:
s.frame_set(f);cam.location=p;cam.rotation_euler=(Vector((cx,cy,zbase+.95))-cam.location).to_track_quat('-Z','Y').to_euler();cam.keyframe_insert('location',frame=f);cam.keyframe_insert('rotation_euler',frame=f);cam.data.lens=49;cam.data.keyframe_insert('lens',frame=f)
coll=bpy.data.collections['22 PLAY - guided camera tour'];fonts=[o for o in coll.objects if o.type=='FONT']
ref=next(o for o in fonts if o.data.body.startswith('30 /'))
ref.scale=(0,0,0);ref.keyframe_insert('scale',frame=3601)
caption=ref.copy();caption.data=ref.data.copy();caption.animation_data_clear();coll.objects.link(caption);caption.name='Tour caption 31 - garden Buddha';caption.data.body=title;caption.location=(-36/49*.91,36/49*9/16*.84,-2)
for f,k in [(1,0),(3600,0),(3601,1),(3720,1)]:caption.scale=(k,k,k);caption.keyframe_insert('scale',frame=f)
for ob in [ref,caption]:
for layer in ob.animation_data.action.layers:
for strip in layer.strips:
for bag in strip.channelbags:
for fc in bag.fcurves:
for key in fc.keyframe_points:key.interpolation='CONSTANT'
s.timeline_markers.new(title,frame=3601);s['PLAY THE TOUR']='Hover over the 3D view and press Space. 31 chapters, 2 min 35 sec. Shift+Left Arrow restarts.'
s['Garden Buddha']='Weathered limestone seated Buddha on a low stone plinth, north of the meditation pavilion, facing east into the shared garden court. Version 006.'
text=bpy.data.texts.get('START HERE - PRESS PLAY')
if text:text.clear();text.write(s['PLAY THE TOUR']+'\n\n'+s['Garden Buddha'])
layout=json.load(open(O+'/container-water-layout.json'));layout.update(version=6,buddha=[cx,cy,zbase],buddha_facing='east')
json.dump(layout,open(O+'/buddha-garden-layout.json','w'),indent=2);json.dump(chapters,open(O+'/tour-chapters-buddha-garden.json','w'),indent=2)
s.frame_set(3601);s.render.resolution_percentage=100;s.camera=cam
bpy.ops.wm.save_as_mainfile(filepath=O+'/samford-solarpunk-buddha-garden-tour.blend')
for o in fonts+[caption]:o.hide_render=True
s.render.resolution_percentage=60;s.cycles.samples=48;s.cycles.use_denoising=True
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=O+'/buddha-garden.png';bpy.ops.render.render(write_still=True)
print('BUDDHA_READY',len(c.objects),len(fs),flush=True)

View File

@@ -0,0 +1,138 @@
import bpy,math,os,json
from mathutils import Vector,Matrix
from math import cos,sin,pi
O=os.path.dirname(__file__);s=bpy.context.scene;detail=bpy.data.collections['DETAIL - full geometry for renders'];fast=bpy.data.collections['00 FAST TOUR - lightweight viewport'];services=bpy.data.collections['05 Water and services']
c=bpy.data.collections.new('35 Shipping container - rainwater storage');detail.children.link(c);COL={'new':c};active='new'
src=open(O+'/../samford-modular/build_scene.py').read();exec(src[src.index('def mesh('):src.index('timber=textured(')])
cubefs=[tuple(reversed(f)) for f in cubefs]
green=textured('Container olive green powder-coated steel',(.065,.12,.080),(.095,.17,.11),(95,95,95),.43,.0006);green.node_tree.nodes['Principled BSDF'].inputs['Metallic'].default_value=.65
steel=bpy.data.materials['Reusable dark steel bolts and shoes'];stone=bpy.data.materials['Split sandstone facing - mineral grain'];metal=bpy.data.materials['Appliance brushed metal'];wood=bpy.data.materials['Unpainted hardwood - long X grain'];gravel=bpy.data.materials['Loose local gravel - fine stones']
watermat=mat('Container enclosed water tanks pale grey polymer',(.59,.66,.57),.50);pipe=mat('Rainwater pipe dark polyethylene',(.03,.047,.035),.43);labelmat=mat('Container cream stencil lettering',(.74,.75,.62),.65)
def ground(x,y):return -.024*y+.004*x+.12*sin(x*.19)*cos(y*.14)+.055*sin(x*.72+y*.32)
removed=[]
for ob in list(services.objects):
if ob.name.startswith(('Gravel tank pad','2000 mm dark green poly rainwater tank','Poly tank','Tank service lid','Accessible tank outlet')):removed.append(ob.name);bpy.data.objects.remove(ob,do_unlink=True)
cx,cy,base=-25,-8,.42;L,W,H=6.06,2.44,2.59;xs,xe=cx-L/2,cx+L/2;ys,yn=cy-W/2,cy+W/2
# Rectangular container corner posts, ISO-style castings and structural rails.
box('CONTAINER WATER - steel base frame',(cx,cy,base+.075),(L,W,.15),green,.01)
box('Container non-absorbent interior floor',(cx,cy,base+.165),(L-.15,W-.15,.03),steel,.005)
for x in [xs+.08,xe-.08]:
for y in [ys+.08,yn-.08]:
g=ground(x,y);box('Container support pier',(x,y,(g+base)/2),(.38,.38,max(.1,base-g)),stone,.012)
box('Container structural corner post',(x,y,base+H/2),(.15,.15,H),green,.01)
for z in [base+.10,base+H-.10]:
box('ISO corner casting',(x,y,z),(.19,.18,.19),metal,.015)
box('ISO casting lifting recess',(x,y+(.093 if y>cy else -.093),z),(.075,.006,.065),steel,.014)
for y in [ys+.06,yn-.06]:
for z in [base+.18,base+H-.075]:box('Container long structural rail',(cx,y,z),(L,.13,.15),green,.007)
for x in [xs+.06,xe-.06]:box('Container upper end rail',(x,cy,base+H-.075),(.13,W,.15),green,.007)
# Corrugated long walls: folded sheet geometry rather than flat paint stripes.
for y,sign in [(ys,-1),(yn,1)]:
vs=[];faces=[];n=160
for i in range(n+1):
x=xs+.15+(L-.30)*i/n;fold=.028 if i%4 in [1,2] else -.028
vs.extend([(x,y+sign*fold,base+.24),(x,y+sign*fold,base+H-.15)])
for i in range(n):k=i*2;faces.append((k,k+2,k+3,k+1) if sign<0 else (k,k+1,k+3,k+2))
mesh('Container corrugated '+('south' if sign<0 else 'north')+' steel wall',vs,faces,green)
box('Container rain-shedding roof',(cx,cy,base+H-.035),(L-.12,W-.12,.055),green,.008)
for i in range(28):box('Container roof corrugation',(xs+.18+i*.21,cy,base+H+.005),(.055,W-.22,.025),green,.006)
# Recognisable double cargo doors at the east end, seals and locking bars.
for y in [cy-.56,cy+.56]:
box('Container cargo door dark gasket',(xe-.055,y,base+1.38),(.045,1.115,2.25),steel,.006)
box('Container cargo door panel',(xe-.021,y,base+1.38),(.04,1.065,2.20),green,.007)
for yy in [y-.25,y+.25]:
rod('Container door locking bar',(xe+.036,yy,base+.30),(xe+.036,yy,base+2.42),.015,metal,sides=16)
for z in [base+.42,base+1.19,base+2.28]:box('Door locking bar keeper',(xe+.051,yy,z),(.035,.075,.075),green,.007)
rod('Cargo door latch handle',(xe+.085,yy,base+1.13),(xe+.085,yy+.16,base+1.13),.013,metal,sides=12)
for z in [base+.48,base+1.36,base+2.21]:box('Container door hinge',(xe+.016,y+(.52 if y>cy else -.52),z),(.07,.12,.095),metal,.008)
# West end is a presentation cutaway, matching the other building cutaway views.
cut=mat('VIEW container west end transparent steel',(.07,.13,.085),.45,.6);ns=cut.node_tree.nodes;ls=cut.node_tree.links;tr=ns.new('ShaderNodeBsdfTransparent');mix=ns.new('ShaderNodeMixShader');mix.inputs[0].default_value=.07;ls.new(tr.outputs[0],mix.inputs[1]);ls.new(ns.get('Principled BSDF').outputs[0],mix.inputs[2]);ls.new(mix.outputs[0],ns.get('Material Output').inputs['Surface'])
cut.diffuse_color=(.07,.13,.085,.07)
ob=box('CONTAINER - west inspection cutaway',(xs+.035,cy,base+H/2),(.04,W-.20,H-.30),cut);ob.hide_set(True);ob['Presentation only']='West wall transparent for inspection. Restore olive container steel material for a closed exterior.'
# Two separate sealed tank vessels; the container shell itself is not a pressure/water vessel.
for x in [cx-1.55,cx+.75]:
z=base+.20
rod('INTERNAL RAINWATER TANK - sealed vessel',(x,cy,z),(x,cy,z+1.88),.92,watermat,sides=64)
rod('Internal water tank lid',(x,cy,z+1.88),(x,cy,z+1.92),.89,watermat,sides=64)
rod('Tank inspection hatch',(x,cy,z+1.92),(x,cy,z+1.965),.17,steel,sides=32)
for j in range(9):
zz=z+.15+j*.19;rod('Tank internal reinforcing band',(x,cy,zz),(x,cy,zz+.02),.933,watermat,sides=64)
rod('Tank top inlet connection',(x,cy,z+1.96),(x,cy,z+2.09),.033,pipe,sides=20)
rod('Tank manifold branch',(x,cy,z+2.09),(x,cy+.63,z+2.09),.033,pipe,sides=20)
rod('Tank low service connection',(x,cy-.88,z+.13),(x,cy-1.02,z+.13),.031,pipe,sides=20)
rod('Rainwater shared inlet manifold',(cx-1.55,cy+.63,base+2.29),(xe-.6,cy+.63,base+2.29),.035,pipe,sides=20)
rod('Rainwater shared outlet manifold',(cx-1.55,cy-1.02,base+.33),(xe-.6,cy-1.02,base+.33),.035,pipe,sides=20)
rod('Rainwater external inlet riser',(xe-.6,yn+.2,base+.1),(xe-.6,yn+.2,base+2.29),.04,pipe,sides=24)
rod('First flush collection chamber',(xe-1.0,yn+.2,base+.25),(xe-1.0,yn+.2,base+1.15),.10,watermat,sides=32)
box('Water service pump plinth',(xe-.7,ys-.65,base+.10),(.64,.72,.20),stone,.01)
rod('Water service pump motor',(xe-.7,ys-.89,base+.35),(xe-.7,ys-.41,base+.35),.13,metal,sides=32)
for x in [xe-.95,xe-.45]:box('Water pump fixing foot',(x,ys-.65,base+.245),(.075,.30,.09),steel,.007)
box('Rainwater outlet isolation valve',(xe-.6,ys-.25,base+.35),(.10,.11,.12),metal,.009)
box('Rainwater valve lever',(xe-.6,ys-.25,base+.46),(.21,.026,.02),green,.004)
rod('Inlet through-wall connection',(xe-.6,cy+.63,base+2.29),(xe-.6,yn+.2,base+2.29),.035,pipe,sides=20)
rod('Outlet through-wall connection',(xe-.6,cy-1.02,base+.33),(xe-.6,ys-.4,base+.33),.035,pipe,sides=20)
# Collection route toward the existing parents-wing downpipe, clear of paths above.
for a,b in [((-15.7,-7.83,-.15),(-18.4,-8.0,-.15)),((-18.4,-8,-.15),(xe-.6,yn+.2,-.15))]:rod('Buried roof collection pipe - concept route',a,b,.04,pipe,sides=20)
# Long-side stencil helps the object read clearly as a service container.
cu=bpy.data.curves.new('Rainwater container stencil','FONT');cu.body='RAINWATER';cu.size=.19;cu.extrude=.0005;cu.materials.append(labelmat)
t=bpy.data.objects.new('Container RAINWATER stencil',cu);c.objects.link(t);t.location=(cx+.7,yn+.035,base+1.5);t.rotation_euler=(pi/2,0,pi)
# Adjust the former tank path to approach the container's east cargo doors.
gardens=bpy.data.collections['34 Garden court - aligned pavilions and flowing landscape'];old=bpy.data.objects.get('Rainwater service garden path')
if old:bpy.data.objects.remove(old,do_unlink=True)
layout=json.load(open(O+'/garden-flow-layout.json'));layout['version']=5;layout['water_container']=[cx,cy,L,W,H]
points=[(-23,8.1),(-28.5,8.2),(-29.3,1),(-29.1,-5),(-29.1,-11.5),(-25,-12),(-20.5,-11.4),(-20.5,-8),(xe,-8)]
# Smooth Catmull-Rom route follows terrain and stops at the east cargo doors.
pts=[];p=[Vector(q) for q in points]
for i in range(len(p)-1):
a=p[max(0,i-1)];b=p[i];cc=p[i+1];d=p[min(i+2,len(p)-1)]
for j in range(20):
f=j/20;v=.5*(2*b+(-a+cc)*f+(2*a-5*b+4*cc-d)*f*f+(-a+3*b-3*cc+d)*f*f*f);pts.append(tuple(v))
pts.append(tuple(p[-1]));vs=[];fs=[]
for i,q in enumerate(pts):
v=Vector(q);d=Vector(pts[min(i+1,len(pts)-1)])-Vector(pts[max(i-1,0)]);side=Vector((-d.y,d.x)).normalized()*.575
for vv in [v-side,v+side]:vs.append((vv.x,vv.y,ground(*vv)+.085))
for i in range(len(pts)-1):k=i*2;fs.append((k,k+1,k+3,k+2))
mesh('Rainwater container service garden path',vs,fs,gravel)
for path in layout['paths']:
if path['name']=='Rainwater service garden path':path.update(name='Rainwater container service garden path',points=pts)
# Refresh only the affected fast display meshes, leaving tree simplification untouched.
def combine(coll,name):
old=bpy.data.objects.get(name)
if old:bpy.data.objects.remove(old,do_unlink=True)
vs=[];fs=[];indices=[];mats=[];lookup={}
for ob in coll.objects:
if ob.type!='MESH' or ob.hide_render or ob.hide_get():continue
remap=[]
for m in ob.data.materials:
if m not in lookup:lookup[m]=len(mats);mats.append(m)
remap.append(lookup[m])
mw=Matrix.LocRotScale(ob.location,ob.rotation_euler.to_quaternion(),ob.scale);off=len(vs);vs.extend(tuple(mw@v.co) for v in ob.data.vertices)
for poly in ob.data.polygons:fs.append(tuple(off+j for j in poly.vertices));indices.append(remap[poly.material_index])
me=bpy.data.meshes.new(name);me.from_pydata(vs,[],fs);me.update()
for m in mats:me.materials.append(m)
me.polygons.foreach_set('material_index',indices);ob=bpy.data.objects.new(name,me);fast.objects.link(ob)
combine(services,'FAST | 05 Water and services');combine(gardens,'FAST | Aligned garden court and flowers');combine(c,'FAST | Container rainwater storage')
cam=bpy.data.objects['PLAY TOUR camera'];chapters=json.load(open(O+'/tour-chapters-garden-flow.json'));chapters[12]['title']='13 / CONTAINER RAINWATER STORAGE'
for f,pos in [(1441,(-17,-2.5,4.6)),(1560,(-17.5,-3.1,4.3))]:
s.frame_set(f);cam.location=pos;cam.rotation_euler=(Vector((-25,-8,1.6))-cam.location).to_track_quat('-Z','Y').to_euler();cam.keyframe_insert('location',frame=f);cam.keyframe_insert('rotation_euler',frame=f);cam.data.lens=40;cam.data.keyframe_insert('lens',frame=f)
fonts=[o for o in bpy.data.collections['22 PLAY - guided camera tour'].objects if o.type=='FONT']
for o in fonts:
if o.data.body.startswith('13 /'):o.data.body=chapters[12]['title'];half=36/40;o.location=(-half*.91,half*9/16*.84,-2)
for m in s.timeline_markers:
if m.frame==1441:m.name=chapters[12]['title']
s['Water storage']='20-foot container-style enclosure with two separate sealed internal tanks, corrugated steel shell, cargo doors, plumbing and a west inspection cutaway. Container shell is not modelled as the water-retaining vessel. Structural/loading, tank product and water-system sizing remain concept design.'
s['Current design']=s.get('Current design','')+' Exposed cylindrical tanks replaced by a container water-storage module in version 005.'
s.frame_set(1441);s.render.resolution_percentage=100
json.dump(layout,open(O+'/container-water-layout.json','w'),indent=2);json.dump(chapters,open(O+'/tour-chapters-container-water.json','w'),indent=2)
report={'container_dimensions_m':[L,W,H],'internal_tanks':sum(o.name.startswith('INTERNAL RAINWATER TANK') for o in s.objects),'old_exposed_tanks_removed':not any(o.name.startswith('2000 mm dark green poly rainwater tank') for o in s.objects),'west_inspection_cutaway':True,'tour_chapters':len(chapters),'removed_old_objects':len(removed)}
assert report['internal_tanks']==2 and report['old_exposed_tanks_removed']
json.dump(report,open(O+'/container-water-checks.json','w'),indent=2)
bpy.ops.wm.save_as_mainfile(filepath=O+'/samford-solarpunk-container-water-tour.blend')
for o in fonts:o.hide_render=True
s.render.resolution_percentage=60;s.cycles.samples=32;s.cycles.use_denoising=True
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'
for name,f in [('container-water.png',1480),('container-water-overview.png',45)]:s.frame_set(f);s.render.filepath=O+'/'+name;bpy.ops.render.render(write_still=True)
cam.animation_data_clear();cam.data.animation_data_clear();cam.location=(-33,-3.5,4);cam.rotation_euler=(Vector((-25.5,-8,1.6))-cam.location).to_track_quat('-Z','Y').to_euler();cam.data.lens=38;s.render.filepath=O+'/container-water-cutaway.png';bpy.ops.render.render(write_still=True)
print('CONTAINER_WATER_READY '+json.dumps(report),flush=True)

View File

@@ -1,6 +1,6 @@
from pathlib import Path from pathlib import Path
import json,html import json,html
O=Path(__file__).parent;d=json.loads((O/'garden-flow-layout.json').read_text());p=[] O=Path(__file__).parent;d=json.loads((O/('container-water-layout.json' if (O/'container-water-layout.json').exists() else 'garden-flow-layout.json')).read_text());p=[]
p.append('<svg xmlns="http://www.w3.org/2000/svg" width="1400" height="1180" viewBox="0 0 1400 1180"><rect width="1400" height="1180" fill="#f3f0e7"/><style>text{font-family:Arial,sans-serif;fill:#30433b}.sub{fill:#68756b}</style><text x="60" y="58" font-size="31" font-weight="600">A home held together by its garden.</text><text x="60" y="91" font-size="16" class="sub">SAMFORD VALLEY / Aligned pavilions, soft garden curves and room to grow · Concept 004</text>') p.append('<svg xmlns="http://www.w3.org/2000/svg" width="1400" height="1180" viewBox="0 0 1400 1180"><rect width="1400" height="1180" fill="#f3f0e7"/><style>text{font-family:Arial,sans-serif;fill:#30433b}.sub{fill:#68756b}</style><text x="60" y="58" font-size="31" font-weight="600">A home held together by its garden.</text><text x="60" y="91" font-size="16" class="sub">SAMFORD VALLEY / Aligned pavilions, soft garden curves and room to grow · Concept 004</text>')
def pt(x,y):return (600+x*13,500-y*13) def pt(x,y):return (600+x*13,500-y*13)
def line(pts,color,w,dash=''): def line(pts,color,w,dash=''):
@@ -39,8 +39,11 @@ rect(*d['solar'],'#849a9d');label(9.4,-18.7,['GROUND SOLAR'],9)
label(0,-25,['Aligned garage, training and energy zone'],11) label(0,-25,['Aligned garage, training and energy zone'],11)
x,y=d['sauna'];ellipse(x,y,2.2,2.0,'#ba9b75');label(x,y+.15,['SAUNA'],10) x,y=d['sauna'];ellipse(x,y,2.2,2.0,'#ba9b75');label(x,y+.15,['SAUNA'],10)
rect(-27,6.8,1.3,1.3,'#b0c5c1');label(-29,10,['Outdoor shower'],10) rect(-27,6.8,1.3,1.3,'#b0c5c1');label(-29,10,['Outdoor shower'],10)
for x in [-23.95,-26.25]:ellipse(x,-8,1,1,'#6d8563') if 'water_container' in d:
label(-25,-10.8,['Rainwater tanks'],10) rect(*d['water_container'][:4],'#6d8563');label(-25,-13.8,['CONTAINER WATER','2 enclosed tanks'],10)
else:
for x in [-23.95,-26.25]:ellipse(x,-8,1,1,'#6d8563')
label(-25,-10.8,['Rainwater tanks'],10)
rect(24.2,-7.5,4.3,5,'#c3d7c2');label(24.2,-7.4,['GREENHOUSE'],9) rect(24.2,-7.5,4.3,5,'#c3d7c2');label(24.2,-7.4,['GREENHOUSE'],9)
for x in [23.8,27.5]: for x in [23.8,27.5]:
for y in [-1.7,1.5,4.7]:rect(x,y,2.3,1.3,'#ad9573') for y in [-1.7,1.5,4.7]:rect(x,y,2.3,1.3,'#ad9573')
@@ -51,4 +54,4 @@ label(12,-7,['FLOWER','GARDEN'],10)
rect(*d['future_basketball'],'#edf0e6','stroke-dasharray="6 6"');label(13,-35,['FUTURE','BASKETBALL','Unbuilt reserve'],11) rect(*d['future_basketball'],'#edf0e6','stroke-dasharray="6 6"');label(13,-35,['FUTURE','BASKETBALL','Unbuilt reserve'],11)
label(27,-29,['4 m gravel access'],11) label(27,-29,['4 m gravel access'],11)
p.extend(['<path d="M1250 220V153m0 0l-9 18m9-18l9 18" fill="none" stroke="#30433b" stroke-width="3"/><text x="1250" y="140" text-anchor="middle" font-size="17">N</text>','<line x1="65" y1="1030" x2="195" y2="1030" stroke="#30433b" stroke-width="4"/><text x="65" y="1060" font-size="13">10 metres</text>','<line x1="60" y1="1090" x2="1340" y2="1090" stroke="#c5cebd"/><text x="60" y="1120" font-size="14">13 planted garden beds · Smooth pedestrian routes · Future pavilions remain shadows · Table-tennis deck removed</text>','<text x="60" y="1147" font-size="13" class="sub">Concept only: illustrative terrain, no surveyed boundary. Plant forms and structural connections require site-specific design development.</text></svg>']) p.extend(['<path d="M1250 220V153m0 0l-9 18m9-18l9 18" fill="none" stroke="#30433b" stroke-width="3"/><text x="1250" y="140" text-anchor="middle" font-size="17">N</text>','<line x1="65" y1="1030" x2="195" y2="1030" stroke="#30433b" stroke-width="4"/><text x="65" y="1060" font-size="13">10 metres</text>','<line x1="60" y1="1090" x2="1340" y2="1090" stroke="#c5cebd"/><text x="60" y="1120" font-size="14">13 planted garden beds · Smooth pedestrian routes · Future pavilions remain shadows · Table-tennis deck removed</text>','<text x="60" y="1147" font-size="13" class="sub">Concept only: illustrative terrain, no surveyed boundary. Plant forms and structural connections require site-specific design development.</text></svg>'])
(O/'garden-flow-plan.svg').write_text(''.join(p)) (O/('container-water-plan.svg' if d['version']==5 else 'garden-flow-plan.svg')).write_text(''.join(p).replace('Concept 004','Concept 005' if d['version']==5 else 'Concept 004'))

View File

@@ -0,0 +1,19 @@
import bpy,json,os,math
from mathutils import Vector
O=os.path.dirname(__file__);s=bpy.context.scene;chapters=json.load(open(O+'/tour-chapters-buddha-garden.json'));fonts=[o for o in bpy.data.collections['22 PLAY - guided camera tour'].objects if o.type=='FONT'];issues=[]
for ch in chapters:
s.frame_set(ch['start']+30);shown=[o.data.body for o in fonts if o.scale.length>.5]
if shown!=[ch['title']]:issues.append([ch['title'],shown])
names=[o.name for o in s.objects];layout=json.load(open(O+'/buddha-garden-layout.json'));x,y,z=layout['buddha']
# Actual rotated rectangular plinth lies outside the pavilion and walking-path ribbon.
mx,my,mw,md=layout['meditation'];assert y-.78>my+md/2
clearance=999
for path in layout['paths']:
if path['kind']=='roofed walk':continue
for q in path['points']:
dist=math.hypot(max(abs(q[0]-x)-.59,0),max(abs(q[1]-y)-.78,0))-path['width']/2
clearance=min(clearance,dist)
assert clearance>.05,clearance
report={'buddha_collection_objects':len(bpy.data.collections['36 Buddha - meditation garden'].objects),'viewport_proxy':'FAST | Garden Buddha statue' in names,'tour_chapters':len(chapters),'caption_issues':issues,'path_clearance_m':round(clearance,3),'statue_outside_room':True,'internal_water_tanks':sum(n.startswith('INTERNAL RAINWATER TANK') for n in names),'kitchen_preserved':'ISLAND - honed marble countertop' in names,'no_table_tennis':not any('table tennis' in n.lower() for n in names),'render_size':[s.render.resolution_x,s.render.resolution_y,s.render.resolution_percentage]}
assert len(chapters)==31 and s.frame_end==3720 and not issues and report['viewport_proxy'] and report['internal_water_tanks']==2 and report['kitchen_preserved'] and report['no_table_tennis'] and report['render_size']==[2560,1440,100]
json.dump(report,open(O+'/buddha-garden-verification.json','w'),indent=2);print('VERIFIED '+json.dumps(report),flush=True)

View File

@@ -0,0 +1,19 @@
import bpy,json,os
from mathutils import Matrix,Vector
O=os.path.dirname(__file__);s=bpy.context.scene
chapters=json.load(open(O+'/tour-chapters-container-water.json'));fonts=[o for o in bpy.data.collections['22 PLAY - guided camera tour'].objects if o.type=='FONT'];issues=[]
for c in chapters:
s.frame_set(c['start']+30);shown=[o.data.body for o in fonts if o.scale.length>.5]
if shown!=[c['title']]:issues.append([c['title'],shown])
names=[o.name for o in s.objects]
report={'internal_tanks':sum(n.startswith('INTERNAL RAINWATER TANK') for n in names),'old_exposed_tanks_removed':not any(n.startswith('2000 mm dark green poly rainwater tank') for n in names),'container':all(n in names for n in ['CONTAINER WATER - steel base frame','Container corrugated north steel wall','CONTAINER - west inspection cutaway']),'tour_chapters':len(chapters),'caption_issues':issues,'render_size':[s.render.resolution_x,s.render.resolution_y,s.render.resolution_percentage],'kitchen_preserved':'ISLAND - honed marble countertop' in names,'no_table_tennis':not any('table tennis' in n.lower() for n in names)}
assert report['internal_tanks']==2 and report['old_exposed_tanks_removed'] and report['container'] and not issues and report['kitchen_preserved'] and report['no_table_tennis']
assert report['render_size']==[2560,1440,100] and s.frame_end==3600
# Internal tank bounding boxes fit within the structural enclosure.
for o in s.objects:
if o.name.startswith('INTERNAL RAINWATER TANK'):
m=Matrix.LocRotScale(o.location,o.rotation_euler.to_quaternion(),o.scale)
for b in o.bound_box:
v=m@Vector(b);assert -27.98<v.x<-22.02 and -9.17<v.y<-6.83 and .58<v.z<2.9
s.frame_set(1441);bpy.ops.wm.save_as_mainfile(filepath=O+'/samford-solarpunk-container-water-tour.blend')
json.dump(report,open(O+'/container-water-verification.json','w'),indent=2);print('VERIFIED '+json.dumps(report),flush=True)