💻 Rhino 5
🔼 Rhino Script
🛠️ Visual Basic
This rhino script allows the user to create highly varied, yet controllable, low polygon count “hairs”. This script operates based on the world coordinate system, growing upwards from a user-selected series of points.
Version 2 allows for the selection of a surface which will be randomly populated with grass blades perpendicular to the surface (about the surface normal) The user is given the option to specify the range of lengths (min-max), the range of bending per segment, and the base and tip radius. The user can control the number of segments the blade will have, the more segments, the smoother the bend, the greater the polygons. In addition as part of the interest in polygon optimization, the user can specify the number of sides on each blade, a 2 sided blade is flat, 3 sided become three dimensional (triangular), 4 rectangular, etc. the higher the number the rounder it is, the higher the polygon count.
Option Explicit
'Script written by <David Mans>
'Script copyrighted by <Neoarchaic Studio>
'Script version Sunday, July 05, 2009 9:42:52 PM
Call Main()
Sub Main()
Dim strSurface, arrInputs
strSurface = Rhino.GetObject("Select Surface", 8)
If isNull(strSurface) Then Exit Sub
Call reparameterize(strSurface)
arrInputs = Rhino.PropertyListBox(array("Count", "Min Length", "Max Length", "Min Hair Bend", "Max Hair Bend", "Base Radius", "Tip Radius", "Segments", "Sides"), array(1000, 4, 12, 10, 45, 0.1, 0.01, 5, 2))
If isNull(arrInputs) Then Exit Sub
Dim i, stem(), blades(), sides
If CInt(arrInputs(7)) < 2 Then
sides = 2
Else
sides = CInt(arrInputs(7))
End If
Dim arrPlanes
Call Rhino.EnableRedraw(False)
arrPlanes = randomPtsSrf(strSurface, CInt(arrInputs(0)))
ReDim stem(uBound(arrPlanes)), blades(uBound(arrPlanes))
For i = 0 To uBound(arrPlanes) Step 1
stem(i) = segmentedStem(arrPlanes(i), random(CDbl(arrInputs(1)), CDbl(arrInputs(2))), CInt(arrInputs(7)), random(CDbl(arrInputs(3)), CDbl(arrInputs(4))))
blades(i) = bladesFlat(stem(i), CDbl(arrInputs(5)), CDbl(arrInputs(6)), sides)
Next
Call Rhino.EnableRedraw(True)
End Sub
Function randomPtsSrf(strSurface, intCount)
randomPtsSrf = Null
Dim i, uDom, vDom, arrOutput()
ReDim arrOutput(intCount-1)
uDom = Rhino.SurfaceDomain(strSurface, 0)
vDom = Rhino.SurfaceDomain(strSurface, 1)
For i = 0 To intCount - 1 Step 1
arrOutput(i) = Rhino.SurfaceFrame(strSurface, array(random(uDom(0), uDom(1)), random(vDom(0), vDom(1))))
Next
randomPtsSrf = arrOutput
End Function
Function bladesFlat(arrPlanes, radB, radT, intSteps)
bladesFlat = Null
Dim i, j, k, r, arrOutput
Dim radStep, rotStep
Dim arrPoints(),arrFaces(), arrMesh()
ReDim arrMesh(intSteps-1)
If radB > radT Then
radStep = -(radB - radT) / uBound(arrPlanes)
Else
radStep = (radT - radB) / uBound(arrPlanes)
End If
rotStep = 360 / intSteps
For k = 0 To intSteps - 1 Step 1
r = 0
For i = 0 To uBound(arrPlanes) Step 1
ReDim Preserve arrPoints(r)
arrPoints(r) = Rhino.PointAdd(arrPlanes(i)(0), Rhino.VectorScale(Rhino.VectorUnitize(Rhino.RotatePlane(arrPlanes(i), k * rotStep, arrPlanes(i)(3))(1)), radB + i * radStep))
r = r + 1
ReDim Preserve arrPoints(r)
arrPoints(r) = Rhino.PointAdd(arrPlanes(i)(0), Rhino.VectorScale(Rhino.VectorUnitize(Rhino.RotatePlane(arrPlanes(i), (k + 1) * rotStep, arrPlanes(i)(3))(1)), radB + i * radStep))
r = r + 1
Next
r = 0
ReDim arrFaces(uBound(arrPoints)-2)
For i = 0 To uBound(arrPoints) - 2 Step 2
arrFaces(r) = array(i, i + 1, i + 3, i + 3)
r = r + 1
arrFaces(r) = array(i, i + 3, i + 2, i + 2)
r = r + 1
Next
If intSteps = 2 Then
If k = 1 Then
arrOutput = Rhino.addmesh(arrPoints, arrFaces)
End If
Else
arrMesh(k) = Rhino.addmesh(arrPoints, arrFaces)
End If
Next
If intSteps >< 2 Then
arrOutput = Rhino.MeshBooleanUnion(arrMesh)
End If
bladesFlat = arrOutput
End Function
Function segmentedStem(arrPlane, dblHeight, dblSegments, maxRotation)
segmentedStem = Null
Dim i, count
count = dblSegments - 1
Dim dblStep, tempLen, dblLen()
Dim mPlane(), tmpAngle(1), blnWavy
ReDim dblLen(count), mPlane(count+1)
mPlane(0) = Rhino.RotatePlane(arrPlane, random(0, 360), arrPlane(3))
blnWavy = random(-1, 1)
dblStep = dblHeight / dblSegments
For i = 0 To count Step 1
If i = 0 Then
tempLen = random(0.5, 1) * dblStep
dblLen(i) = dblStep - tempLen
ElseIf i = count Then
tempLen = dblStep + dblLen(i - 1)
Else
tempLen = random(0.5, 1) * (dblStep + dblLen(i - 1))
dblLen(i) = dblStep + dblLen(i - 1) - tempLen
End If
If blnWavy >= 0 Then
tmpAngle(0) = random(0, maxRotation)
tmpAngle(1) = random(0, maxRotation)
Else
tmpAngle(0) = random(-maxRotation, 0)
tmpAngle(1) = random(-maxRotation, 0)
End If
mPlane(i + 1) = Rhino.RotatePlane(Rhino.RotatePlane(Rhino.moveplane(mPlane(i), Rhino.PointAdd(mPlane(i)(0), Rhino.VectorScale(Rhino.VectorUnitize(mPlane(i)(3)), tempLen))), tmpAngle(0), mPlane(i)(1)), tmpAngle(1), mPlane(i)(2))
Next
segmentedStem = mPlane
End Function
Function reparameterize(strObjectID)
If Rhino.IsCurve(strObjectID) = True Then
Call rhino.SelectObject(strObjectID)
Call rhino.Command("reparameterize 0 1", False)
Call rhino.UnselectAllObjects()
End If
If Rhino.IsSurface(strObjectID) = True Then
Call rhino.SelectObject(strObjectID)
Call rhino.Command("reparameterize 0 1 0 1", False)
Call rhino.UnselectAllObjects()
End If
End Function
Function random(min, max)
random = Null
Dim dblValue: dblValue = min + (max - min) * rnd()
random = dblValue
End Function
Comments