'Coded by Daniel Cardoso & Neri Oxman 'January 2006 'for Kenfield Griffith and John Snavely's Computational Design Solutions I '----------------------------------------------------------------------------------------------------------------------------------------------- function makeCurves() 'curves will be created from 4 points 'types of curves, but the minimum should be 4 Dim crv1 Dim crv2 dim ptNum1 : ptNum1=10 dim ptNum2 : ptNum2=20 'ptNum1 represents the number of points along the "mother" curves to indicate the number of subdivisions. 'ptNum2 represents the number of points along the "child" curves (perpendicular to the mother curves) to indicate the number of subdivisions. crv1 = Rhino.getObject( "Enter first curve", 4 ) crv2 = Rhino.getObject( "Enter second curve", 4 ) ptNum1 = Rhino.IntegerBox("Enter number of Subdivisions along initial curves: ", ptNum1 ) ptNum2 = Rhino.IntegerBox("Enter number of Subdivisions along initial curves: ", ptNum2 ) 'Use the built curves to build bridge call makeBridge(crv1, crv2, ptNum1, ptNum2) end function '----------------------------------------------------------------------------------------------------------- OFFSET and join FUNCTION function offsetLine(arr, offsetv) 'This function takes an array of lines, joins them, and offsets this line a distance dim joinedSegLines : joinedSegLines = Rhino.JoinCurves(arr, true) redim offsetPoint(2) offsetPoint(0) = Rhino.CurveStartPoint(joinedSegLines(0))(0) offsetPoint(1) = Rhino.CurveStartPoint(joinedSegLines(0))(1) offsetPoint(2) = Rhino.CurveStartPoint(joinedSegLines(0))(2) + offsetv dim offsetSegLine : offsetSegLine = Rhino.CopyObject (joinedSegLines(0) , Rhino.CurveStartPoint(joinedSegLines(0)) , offsetPoint) end function '------------------------------------------------------------------------------------------------------------ FINDING EXTRUDE HEIGHT 'This function takes an array of heights and returns the value of the height of the extrusion of the beam function findExtrudeHeight(arr) dim lowValue : lowValue = Rhino.CurveLength( arr(0) ) dim offsetValue 'finding min for j = 1 to UBound(arr) if Rhino.CurveLength(arr( j )) < lowValue then lowValue = Rhino.CurveLength(arr( j )) else lowValue = lowValue end if next offsetValue = (lowValue * 0.5) + 1 findExtrudeHeight = offsetValue end function '----------------------------------------------------------------------------------------------------------- MAKE BRIDGE function makeBridge(c1, c2, ptNum1, ptNum2) 'c1,c2 are two given curves. We call them: "mother curves" 'PtNum1 and PtNum2 are the number of separations along c1 and c2 and along the child curves, as entered by the user 'Declare variables 'ParamsC1 stores the Umin and Umax values of curve C1. 'ParamsC2 stores the Umin and Umax values of curve C2. dim ParamsC1 dim ParamsC2 'Pts1 stands for the actual points to be placed on curve C1. 'Pts2 stands for the actual points to be placed on curve C2. dim Pts1 dim Pts2 'i is the counter for the subdivision points ptNum1 dim i 'j is the counter for the subdivision points ptNum2 dim j dim Uval1 dim Uval2 'Uval is assigned the relative position of any given points (Pts1 and Pts2 respectfully) along the BSpline curves (c1 and c2 respectively). 'It's actually the same as a Tvalue point in GC. ParamsC1=Rhino.curveDomain(c1) ParamsC2=Rhino.curveDomain(c2) 'params(0) = Umin -----> 'params(1) = Umax -----> 'mat stands for the 2D array which will be created out of the suvdivision points of the mother and child curves. dim mat(100, 200) for i=0 to ptNum1 Uval1=((ParamsC1(1)-ParamsC1(0))/(ptNum1))*(i) Uval2=((ParamsC2(1)-ParamsC2(0))/(ptNum1))*(i) Pts1=Rhino.EvaluateCurve(c1,Uval1) Pts2=Rhino.EvaluateCurve(c2,Uval2) 'this process allows us to place points along the two mother curves. These points are relative points and thus use the same Uval. dim currentLine: currentLine = Rhino.AddLine(Pts1,Pts2) 'each line, as it is being created, is stored in "currentLine" 'Rhino.Print "bottom_segments: " & Rhino.AddLayer("bottom_segments", RGB(0, 24, 255), 2) 'layer change Rhino.CurrentLayer("bottom_segments") 'layer change for j=0 to ptNum2 dim paramsCurrentLine : paramsCurrentLine = Rhino.CurveDomain(currentLine) dim UvalCurrent : UvalCurrent = ((paramsCurrentLine(1)-paramsCurrentLine(0))/(ptNum2))*(j) mat(i,j) = Rhino.EvaluateCurve(currentLine,UvalCurrent) next next 'this nested loop (above) creates a matrix of points which are place on "mother lines" ' CREATING CONNECTING LINES redim beams1(ptNum2) 'This array stores the joined segments for m=0 to ptNum2 '---------- > Iterating through the beams redim segLinesArr(ptNum1-1) 'Rhino.Print "Rib:" 'Rhino.Sleep 80 for n=0 to ptNum1 '---------- > Iterating through the segments if n < ptNum1 then dim seg : seg = Rhino.AddLine(mat(n,m),mat(n+1,m)) 'Creating the lines segLinesArr(n) = seg 'Populating the array ' Rhino.Sleep 50 else end if next If UBound(segLinesArr) > 0 Then beams1(m) = Rhino.JoinCurves( segLinesArr, true ) End If 'dim oLine : oLine = offsetLine(segLinesArr, 0.5) next '---- 'ANGLES, HEIGHTS, SURFACES redim beams2(ptNum2) 'This array stores the joined segments 'loop 1 ================================================================================= for j=0 to ptNum2 '---> Iterating through the beams 'loop 1a ================================================================================= for i=1 to ptNum1 '---> Iterating through the segments if i > 0 then 'create a point (for a given location j) which occupies the smae z position as its former point (located in position j-1) 'the x and y values of this point are the same as the position of the current point in mat (i,j) 'measure the angle between two lines given:the first line is connecting between (i,j) and (i,j-1) 'the second line is connecting between proPt and mat(i,j-1). 'This second line is like a projected line which allows to measure a 90 degree angle. redim arrProPt(2) arrProPt(0)=mat(i,j)(0) arrProPt(1)=mat(i,j)(1) arrProPt(2)=mat(i-1,j)(2) 'the following is the array for the connecting line: redim arrProLn(1) arrProLn(0)=mat(i-1,j) arrProLn(1)=arrProPt redim arrSegLn(1) arrSegLn(0)=mat(i,j) arrSegLn(1)=mat(i-1,j) dim helpLn1 : helpLn1 = Rhino.AddLine (arrProPt, mat(i,j)) 'Rhino.SelectObject(helpLn1) 'Rhino.Command "-Properties Object Color Object " & Int(153) & "," & Int(255)&"," & Int(102) & " Enter Enter" 'Rhino.UnselectAllObjects() 'Rhino.Print "help_lines_1: " & Rhino.AddLayer("help_lines_1", RGB(104, 231, 253), 2) 'layer change Rhino.CurrentLayer("help_lines_1") 'layer change dim helpLn2 : helpLn2 = Rhino.AddLine (arrProPt, mat(i-1,j)) 'helpLn2 is the greean line 'helpLn1 is the blue line 'Rhino.Print "help_lines_2: " & Rhino.AddLayer("help_lines_2", RGB(153, 255, 102), 2) 'layer change Rhino.CurrentLayer("help_lines_2") 'layer change 'measure the direction of helpLn2 and mark where the direction is changing. 'the curvature analysis is flipping at specific points. 'inflection points occur where the dicrease turns into an increase ( in the angle measurements) dim segAng : segAng = Rhino.Angle2(arrProLn,arrSegLn) redim segAngArr(500) 'created an array for storing the data of each of the angles that will come later to indicate the size of each segment line segAngArr(i)=segAng(0) 'storing the angles to the array declared dbefore end If if j>0 then 'call Rhino.AddSrfPt(Array(mat(i,j),mat(i-1,j),mat(i-1,j-1))) 'Add triangulated surface patches are set in an alternate (fishbone) pattern 'call Rhino.AddSrfPt(Array(mat(i,j),mat(i-1,j-1),mat(i,j-1))) 'Those triangles are fabricateable as flat pieces. end If next 'this ends the "segment" loop 'End of loop 1a ================================================================================= '* 'BEFORE JUMPING TO THE NEXT BEAM, WE MUST 'declare an array for the top segment points which are placed on the i curves redim arrTopSegLn(ptNum1) redim arrBeamHts(ptNum1) for k = 0 to ptNum1 dim FACT redim beamHt(2) dim beamLn if k < ptNum1 then FACT = (segAngArr(k)+(segAngArr(k)*segAngArr(k))) * 20 beamHt(0) = mat(k,j)(0) beamHt(1) = mat(k,j)(1) beamHt(2) = 1 + abs(mat(k,j)(2)) + abs( FACT + (segAngArr(k))) 'populating the array for connecting the beam height points arrTopSegLn(k)=beamHt 'Rhino.Print "height_lines: " & Rhino.AddLayer("height_lines", RGB(255, 0, 0), 2) 'layer change Rhino.CurrentLayer("height_lines") 'layer change beamLn = Rhino.AddLine( mat(k,j), beamHt ) arrBeamHts(k) = beamLn else FACT = (segAngArr(k-1)+(segAngArr(k-1)*segAngArr(k-1))) * 20 beamHt(0) = mat(k,j)(0) beamHt(1) = mat(k,j)(1) beamHt(2) = 1 + abs(mat(k,j)(2)) + abs( FACT + (segAngArr(k-1))) arrTopSegLn(k)=beamHt beamLn = Rhino.AddLine( mat(k,j), beamHt ) arrBeamHts(k) = beamLn end if next 'CREATING TOP SEGMENTS, JOINING THEM, STORING THEM redim topArr(ptNum1-1) for i = 0 to ptNum1-1 'if i = ptNum1 - 1 then dim topSegLn 'Rhino.Print "top_segment_lines: " & Rhino.AddLayer("top_segment_lines", RGB(255, 202, 0), 2) 'layer change 'Rhino.CurrentLayer("top_segment_lines") 'layer change 'Rhino.Print arrTopSegLn(i)(0) 'Rhino.Print arrTopSegLn(i+1)(0) topSegLn = Rhino.AddLine(arrTopSegLn(i),arrTopSegLn(i+1)) 'draw top seg lines topArr(i) = topSegLn 'else 'end if next if UBound(topArr) > 0 then beams2(j) = Rhino.JoinCurves(topArr, true) end if 'EXTRUSION, ETC 'We find the extrusion height according to arrBeamHts dim eHt : eHt = findExtrudeHeight(arrBeamHts) dim srf1 dim path dim originPt, newPt dim srf2 dim path2 dim originPt2, newPt2 redim surfacesToJoin(1) originPt = Rhino.CurveEndPoint(beams1(j)(0)) newPt = Rhino.CurveEndPoint(beams1(j)(0)) newPt(2) = newPt(2) + eHt + 0.25 path = Rhino.AddLine(originPt,newPt) 'Here, we extrude the base line of the beams srf1 = Rhino.ExtrudeCurve( beams1(j)(0), path) surfacesToJoin(0) = srf1 originPt2 = Rhino.CurveEndPoint(beams2(j)(0)) newPt2 = Rhino.CurveEndPoint(beams2(j)(0)) newPt2(2) = newPt(2) - eHt - 0.25 path2 = Rhino.AddLine(originPt2,newPt2) srf2 = Rhino.ExtrudeCurve( beams2(j)(0), path) surfacesToJoin(1) = srf2 surfacesToJoin(1) = srf2 Rhino.Print "I'm here 1" If UBound(surfacesToJoin) > 0 Then Rhino.Print "I'm here 2" Rhino.JoinSurfaces surfacesToJoin, true End If 'Rhino.JoinSurfaces surfacesToJoin ,true next end function makeCurves