Jitterbug via Dynamo

Build the entire geometry with a script — no manual clicking

← Back to Jitterbug Academy

Why click 12 points manually when a script can generate
12 vertices + 24 edges + 14 faces in milliseconds?

Manual vs Scripted Approach

❌ Manual in Family Editor

  • Place 12 points by clicking
  • Calculate coordinates manually
  • Draw 24 lines one by one
  • Create 14 surfaces individually
  • Error-prone
  • Hard to modify
  • Cannot animate transformation

✓ Scripted via Dynamo

  • Python calculates all coordinates
  • All geometry generated instantly
  • Change EdgeLength → regenerates
  • Change RhombusAngle → transforms
  • Precise and repeatable
  • Easy to modify
  • Can animate between states

How It Works

┌─────────────────┐     ┌─────────────────────────────────────┐     ┌─────────────────┐
│  NUMBER SLIDER  │────▶│                                     │────▶│    VERTICES     │
│  EdgeLength     │     │                                     │     │   (12 Points)   │
│  (15.24 cm)     │     │                                     │     └─────────────────┘
└─────────────────┘     │                                     │
                        │         PYTHON SCRIPT               │     ┌─────────────────┐
┌─────────────────┐     │                                     │────▶│      EDGES      │
│  NUMBER SLIDER  │────▶│   • Calculates 12 vertices          │     │   (24 Lines)    │
│  RhombusAngle   │     │   • Creates 24 edges                │     └─────────────────┘
│  (90° to 0°)    │     │   • Creates 14 faces                │
└─────────────────┘     │   • Reports state name              │     ┌─────────────────┐
                        │                                     │────▶│      FACES      │
┌─────────────────┐     │                                     │     │  (14 Surfaces)  │
│    BOOLEAN      │────▶│                                     │     └─────────────────┘
│  Create Faces?  │     │                                     │
│  (True/False)   │     └─────────────────────────────────────┘     ┌─────────────────┐
└─────────────────┘                                           ────▶│   STATE NAME    │
                                                                    │ "Vector Equil." │
                                                                    └─────────────────┘
                                                                            │
                                                                            ▼
                                                              ┌─────────────────────────┐
                                                              │     DIRECTSHAPE or      │
                                                              │   ADAPTIVE COMPONENT    │
                                                              │      (to Revit)         │
                                                              └─────────────────────────┘

Step-by-Step Setup

1. Open Dynamo

1

Launch Dynamo from Revit

Manage tab → Visual Programming panel → Dynamo

Or search "Dynamo" in the Revit search bar.

2

Create a new script

In Dynamo: File → New

Save immediately: File → Save As → Jitterbug.dyn

2. Create Input Nodes

3

Add EdgeLength slider

Search for Number Slider in the node library

Drag it onto the canvas

Double-click to configure: Min: 5, Max: 50, Value: 15.24

Right-click → Rename: EdgeLength (cm)

4

Add RhombusAngle slider

Add another Number Slider

Configure: Min: 0, Max: 90, Value: 90

Rename: RhombusAngle (degrees)

5

Add CreateFaces toggle

Search for Boolean

Set to True

Rename: Create Faces?

3. Add the Python Script

6

Add Python Script node

Search for Python Script

Drag onto canvas

Click the + button to add input ports until you have 3 (IN[0], IN[1], IN[2])

7

Paste the script

Click Edit... on the Python node

Delete the default code

Paste the entire contents of Jitterbug_Dynamo_Complete.py

Click Run (or close the editor)

8

Connect inputs

  • Connect EdgeLength sliderIN[0]
  • Connect RhombusAngle sliderIN[1]
  • Connect CreateFaces booleanIN[2]

4. View the Output

9

Enable geometry preview

Click on the Python node

In the preview below, you should see the Jitterbug geometry

If not visible, right-click node → PreviewOn

10

Test the transformation

Move the RhombusAngle slider:

  • 90° = Vector Equilibrium (squares)
  • ~63° = Icosahedron
  • = Octahedron (collapsed)

5. Push to Revit — Making Geometry Permanent

Why This Step Matters

Dynamo geometry is temporary — it only exists in Dynamo's preview. Close Dynamo and it disappears. To make it permanent in your Revit project, you must "push" it to Revit using one of these nodes.

Option A: DirectShape (Recommended for Quick Results)

What is DirectShape? A Revit element that holds arbitrary geometry. It's the fastest way to get Dynamo geometry into Revit, but it's not a "family" — you can't schedule it or reuse it easily.

11

Add a Categories node

In the Dynamo node library, search for Categories

Drag it onto the canvas

Click the dropdown and select Generic Models

This tells Revit what category the geometry belongs to.

12

Add DirectShape.ByGeometry node

Search for DirectShape.ByGeometry

Drag it onto the canvas

