Recursive Tree

 RecursiveTree

Recursive Tree Definition

This sample script creates a recursive tree by controling the total number of branches, the minimum branch length, and the rotation. It can also bake geometry by adding custom attributes, therefore expanding the native grasshopper capabilities.

#you can also see http://atlv.org/education/ghpython/ for material properties

#import rhinoscriptsyntax to perform operations

#import rhino geometry to add geometry

import rhinoscriptsyntax as rss

import Rhino.Geometry as rg

import random

 

#import libraries that allow us to add objects to document

#with changed attributes

import Rhino

import System.Drawing as sd

import Rhino.DocObjects as rd

import scriptcontext as sc

 

#define list for output 

#empty

pts = []

vecPts = []

crvs = []

crvsTmp = []

 

#define a list to contain mapped values

clrs = []

 

#obtain current document

sc.doc = Rhino.RhinoDoc.ActiveDoc

 

#definition

def recBranching(line,currBranches):

    #object coordinates of start and end points

    pt1Coord = rss.CurveStartPoint(line)

    pt2Coord = rss.CurveEndPoint(line)

    

    #point object to DRAW

    pt1 = rg.Point3d(pt1Coord)

    pt2 = rg.Point3d(pt2Coord)

    

    #append points to the list to get the output

    pts.append(pt1)

    pts.append(pt2)

    

    #takes coordinates of the points

    vec1 = rss.VectorCreate(pt2Coord,pt1Coord)

    vec2 = rss.VectorCreate(pt2Coord,pt1Coord)

    

    #modify the vector

    userFactor1 = 0.8

    userFactor2 = 0.6

    scFactor1 = random.random()*(1-userFactor1)+(userFactor1)

    scFactor2 = random.random()*(1-userFactor2)+(userFactor2)

    vec1 = rss.VectorScale(vec1,scFactor1)

    vec2 = rss.VectorScale(vec2,scFactor2)

    

    rotateFactor = roFactor

    vec1 = rss.VectorRotate(vec1,-rotateFactor,rg.Vector3d.ZAxis)

    vec2 = rss.VectorRotate(vec2,rotateFactor,rg.Vector3d.ZAxis)

    

    vec1 = rss.VectorAdd(vec1,pt2Coord)

    vec2 = rss.VectorAdd(vec2,pt2Coord)

    

    #point object to DRAW

    vecPt1 = rg.Point3d(vec1)

    vecPt2 = rg.Point3d(vec2)

    

    vecPts.append(vecPt1)

    vecPts.append(vecPt2)

    

    #add the curves

    ptList1 = (pt2Coord,vec1)

    ptList2 = (pt2Coord,vec2)

    ptGeoList1 = (rg.Point3d(pt2Coord),rg.Point3d(vec1))

    ptGeoList2 = (rg.Point3d(pt2Coord),rg.Point3d(vec2))

    crv1 = rg.NurbsCurve.CreateControlPointCurve(ptGeoList1,1)

    crv2 = rg.NurbsCurve.CreateControlPointCurve(ptGeoList2,1)

    #crv1 = rss.AddCurve(ptList1,1)

    #crv2 = rss.AddCurve(ptList2,1)

    

    #add curves to output (fill the list)

    crvs.append(crv1)

    crvs.append(crv2)

    

    #implement control

    currLen1 = rss.CurveLength(crv1)

    currLen2 = rss.CurveLength(crv2)

    if((minLen<currLen1)and(currBranches>1)):

        recBranching(crv1,currBranches-1)

    if((minLen<currLen2)and(currBranches>1)):

        recBranching(crv2,currBranches-1)

        

 

#calculate the minimum length of a list of curves

def calculateMinLen(inCurves):

    minLen = 10000000

    for i in range(len(inCurves)):

        currCurve = inCurves[i]

        currLen = rss.CurveLength(currCurve)

        if(currLen<minLen):

            minLen = currLen

    return minLen

    

#calculate the maximum length of a list of curves

def calculateMaxLen(inCurves):

    maxLen = 0

    for i in range(len(inCurves)):

        currCurve = inCurves[i]

        currLen = rss.CurveLength(currCurve)

        if(currLen>maxLen):

            maxLen = currLen

    return maxLen

 

#map value between a given IN range and return in a given OUT range

def mapValues(val,minRefIn,maxRefIn,minRefOut,maxRefOut):

    if((val>=minRefIn)and(val<=maxRefIn)):

        lenIn = maxRefIn-minRefIn

        lenOut = maxRefOut-minRefOut

        outVal = ((val-minRefIn)/lenIn)*lenOut+minRefOut

    else:

        return None

    return outVal

 

def calculateColor(crvs):

    minBrLen = calculateMinLen(crvs)

    print ("The minimum length is " + str(minBrLen))

    

    maxBrLen = calculateMaxLen(crvs)

    print ("The maximum length is " + str(maxBrLen))

    

    #calculate the color of each branch

    #remap the length to obtain the channel value between 0 and 255

    for i in range(len(crvs)):

        currCurve = crvs[i]

        currLen = rss.CurveLength(currCurve)

        clr = mapValues(currLen,minBrLen,maxBrLen,0,255)

        clrs.append(clr)

    #print (clr)

 

#call definition

recBranching(userLine,nrBranches)

calculateColor(crvs)

 

if(bake==True):

    #bake objects with changed attributes - color

    #add all curves to document

    print ("Vamos a cocinar!!")

    for i in range(len(crvs)):

        #add Objects to current document

        #get object attributes

        attr = rd.ObjectAttributes()

        attr.ColorSource = rd.ObjectColorSource.ColorFromObject

        attr.ObjectColor = sd.Color.FromArgb(clrs[i],0,255-clrs[i])

        sc.doc.Objects.AddCurve(crvs[i],attr)

Search Site




archi·o·logics survey

I am interested in: