Enclose rainwater tanks in a shipping-container module

This commit is contained in:
2026-09-10 21:15:34 +10:00
parent 62713b9e38
commit 79c5eeddbb
18 changed files with 5865 additions and 20 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-container-water-tour.blend, version 005.
- 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.
@@ -14,3 +14,5 @@ Read README.md, docs/PROJECT-CONTEXT.md, docs/REQUEST-HISTORY.md and the latest
- Marcus authorised making the repository, working files and design context public. The separate website gallery 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.

View File

@@ -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-container-water-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 container water-storage 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/container-water-plan.svg`. Current version 005 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,7 @@ 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.

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.

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,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

@@ -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 005, 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-container-water-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.
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/container-water-plan.svg`. It is generated from the same `container-water-layout.json` coordinates used by the Blender revision. Latest 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,13 +58,13 @@ 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 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 chapter 13, container rainwater storage. 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.
@@ -75,3 +75,7 @@ Public repository: https://git.rehbock.xyz/marcus/samford-valley-home . Server w
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.

View File

@@ -40,3 +40,7 @@ Actual property and required area; surveyed levels/boundaries; planning approval
## Subsequent visibility decision ## 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. 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.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

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,14 @@
{ {
"milestone": "2026-09-10-v004-garden-flow", "milestone": "2026-09-10-v005-container-water",
"files": { "files": {
".gitattributes": "d4f9cc15aed223cff7a906452370117fc93992272828cb1efbdd94c61422ad19", ".gitattributes": "d4f9cc15aed223cff7a906452370117fc93992272828cb1efbdd94c61422ad19",
".gitignore": "d38c3a1d58416906185c4c7695ea24f9401be3b610fcce0e624f41dff9fe1675", ".gitignore": "d38c3a1d58416906185c4c7695ea24f9401be3b610fcce0e624f41dff9fe1675",
"AGENTS.md": "2f8161360734c48e15aee2876b5ec778bcf872a3fd7e0f70ebe1575e9a6ecb4c", "AGENTS.md": "b4c5ed43cf84a524961fa81babcd3f83a33506edf0b3cb1f9abd56afc9dcf933",
"README.md": "7b72cab83d902af1791bffec1d845dd8983b7bde4422c22da403d4491be37fd6", "README.md": "7ae06d8f50612a0a50249be16be4f636846763ffc9b8aa15ed703aa3248153bf",
"blender/bedroom-sleep-checks.json": "4f28426b4c23e55c956a4c5bc94947706da63e35de455cfaedd8e90e330f1114", "blender/bedroom-sleep-checks.json": "4f28426b4c23e55c956a4c5bc94947706da63e35de455cfaedd8e90e330f1114",
"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 +17,7 @@
"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-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 +25,28 @@
"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-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": "cbe4906dcea6617cc72b08ce7c8b25d0750481eeb39bf74a01b19032be426631", "decisions/2026-09-10-v005-container-water.md": "5fc937e7231a6b3d1856a0f7db2a998c81e4b51afb31fa4222a8d3e931de53fc",
"docs/REQUEST-HISTORY.md": "0086ad7253c6067b36ab7fc3586b5a5d702d0e051795c3932c7fb93dcd99b154", "docs/PROJECT-CONTEXT.md": "c283ab1c20e78cec8cfdd27998505fd1db5b4c9e5c859cc07dad6a7a8a963324",
"docs/REQUEST-HISTORY.md": "1c2797c29a437091a359e199343c7f9bbeb7c039b00736097769aedc93dccb58",
"plans/architectural/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "plans/architectural/.gitkeep": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"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/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",
@@ -68,7 +79,8 @@
"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 +103,7 @@
"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_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",
@@ -320,7 +333,6 @@
"unreal/Textures/M_11_Meditation_cushion_charcoal_linen_Normal.png": "4b0a80b762c24675c40ac26fd16272bd45039fa88098ada032631554da4dde57", "unreal/Textures/M_11_Meditation_cushion_charcoal_linen_Normal.png": "4b0a80b762c24675c40ac26fd16272bd45039fa88098ada032631554da4dde57",
"unreal/meditation-room-manifest.json": "3a900693fd579ee176955618d889fce6f72632878e5ee566ff4061222af58318", "unreal/meditation-room-manifest.json": "3a900693fd579ee176955618d889fce6f72632878e5ee566ff4061222af58318",
"unreal/unreal-scene-checks.json": "bed6fe7aea84a3dbe92dd382f970e7014e045365e38d05de12b69b933ffb634d", "unreal/unreal-scene-checks.json": "bed6fe7aea84a3dbe92dd382f970e7014e045365e38d05de12b69b933ffb634d",
"walkthroughs/UNREAL-CAMERA-ANIMATION.md": "f0c53352a5b6651409e99b6b696a95eca2330a8527fe347534efaabfe277b21a", "walkthroughs/UNREAL-CAMERA-ANIMATION.md": "f0c53352a5b6651409e99b6b696a95eca2330a8527fe347534efaabfe277b21a"
"decisions/2026-09-10-repository-public.md": "3ded28ebf5fde19aeed74caac9308260602551651fdaebf58494fe625d0d27ad"
} }
} }

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,6 +39,9 @@ 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)
if 'water_container' in d:
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') for x in [-23.95,-26.25]:ellipse(x,-8,1,1,'#6d8563')
label(-25,-10.8,['Rainwater tanks'],10) 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)
@@ -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
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)