top of page
Writer's pictureDavid Mans

Ripple Unfold

💻 Rhino 5

🔼 Rhino Script

🛠️ Visual Basic

 

This fabrication script presents a simple tool to evaluate a surface with a triangular pattern and unfold this pattern in a series of bands. These bands are tabbed a numbered for easy assembly. This script is the first and simplest step in a series of Rhino Scripts which will attempt to provide rigid structural skins with a simple triangulation technique.

 
Option Explicit
'Script written by <David Mans>
'Script copyrighted by <Neoarchaic Design>
'Script version Monday, May 26, 2008 1:43:26 PM
 
Call Main()
Sub Main()
    Dim surf
    surf = Rhino.GetObject("select surface", 8)
    If isNull(surf) Then Exit Sub
    Call reparameterize(surf)
     
    Dim arrItems, arrValues, arrResults
    arrItems = array("Colums", "Rows", "Offset", "tabHeight", "ripple", "cutTemplate", "surfaces")
    arrValues = array(20, 20, 2, 1, False, True, True)
    arrResults = Rhino.PropertyListBox(arrItems, arrValues,, "Volume Parameters")
    Dim tri
    Call Rhino.EnableRedraw(False)
    tri = TriangulateSurface(surf, CDbl(arrResults(0)), CDbl(arrResults(1)), CDbl(arrResults(2)), array(CBool(arrResults(4))))
    If CBool(arrResults(6)) = True Then
        Call SurfaceMe(tri, RGB(255, 0, 0))
    End If
     
    If CBool(arrResults(5)) = True Then
        Call UnfoldMe(tri, CDbl(arrResults(3)))
    End If
     
    Call Rhino.EnableRedraw(True)
     
End Sub
Function TriangulateSurface(surface, cols, rows, offset, arrBln)
    TriangulateSurface = Null
    Dim i,j
    Dim uDom,vDom,uStep,vStep
    uDom = Rhino.SurfaceDomain(surface, 0)(1): uStep = uDom / cols
    vDom = Rhino.SurfaceDomain(surface, 1)(1): VStep = vDom / rows
     
    ReDim uv(rows),pt(rows),uvSet(cols),ptSet(cols)
    'plot point grid
    For i = 0 To cols Step 1
        For j = 0 To rows Step 1
            uv(j) = array(i * uStep, j * vStep)
            If i Mod (2) Then
                If j Mod (2) Then              
                    pt(j) = Rhino.PointAdd(Rhino.EvaluateSurface(surface, uv(j)), Rhino.VectorScale(Rhino.VectorUnitize(Rhino.SurfaceNormal(surface, uv(j))), offset))
 
                Else
                    pt(j) = Rhino.EvaluateSurface(surface, uv(j))
                End If
            Else
                If j Mod (2) Then              
                    pt(j) = Rhino.EvaluateSurface(surface, uv(j))
                Else
                    If arrBln(0) = True Then
                        pt(j) = Rhino.PointAdd(Rhino.EvaluateSurface(surface, uv(j)), Rhino.VectorScale(Rhino.VectorUnitize(Rhino.SurfaceNormal(surface, uv(j))), -offset))
                    Else
                        pt(j) = Rhino.PointAdd(Rhino.EvaluateSurface(surface, uv(j)), Rhino.VectorScale(Rhino.VectorUnitize(Rhino.SurfaceNormal(surface, uv(j))), offset))
                    End If
                End If
            End If
        Next
        uvSet(i) = uv
        ptSet(i) = pt
    Next
    TriangulateSurface = ptSet
