OPMVP
I ain’t calling whatever this stack of work is BIM. This mystery project is simply titled OnlyPlans after our April fools joke from a year ago, and perhaps for my propensity to want to automate plan so I can think in elevations/ sections more easily.
System rules for the OPMVP so Far:
The Facade Container
All buildings have a closed boundary, this is the facade, or ‘canvas container’

Rooms are Closed
Within that closed boundary are rooms, also a closed boundary of minimum area, the closed boundary is a cell

Edges are Walls
Edges that separate cells from each other will be considered walls
{ "wall_rules": { "rooms": [ { "name": "Living Room", "id": "room_001" }, { "name": "Kitchen", "id": "room_002" } ], "wall_properties": { "material": "Drywall", "thickness_inch": 6, "insulation": { "type": "Fiberglass", "r_value": 13 }, "soundproofing": { "rating": "STC 50", "requirements": [ "No major appliances adjacent", "Sealed gaps" ] }, "fire_rating": { "duration_hours": 1, "requirements": [ "Fire-rated drywall", "No penetrations without firestop" ] }, "doorways": { "allowed": true, "max_width_ft": 4, "min_distance_from_corner_ft": 2 }, "windows": { "allowed": false }, "load_bearing": { "status": "Non-load-bearing", "supporting_structure": null }, "electrical_requirements": { "outlets_per_wall": 2, "conduit_type": "Metallic", "requirements": [ "No exposed wiring", "Grounded outlets" ] } }, "shared_wall_rules": { "shared_wall_insulation": "Double-layer fiberglass", "shared_wall_thickness_inch": 8, "noise_reduction_coefficient": 0.85, "ventilation": { "status": "Required", "vent_type": "Shared HVAC duct", "requirements": [ "Backdraft damper", "Sound insulation within duct" ] } } } }
Rooms have requirements
- min / max size
- door / window elements hosted on walls
- specific egress load (driving door and window elements)
- power / water / wastewater / air / stc rating / R rating
- wall hosted objects
- floor hosted objects
{ "room": { "name": "Conference Room", "dimensions": { "width_ft": 20, "length_ft": 30, "height_ft": 10 }, "occupancy": { "max_people": 25, "type": "Business" }, "features": { "windows": 2, "doors": 1, "electrical_outlets": 4, "lighting_type": "LED", "hvac": true, "natural_light": true, "soundproofing": "High" }, "furniture": { "tables": { "type": "Conference Table", "quantity": 1, "dimensions_ft": { "length": 15, "width": 5 } }, "chairs": { "type": "Ergonomic Office Chair", "quantity": 25 }, "whiteboard": { "type": "Magnetic", "quantity": 1, "dimensions_ft": { "width": 6, "height": 4 } } }, "technology": { "projector": true, "screen_size_inch": 120, "speakers": true, "microphone": true, "wifi": true }, "requirements": { "fire_safety": { "smoke_detectors": 2, "sprinklers": true, "fire_extinguishers": 1 }, "accessibility": { "wheelchair_accessible": true, "hearing_aid_compatible": false }, "energy_efficiency": { "insulation_rating": "R30", "solar_panels": false } } } }
Objects Have Requirements
Every room has its object requirements, but objects have their own requirements.
{ "object_requirements": [ { "id": "obj_001", "type": "Sofa", "clearances": { "from_walls": { "min_ft": 1, "preferred_ft": 2, "regulation": "IBC Section 1208" // Reference to IBC code on spatial clearance }, "from_adjacent_objects": { "Coffee Table": { "min_ft": 2, "max_ft": 5, "regulation": "IBC Section 1208" // General clearance requirements } } }, "ada_requirements": { "accessible_path_width_ft": 3, // ADA path clearance width "turning_space_diameter_ft": 5, // ADA turning radius for wheelchair access "regulation": "ADA 2010 Standards, Section 307" }, "placement_rules": { "must_be_adjacent_to": ["Wall"], "must_not_be_adjacent_to": ["Window", "Door"], "must_face": "Television", "justification": "center" } }, { "id": "obj_002", "type": "Coffee Table", "clearances": { "from_adjacent_objects": { "Sofa": { "min_ft": 2, "max_ft": 5, "regulation": "IBC Section 1208" } } }, "nfpa_requirements": { "distance_from_fire_extinguisher_ft": 10, // NFPA rule for fire extinguisher access "flammable_material_clearance_ft": 3, // Clearance from any flammable objects "regulation": "NFPA 10, Chapter 6" }, "placement_rules": { "must_be_adjacent_to": ["Sofa"], "justification": "left" } }, { "id": "obj_003", "type": "Television", "clearances": { "from_walls": { "min_ft": 0, "regulation": "IBC Section 1208" }, "from_adjacent_objects": { "Sofa": { "min_ft": 8, "max_ft": 12, "regulation": "IBC Section 1208" } } }, "placement_rules": { "must_be_adjacent_to": ["Wall"], "must_face": "Sofa", "justification": "center" }, "nfpa_requirements": { "distance_from_heat_sources_ft": 4, // Safe distance from any heat-generating objects (NFPA) "regulation": "NFPA 70 (National Electric Code)" } } ] }
Doors and Windows are Owned by 2 Rooms
Since we don’t ever want to place a door and then change its type, we want to, in fact, never place any object manually first. Doors and windows need to be jointly owned in concept.
{ "doors": [ { "from_room": "Living Room", "to_room": "Kitchen", "door_details": { "type": "Sliding Door", "material": "Glass", "dimensions": { "width_ft": 6, "height_ft": 7 }, "notes": "A glass sliding door connecting the living room and kitchen" } }, { "from_room": "Living Room", "to_room": "Master Bedroom", "door_details": { "type": "Swing Door", "material": "Wood", "dimensions": { "width_ft": 3, "height_ft": 7 }, "notes": "A wooden swing door leading to the master bedroom" } }, { "from_room": "Kitchen", "to_room": "Bathroom", "door_details": { "type": "Swing Door", "material": "Wood", "dimensions": { "width_ft": 3, "height_ft": 7 }, "notes": "A swing door connecting the kitchen to the bathroom" } }, { "from_room": "Master Bedroom", "to_room": "Dining Room", "door_details": { "type": "Pocket Door", "material": "Wood", "dimensions": { "width_ft": 4, "height_ft": 7 }, "notes": "A wooden pocket door leading to the dining room" } } ] }
Alright so here is the information hierarchy in my head:
Deal Pipeline > Deal > Scheme > Site > Building > Room > Object
This MVP will take a building shape as an input, place rooms from a program lookup (the shape will be named). Still a bit more thinking to go before I fully understand the full problem…
Required placement Algorithms?:
- Populate generic mass with rooms (could use ben) but the hierarchies and adjacencies will be compute heavy (could precompute min size based on object requirements
- Assuming that goes well, place doors based on all the load factors of those rooms (auto firewall?)
- Assuming that goes well, windows with their own placement logic
- Then the first priority objects and their adjacencies per sub space, moving down the list to second and third and so on
- What do you do when you have a large leftover middle area (subdivide tools)
- room object auto-orientation based on egress and clearance
Required co-creation tools?
- room bounds grips
- room layer level
- room position magnets (edge 1/3 : L C R T M B )corner: TL TR BL BR)
- object re-ordering
- relabel room (drive literally the entire model)
I think we could create something with a polygon and a label as base human input and get meaningful room level geometry from it, as long as this system is simple. Need to simplify even further if possible.
Error Handling Ideas
-If no room is placed and there is leftover space, default it to circulation space (often this literally is the leftover space).
-If in an object lookup table, all required items have been placed, then we can place filler items. Filler items need a max count/ inch or % (Kitchen Configurator)
-Fully clipping geometry by hierarchy is a winning strat not only for rooms but for series of objects:
{ "room": { "id": "room_001", "name": "Living Room", "dimensions": { "width_ft": 20, "length_ft": 15, "height_ft": 10 }, "objects": [ { "id": "obj_001", "type": "Sofa", "dimensions": { "width_ft": 6, "length_ft": 3, "height_ft": 3 }, "position": { "edge_number": 1, // Edge 1 could represent a specific wall "min_distance_ft": 2, // Minimum distance from edge 1 "preferred_position_percent": 50, // Centered along the edge "justification": "center" // Sofa should be center-aligned }, "placement_priority": 1, "adjacency_rules": { "must_be_adjacent_to": ["Wall"], "distance_from": { "Coffee Table": { "min_ft": 2, "max_ft": 5 } } } }, { "id": "obj_002", "type": "Coffee Table", "dimensions": { "width_ft": 4, "length_ft": 2, "height_ft": 1.5 }, "position": { "edge_number": 2, // Placed along a different edge "min_distance_ft": 1, // Minimum distance from edge 2 "preferred_position_percent": 30, // 30% along the edge "justification": "left" // Coffee table is left-aligned along the edge }, "placement_priority": 2, "adjacency_rules": { "must_be_adjacent_to": ["Sofa"], "distance_from": { "Sofa": { "min_ft": 2, "max_ft": 5 } } } }, { "id": "obj_003", "type": "Television", "dimensions": { "width_ft": 5, "length_ft": 0.5, "height_ft": 3 }, "position": { "edge_number": 3, "min_distance_ft": 0, // Directly on edge 3 (likely a wall) "preferred_position_percent": 50, // Centered along edge 3 "justification": "center" }, "placement_priority": 3, "adjacency_rules": { "must_face": "Sofa", "must_be_adjacent_to": ["Wall"], "distance_from": { "Sofa": { "min_ft": 8, "max_ft": 12 } } } }, { "id": "obj_004", "type": "Bookshelf", "dimensions": { "width_ft": 4, "length_ft": 1, "height_ft": 6 }, "position": { "edge_number": 4, "min_distance_ft": 1, "preferred_position_percent": 75, // Positioned at 75% along edge 4 "justification": "right" }, "placement_priority": 4, "adjacency_rules": { "must_be_adjacent_to": ["Wall"] } } ] } }