'SpaceframeFromSurface.rvb 'This script produces a spaceframe with a constant depth 'In: Surface, U and V divisions, height, grid size 'Out: Folded Tiles on Surface and unfolded curves on XY plane, labelled, and ready to be laser cut

Option Explicit

Sub SpaceFrameFromSurface

   Dim sourceSurface, uDiv, vDiv, height, grid
   Dim uStep, vStep
   Dim uVal, vVal
   Dim i, j
   Dim tilePoints(3)
   Dim apexData, apexPoint

   'Prompt user for input data
   sourceSurface = Rhino.GetObject("Select a surface to populate with spaceframe", 8)
   uDiv = Rhino.GetInteger("Enter the number of divisions in the U direction", 10, 1)
   vDiv = Rhino.GetInteger("Enter the number of divisions in the V direction", 10, 1)
   height = Rhino.GetReal("Enter a height for the spaceframe")
   'End input data
   'To simplify the script, the surface is reparameterized to go from 0 to 1 in both directions
   Rhino.SelectObject sourceSurface
   Rhino.Command "Reparameterize 0 1 0 1 "
   'Redimension the arrays that will hold all the values of U and V to the number of tiles in each direction
   Redim uVal(uDiv)
   Redim vVal(vDiv)
   ReDim apexPoint ((uDiv-1),(vDiv-1))
   'Find the step value, i.e. the distance between tiles in each direction. (note: this is not the euclidian distance, it is the distance measured in UV space)
   uStep = 1/uDiv
   vStep = 1/vDiv
   'Fill the arrays with the actual values of U and V at each step
   For i = 0 To uDiv
       uVal(i) = i * uStep
       Rhino.Print "uVal(" & i & "):" & uVal(i)
   For i = 0 To vDiv
       vVal(i) = i * vStep
       Rhino.Print "vVal(" & i & "):" & vVal(i)
   'Disable Rhino from redrawing the views during the tile construction to speed things up
   Rhino.EnableRedraw vbFalse
   Rhino.Print "Constructing spaceframe..."
   'Start looping through each u and v division and create the tile within
   For i = 0 to uDiv-1
       For j = 0 to vDiv-1
           'Find the 3D coordinate for each of the 4 corners of the tile using the UV coordinates as input
           tilePoints(0) = Rhino.EvaluateSurface(sourceSurface, array(uVal(i), vVal(j)))
           tilePoints(1) = Rhino.EvaluateSurface(sourceSurface, array(uVal(i+1), vVal(j)))
           tilePoints(2) = Rhino.EvaluateSurface(sourceSurface, array(uVal(i+1), vVal(j+1)))
           tilePoints(3) = Rhino.EvaluateSurface(sourceSurface, array(uVal(i), vVal(j+1)))
           'Find the 3D coordinate normal to the specified UV coordinate for the given height
           apexData = Rhino.SurfaceCurvature(sourceSurface, array(uVal(i)+(uVal(1)/2), vVal(j)+(vVal(1)/2)))
           apexPoint(i,j) = offsetCalc(apexData, height)
           'Add two top struts
           Rhino.AddLine tilePoints(0), tilePoints(1)
           Rhino.AddLine tilePoints(0), tilePoints(3)
           'If in the last u row then add another strut
           If (i = uDiv-1) Then
              Rhino.AddLine tilePoints(1), tilePoints(2)
           End If
           'If in the last v row then add another strut
           If (j = vDiv-1) Then
              Rhino.AddLine tilePoints(3), tilePoints(2)
           End If
           'Add 4 diagonal struts
           Rhino.AddLine tilePoints(0), apexPoint(i,j)
           Rhino.AddLine tilePoints(1), apexPoint(i,j)
           Rhino.AddLine tilePoints(2), apexPoint(i,j)
           Rhino.AddLine tilePoints(3), apexPoint(i,j)
           'If not in the first u row then add a bottom strut
           If (i > 0) Then
              Rhino.AddLine apexPoint(i,j), apexPoint(i-1,j)
           End If
           'If not in the first v row then add a bottom strut
           If (j > 0) Then
              Rhino.AddLine apexPoint(i,j), apexPoint(i,j-1)
           End If

   'Re-enable the redraw so that we can see the result of the tile construction
   Rhino.EnableRedraw vbTrue

End Sub

'Call the sub SpaceFrameFromSurface

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'This fucntion finds the coordinate of a point normal to, and at a <height> from, a point on the surface Function offsetCalc(oData, height)

        Dim vscaled
        vscaled = VectorScale(oData(1),height)
        offsetCalc = VectorAdd(vscaled,oData(0))

End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'function by RMA, "vectors.rvb" Function VectorAdd(v1, v2)

        VectorAdd = Null
        If Not IsArray(v1) Or (UBound(v1) <> 2) Then Exit Function
        If Not IsArray(v2) Or (UBound(v2) <> 2) Then Exit Function
        VectorAdd = Array(v1(0) + v2(0), v1(1) + v2(1), v1(2) + v2(2))

End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'function by RMA, "vectors.rvb" Function VectorScale(v, d)

        VectorScale = Null
        If Not IsArray(v) Or (UBound(v) <> 2) Then Exit Function
        If Not IsNumeric(d) Then Exit Function
        VectorScale = Array(v(0) * d, v(1) * d, v(2) * d)

End Function

'-------------------------------------------------------------------------------------------------------------------- 'This function checks if the current layer is <layername> and if it isn't, makes it so. If the layer <layername> doesn't ' exist then it creates it with the name <layername>. Function CheckLayer(layername)

        If Rhino.IsLayer(layername) Then
        End If

End Function

Ad blocker interference detected!

Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.