End Function
Function SurfaceMe(ptSet, objClr)
    SurfaceMe = Null
    If Rhino.IsLayer("surfaces") = False Then
        Call Rhino.AddLayer("surfaces", RGB(0, 0, 255))
    End If
     
    Dim i,j
    Dim cols, rows
    cols = uBound(ptSet)
    rows = uBound(ptSet(0))
     
    Dim srfA(),srfB()
    ReDim srfA(rows-1),srfB(rows-1)
    ReDim s(cols-1)
    For i = 0 To cols - 1 Step 1
        For j = 0 To rows - 1 Step 1
            If i Mod (2) Then
                If j Mod (2) Then
                    srfA(j) = Rhino.AddSrfPt(array(ptSet(i)(j), ptSet(i)(j + 1), ptSet(i + 1)(j)))
                    srfB(j) = Rhino.AddSrfPt(array(ptSet(i + 1)(j + 1), ptSet(i)(j + 1), ptSet(i + 1)(j)))
                Else
                    srfA(j) = Rhino.AddSrfPt(array(ptSet(i + 1)(j), ptSet(i + 1)(j + 1), ptSet(i)(j)))
                    srfB(j) = Rhino.AddSrfPt(array(ptSet(i)(j + 1), ptSet(i + 1)(j + 1), ptSet(i)(j)))
                End If
            Else
                If j Mod (2) Then
                    srfA(j) = Rhino.AddSrfPt(array(ptSet(i + 1)(j), ptSet(i + 1)(j + 1), ptSet(i)(j)))
                    srfB(j) = Rhino.AddSrfPt(array(ptSet(i)(j + 1), ptSet(i + 1)(j + 1), ptSet(i)(j)))
                Else
                    srfA(j) = Rhino.AddSrfPt(array(ptSet(i)(j), ptSet(i)(j + 1), ptSet(i + 1)(j)))
                    srfB(j) = Rhino.AddSrfPt(array(ptSet(i + 1)(j + 1), ptSet(i)(j + 1), ptSet(i + 1)(j)))
                End If
            End If
            Call Rhino.ObjectColor(srfA(j), objClr)
            Call Rhino.ObjectColor(srfB(j), objClr)
            Call Rhino.ObjectLayer(srfA(j), "surfaces")
            Call Rhino.ObjectLayer(srfB(j), "surfaces")
        Next
        s(i) = array(srfA, srfB)
    Next
    SurfaceMe = s
End Function
Function UnfoldMe(ptSet, tabHeight)
    UnfoldMe = Null
    If Rhino.IsLayer("cuts") = False Then
        Call Rhino.AddLayer("cuts", RGB(255, 0, 0))
    End If
    If Rhino.IsLayer("scores") = False Then
        Call Rhino.AddLayer("scores", RGB(0, 0, 0))
    End If
     
    Dim i,j,r
    Dim cols, rows, wrldCS
    cols = uBound(ptSet)
    rows = uBound(ptSet(0))
    wrldCS = Rhino.WorldXYPlane()
    Dim oriPt(), angX(), ptA(), ptB(), ptC(),pts(),minX(),maxX(),mn(),mx()
    ReDim oriPt(rows-1), angX(rows-1), ptA(rows-1), ptB(rows-1), ptC(rows-1),minX(rows-1),maxX(rows-1),mn(cols-1),mx(cols-1),pts(cols-1)
     
    Dim angA(),angB(),angC(),disA(),disB(),disC(),s(),a(),d()
    ReDim angA(rows-1),angB(rows-1),angC(rows-1),disA(rows-1),disB(rows-1),disC(rows-1)
    ReDim a(cols-1), d(cols-1)
    For i = 0 To cols - 1 Step 1
        For j = 0 To rows - 1 Step 1
            If i Mod (2) Then
                If j Mod (2) Then
                    angA(j) = Rhino.angle2(array(ptSet(i)(j), ptSet(i + 1)(j)), array(ptSet(i)(j), ptSet(i)(j + 1)))(0)
                    angB(j) = Rhino.angle2(array(ptSet(i + 1)(j), ptSet(i)(j)), array(ptSet(i + 1)(j), ptSet(i)(j + 1)))(0)
                    angC(j) = Rhino.angle2(array(ptSet(i + 1)(j), ptSet(i)(j + 1)), array(ptSet(i + 1)(j), ptSet(i + 1)(j + 1)))(0)
                    disA(j) = Rhino.Distance(ptSet(i)(j), ptSet(i + 1)(j))
                    disB(j) = Rhino.Distance(ptSet(i)(j), ptSet(i)(j + 1))
                    disC(j) = Rhino.Distance(ptSet(i + 1)(j), ptSet(i + 1)(j + 1))
                Else
                    angA(j) = Rhino.angle2(array(ptSet(i + 1)(j), ptSet(i)(j)), array(ptSet(i + 1)(j), ptSet(i + 1)(j + 1)))(0)
                    angB(j) = Rhino.angle2(array(ptSet(i)(j), ptSet(i + 1)(j)), array(ptSet(i)(j), ptSet(i + 1)(j + 1)))(0)
                    angC(j) = Rhino.angle2(array(ptSet(i)(j), ptSet(i + 1)(j + 1)), array(ptSet(i)(j), ptSet(i)(j + 1)))(0)
                    disA(j) = Rhino.Distance(ptSet(i + 1)(j), ptSet(i)(j))
                    disB(j) = Rhino.Distance(ptSet(i + 1)(j), ptSet(i + 1)(j + 1))
                    disC(j) = Rhino.Distance(ptSet(i)(j), ptSet(i)(j + 1))
                End If
            Else
                If j Mod (2) Then
                    angA(j) = Rhino.angle2(array(ptSet(i + 1)(j), ptSet(i)(j)), array(ptSet(i + 1)(j), ptSet(i + 1)(j + 1)))(0)
                    angB(j) = Rhino.angle2(array(ptSet(i)(j), ptSet(i + 1)(j)), array(ptSet(i)(j), ptSet(i + 1)(j + 1)))(0)
                    angC(j) = Rhino.angle2(array(ptSet(i)(j), ptSet(i + 1)(j + 1)), array(ptSet(i)(j), ptSet(i)(j + 1)))(0)
                    disA(j) = Rhino.Distance(ptSet(i + 1)(j), ptSet(i)(j))
                    disB(j) = Rhino.Distance(ptSet(i + 1)(j), ptSet(i + 1)(j + 1))
                    disC(j) = Rhino.Distance(ptSet(i)(j), ptSet(i)(j + 1))
                Else
                    angA(j) = Rhino.angle2(array(ptSet(i)(j), ptSet(i + 1)(j)), array(ptSet(i)(j), ptSet(i)(j + 1)))(0)
                    angB(j) = Rhino.angle2(array(ptSet(i + 1)(j), ptSet(i)(j)), array(ptSet(i + 1)(j), ptSet(i)(j + 1)))(0)
                    angC(j) = Rhino.angle2(array(ptSet(i + 1)(j), ptSet(i)(j + 1)), array(ptSet(i + 1)(j), ptSet(i + 1)(j + 1)))(0)
                    disA(j) = Rhino.Distance(ptSet(i)(j), ptSet(i + 1)(j))
                    disB(j) = Rhino.Distance(ptSet(i)(j), ptSet(i)(j + 1))
                    disC(j) = Rhino.Distance(ptSet(i + 1)(j), ptSet(i + 1)(j + 1))
                End If
            End If
        Next
        a(i) = array(angA, angB, angC)
        d(i) = array(disA, disB, disC)
    Next
     
    For i = 0 To cols - 1 Step 1
        r = 0
        For j = 0 To rows - 1 Step 1
            If j = 0 Then
                oriPt(j) = array(0, 0, 0)
                angX(j) = 0
            Else
                oriPt(j) = ptB(j - 1)
                If ptB(j - 1)(1) > ptC(j - 1)(1) Then
                    angX(j) = -Rhino.Angle2(array(ptB(j - 1), Rhino.PointAdd(ptB(j - 1), wrldCS(1))), array(ptB(j - 1), ptC(j - 1)))(0)
                Else
                    angX(j) = Rhino.Angle2(array(ptB(j - 1), Rhino.PointAdd(ptB(j - 1), wrldCS(1))), array(ptB(j - 1), ptC(j - 1)))(0)
                End If
            End If
            If i Mod (2) Then
                r = j + 1
            Else
                r = j
            End If
            If r Mod (2) Then
                ptA(j) = Rhino.PointAdd(oriPt(j), Rhino.VectorScale(Rhino.VectorRotate(wrldCS(1), angX(j), wrldCS(3)), d(i)(0)(j)))
                ptB(j) = Rhino.PointAdd(oriPt(j), Rhino.VectorScale(Rhino.VectorRotate(wrldCS(1), angX(j) + a(i)(1)(j) + a(i)(2)(j), wrldCS(3)), d(i)(2)(j)))
                ptC(j) = Rhino.PointAdd(ptA(j), Rhino.VectorScale(Rhino.VectorRotate(wrldCS(1), angX(j) + 180 - a(i)(0)(j), wrldCS(3)), d(i)(1)(j)))
            Else
                ptA(j) = Rhino.PointAdd(oriPt(j), Rhino.VectorScale(Rhino.VectorRotate(wrldCS(1), angX(j), wrldCS(3)), d(i)(0)(j)))
                ptB(j) = Rhino.PointAdd(oriPt(j), Rhino.VectorScale(Rhino.VectorRotate(wrldCS(1), angX(j) + a(i)(0)(j), wrldCS(3)), d(i)(1)(j)))
                ptC(j) = Rhino.PointAdd(ptA(j), Rhino.VectorScale(Rhino.VectorRotate(wrldCS(1), angX(j) + 180 - a(i)(1)(j) - a(i)(2)(j), wrldCS(3)), d(i)(2)(j)))
            End If
            minX(j) = Rhino.Min(array(ptA(j)(0), ptB(j)(0), ptC(j)(0)))
            maxX(j) = Rhino.Max(array(ptA(j)(0), ptB(j)(0), ptC(j)(0)))
            r = r + 1
        Next
        mn(i) = Rhino.Min(minX)
        If mn(i) > 0 Then
            mn(i) = 0
        Else
            mn(i) = abs(mn(i))
        End If
        mx(i) = abs(Rhino.Max(maxX))
        pts(i) = array(oriPt, ptA, ptB, ptC)
    Next
    Dim ptX, k
    Dim edge(),edgeA(), edgeB(), span()
    ReDim edge(cols-1),edgeA(rows-1), edgeB(rows-1), span(rows*2)
    r = 0
    For i = 0 To cols - 1 Step 1
        k = 0
        If i > 0 Then
            r = r + mx(i - 1) + mn(i) + tabHeight * 2
        End If
        For j = 0 To rows - 1 Step 1
            ptX = array(r, 0, 0)
            If j Mod (2) Then
                span(k) = Rhino.AddLine(Rhino.PointAdd(ptX, pts(i)(0)(j)), Rhino.PointAdd(ptX, pts(i)(3)(j)))
                Call Rhino.ObjectLayer(span(k), "scores")
                k = k + 1
            Else
                span(k) = Rhino.AddLine(Rhino.PointAdd(ptX, pts(i)(1)(j)), Rhino.PointAdd(ptX, pts(i)(2)(j)))
                Call Rhino.ObjectLayer(span(k), "scores")
                k = k + 1
            End If
            If j = 0 Then
                span(k) = Rhino.AddLine(Rhino.PointAdd(ptX, pts(i)(0)(j)), Rhino.PointAdd(ptX, pts(i)(1)(j)))
                Call Rhino.ObjectLayer(span(k), "cuts")
                k = k + 1
            End If
            If j = rows - 1 Then
                span(k) = Rhino.AddLine(Rhino.PointAdd(ptX, pts(i)(2)(j)), Rhino.PointAdd(ptX, pts(i)(3)(j)))
                Call Rhino.ObjectLayer(span(k), "cuts")
                k = k + 1
            Else
                span(k) = Rhino.AddLine(Rhino.PointAdd(ptX, pts(i)(2)(j)), Rhino.PointAdd(ptX, pts(i)(3)(j)))
                Call Rhino.ObjectLayer(span(k), "scores")
                k = k + 1
            End If
            edgeA(j) = Rhino.AddLine(Rhino.PointAdd(ptX, pts(i)(0)(j)), Rhino.PointAdd(ptX, pts(i)(2)(j)))
            Call Rhino.ObjectLayer(edgeA(j), "scores")
            edgeB(j) = Rhino.AddLine(Rhino.PointAdd(ptX, pts(i)(1)(j)), Rhino.PointAdd(ptX, pts(i)(3)(j)))
            Call Rhino.ObjectLayer(edgeB(j), "scores")
        Next
        edge(i) = array(edgeA, edgeB)
    Next
     
    Dim tabA(), tabB(), lblA(), lblB()
    ReDim tabA(rows-1), tabB(rows-1), lblA(rows-1), lblB(rows-1)
    For i = 0 To cols - 1 Step 1
        For j = 0 To rows - 1 Step 1
            tabA(j) = tabMaker(edge(i)(0)(j), -90, tabHeight)
            tabB(j) = tabMaker(edge(i)(1)(j), 90, tabHeight)
            Call Rhino.ObjectLayer(tabA(j), "cuts")
            Call Rhino.ObjectLayer(tabB(j), "cuts")
             
            If i = cols - 1 Then
                lblB(j) = labelMaker(edge(i)(1)(j), cols - 1 &amp; "." &amp; j, tabHeight * .25, 0, True)
            Else
                lblB(j) = labelMaker(edge(i)(1)(j), i + 1 &amp; "." &amp; j, tabHeight * .25, 0, True)
            End If
            lblA(j) = labelMaker(edge(i)(0)(j), i &amp; "." &amp; j, tabHeight * .25, 180, True)
        Next
    Next