This node has these inputs:

  • geometry — the geometry to create
  • category — what Revit category it belongs to
  • material — (optional) what material to apply
  • name — (optional) a name for the element
13

Connect the nodes

  • Connect Categories output → DirectShape category input
  • Connect Python OUT[1] (the 24 edges) → DirectShape geometry input
14

Run the script

Click Run in Dynamo (or enable Automatic run)

Switch to your Revit view — the Jitterbug edges should now appear!

If you don't see it, check: View → Visibility/Graphics → Generic Models is visible

Important: DirectShape Updates

Every time you run the Dynamo script, it creates new DirectShape elements. If you run it 5 times, you'll have 5 Jitterbugs stacked on top of each other. Either:

Including Faces (Not Just Edges)

To push edges AND faces to Revit:

15

Combine all geometry

Search for List.Join node

Connect:

  • Python OUT[1] (edges) → List.Join list0
  • Python OUT[2] (triangle faces) → List.Join list1
  • Python OUT[3] (rhombus faces) → List.Join list2

Connect List.Join output → DirectShape geometry input

Visual: Complete Node Setup

┌─────────────────┐
│  Number Slider  │
│  EdgeLength     │──────────────┐
│  (15.24)        │              │
└─────────────────┘              │
                                 │     ┌─────────────────────────┐
┌─────────────────┐              ├────▶│ IN[0]                   │
│  Number Slider  │              │     │                         │     ┌─────────────────┐
│  RhombusAngle   │──────────────┼────▶│ IN[1]   PYTHON    OUT[0]│────▶│ (12 vertices)   │
│  (90)           │              │     │         SCRIPT          │     └─────────────────┘
└─────────────────┘              │     │                   OUT[1]│──┐
                                 │     │                         │  │  ┌─────────────────┐
┌─────────────────┐              │     │                   OUT[2]│──┼─▶│                 │
│    Boolean      │──────────────┘────▶│ IN[2]             OUT[3]│──┼─▶│   List.Join     │───┐
│  Create Faces   │                    │                   OUT[4]│  └─▶│                 │   │
│  (True)         │                    │                   OUT[5]│     └─────────────────┘   │
└─────────────────┘                    └─────────────────────────┘                           │
                                                                                             │
                                                                                             │
┌─────────────────┐                    ┌─────────────────────────┐                           │
│   Categories    │                    │                         │                           │
│                 │───────────────────▶│ category                │                           │
│ Generic Models  │                    │                         │                           │
└─────────────────┘                    │    DirectShape          │◀──────────────────────────┘
                                       │    .ByGeometry          │
                                       │                         │         ┌─────────────────┐
                                       │                   output│────────▶│ REVIT GEOMETRY  │
                                       │                         │         │ (permanent!)    │
                                       └─────────────────────────┘         └─────────────────┘

Option B: AdaptiveComponent.ByPoints (For Reusable Families)

When to use this: If you want a proper Revit family that you can schedule, tag, and reuse. Requires creating an Adaptive Component family first.

Alt

AdaptiveComponent workflow (advanced)

  1. Create an Adaptive Component family with 12 Adaptive Points
  2. Load it into your project
  3. In Dynamo, use AdaptiveComponent.ByPoints
  4. Connect Python OUT[0] (12 vertices) as the points
  5. Select your family type

This places an instance of your family with vertices at the calculated positions. Dynamo drives the family's adaptive points.

Summary: Which Method?

Method Pros Cons Use When
DirectShape Fast, simple, no family needed Not schedulable, creates duplicates on re-run Quick visualization, one-off models
AdaptiveComponent Reusable, schedulable, proper BIM Requires pre-made family, more complex Production work, multiple instances

Quick Reference: Output Nodes

Node What It Creates Key Input
DirectShape.ByGeometry Generic geometry in project geometry, category
ImportInstance.ByGeometry Imported geometry (like SAT file) geometry
FamilyInstance.ByGeometry In-place family geometry, category
AdaptiveComponent.ByPoints Instance of adaptive family points, familyType

Downloads

📥 Jitterbug_Dynamo_Complete.py 📥 JitterbugDynamo.py (Revit Family version)

About the Transformation

Simplified Kinematics

The Python script uses a simplified transformation model. True Jitterbug kinematics maintains constant edge lengths throughout the transformation, which requires solving constraint equations.

For accurate constant-edge-length transformation, use Grasshopper + Kangaroo (a constraint solver), then export to Revit.

The Dynamo version is excellent for:

Python Node Outputs Reference

Output Port Content Type
OUT[0] 12 Vertices List of Points
OUT[1] 24 Edges List of Lines
OUT[2] 8 Triangle Faces List of Surfaces
OUT[3] 6 Rhombus Faces List of Surfaces
OUT[4] State Name String ("Vector Equilibrium", etc.)
OUT[5] Edge Length Verification String (min/max/target)

← Back to Jitterbug Academy · Revit Fundamentals · Manual Family Guide