Sunday, April 29, 2012

Corals - Surface Dependant 3D Branching

  


Input : Surface from Rhino
Outputs: Quad Tessellated Surface with 3D Branches growing normal, of the centre of each tessellation.


3D branching depends on surface curvature, changes in size, branching levels and random range for angles of branches.




import rhinoscriptsyntax as rs
import random 
import scriptcontext
rs.EnableRedraw(False)

surface = rs.GetObject('select surface',8)

udomain = rs.SurfaceDomain(surface,0)
vdomain = rs.SurfaceDomain(surface,1)

stepu = 15
stepv = 15

divisionsu  = udomain[1] / stepu
divisionsv = vdomain[1] / stepv
surfaceptv = []

## GRID OF POINTS UV##
for u in range(0,stepu+1):
    listupt = []
    for v in rs.frange(0,vdomain[1],divisionsv):
        
        pt = rs.EvaluateSurface(surface,u*divisionsu,v)
        pt1 = rs.AddPoint(pt)
        listupt.append(pt1)
    surfaceptv.append(listupt)


##ROW MIDPOINTS##
midpoints1 = []
for i in range(0,stepu+1):
    points1 = []
    for j in range(0,stepv-1):
        a = surfaceptv[i][j]
        acoord = rs.PointCoordinates(a)
        b = surfaceptv[i][j+1]
        bcoord = rs.PointCoordinates(b)
        cX = (acoord[0]+bcoord[0])/2 
        cY = (acoord[1]+bcoord[1])/2 
        cZ = (acoord[2]+bcoord[2])/2 
        c = [cX,cY,cZ]
        points1.append(c)
    midpoints1.append(points1)

##FIND MIDPOINTS##
midpoints = []
for i in range(0,stepu):
    rows = []
    for j in range(0,stepv-1):
        
        a0 = midpoints1[0+i][j]
        a1 = midpoints1[1+i][j]
        mpX= (a0[0]+a1[0])/2
        mpY= (a0[1]+a1[1])/2
        mpZ= (a0[2]+a1[2])/2
        a = rs.AddPoint([mpX,mpY,mpZ])
        rows.append(a)
    midpoints.append(rows)

##curvature evaluation##
slope = []
for i in range(0,stepu):
    for j in range(0,stepv-1):
        
        p1 = rs.PointCoordinates(surfaceptv[0+i][0+j])
        p2 = rs.PointCoordinates(surfaceptv[0+i][1+j])
        p3 = rs.PointCoordinates(surfaceptv[1+i][1+j])
        p4 = rs.PointCoordinates(surfaceptv[1+i][0+j])
        
        p1o= p1[2]
        p2o= p2[2]
        p3o= p3[2]
        p4o= p4[2]
        po = [p1o,p2o,p3o,p4o]
        
        difference = max(po) - min(po)
        slope.append(difference)

smax =  max(slope)
smin =  min(slope)
srange = max(slope) - min(slope)
sint = srange/3
rangemid1 = smin + sint
rangemid2 = rangemid1 + sint

rad_low = 0.07
rad_mid = 0.1 
rad_high= 0.13

LineBList = []

lowslope = []
midslope = []
highslope= []

