Hrithik Shetty
All projects

Configurator

House Generator in Rhino

Fig. Parametric facade and design automation in Rhino using Python and Eto.Forms

This project showcases a “House Generator”, a parametric design tool developed in Python for Rhino. Leveraging the rhinoscriptsyntax library for geometric operations and the Eto.Forms framework for the user interface, the script enables rapid generation of residential building typologies. Users can define key parameters such as building dimensions, floor plan types and fenestration sizes through a custom configurator, allowing for efficient design exploration and iteration.

The dialog exposes only the decisions that matter — length, width, plan type, two window sizes, main and internal door widths — and derives everything else. A Check button previews the resulting 2D plan with room names and dimensions before committing; Generate builds the full 3D model.

The dialog floats beside the model instead of locking Rhino, so a preview can be orbited and inspected between runs. Before it builds, the script sets the document to metres with a millimetre tolerance, so the model comes out the same whatever file it runs in, and it draws in wireframe until the last solid is placed.

  1. PythonScripted logic and parameters
  2. rhinoscriptsyntaxGeometry · Eto.Forms interface
  3. RhinocerosModel output
Type
Individual project
Collaboration
TH OWL, Detmold
Location
Detmold, Germany
Course
TH OWL — MID Computational Design
The House Generator dialog annotated: numeric inputs for length and width, dropdowns of preset sizes for the plan, windows and doors, and the Check, Generate and Close buttons
Fig. The dialog: two numeric inputs, five preset dropdowns, and Check before Generate

From a dialog to a dictionary

The dialog is an Eto form, and it never talks to the geometry directly. Every button reads the seven controls through one method, which hands back a plain dictionary of numbers and names. Check and Generate both start from that dictionary, so the preview and the model can never disagree about what was typed — and adding an eighth input means adding one line here rather than finding every place a value is read.

S7_House_generator.py Python · lines 85–94

    def get_parameters(self):
        return {
            "length": self.length_numeric.Value,
            "width": self.width_numeric.Value,
            "plan_type": str(self.plan_combo.SelectedValue),
            "w1_wid": float(self.window1_combo.SelectedValue),
            "w2_wid": float(self.window2_combo.SelectedValue),
            "main_door": float(self.main_door_combo.SelectedValue),
            "dr_wid": float(self.internal_door_combo.SelectedValue)
        }
Fig. Every control, read in one place and handed on as a dictionary
Rendered two-storey house produced by the generator: white walls, a flat overhanging roof, and tall black-framed glazing with the staircase visible through the corner
Fig. One run of the generator, rendered — every wall, frame and step placed by the script

How the plan resolves

Building dimensions and plan type drive column positions, internal walls, and the standardised internal dimensions that in turn place entrance openings, facade openings, internal door openings, windows and the staircase. Because each stage reads from the one before it, a change to overall width propagates through the whole plan rather than breaking it.

The plan is written as proportions, not measurements. Room depths are fixed fractions of the width — the living and dining area takes 4.5/15 of it, the kitchen 3.5/15, the room 4/15 — the rooms run half the length, and the corridor is a fifth of it. Those proportions set a small family of named points: the C points place the columns, the letters A to L the walls, doors and staircase. Every later step is built from those points, never from absolute coordinates.

Two plan types share the same points. Plan-1 keeps a kitchen beside the living area; Plan-2 carries one wall across the full length, turning that space into a study and adds a kitchen and store room at the back.

Exposed parameters

  • Length
  • Width
  • Plan type
  • Window type 1
  • Window type 2
  • Main door
  • Internal door
S7_House_generator.py Python · lines 322–329

        int_len_1 = length/2                             # Length of the first internal wall
        corridor_wid = 1/5*length                        # Corridor width

        room1_wid = 4/15*width            # Width of room 1
        kitchen_wid = 3.5/15*width        # Width of kitchen
        living_room_wid = 4.5/15*width    # Width of living/dinning area

        staircase_wid = 4.5
Fig. The plan as proportions — only the staircase keeps a fixed size, because a stair’s geometry does not scale with the house
Dimensioned ground-floor plan of a 10 by 15 metre house with column points C1 to C13 and control points A to L marking the bathroom, room, kitchen, common washroom, staircase and living area
Fig. The control points — columns C1–C13, walls and openings A–L
The Check preview: an outline plan labelled Bathroom 4.85 by 3.0 m, Room 4.85 by 4.0 m, Kitchen/Room 4.85 by 3.5 m, Common Bathroom, Staircase, and Living and Dining Area 10.0 by 4.5 m
Fig. What Check draws for a 10 × 15 m Plan-1

A facade that counts its panels

The glazing never stretches. Every facade panel is 2 m wide, so the script starts from the front length and sets about 4 m aside for the entrance bay. What is left is the stretch the glazing has to fill.

It fills it with whole panels only. When the remainder divides into 2 m panels exactly, they all fit; when it does not, % 2 rounds it down to the last whole panel and the leftover goes back to the entrance. The elevation closes cleanly at any size, and a longer house simply gains another panel of light over the living space.

The side facade over the living room follows the same rule with one addition. If less than half a metre would be left beside the glazing, it gives up one more panel, so the corner is never a sliver of wall too thin to build.

S7_House_generator.py Python · lines 331–345

        if length > 0:
            ent_main = 4
            fac_1 = length - ent_main
            if fac_1 % 2 == 0:
                facade_1 = fac_1
                ent_main = length - facade_1
            else:
                facade_1 = fac_1 - (fac_1 % 2)
                ent_main = length - facade_1

        if width > 0:
            if living_room_wid % 2 >= 0.5:
                facade_2 = living_room_wid - (living_room_wid % 2)
            else:
                facade_2 = living_room_wid - (living_room_wid % 2) - 2
Fig. The facade in fifteen lines — % 2 is the panel width, and whatever it leaves over goes to the entrance

Around that, the model is built as real construction rather than massing: 300 mm outer walls and 150 mm inner walls, a plinth slab, a first floor with the stair opening cut out of it, and an overhanging flat roof. Windows are made once as Rhino blocks and inserted at each position. The main door is a glass double door that becomes a single leaf when a narrower opening is chosen, and internal door openings are cut through both floors at the chosen width.

In the model

  • Columns
  • Outer walls
  • Inner walls
  • Slabs & roof
  • Facade frames
  • Window blocks
  • Glass main door
  • Dog-leg staircase
  • Glass balustrade
Shaded Rhino view of the generated house with cyan glass panels in black frames along the front and side facades
Fig. Front and side facades, resolved into 2 m panels
Cut-away view through both floors showing the slabs, inner walls and internal door openings
Fig. Section through both floors — 150 mm inner walls and door openings
Close-up of the generated glass double entrance door with two vertical pull handles, set in its frame
Fig. The main door, a block that switches between double and single leaf
Interior view of the floating dog-leg staircase rising to the first floor behind a glass balustrade
Fig. Floating dog-leg stair and glass balustrade over the living area
Two diagrams: rhinoscriptsyntax calling functions that make Rhino geometry and getting back a GUID for each object, and the script's logic from building and internal dimensions and plan types through columns, walls and openings to the staircase
Fig. Every object comes back as a GUID, and the script’s order follows from what each stage needs
The Check preview drawn in a Rhino perspective viewport, with the House Generator dialog floating in the corner
Fig. The preview in Rhino, with the dialog floating beside it rather than locking the model