End Function
Function tabMaker(curve, rotVal, scale)
    tabMaker = Null
    Dim tabLN(1), tabPT(2),crvDom, wrldCS, i
    crvDom = Rhino.CurveDomain(curve)
    wrldCS = Rhino.WorldXYPlane()
    tabPT(0) = Rhino.CurveStartPoint(curve)
    tabPT(2) = Rhino.CurveEndPoint(curve)
    tabPT(1) = Rhino.PointAdd(Rhino.EvaluateCurve(curve, crvDom(1) * .5),Rhino.VectorScale(Rhino.VectorUnitize(Rhino.VectorRotate(Rhino.VectorCreate(Rhino.EvaluateCurve(curve, crvDom(1) * .4),tabPT(2)),rotVal, wrldCS(3))),scale))
    For i = 0 To 1 Step 1
        tabLN(i) = Rhino.AddLine(tabPT(i), tabPT(i + 1))
    Next
    tabMaker = tabLN
End Function
Function labelMaker(curve, title, size, angle, blnAlign)
    labelMaker = Null
    Dim txt, wrldCS
    If Rhino.IsLayer("numbering") = False Then
        Call Rhino.AddLayer("numbering", RGB(0, 255, 0))
    End If
    wrldCS = Rhino.WorldXYPlane()
    txt = Rhino.AddText(title, Rhino.CurveMidPoint(curve), size)
    If blnAlign = True Then
        Call Rhino.TextObjectPlane(txt, array(Rhino.CurveMidPoint(curve), Rhino.VectorCreate(Rhino.CurveMidPoint(curve), Rhino.CurveEndPoint(curve)), Rhino.VectorRotate(Rhino.VectorCreate(Rhino.CurveMidPoint(curve), Rhino.CurveEndPoint(curve)), 90, wrldCS(3)), wrldCS(3)))
        Call Rhino.RotateObject(txt, Rhino.CurveMidPoint(curve), angle, wrldCS(3))
    End If
    Call Rhino.ObjectLayer(txt, "numbering")
    labelMaker = txt
End Function
Function reparameterize(strObjectID)
    If Rhino.IsCurve(strObjectID) = True Then
        Call rhino.SelectObject(strObjectID)
        Call rhino.Command("reparameterize 0 1")
        Call rhino.UnselectAllObjects()
    End If
    If Rhino.IsSurface(strObjectID) = True Then
        Call rhino.SelectObject(strObjectID)
        Call rhino.Command("reparameterize 0 1 0 1")
        Call rhino.UnselectAllObjects()
    End If     
End Function
 


1 view

Recent Posts

See All

Comments


bottom of page