RhinoScript substitution system aggregation
From KokkugiaWiki
this tutorial builds off a simple rhinoScript recursive aggregation script while adding object types and a set of conditional substitution rules.
the script requires a file with appropriately named objects which can be downloaded here
Option Explicit
Call Main()
Sub Main()
Dim gens, sLoc, i, j, arrTemp, objArrSingle(), objArr(2), refPtsSingle(), refPts(2), sObjArr
' user input - gens + start loc
gens = Rhino.GetReal("how many generations", 10)
sLoc = Rhino.GetPoint("select a starting location")
' compile named objects into arrays
For i = 0 To 2
ReDim objArrSingle(9)
For j = 0 To 9
arrTemp = Rhino.ObjectsByName("obj_" & CStr(i) & "_" & CStr(j) )
If Not isarray(arrTemp) Then Exit Sub
objArrSingle(j) = arrTemp(0)
Next
objArr(i) = objArrSingle
Next
' reference points / base
For i = 0 To 2
ReDim refPtsSingle(2)
For j = 1 To 3
refPtsSingle(j-1) = Rhino.PointCoordinates(objArr(i)(j))
Next
refPts(i) = refPtsSingle
Next
' make start object - "a"
sObjArr = Rhino.CopyObjects(objArr(0), refPts(0)(0), sLoc)
' call recursive function
substitute objArr, refPts, sObjArr, gens
End Sub
Function substitute(objArr, refPts, sObj, gens)
Dim objType, newObjArr, target, nextObj
' conditional - if - gens
If gens > 0 Then
' get type
objType = Rhino.GetObjectData(sObj(0), "section", "type")
' rules based on type
Select Case objType
Case "a" ' a-b
target = 0 '''' 0 or 1
nextObj = 1 '''' 0 or 1 or 2 (a,b,c)
' orient the object - use as input to a recursive function call
newObjArr = orient(sObj, refPts(nextObj), objArr(nextObj), target)
substitute objArr, refPts, newObjArr, gens-1
Case "b" ' b-ca
target = 0 '''' 0 or 1
nextObj = 2 '''' 0 or 1 or 2 (a,b,c)
newObjArr = orient(sObj, refPts(nextObj), objArr(nextObj), target)
substitute objArr, refPts, newObjArr, gens-1
target = 1 '''' 0 or 1
nextObj = 0 '''' 0 or 1 or 2 (a,b,c)
newObjArr = orient(sObj, refPts(nextObj), objArr(nextObj), target)
substitute objArr, refPts, newObjArr, gens-1
Case "c" ' c-a
target = 1 '''' 0 or 1
nextObj = 0 '''' 0 or 1 or 2 (a,b,c)
newObjArr = orient(sObj, refPts(nextObj), objArr(nextObj), target)
substitute objArr, refPts, newObjArr, gens-1
End Select
End If
End Function
Function orient(sObj, refPts, objArr, tarIndex)
Dim tarArrPts(), i, newObjs
' decides on target
If tarIndex = 0 Then
' target 1
For i = 4 To 6
ReDim Preserve tarArrPts(i-4)
tarArrPts(i-4) = Rhino.PointCoordinates(sObj(i))
Next
Else
' target 2
For i = 7 To 9
ReDim Preserve tarArrPts(i-7)
tarArrPts(i-7) = Rhino.PointCoordinates(sObj(i))
Next
End If
' orients objs
newObjs= Rhino.OrientObjects(objArr, refPts, tarArrPts, 1)
For i = 0 To UBound(newObjs)
Rhino.ObjectName newObjs(i), ""
Next
orient = newObjs
End Function
the following script assigns names and types to the objects to run the above script
Call assignType()
Sub assignType()
Dim strObject
For i = 0 To 2
For j = 0 To 9
If j = 0 Then
strObject = Rhino.GetObject("select object " & CStr(i) & " mesh")
Select Case i
Case 0
Rhino.SetObjectData strObject, "section", "type", "a"
Case 1
Rhino.SetObjectData strObject, "section", "type", "b"
Case 2
Rhino.SetObjectData strObject, "section", "type", "c"
End Select
Else
strObject = Rhino.GetObject("select object " & CStr(i) & " point " & CStr(j), 1)
End If
Rhino.ObjectName strObject, "obj_" & CStr(i) & "_" & CStr(j)
Next
Next
End Sub
this script assigns a type to the objects as object data
Call assignType()
Sub assignType()
Dim strObject
strObject = Rhino.GetObject("select object a")
Rhino.SetObjectData strObject, "section", "type", "a"
strObject = Rhino.GetObject("select object b")
Rhino.SetObjectData strObject, "section", "type", "b"
strObject = Rhino.GetObject("select object c")
Rhino.SetObjectData strObject, "section", "type", "c"
End Sub
this script prints object data
Call printType()
Sub printType()
Dim strObject
strObject = Rhino.GetObject("select object to test type")
Rhino.Print Rhino.GetObjectData(strObject, "section", "type")
End Sub
......another version of the code
Option Explicit
Call Main()
Sub Main()
Dim gens, arrObjs(2), arrObjSingle(9), i, j, basePoint, startObjs, startPos, arrObjTemp
' user input: gens, 1 mesh, 9 points - into a single array
gens = Rhino.GetReal("how many generations", 7)
startPos = Rhino.GetPoint("select a starting position")
' arrObjs( (mesh, pt1, pt2, pt3.....pt9), (mesh, pt1, pt2, pt3.....pt9), (mesh, pt1, pt2, pt3.....pt9) )
' arrObjSingle(mesh, pt1, pt2, pt3.....pt9)
For j = 0 To 2
For i = 0 To 9
arrObjTemp = Rhino.ObjectsByName("obj_" & j & "_" & i)
arrObjSingle(i) = arrObjTemp(0)
Next
arrObjs(j) = arrObjSingle
Next
' get object 1 base point
basePoint = Rhino.PointCoordinates(arrObjs(0)(1))
' copy the first object
startObjs = Rhino.CopyObjects(arrObjs(0), basePoint, startPos)
' call the recursive function
Call substitute(arrObjs, gens, startObjs)
End Sub
Function substitute(arrObjs, gens, currentObjs)
Dim objType, newArrObjs
' conditional statement
If gens > 1 Then
objType = Rhino.GetObjectData(currentObjs(0), "section", "type")
' rule sets - call aggregate function -
Select Case objType
Case "a" ' a - b
' call the aggregate function
newArrObjs = aggregate(currentObjs, arrObjs(1), 1)
' call substitute function - RECURSIVE
Call substitute(arrObjs, gens-1, newArrObjs)
Case "b" ' b - c
newArrObjs = aggregate(currentObjs, arrObjs(2), 1)
Call substitute(arrObjs, gens-1, newArrObjs)
newArrObjs = aggregate(currentObjs, arrObjs(1), 2)
Call substitute(arrObjs, gens-1, newArrObjs)
Case "c" ' c - ac
newArrObjs = aggregate(currentObjs, arrObjs(0), 2)
Call substitute(arrObjs, gens-1, newArrObjs)
newArrObjs = aggregate(currentObjs, arrObjs(2), 1)
Call substitute(arrObjs, gens-1, newArrObjs)
End Select
End If
End Function
Function aggregate(arrCurrentObjs, arrNewObjs, target)
Dim arrRefPts(2), arrTarPts(2)
' compile an array of refPoints + targetPoints (x2)
arrRefPts(0) = Rhino.PointCoordinates(arrNewObjs(1))
arrRefPts(1) = Rhino.PointCoordinates(arrNewObjs(2))
arrRefPts(2) = Rhino.PointCoordinates(arrNewObjs(3))
If target = 1 Then
arrTarPts(0) = Rhino.PointCoordinates(arrCurrentObjs(4))
arrTarPts(1) = Rhino.PointCoordinates(arrCurrentObjs(5))
arrTarPts(2) = Rhino.PointCoordinates(arrCurrentObjs(6))
Else
arrTarPts(0) = Rhino.PointCoordinates(arrCurrentObjs(7))
arrTarPts(1) = Rhino.PointCoordinates(arrCurrentObjs(8))
arrTarPts(2) = Rhino.PointCoordinates(arrCurrentObjs(9))
End If
' orient objects
aggregate = Rhino.OrientObjects(arrNewObjs, arrRefPts, arrTarPts, 1)
End Function
