Introduction: Projet1_ornamental_pattern

About: PhD student at University of California, Santa Barbara, in the Expressive Computation Lab (

This ornamental project aims to familiar myself with Rhino, Grasshopper, and the Python script component in order to generate parametric design. Note that I know nothing about these softwares (though arguably now I know a little bit after making this first project), but I know how to code, which made it easier to tackle the task. Investigating digital fabrication through programming made sense for me.

But I didn't want to get done with this work without the feeling that I discovered new possibilities hidden behind the super combo Rhino+Grasshopper. Each software frames certain ways of creation, I am slowly figuring out what they are. I explored different approaches to shape the third dimension of a 2D design, to investigate noise, to thicken vectorial lines, and to explore image composition with multiple versions of the pattern.

Step 1: Creating the Pattern in Python

I started with a simpler/slightly modified version of the Python program provided by my instructor, Jennifer Jacobs. This code is located in the Grasshopper Python script component. I added an element of randomness. Therefore, as you increase the r variable, the pattern gets more distorted from its original structure (when r = 0).

import rhinoscriptsyntax as rs
import math
import random

listPt = []
distX = (p2.X - p1.X)/rx
distY = (p2.Y - p1.Y)/ry
""" adding pattern of points in Rhino """
for i in range(0,int(rx+1)):
    for j in range(0,int(ry+1)):
        x = distX*i
        y = distY*j
        if (i*j*j % mod == 0):
            listPt.append(rs.CreatePoint(x+random.uniform(-randomness,randomness), y+random.uniform(-randomness,randomness), 0.0))
a = listPt
""" distance square between two points """
def dist2(p1, p2):
    return (p1.X-p2.X)*(p1.X-p2.X)+(p1.Y-p2.Y)*(p1.Y-p2.Y)
""" adding lines """
listLn = []
for j in range (0,len(listPt)):
    for i in range (0, len(listPt)):
        d = dist2(listPt[i], listPt[j])
        if(d < minDist and d > maxDist):
            listLn.append(rs.AddLine(listPt[i], listPt[j]))
b = listLn

Step 2: Creating the Third Dimensionality of the Pattern

Following parts of this tutorial found online, I created a surface made of two curves in Rhino connected through the loft component from Grasshopper. I used the Grasshopper Project component to project the points and lines created by the Python script onto the surface. Then, using the OffsetSurface component from Pufferfish, I connected the two-dimensional pattern to the projected curves. I baked the SUnion component and exported a .stl object from Rhino.

Note that I experimented with different thickening options to finally realize that Pufferfish was also offering an offset surface component (not only an offset curve component). I also tried the Pipe option, which created weird artifacts around the junctions.

Step 3: Visualizing in Cura

I imported four versions of my pattern in cura to see how long the print would take if printing the four objects at the same time. It would take an hour and a half, which seems reasonable (to which standard?).

Step 4: Image Composition in Blender

I finished by visualizing the potential of ordering, moving around, combining the different versions of the pattern in space. I used Blender to do so and rendered a few shots that I found interesting. I incorporated one of my drawings in the scene in order to contemplate the design in combination with other non three-dimensional media. I wanted to begin a visual conversation between different artistic practices that I am interested in.

I also tried to generate a second design that would resemble a body in motion in response to the dancing body illustrated in the drawing. I made a pattern that reminded me dancers in action. I appreciated the contrast between the fluid shapes of the drawing and the geometrical aesthetic of the parametric design.