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 rhinoscripts which will attempt to provide rigid structural skins with a simple triangulation technique.
Rhino Script
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 & "." & j, tabHeight * .25, 0, True) Else lblB(j) = labelMaker(edge(i)(1)(j), i + 1 & "." & j, tabHeight * .25, 0, True) End If lblA(j) = labelMaker(edge(i)(0)(j), i & "." & 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