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])


1 comment:

  1. All office functions, including dictation, typing, filing, copying, fax, Telex, microfilm and records management, telephone and telephone switchboard operations, fall into this category.

    automated welding

    ReplyDelete