for i in range(0,stepu):
    for j in range(0,stepv-1):
        pl = rs.AddPolyline([surfaceptv[0+i][0+j],surfaceptv[1+i][0+j],surfaceptv[1+i][1+j],surfaceptv[0+i][1+j],surfaceptv[0+i][0+j]])       
        points = [surfaceptv[0+i][0+j],surfaceptv[1+i][0+j],surfaceptv[1+i][1+j],surfaceptv[0+i][1+j]]
        srf = rs.AddSrfPt(points)
        uv = rs.SurfaceClosestPoint(srf, midpoints[i][j])
        pt = rs.PointCoordinates(midpoints[i][j])
        norm = rs.SurfaceNormal(srf, uv)
        
        
        p1 = rs.PointCoordinates(surfaceptv[0+i][0+j])
        p2 = rs.PointCoordinates(surfaceptv[0+i][1+j])
        p3 = rs.PointCoordinates(surfaceptv[1+i][1+j])
        p4 = rs.PointCoordinates(surfaceptv[1+i][0+j])
        p1o= p1[2]
        p2o= p2[2]
        p3o= p3[2]
        p4o= p4[2]
        po = [p1o,p2o,p3o,p4o]
        
        difference = max(po) - min(po)
        
        if (difference < rangemid1) and (difference >= smin): 
            vect0 = rs.VectorScale(norm, 0.6)
        elif (difference < rangemid2 ) and (difference > rangemid1):
            vect0 = rs.VectorScale(norm, 0.8)
        elif (difference <= smax) and (difference > rangemid2):
            vect0 = rs.VectorScale(norm, 0.4)
        
        vect = rs.VectorAdd(vect0, pt)
        
        plane = rs.PlaneFromNormal(midpoints[i][j],norm)
        
        l = rs.AddLine(midpoints[i][j],vect)
        if (difference < rangemid1) and (difference >= smin): 
            lowslope.append(l)
            circle = rs.AddCircle(plane,rad_low)
            mcircle = rs.MoveObject(circle,vect0)
        elif (difference < rangemid2 ) and (difference > rangemid1):
            midslope.append(l)
            circle = rs.AddCircle(plane,rad_mid)
            mcircle = rs.MoveObject(circle,vect0)
        elif (difference <= smax) and (difference > rangemid2):
            highslope.append(l)
            circle = rs.AddCircle(plane,rad_high)
            mcircle = rs.MoveObject(circle,vect0)
            
        loft = rs.AddLoftSrf([pl,circle])


## 3D BRANCHING##
def drawbranch1 (x, line):
    scriptcontext.escape_test()
    
    if x==0:
        return
    else:
        for i in range(0,4):
            end_pt = rs.CurveEndPoint(line)
            st_pt = rs.CurveStartPoint(line)
            rnd = random.randint(-50, 50)
            rndrot1 = random.randint(-40,40)
            rndrot2 = random.randint(-40,40)
            vect = rs.VectorCreate(end_pt, st_pt)
            vect = rs.VectorRotate(vect, rnd, [rndrot1,rndrot2,0])
            ptadd = rs.PointAdd(end_pt, vect)
            #cyl = rs.AddCylinder(st_pt,end_pt,rad_low,False)
            line = rs.AddLine(end_pt,ptadd)
            drawbranch1(x-1, line)

for i in range(len(lowslope)):
    a = drawbranch1(3, lowslope[i])



def drawbranch2 (x, line):
    scriptcontext.escape_test()
    if x==0:
        return
    else:
        for i in range(0,4):
            end_pt = rs.CurveEndPoint(line)
            st_pt = rs.CurveStartPoint(line)
            rnd = random.randint(-30, 30)
            rndrot1 = random.randint(-30,30)
            rndrot2 = random.randint(-30,30)
            vect = rs.VectorCreate(end_pt, st_pt)
            vect = rs.VectorRotate(vect, rnd, [rndrot1,rndrot2,0])
            ptadd = rs.PointAdd(end_pt, vect)
            #cyl = rs.AddCylinder(st_pt,end_pt,rad_mid,False)
            line = rs.AddLine(end_pt,ptadd)
            drawbranch2(x-1, line)

for i in range(len(midslope)):
    a = drawbranch2(3, midslope[i])



def drawbranch3 (x, line):
    scriptcontext.escape_test()
    if x==0:
        return
    else:
        for i in range(0,3):
            end_pt = rs.CurveEndPoint(line)
            st_pt = rs.CurveStartPoint(line)
            rnd = random.randint(-15, 15)
            rndrot1 = random.randint(-90,90)
            rndrot2 = random.randint(-90,90)
            vect = rs.VectorCreate(end_pt, st_pt)
            vect = rs.VectorRotate(vect, rnd, [rndrot1,rndrot2,0])
            ptadd = rs.PointAdd(end_pt, vect)
            #cyl = rs.AddCylinder(st_pt,end_pt,rad_high,False)
            line = rs.AddLine(end_pt,ptadd)
            drawbranch3(x-1, line)

for i in range(len(highslope)):
    a = drawbranch3(3, highslope[i])


SURFACE TESSELATION

www.juliakoerner.com
 



import rhinoscriptsyntax as rs
import math

#definition for surface sampling
def samplesurface(strSurf,intUdivisions,intVdivisions):
    listUDomain =rs.SurfaceDomain(strSurf,0)
    listVDomain =rs.SurfaceDomain(strSurf,1)
   
    floatUstep = (listUDomain[1]-listUDomain[0])/intUdivisions
    floatVstep = (listVDomain[1]-listUDomain[0])/intVdivisions
   
    listofrows =[]
   
    for i in rs.frange(listUDomain[0],listUDomain[1],floatUstep):
        columnlist = []
        for j in rs.frange(listVDomain[0],listVDomain[1]+0.01,floatVstep):
            columnlist.append(rs.EvaluateSurface(strSurf,i,j))
            rs.AddPoint(rs.EvaluateSurface(strSurf,i,j))
       
        listofrows.append(columnlist)
       
    return listofrows


#draw a surface and 2 attractor points so you can select it for the skript

Surf = rs.GetObject("surface",8)

attractorpoints = rs.GetObjects("points")

rs.EnableRedraw(False)


intU =30
intV =30

listofpoints = samplesurface(Surf,intU, intV)

for i in range (0, len(listofpoints)):
    for j in range (0,len(listofpoints[i])):
        rs.AddPoint(listofpoints[i][j])

#definition for centerpoints of surface sampling  
def centerpoints(listofCpt):
    x=0
    y=0
    z=0
   
    for i in range (0,len(listofCpt)):
       
        x= x + listofCpt[i][0]
        y= y + listofCpt[i][1]
        z= z + listofCpt[i][2]

    x = x / len(listofCpt)
    y = y / len(listofCpt)
    z = z / len(listofCpt)
       
       
       
    return [x,y,z]


midpoints = []

for i in range(0,intU-1):
    list0 = []
    for j in range(0,intV):
        a=([listofpoints[i][j],listofpoints[i+1][j],listofpoints[i+1][j+1],listofpoints[i][j+1]])
       
        listofCpt = []
       
        listofCpt.extend(a)
       
        midpoints0 = centerpoints(listofCpt)
       
        midpoints1 = rs.AddPoint(midpoints0)
        list0.append(midpoints0)
    midpoints.append(list0)


listofextrudedSrf1 =[]
listofextrudedSrf2 =[]


for i in range (0,intU-1):
    for j in range (0,intV):
        pl = rs.AddPolyline([listofpoints[i][j],listofpoints[i+1][j],listofpoints[i+1][j+1],listofpoints[i][j+1],listofpoints[i][j]])
        points = [listofpoints[i][j],listofpoints[i+1][j],listofpoints[i+1][j+1],listofpoints[i][j+1]]
        srf = rs.AddSrfPt(points)
        uv = rs.SurfaceClosestPoint(srf, midpoints[i][j])
        norm = rs.SurfaceNormal(srf, uv)
       
       
        indexattractors = rs.PointArrayClosestPoint(attractorpoints,midpoints[i][j])
       
        #attractorpoint hight of pyramid
        distance = rs.Distance(midpoints[i][j], attractorpoints[indexattractors])
       
       
        #positive direction
        vect = rs.VectorScale(norm,distance*distance/2400)
        vect0 = rs.VectorAdd(vect,midpoints[i][j])
        extr1 = rs.ExtrudeCurvePoint(pl, vect0)
       
        listofextrudedSrf1.append(extr1)
           
       
        #Peakpoints

        peakPt = rs.AddPoint(vect0)
       
        #polylines of each side of pyramid
        polyline1 = rs.AddPolyline([listofpoints[i][j],listofpoints[i+1][j],peakPt,listofpoints[i][j]])
        polyline2 = rs.AddPolyline([listofpoints[i+1][j],listofpoints[i+1][j+1],peakPt,listofpoints[i+1][j]])
        polyline3 = rs.AddPolyline([listofpoints[i+1][j+1], listofpoints[i][j+1], peakPt,listofpoints[i+1][j+1]])
        polyline4 = rs.AddPolyline([listofpoints[i][j], listofpoints[i][j+1], peakPt,listofpoints[i][j]])
       
        #polyline centers of each pyramid side
        polylinecenters1 = rs.CurveAreaCentroid(polyline1)
        polylinecenters2 = rs.CurveAreaCentroid(polyline2)
        polylinecenters3 = rs.CurveAreaCentroid(polyline3)
        polylinecenters4 = rs.CurveAreaCentroid(polyline4)
       
        #because Curve Area Centroid returns two items a point 3d and a vektor
        #I have to tell him to only select item one
        fixedpolylinecenters1 = polylinecenters1[0]
        fixedpolylinecenters2 = polylinecenters2[0]
        fixedpolylinecenters3 = polylinecenters3[0]
        fixedpolylinecenters4 = polylinecenters4[0]
       
        polylinecenterspoints1 = rs.AddPoint(fixedpolylinecenters1)
        polylinecenterspoints2 = rs.AddPoint(fixedpolylinecenters2)
        polylinecenterspoints3 = rs.AddPoint(fixedpolylinecenters3)
        polylinecenterspoints4 = rs.AddPoint(fixedpolylinecenters4)
       
        #scale the polylines
        s1 = 0.5
        s2 = 0.5
        s3 = 0.5
       
        scalepolyline1 = rs.ScaleObject(polyline1, fixedpolylinecenters1, (s1,s2,s3), True)
        scalepolyline2 = rs.ScaleObject(polyline2, fixedpolylinecenters2, (s1,s2,s3), True)
        scalepolyline3 = rs.ScaleObject(polyline3, fixedpolylinecenters3, (s1,s2,s3), True)
        scalepolyline4 = rs.ScaleObject(polyline4, fixedpolylinecenters4, (s1,s2,s3), True)
       
       
        #loft the polylines
        loft1 = rs.AddLoftSrf([polyline1 ,scalepolyline1])
        loft2 = rs.AddLoftSrf([polyline2 ,scalepolyline2])
        loft3 = rs.AddLoftSrf([polyline3 ,scalepolyline3])
        loft4 = rs.AddLoftSrf([polyline4 ,scalepolyline4])
       
        rs.DeleteObject(extr1)
        rs.DeleteObject(srf)
       
        joinedsurfaces = rs.JoinSurfaces([loft1,loft2,loft3,loft4],True)
       
        #negative direction
        vect2 = rs.VectorScale(vect,-1)
        vect0 = rs.VectorAdd(vect2,midpoints[i][j])
        extr2 = rs.ExtrudeCurvePoint(pl, vect0)
       
        listofextrudedSrf2.append(extr2)

        # dublicate the Loop of Peakpoints for negative direction
Scripted shape of an HIV Virus. 
The base shape is an icosahedron and the size of the sphere units in each face are dependent to the distance to an attractor point.









+ Artichokes



import rhinoscriptsyntax as rs

def samplesurface(strSurf, intUdivisions, intVdivisions):
   
    uDomain = rs.SurfaceDomain(surface,0)
    #print uDomain
    vDomain = rs.SurfaceDomain(surface,1)
    #print vDomain
   
    listOfRows = []
   
    for i in rs.frange(uDomain[0], uDomain[1]+.001, (uDomain[1]-uDomain[0])/intUdivisions):
        columnList = []
        for j in rs.frange(vDomain[0], vDomain[1]+.001,(vDomain[1]-vDomain[0])/intVdivisions):
            pt = rs.EvaluateSurface(surface,i,j)
            columnList.append(pt)
        listOfRows.append(columnList)
    return listOfRows

def CenterPt(listOfPoints):
  
    X = 0
    Y = 0
    Z = 0
    for i in range (0,len(listOfPoints)):
        X = X + (listOfPoints[i][0])
        Y = Y + (listOfPoints[i][1])
        Z = Z + (listOfPoints[i][2])
    XMid = X/len(listOfPoints)
    YMid = Y/len(listOfPoints)
    ZMid = Z/len(listOfPoints)
  
    CentPt = [XMid, YMid, ZMid]
    CentPtViz = rs.AddPoint([XMid, YMid, ZMid])
    return CentPt

def NewVec(pt1, pt2, scaleval):
    vectorbetween = rs.VectorCreate(pt1, pt2)
    scaledvector = rs.VectorScale(vectorbetween, -scaleval)
    mynewpoint = rs.VectorAdd( scaledvector, pt1)
    return mynewpoint

rs.EnableRedraw(False)
surface = rs.GetObject("surface",8)

udivisions = 10
vdivisions = 10

Udomain = rs.SurfaceDomain(surface,0)
Vdomain = rs.SurfaceDomain(surface,1)

ustep = (Udomain[1]-Udomain[0])/udivisions
vstep = (Vdomain[1]-Vdomain[0])/vdivisions

listofpoints = []

intUdivisions = 10 #divisions of the surface
intVdivisions = 10

listOfPoints = samplesurface(surface, intUdivisions, intVdivisions)

##diamonds 01
for i in range(0,len(listOfPoints)-1,2):
    for j in range(0,len(listOfPoints[i])-2,2):
        CurveAdd = rs.AddCurve([listOfPoints[i][j+1], listOfPoints[i+1][j+2], listOfPoints[i+2][j+1], listOfPoints[i+1][j], listOfPoints[i][j+1]],2)
        Romb1 = rs.AddSrfPt([listOfPoints[i][j+1], listOfPoints[i+1][j+2], listOfPoints[i+2][j+1], listOfPoints[i+1][j]])
        Points = ([listOfPoints[i][j+1], listOfPoints[i+1][j+2], listOfPoints[i+2][j+1], listOfPoints[i+1][j]])
       
        borderPts = [listOfPoints[i][j+1], listOfPoints[i+1][j+2], listOfPoints[i+2][j+1],listOfPoints[i+1][j]]
        MidPt = CenterPt(borderPts) #places the borderPts into MidPT
        innerPts = []
       
        for k in range(0,len(borderPts)):
            innerPts.append(NewVec(borderPts[k],MidPt,.2))
           
        uv = rs.SurfaceClosestPoint(surface, innerPts[3])
        norm = rs.SurfaceNormal(surface,uv) # is giving you the normal at [0,0,0]
        norm = rs.VectorUnitize(norm) # it is making the lenght of the vector = 1 (still at the origin)
        norm = rs.VectorScale(norm, j/7)
        norm = rs.VectorAdd(innerPts[3],norm)
        srf01= rs.AddSrfPt([innerPts[0], innerPts[1],borderPts[1],borderPts[0]])
        srf02= rs.AddSrfPt([innerPts[1], innerPts[2],borderPts[2],borderPts[1]])
        srf03= rs.AddSrfPt([innerPts[2], innerPts[3],borderPts[3],borderPts[2]])
        srf04= rs.AddSrfPt([innerPts[0], innerPts[3],borderPts[3],borderPts[0]])
        srf05= rs.AddSrfPt([innerPts[0], innerPts[1],innerPts[2],norm])

##diamonds 02
for i in range(1,len(listOfPoints)-2,2):
    for j in range(1,len(listOfPoints[i])-3,2):
       
        uv = rs.SurfaceClosestPoint(surface, listOfPoints[i+1][j])
       
        borderPts = [listOfPoints[i][j+1], listOfPoints[i+1][j+2], listOfPoints[i+2][j+1],listOfPoints[i+1][j]]
        MidPt = CenterPt(borderPts) #places the borderPts into MidPT
        innerPts = []
       
        for k in range(0,len(borderPts)):
            innerPts.append(NewVec(borderPts[k],MidPt,.2))
           
        uv = rs.SurfaceClosestPoint(surface, innerPts[3])
        norm = rs.SurfaceNormal(surface,uv) # is giving you the normal at [0,0,0]
        norm = rs.VectorUnitize(norm) # it is making the lenght of the vector = 1 (still at the origin)
        norm = rs.VectorScale(norm, j/7)
        norm = rs.VectorAdd(innerPts[3],norm)
        srf01= rs.AddSrfPt([innerPts[0], innerPts[1],borderPts[1],borderPts[0]])
        srf02= rs.AddSrfPt([innerPts[1], innerPts[2],borderPts[2],borderPts[1]])
        srf03= rs.AddSrfPt([innerPts[2], innerPts[3],borderPts[3],borderPts[2]])
        srf04= rs.AddSrfPt([innerPts[0], innerPts[3],borderPts[3],borderPts[0]])
        srf05= rs.AddSrfPt([innerPts[0], innerPts[1],innerPts[2],norm])
       
        CurveAdd2 = rs.AddCurve([listOfPoints[i][j+1], listOfPoints[i+1][j+2], listOfPoints[i+2][j+1], norm, listOfPoints[i][j+1]],2)
        Romb2 = rs.AddSrfPt([listOfPoints[i][j+1], listOfPoints[i+1][j+2], listOfPoints[i+2][j+1], norm])


##to make the seam diamonds, diamonds 03
for i in range(0,(vdivisions),2):
    for j in range(0,(udivisions),2):
#        rs.AddSrfPt([listOfPoints[len(listOfPoints)-2][j+2], listOfPoints[len(listOfPoints)-1][j+3], listOfPoints[i+1][j+2],listOfPoints[len(listOfPoints)-1][j+1]])
       
        uv = rs.SurfaceClosestPoint(surface, listOfPoints[len(listOfPoints)-1][j+1])
       
        borderPts = [listOfPoints[len(listOfPoints)-2][j+2], listOfPoints[len(listOfPoints)-1][j+3], listOfPoints[i+1][j+2],listOfPoints[len(listOfPoints)-1][j+1]]
        MidPt = CenterPt(borderPts) #places the borderPts into MidPT
        innerPts = []
       
        for k in range(0,len(borderPts)):
            innerPts.append(NewVec(borderPts[k],MidPt,.2))
        norm = rs.SurfaceNormal(surface,uv)
        norm = rs.VectorUnitize(norm)
        norm = rs.VectorScale(norm, j/7)
       
        norm = rs.VectorAdd(listOfPoints[len(listOfPoints)-1][j+1],norm)
       
        uv = rs.SurfaceClosestPoint(surface, innerPts[3])
        norm = rs.SurfaceNormal(surface,uv) # is giving you the normal at [0,0,0]
        norm = rs.VectorUnitize(norm) # it is making the lenght of the vector = 1 (still at the origin)
        norm = rs.VectorScale(norm, j/7)
        norm = rs.VectorAdd(innerPts[3],norm)
        srf01= rs.AddSrfPt([innerPts[0], innerPts[1],borderPts[1],borderPts[0]])
        srf02= rs.AddSrfPt([innerPts[1], innerPts[2],borderPts[2],borderPts[1]])
        srf03= rs.AddSrfPt([innerPts[2], innerPts[3],borderPts[3],borderPts[2]])
        srf04= rs.AddSrfPt([innerPts[0], innerPts[3],borderPts[3],borderPts[0]])
        srf05= rs.AddSrfPt([innerPts[0], innerPts[1],innerPts[2],norm])
       

rs.EnableRedraw(True)