top of page
  • Writer's pictureDavid Mans

Hair From Points

💻 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. 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 arrPts, arrInputs 
    arrPts = Rhino.GetObjects("Select Points", 1) 
    If isNull(arrPts) Then Exit Sub
    arrInputs = Rhino.PropertyListBox(array("Min Length", "Max Length", "Min Hair Bend", "Max Hair Bend", "Base Radius", "Tip Radius", "Segments", "Sides"), array(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
    ReDim stem(uBound(arrPts)), blades(uBound(arrPts)) 
    Call Rhino.EnableRedraw(False) 
    For i = 0 To uBound(arrPts) Step 1 
        stem(i) = segmentedStem(Rhino.PointCoordinates(arrPts(i)), random(CDbl(arrInputs(0)), CDbl(arrInputs(1))), CInt(arrInputs(6)), random(CDbl(arrInputs(2)), CDbl(arrInputs(3)))) blades(i) = bladesFlat(stem(i), CDbl(arrInputs(4)), CDbl(arrInputs(5)), sides) 
    Next
    Call Rhino.EnableRedraw(True) 
End Sub
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(arrPoint, 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.MovePlane(Rhino.RotatePlane(Rhino.WorldXYPlane(), random(0, 360), Rhino.WorldXYPlane()(3)), arrPoint) 
    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 random(min, max) 
    random = Null 
    Dim dblValue: dblValue = min + (max - min) * rnd() 
    random = dblValue 
End Function
 


0 views

Recent Posts

See All
bottom of page