Skip to content

AIStockBrah/BlendaModula

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

BlendaModula

A complete pipeline for authoring 3D building components in Blender, exporting them as GLB + JSON metadata, and assembling them in a configurator engine with placement validation, rendering presets, and live pricing.

Built for the Tiny House Titans CabinPlanner configurator.


What This Is

BlendaModula solves a specific problem: you want to design tiny houses by snapping together pre-authored 3D components (windows, doors, roof trim, corner boards) onto a shell, and have the system automatically validate placement rules, compute materials costs, and render the result with production-quality lighting.

The pipeline has three layers:

  1. Blender authoring — Model components in Blender following naming conventions. Each component has anchor points ("ports") that define how it attaches to the building shell.

  2. Python tooling — Validate and export .blend files to GLB format. Batch process an entire library. Generate consistent preview thumbnails.

  3. TypeScript configurator engine — Place modules on walls/roofs/corners with rule validation, detect collisions, compute BOM and pricing, apply render presets.


Quick Start

Prerequisites

  • Blender 4.0+ (for authoring and export tooling)
  • Node.js 18+ (for the configurator engine)
  • Python 3.10+ (for standalone JSON validation; Blender scripts use Blender's built-in Python)

Install the configurator

cd modules_3d/configurator
npm install

Run tests

# TypeScript engine tests (60 tests)
cd modules_3d/configurator
npm test

# Type-check
npm run build

# Validate all module JSON metadata (no Blender needed)
cd /path/to/BlendaModula
python3 modules_3d/tools/blender/batch_export.py -- \
  --library-root modules_3d/library \
  --json-only \
  --output-report batch_report.json

Project Structure

BlendaModula/
  CLAUDE.md                         # Build spec and project status
  README.md                         # This file

  modules_3d/
    library/                        # Module library (10 components)
      windows/                      # 3 window types
      doors/                        # 3 door types
      roof_edges/                   # 2 roof edge kits
      corners_trims/                # 2 trim kits
      furniture/                    # Placeholder for future modules

    tools/
      blender/                      # Blender Python automation scripts
      schema/                       # JSON Schema for module.json

    configurator/                   # TypeScript engine
      types.ts                      # Shared type definitions
      placement/                    # Port math, host rules, collision, resolver
      render/                       # PBR setup, HDRI, shadows/tone mapping
      pricing/                      # BOM aggregation and pricing computation
      templates/                    # Tiny house preset configurations

    docs/                           # Technical documentation
      MODULE_STANDARD.md            # Blender authoring guide
      PORTS_AND_HOSTING.md          # Port system reference
      RENDERING_GUIDE.md            # PBR and lighting guide
      PRICING_BOM_GUIDE.md          # BOM and pricing formula

Module Library

Each module lives in its own folder with these files:

File Purpose Required
module.blend Blender source file Yes*
module.glb Exported binary glTF Yes*
module.json Metadata, ports, rules, BOM Yes
preview.png 512x512 thumbnail Yes*

*The .blend, .glb, and .png files are generated during authoring. The V1 build includes complete module.json stubs for all 10 components — Blender geometry authoring is the next step.

The 10 Components

These were chosen to maximize visual impact on tiny house exteriors:

Windows

  • WIN_AWNING_24x36_v1 — 24"x36" top-hinged awning window. Common in bathrooms and kitchens.
  • WIN_CASEMENT_30x48_v1 — 30"x48" side-hinged casement. Egress-capable. Most common operable window in tiny houses.
  • WIN_PICTURE_48x48_v1 — 48"x48" fixed picture window. Biggest visual impact on elevations.

Doors

  • DOR_ENTRY_36_v1 — Standard 36" entry door with lever handle. Multiple panel styles.
  • DOR_SLIDER_72_v1 — 72" two-panel sliding glass door. Major feature element.
  • DOR_FRENCH_60_v1 — 60" double-leaf French door with glass lites. Premium feel.

Roof Edge Kits (1.0m tileable segments)

  • ROOF_EAVE_KIT_v1 — Fascia board + soffit panel + optional frieze. Tiles along eave edges.
  • ROOF_RAKE_KIT_v1 — Rake/barge board + optional boxed return. Runs along gable edges.

Corner and Trim Kits (1.0m tileable segments)

  • CORNER_TRIM_OUTSIDE_v1 — Two intersecting boards for outside corners. Huge visual upgrade.
  • OPENING_CASING_KIT_v1 — Parametric casing for any window or door opening. Highest impact-per-effort module.

Blender Authoring Workflow

1. Model your component

Follow the naming conventions:

Prefix Purpose Example
MESH_ Visible geometry MESH_frame
PORT_ Anchor empties (ports) PORT_HOST_WALL_PLANE
COLL_ Collision proxy (optional) COLL_bounds
HELP_ Helper empty (optional) HELP_center_ref

2. Place port empties

Ports are Blender empties (Plain Axes) that define attachment points. Each module type has required ports — for example, a window needs PORT_HOST_WALL_PLANE, PORT_OPENING_CENTER, PORT_LEFT_JAMB, PORT_RIGHT_JAMB, PORT_SILL_LINE, and PORT_HEADER.

Port orientation: +Y = outward, +X = right, +Z = up.

3. Apply transforms

All objects must have scale (1,1,1) and rotation (0,0,0). In Blender: Ctrl+A > All Transforms.

4. Validate

blender -b module.blend -P validate_module.py -- \
  --json-path ./module.json \
  --report ./validation_report.json

The validator checks naming, transforms, ports, materials, bounding box, and JSON Schema compliance. Fix all errors before exporting.

5. Export

blender -b module.blend -P export_module.py -- \
  --out ./module.glb \
  --embed-textures \
  --update-bbox \
  --json-path ./module.json

6. Generate preview

blender -b module.blend -P bake_previews.py -- \
  --out ./preview.png \
  --resolution 512

7. Batch process the library

blender -b -P batch_export.py -- \
  --library-root ./library \
  --output-report ./batch_report.json

See modules_3d/tools/blender/README.md for full CLI documentation.


Configurator Engine

The TypeScript engine handles everything after export.

Placement System

The placement system resolves where modules go and validates the result:

import { registerModule, resolve } from "./placement/resolver.js";
import { canHost } from "./placement/host_rules.js";
import { findConflicts } from "./placement/collision.js";

// Register module metadata (loaded from module.json)
registerModule(windowMetadata);

// Resolve a placement
const result = resolve({
  moduleId: "WIN_CASEMENT_30x48_v1",
  hostId: "front_wall",
  insertionParam: 0.5,    // halfway along wall
  heightOffset: 0.914,    // sill height
  parameters: { flipX: false },
}, scene);

if (result.errors.length === 0) {
  // result.transform — 4x4 matrix to position the module
  // result.bomLineItems — cost items generated by this placement
  // result.hostModifications — e.g., "cut opening" record
}

Validation checks performed automatically:

  • Module type compatible with host type
  • Wall type in module's allowed list
  • Minimum distance from wall corners
  • Minimum spacing between openings
  • Opening doesn't exceed 70% of wall length
  • No bounding box overlaps with existing modules

Port Math

All transforms use 4x4 matrices in column-major order (matching glTF/WebGL):

import {
  alignPlaneToPlane,   // Snap module port to host wall surface
  alignPointToPoint,   // Translate module to host point
  applyFlip,           // Mirror for flipX parameter
  interpolateEdge,     // Position along edge (t=0..1)
  getPortTransform,    // Extract port from GLB scene graph
} from "./placement/port_math.js";

Render Configuration

Apply production-quality rendering settings:

import { getRenderConfig, listRenderPresets } from "./render/shadows.js";
import { getHDRIConfig } from "./render/hdri.js";

// Get a complete render config
const config = getRenderConfig("production_exterior");
// Returns: { preset, shadow, ssao, toneMapping, sunLight }

// Available presets:
// "production_exterior"  — Default. Bright overcast, soft shadows
// "golden_hour_exterior" — Warm sun, long shadows, dramatic
// "studio_clean"         — Neutral studio, even lighting
// "night_mood"           — Dark ambient, no sun

BOM and Pricing

Every placed module contributes line items to the bill of materials:

import { aggregateBom, exportBom } from "./pricing/bom.js";
import { computePricing, formatPricingSummary } from "./pricing/pricing.js";

// Collect BOM from all placed modules
const bom = aggregateBom(scene);

// Compute pricing
const pricing = computePricing(bom, {
  marginPercent: 0.25,   // 25% margin
  shippingFlat: 500.00,  // Flat shipping
  taxRate: 0.07,         // 7% tax
  laborRate: 65.00,      // $/hr override for labor items
});

console.log(formatPricingSummary(pricing));
// === Pricing Summary ===
// Materials:   $2,450.00
// Labor:       $487.50
// Hardware:    $205.00
//   Subtotal:  $3,142.50
//   Margin (25%): $785.63
//   Shipping:  $500.00
//   Tax (7.0%):   $309.97
//   ──────────────────
//   TOTAL:     $4,738.09

// Export as CSV or JSON
const csv = exportBom(bom, "csv");
const json = exportBom(bom, "json");

Templates

Load a preset tiny house configuration:

import { listTemplates, loadTemplate, computeSceneBom } from "./templates/template_loader.js";

// See available presets
const templates = listTemplates();
// 10 presets: Classic Gable 16'/20'/24'/28', Modern Shed 16'/20'/24',
//             Modern Flat 20'/24', A-Frame 20'

// Load a template — generates shell geometry and resolves all module placements
const scene = loadTemplate("TMPL_CLASSIC_GABLE_20");

// Get the BOM for the loaded scene
const bom = computeSceneBom(scene);

Each template defines:

  • Shell geometry — length, width, wall height, roof type/pitch, wall types
  • Module placements — which modules go on which walls/edges, at what position
  • Render preset — which lighting configuration to apply

JSON Schema

Every module.json is validated against modules_3d/tools/schema/module.schema.json (JSON Schema Draft 2020-12).

The schema enforces:

  • Required fields for all modules (id, type, category, version, bbox, ports, hosts, bom, tags)
  • ID pattern: ^[A-Z][A-Za-z0-9_]+_v[0-9]+$
  • Semantic version format for version field
  • Port name pattern: ^[A-Z][A-Z0-9_]+$ with PORT_ prefix on object names
  • Conditional port requirements — window modules must have HOST_WALL_PLANE + OPENING_CENTER + LEFT_JAMB + RIGHT_JAMB + SILL_LINE + HEADER; door modules must have THRESHOLD instead of SILL_LINE; etc.
  • BOM SKU pattern: ^[A-Z]+-[A-Z]+-[A-Z0-9]+$
  • Tag format: lowercase kebab-case

Testing

cd modules_3d/configurator

# Run all tests
npm test

# Results:
# placement/port_math.test.ts    — 33 tests (matrix ops, vector math, alignment, flip, interpolation)
# placement/collision.test.ts    — 11 tests (AABB overlap, world bbox, fits-within, conflicts)
# placement/host_rules.test.ts   —  7 tests (host compatibility, spacing, structural limits)
# pricing/pricing.test.ts        —  9 tests (BOM aggregation, grouping, export, pricing computation)
# Total: 60 tests, all passing

Module JSON validation (Python):

# Validate all 10 module stubs
python3 modules_3d/tools/blender/batch_export.py -- \
  --library-root modules_3d/library \
  --json-only \
  --output-report batch_report.json

# Result: 10 passed, 0 failed

Documentation

Detailed guides are in modules_3d/docs/:

Document Audience Contents
MODULE_STANDARD.md Blender artists Naming conventions, transforms, ports, materials
PORTS_AND_HOSTING.md Blender artists + devs Port reference, orientation, hosting rules
RENDERING_GUIDE.md Engine developers PBR standards, HDRI presets, shadow/SSAO config
PRICING_BOM_GUIDE.md Engine developers BOM structure, pricing formula, default config

Architecture Decisions

Why GLB + JSON (not just GLB)? GLB carries geometry and materials. JSON carries behavior — placement rules, constraints, parameters, pricing. Keeping them separate means you can update pricing without re-exporting geometry, and validate metadata without loading 3D files.

Why ports instead of bounding-box snapping? Ports give precise, named attachment points with orientation. A window's HOST_WALL_PLANE port defines exactly where it sits on the wall surface with the correct facing direction. This is more reliable than inferring attachment from geometry bounds.

Why tileable segments for roof/corner kits? A 1-meter segment that tiles along an edge means one Blender asset covers any roof length. The engine repeats/trims to fit. This avoids needing separate assets for every roof size.

Why V1 opening strategy (visual overlap)? Boolean CSG on wall meshes is complex and fragile. For exterior-only visualization, simply placing windows/doors on the wall surface looks correct. CSG can be added in V2 when interior views are needed.

Why column-major matrices? Matches glTF and WebGL conventions. No conversion needed when reading transforms from loaded GLB scenes.


Next Steps

The V1 framework is complete. To reach a working configurator:

  1. Author Blender geometry for all 10 modules (.blend files with actual meshes, textures, and port empties)
  2. Integrate with a 3D renderer (Three.js or Babylon.js) to load GLBs and apply placement transforms
  3. Build a frontend UI for selecting templates, placing modules, and seeing live pricing
  4. Add furniture modules (kitchen pack, bath pack)
  5. Implement V2 opening cuts (CSG on wall geometry for interior views)

About

automated blender model creation tool for architectural components

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors