rhinopython

Surface Subdivision in RhinoPython

Surface subdiviision

This generates a subdivision based on any 4-corner surface and names the panels. It also creates tabs, should you want to unroll it for fabrication. The panels are, in addition, named for reference.

#script written by Adolfo Nadal

#import rhinoscriptcontext 

import rhinoscriptsyntax as rss

 

#calculate the normal on the surface with a given scalefactor

def calcNormalWithSize(srf,uParam,vParam,size,ptBase):

    ptNorm = rss.SurfaceNormal(srf,(uParam,vParam))

    ptNorm = rss.VectorScale(ptNorm,size)

    ptNorm = rss.VectorAdd(ptNorm,ptBase)

    return ptNorm

 

#get surface from user: filter 8 for surfaces

srf = rss.GetObject("Please select a surface",8)

 

#get a series of subdivisions

divU = rss.GetInteger("Please enter number of subdivisions in U direction",5,2,100)

divV = rss.GetInteger("Please enter number of subdivisions in V direction",5,2,100)

 

#enter your desired tab size

tabSize = rss.GetReal("Please enter tab size",2,0.1,10)

 

#populate the surface with points

#-surface domain

domU = rss.SurfaceDomain(srf,0)

domV = rss.SurfaceDomain(srf,1)

 

print (domU)

print (domV)

 

#enter variables that contain surface domain

#max will be the second value, therefore [1]

domUMax = domU[1]

domUMin = domU[0]

domVMax = domV[1]

domVMin = domV[0]

 

#calculate the stepSize

stepU = (domUMax-domUMin)/divU

stepV = (domVMax-domVMin)/divV

 

rss.EnableRedraw(False)

 

counter = 0

#create points on surface

for i in range(divU+1):

    for j in range(divV+1):

        if((i>0)and(j>0)):

            #-evaluate surface

            uParam = i*stepU

            vParam = j*stepV

            pt1Coord = rss.EvaluateSurface(srf,uParam,vParam)

            pt2Coord = rss.EvaluateSurface(srf,uParam-stepU,vParam)

            pt3Coord = rss.EvaluateSurface(srf,uParam-stepU,vParam-stepV)

            pt4Coord = rss.EvaluateSurface(srf,uParam,vParam-stepV)

            

            #obtain middle points

            ptMid12Coord = rss.EvaluateSurface(srf,uParam-stepU/2,vParam)

            ptMid23Coord = rss.EvaluateSurface(srf,uParam-stepU,vParam-stepV/2)

            ptMid34Coord = rss.EvaluateSurface(srf,uParam-stepU/2,vParam-stepV)

            ptMid41Coord = rss.EvaluateSurface(srf,uParam,vParam-stepV/2)

            

            #add the point on the surface

            #pt = rss.AddPoint(ptCoord)

            #add components to the surface

            polyPt = (pt1Coord,pt2Coord,pt3Coord,pt4Coord,pt1Coord)

            #poly = rss.AddPolyline(polyPt)

            

            #Add segments ON the surface

            crv1 = rss.AddInterpCrvOnSrf(srf,(pt1Coord,pt2Coord))

            crv2 = rss.AddInterpCrvOnSrf(srf,(pt2Coord,pt3Coord))

            crv3 = rss.AddInterpCrvOnSrf(srf,(pt3Coord,pt4Coord))

            crv4 = rss.AddInterpCrvOnSrf(srf,(pt4Coord,pt1Coord))

            

            #join curve segments into one and delete segments (true)

            crvs = (crv1,crv2,crv3,crv4)

            joinCrv = rss.JoinCurves(crvs,True)

            

            #calculate normals!!!

            #beware, vectors in rhino are by default 0-based (0,0,0)

            #1st calculate normal

            #2nd scale (if desired)

            #3rd move (by adding)

            ptN1Coord = calcNormalWithSize(srf,uParam,vParam,tabSize,pt1Coord)

            ptMidN12Coord = calcNormalWithSize(srf,uParam-stepU/2,vParam,tabSize,ptMid12Coord)

            ptMidN23Coord = calcNormalWithSize(srf,uParam-stepU,vParam-stepV/2,tabSize,ptMid23Coord)

            ptMidN34Coord = calcNormalWithSize(srf,uParam-stepU/2,vParam-stepV,tabSize,ptMid34Coord)

            ptMidN41Coord = calcNormalWithSize(srf,uParam,vParam-stepV/2,tabSize,ptMid41Coord)

            

            #verify that it works

            #rss.AddPoint(ptMidN12Coord)

            #rss.AddPoint(ptMidN23Coord)

            #rss.AddPoint(ptMidN41Coord)

            

            #visualize normal

            #rss.AddLine(pt1Coord,ptN1Coord)

            #add tabs to the model

            triaTab1Pts = (pt1Coord,pt2Coord,ptMidN12Coord)

            triaTab2Pts = (pt2Coord,pt3Coord,ptMidN23Coord)

            triaTab3Pts = (pt3Coord,pt4Coord,ptMidN34Coord)

            triaTab4Pts = (pt4Coord,pt1Coord,ptMidN41Coord)

            

            tab1Srf = rss.AddSrfPt(triaTab1Pts)

            tab2Srf = rss.AddSrfPt(triaTab2Pts)

            tab3Srf = rss.AddSrfPt(triaTab3Pts)

            tab4Srf = rss.AddSrfPt(triaTab4Pts)

            

            basePts = (pt1Coord,pt2Coord,pt3Coord,pt4Coord)

            baseSrf = rss.AddSrfPt(basePts)

            

            #join to create a single polysurface object

            srfs = (tab1Srf,tab2Srf,tab3Srf,tab4Srf,baseSrf)

            basePolySrf = rss.JoinSurfaces(srfs,True)

            

            rss.ObjectColor(basePolySrf,(2*i*j,0,255-2*(i*j)))

            

            ptCtCoord = rss.EvaluateSurface(srf,uParam-stepU/2,vParam-stepV/2)

            rss.AddTextDot(counter,ptCtCoord)

            counter = counter +1

            #rss.AddPoint(ptN1Coord)

            #create panels

 

rss.EnableRedraw(True)

Recursive Triangulation

3D recursive triangle

This recursive scripts generates a tree-like structure based on a simple algorithm. Each branch creates four sub-branches in the next level, making it very easy to multiply geometry in an exponential manner. Be careful as it does not provide sufficient error-checking, it simply assumes that you input the correct geometry.

#brocoli subdivision

#script written by Adolfo Nadal

#import libraries

import rhinoscriptsyntax as rss

import random

 

tmpSrfList = []

#define our function

def subdivideTriaSurf(srf,delete,scFactor):

    #duplicate border->returns a list

    #in this case we know we only want to have the first object [0]

    polyBorderList = rss.DuplicateSurfaceBorder(srf,1)

    polyBorder = polyBorderList[0]

    

    #test

    print (polyBorder)

    

    #get segments from the border as individual curves (helps get the middle points)

    segments = rss.ExplodeCurves(polyBorder)

    segment1 = segments[0]

    segment2 = segments[1]

    segment3 = segments[2]

    

    len = rss.CurveLength(segment1)

    

    #calculate middle points

    midPt1 = rss.CurveMidPoint(segment1)

    midPt2 = rss.CurveMidPoint(segment2)

    midPt3 = rss.CurveMidPoint(segment3)

    

    #calculate vertex

    vertexPts = rss.CurvePoints(polyBorder)

    pt1 = vertexPts[0]

    pt2 = vertexPts[1]

    pt3 = vertexPts[2]

    

    #calculate normal vector

    normVec = rss.SurfaceNormal(srf,(0,0))

    #scaleSurfaceNormal BEFORE ADDING

    normVec = rss.VectorScale(normVec,len*scFactor)

    

    #since normal vector is BY DEFAULT 0-based, we add it to the midPoints

    #to obtain the normals

    midPt1N = rss.VectorAdd(normVec,midPt1)

    midPt2N = rss.VectorAdd(normVec,midPt2)

    midPt3N = rss.VectorAdd(normVec,midPt3)

    

    """

    rss.AddPoint(midPt1N)

    rss.AddPoint(midPt2N)

    rss.AddPoint(midPt3N)

    """

    

    #add surfaces to the model

    baseSrf = rss.AddSrfPt((midPt1N,midPt2N,midPt3N))

    triaSrf1 = rss.AddSrfPt((pt1,midPt1N,midPt3N))

    triaSrf2 = rss.AddSrfPt((pt2,midPt2N,midPt1N))

    triaSrf3 = rss.AddSrfPt((pt3,midPt3N,midPt2N))

    

    #add control for further subdivision

    

    if(len>5):

        subdivideTriaSurf(baseSrf,delete,scFactor)

        subdivideTriaSurf(triaSrf1,delete,scFactor)

        subdivideTriaSurf(triaSrf2,delete,scFactor)

        subdivideTriaSurf(triaSrf3,delete,scFactor)

        tmpSrfList.append(baseSrf)

        tmpSrfList.append(triaSrf1)

        tmpSrfList.append(triaSrf2)

        tmpSrfList.append(triaSrf3)

        if(delete=="Yes"):

            rss.DeleteObjects((baseSrf,triaSrf1,triaSrf2,triaSrf3))

    

    rss.DeleteObject(polyBorder)

 

#obtain geometry

userSrf = rss.GetObject("Please select your surface AND make sure that it needs to be defined by 3 points",8)

 

#obtain other variables

userDelete = rss.GetString("Do you want to delete the temp surfaces?, you can alway s do it later",None,("Yes","No"))

print userDelete

scaleFactor = rss.GetReal("Please enter non-zero scale factor",0.25,0.1,5)

 

#call the function

subdivideTriaSurf(userSrf,userDelete,scaleFactor)

 

#ask the user to erase temp surfaces

if (userDelete=="No"):

    userDeleteAfter = rss.GetString("Do you want to delete the temp surfaces?",None,("Yes","No"))

    if(userDeleteAfter =="Yes"):

        rss.DeleteObjects(tmpSrfList)

Recursive Subdivision 4 sided polygon

Recursive subdivision of a 4-sided polygon 

This generates a subdivision based on a 4-sided polygon. Be careful as it does not provide sufficient error-checking, it simply assumes that you input the correct geometry.

#recursive subdivision

#import library

import rhinoscriptsyntax as rss

import random

 

#definition that subdivides the object

def subdivide(rect,maxLen,ctrlNr):

    #divide into 4 pieces

    #get all 4 segments

    segments = rss.ExplodeCurves(rect)

 

    #print("Los segmentos son:")

    #print(segments)

    #store the segments in different variables (not necessary)

    #segment 1-3 / segment 2-4

    segment1 = segments[0]

    segment2 = segments[1]

    segment3 = segments[2]

    segment4 = segments[3]

 

    #calculate middle points on the segments

    midPt1 = rss.CurveMidPoint(segment1)

    midPt2 = rss.CurveMidPoint(segment2)

    midPt3 = rss.CurveMidPoint(segment3)

    midPt4 = rss.CurveMidPoint(segment4)

 

    #verify it is correct

    #rss.AddPoints((midPt1,midPt2,midPt3,midPt4))

 

    #calculate centerPoint

    #join non-consecutive segments

    midLn1 = rss.AddLine(midPt1,midPt3)

    midLn2 = rss.AddLine(midPt2,midPt4)

 

    ctPt = rss.CurveCurveIntersection(midLn1,midLn2)

    #from the whole list of results we take [0][1]

    #[0]: because we know that we have a SINGLE object: intersection is 1 point

    #[0][1]: because for that one intersection event, we need to get the point coordinates

    ctPt = ctPt[0][1]

    #rss.AddPoint(ctPt)

 

    #extract the vertices of the rectangle in order to use them for the subsivision

    vertexPts = rss.CurvePoints(rect)

    rect1 = rss.AddPolyline((ctPt,midPt4,vertexPts[0],midPt1,ctPt))

    rect2 = rss.AddPolyline((ctPt,midPt1,vertexPts[1],midPt2,ctPt))

    rect3 = rss.AddPolyline((ctPt,midPt2,vertexPts[2],midPt3,ctPt))

    rect4 = rss.AddPolyline((ctPt,midPt3,vertexPts[3],midPt4,ctPt))

    

    #calculate the length and delete unnecesary objects

    len = rss.CurveLength(segment1)

    

    #create extrusions

    crv1 = rss.AddLine((0,0,0),(0,0,len))

    ext1 = rss.ExtrudeCurve(rect1,crv1)

    rss.CapPlanarHoles(ext1)

    rss.DeleteObject(crv1)

 

    len2 = rss.CurveLength(segment2)

    crv2 = rss.AddLine((0,0,0),(0,0,len))

    ext2 = rss.ExtrudeCurve(rect2,crv2)

    rss.CapPlanarHoles(ext2)

    rss.DeleteObject(crv2)

    

    len3 = rss.CurveLength(segment3)

    crv3 = rss.AddLine((0,0,0),(0,0,len))

    ext3 = rss.ExtrudeCurve(rect3,crv3)

    rss.CapPlanarHoles(ext3)

    rss.DeleteObject(crv3)

    

    len4 = rss.CurveLength(segment4)

    crv4 = rss.AddLine((0,0,0),(0,0,len))

    ext4 = rss.ExtrudeCurve(rect4,crv4)

    rss.CapPlanarHoles(ext4)

    rss.DeleteObject(crv4)

    

    rss.DeleteObjects((midLn1,midLn2))

    rss.DeleteObjects(segments)

    

    #add a control number

    randNr = random.random()

    #implement a control(how do i stop?)

    if((len>maxLen)and(randNr<ctrlNr)):

        rss.DeleteObjects((ext1,ext2,ext3,ext4))

        subdivide(rect1,maxLen,ctrlNr)

        subdivide(rect2,maxLen,ctrlNr)

        subdivide(rect3,maxLen,ctrlNr)

        subdivide(rect4,maxLen,ctrlNr)

 

#get object from user

#object needs to be 4-sided (in this case)

rectangles = rss.GetObjects("Please select the curves to be subdivided, note they need to have 4 sides and 4 sides only",4)

maxDesiredLen = rss.GetReal("Please enter minimum desired length",0.3,0.001)

controlNr = rss.GetReal("Please enter control number for random subdivision",0.8,0.1,1)

#use the definition we created above

for i in range(len(rectangles)):

    rss.EnableRedraw(False)

    rectangle = rectangles[i]

    subdivide (rectangle,maxDesiredLen,controlNr)

 

    rss.EnableRedraw(True)

Search Site




archi·o·logics survey

I am interested in: