
Option Explicit
‘Script written and copyrighted by David Rutten
‘Script adapted by J Maigret November 2009 University of Michigan
‘Reconstructivism.net
‘December 7th 2004 revision
Sub SimulateRainDropPaths()
Dim arrDropStart
Dim blnSmoothPath
Dim blnFancyPreview
Dim blnStopOnEdge
Dim SampleStepSize
Dim Tolerance
Dim idObject
Dim strResult, arrOptions
Dim arrPaths(), P, retVal
Dim selMesh
Dim strAllPts, arrAllPts(), obj, idAllPts, intCount, arrOnePt
blnSmoothPath = Rhino.GetSettings(Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “Smooth”)
If IsNull(blnSmoothPath) Then blnSmoothPath = vbFalse Else blnSmoothPath = CBool(blnSmoothPath)
blnFancyPreview = Rhino.GetSettings(Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “Fancy”)
If IsNull(blnFancyPreview) Then blnFancyPreview = vbFalse Else blnFancyPreview = CBool(blnFancyPreview)
blnStopOnEdge = Rhino.GetSettings(Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “StopOnEdge”)
If IsNull(blnStopOnEdge) Then blnStopOnEdge = vbFalse Else blnStopOnEdge = CBool(blnStopOnEdge)
SampleStepSize = Rhino.GetSettings(Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “SampleStepSize”)
If IsNull(SampleStepSize) Then SampleStepSize = 100 * Rhino.UnitAbsoluteTolerance Else SampleStepSize = CDbl(SampleStepSize)
Tolerance = Rhino.UnitAbsoluteTolerance
idObject = Rhino.GetObject(“Pick a surface for raindrop simulation”, 8+16, vbTrue, vbTrue)
If IsNull(idObject) Then Exit Sub
Rhino.EnableRedraw False
Rhino.Command “-_Mesh _PolygonDensity=50 _Enter”, vbFalse
selMesh = Rhino.LastCreatedObjects
If IsNull(selMesh) Then
msgBox “Geometry could not be meshes”, vbOkOnly Or vbCritical, “Drop simulation”
Exit Sub
Else
Rhino.HideObjects selMesh
End If
Rhino.EnableRedraw True
idAllPts = Rhino.GetObjects(“Select points to be used in simulation”, 1, vbTrue, vbTrue)
If IsNull(idAllPts) Then Exit Sub
intCount = 0
Do
If intCount > UBound(idAllPts) Then Exit Do
obj = idAllPts(intCount)
arrOnePt = Rhino.PointCoordinates(obj)
If IsNull(arrOnePt) Then Exit Do
ReDim Preserve arrAllPts(intCount)
arrAllPts(intCount) = arrOnePt
Call Rhino.Print(arrAllPts(intCount)(0)& “+” & arrAllPts(intCount)(1) & “+” & arrAllPts(intCount)(2))
Call Rhino.Print(intCount)
intCount = intCount + 1
Loop
P = 0
Do
‘arrOptions = Array(“Stepsize”, _
‘ “Tolerance”, _
‘ “Smooth_” & Bln2Str(blnSmoothPath), _
‘ “Simulate”, _
‘ “Finish”)
’strResult = Rhino.GetString(“Drop-path simulation”, “Simulate”, arrOptions)
‘If IsNull(strResult) Then strResult = “Finish”
‘If IsNumeric(strResult) Then
‘ SampleStepSize = Abs(CDbl(strResult))
‘ If SampleStepSize = 0 Then SampleStepSize = 100*Rhino.UnitAbsoluteTolerance
‘Else
‘Select Case UCase(Left(strResult, 2))
‘Case “ST”
’strResult = Rhino.GetReal(“Specify a new sample step size”, SampleStepSize, 10*Tolerance)
‘ If Not IsNull(strResult) Then SampleStepSize = strResult
SampleStepSize = 100*Rhino.UnitAbsoluteTolerance
‘Case “TO”
’strResult = Rhino.GetReal(“Specify a new sample progression tolerance”, Tolerance, Rhino.UnitAbsoluteTolerance/100, SampleStepSize/10)
‘If Not IsNull(strResult) Then Tolerance = strResult
Tolerance = Rhino.UnitAbsoluteTolerance/100
‘Case “SM”
‘blnSmoothPath = Not blnSmoothPath
‘Case “QU”
‘blnStopOnEdge = Not blnStopOnEdge
‘Case “SI”
If P > UBound(idAllPts) Then Exit Do
arrDropStart = arrAllPts(P)
Call Rhino.Print(arrDropStart(0)& “+” & arrDropStart(1) & “+” & arrDropStart(2))
If IsArray(arrDropStart) Then
retVal = SimulateDrop(idObject, arrDropStart, blnSmoothPath, blnStopOnEdge, SampleStepSize, Tolerance)
If IsNull(retVal) Then
msgBox “An error occured during the simulation”, vbOkOnly, “Drop simulation”
Else
ReDim Preserve arrPaths(P)
arrPaths(P) = retVal
P = P+1
End If
End If
‘Case “FI”
‘Exit Do
‘Case Else
‘Rhino.Command strResult
‘ End Select
Loop
Rhino.EnableRedraw False
Rhino.ShowObjects selMesh
Rhino.DeleteObjects selMesh
If P > 0 Then
Rhino.SelectObjects arrPaths
Rhino.UnselectObject idObject
End If
Rhino.EnableRedraw True
‘Rhino.SaveSettings Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “Smooth”, blnSmoothPath
‘Rhino.SaveSettings Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “Fancy”, blnFancyPreview
‘Rhino.SaveSettings Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “StopOnEdge”, blnStopOnEdge
‘Rhino.SaveSettings Rhino.InstallFolder & “Gelfling.ini”, “DropSimulation”, “SampleStepSize”, SampleStepSize
Rhino.Print “Raindrop simulation finished”
End Sub
SimulateRainDropPaths
Function SimulateDrop(ByVal idObject, ByVal DropStart, ByVal blnSmoothPath, ByVal blnStopOnEdge, ByVal SampleStepSize, ByVal Tolerance)
SimulateDrop = Null
Dim BBox, S
Dim idPath, arrVertices()
Dim BrepCP
Dim curPt, lowPt, newPt
Dim idPreview, PreviewSize
BBox = Rhino.BoundingBox(idObject)
If IsNull(BBox) Then Exit Function
BrepCP = Rhino.BrepClosestPoint(idObject, DropStart)
curPt = BrepCP(0)
idPreview = “Nothing”
PreviewSize = FastDistance(BBox(0), BBox(6))/500
‘If blnFancyPreview Then Rhino.LockObject idObject
If Not IsNull(curPt) Then
ReDim arrVertices(0)
arrVertices(0) = curPt
S = 0
Do
lowPt = Array(curPt(0), curPt(1), curPt(2)-SampleStepSize)
BrepCP = Rhino.BRepClosestPoint(idObject, lowPt)
newPt = BrepCP(0)
If FastDistance(newPt, curPt) curPt(2) Then Exit Do
ReDim Preserve arrVertices(S)
arrVertices(S) = newPt
S = S+1
‘If blnStopOnEdge And BrepCP(2) 1342177280 Then Exit Do
‘If blnFancyPreview Then
‘ Rhino.EnableRedraw False
‘ Rhino.DeleteObject idPreview
‘ idPreview = DrawFancyArrow(curPt, newPt, PreviewSize)
‘ Rhino.EnableRedraw True
‘End If
curPt = newPt
Loop
Rhino.DeleteObject idPreview
Rhino.UnlockObject idObject
If blnSmoothPath Then
idPath = Rhino.AddCurve(arrVertices, 3)
Else
idPath = Rhino.AddPolyLine(arrVertices)
End If
Else
Rhino.Print “Drop could be projected to the surface… an error occured”
Exit Function
End If
SimulateDrop = idPath
End Function
Function FastDistance(Byval arr1, Byval arr2)
FastDistance = (arr1(0)-arr2(0))*(arr1(0)-arr2(0)) + (arr1(1)-arr2(1))*(arr1(1)-arr2(1)) + (arr1(2)-arr2(2))*(arr1(2)-arr2(2))
FastDistance = Sqr(FastDistance)
End Function
Function Bln2Str(Byval input)
If input Then
Bln2Str = “Yes”
Exit Function
Else
Bln2Str = “No”
Exit Function
End If
End Function


