computational craft

Vectors (forces): Normals, Attractors, Deformation, Cusps, Blebs

posterforce

inflect script

Option Explicit 'Script written by Ezio Blasetti 'July 19th 2007 revision Sub inflect() Dim arrObjects : arrObjects = Rhino.GetObjects("select the objects to inflect", 12) If IsNull(arrObjects) Then Exit Sub Dim arrAttractors : arrAttractors = Rhino.GetObjects("select the attractors", 13) If IsNull(arrAttractors) Then Exit Sub Dim dblRadius, dblIntensity, blnAttr, blnCopy, arrOptions(6), strResult, strAllow dblRadius = Rhino.GetSettings(Rhino.InstallFolder & "Inflect.ini", "infect", "Radius") If IsNull(dblRadius) Then dblRadius = 5 Else dblRadius = CDbl (dblRadius) dblIntensity = Rhino.GetSettings(Rhino.InstallFolder & "Inflect.ini", "infect", "Intensity") If IsNull(dblIntensity) Then dblIntensity = .1 Else dblIntensity = CDbl (dblIntensity) blnAttr = Rhino.GetSettings(Rhino.InstallFolder & "Inflect.ini", "infect", "Attract") If IsNull(blnAttr) Then blnAttr = vbFalse Else blnAttr = CBool(blnAttr) blnCopy = Rhino.GetSettings(Rhino.InstallFolder & "Inflect.ini", "infect", "Copy") If IsNull(blnCopy) Then blnCopy = vbTrue Else blnCopy = CBool(blnCopy) Dim arrNewObjs : arrNewObjs = array("Nothing") Dim arrAllow(), i strAllow = GetObjectsPoints(arrObjects, "Select control points to inflect", vbTrue) ReDim arrAllow(UBound(strAllow)) If Not IsNull(strResult) Then For i = 0 To UBound(strAllow) arrAllow(i) = strAllow(i) Next End If Do Rhino.EnableRedraw vbFalse Rhino.DeleteObjects arrNewObjs rhino.Print "calculating...please wait." arrNewObjs = InflectObjs(arrObjects, arrAttractors, blnAttr, dblRadius, dblIntensity, arrAllow, vbTrue) If IsNull(arrNewObjs) Then arrNewObjs = Array("Nothing") If Not blnCopy Then Rhino.HideObjects arrObjects Else Rhino.ShowObjects arrObjects Rhino.EnableRedraw vbTrue rhino.Print "done." arrOptions(0) = "Radius_" & CStr(Int(dblRadius)) arrOptions(1) = "Intensity" & CStr(Int(dblIntensity)) arrOptions(2) = "Way_" & Bln2Str2(blnAttr) arrOptions(3) = "Copy_" & Bln2Str(blnCopy) arrOptions(4) = "Limit" arrOptions(5) = "Accept" arrOptions(6) = "Quit" strResult = Rhino.GetString("Inflect; Current Radius Is: (" & dblRadius & ")", "Accept", arrOptions) If IsNull(strResult) Then strResult = "Quit" If IsNumeric(strResult) Then dblRadius = Abs(CDbl(strResult)) Else Select Case UCase(Left(strResult, 1)) Case "R" strResult = Rhino.GetReal("Specify radius of affection", dblRadius, 0) If Not IsNull(strResult) Then dblRadius = strResult Case "I" strResult = Rhino.GetReal("Specify intensity of affection", dblIntensity, 0) If Not IsNull(strResult) Then dblIntensity = strResult If strResult > 1 Then print "to avoid blebs keep intensity less or equal to 1..." Case "W" blnAttr = Not blnAttr Case "C" blnCopy = Not blnCopy Case "L" Rhino.EnableRedraw vbFalse Rhino.DeleteObjects arrNewObjs Rhino.ShowObjects arrObjects strResult = GetObjectsPoints(arrObjects, "Select control points to inflect", vbFalse) If Not IsNull(strResult) Then For i = 0 To UBound(strResult) arrAllow(i) = strResult(i) Next End If Case "A" Rhino.EnableRedraw vbFalse Rhino.DeleteObjects arrNewObjs rhino.Print "calculating...please wait." arrNewObjs = InflectObjs(arrObjects, arrAttractors, blnAttr, dblRadius, dblIntensity, arrAllow, vbFalse) Rhino.EnableRedraw vbTrue Exit Do Case "Q" Rhino.ShowObjects arrObjects Rhino.DeleteObjects arrNewObjs Exit Sub End Select End If Loop Rhino.SaveSettings Rhino.InstallFolder & "Inflect.ini", "infect", "Radius", CStr(dblRadius) Rhino.SaveSettings Rhino.InstallFolder & "Inflect.ini", "infect", "Intensity", CStr(dblIntensity) Rhino.SaveSettings Rhino.InstallFolder & "Inflect.ini", "infect", "Attract", CStr(blnAttr) Rhino.SaveSettings Rhino.InstallFolder & "Inflect.ini", "infect", "Copy", CStr(blnCopy) If Not blnCopy Then Rhino.DeleteObjects arrObjects End If rhino.Print "objects inflected." End Sub inflect Function GetObjectsPoints(arrObjects, strMessage, blnAll) GetObjectsPoints = Null Dim arrPt, i, strObj, k Dim objPt(), selPt, arrSelected() k=0 For Each strObj In arrObjects If Rhino.IsCurve(strObj) Then arrPt = Rhino.CurvePoints(strObj) Else arrPt = rhino.SurfacePoints(strObj) End If Rhino.EnableRedraw vbFalse For i = 0 To UBound(arrPt) ReDim Preserve arrSelected(k) arrSelected(k) = vbFalse ReDim Preserve objPt(k) objPt(k) = Rhino.AddPoint(arrPt(i)) Rhino.ObjectName objPt(k), k k=k+1 Next Next If blnAll Then selPt = objPt Else Rhino.EnableRedraw vbTrue selPt = Rhino.GetObjects(strMessage, 1, vbFalse, vbFalse, vbTrue, objPt) End If If IsNull(selPt) Then Exit Function For i = 0 To UBound(selPt) arrSelected(CLng(Rhino.ObjectName(selPt(i)))) = vbTrue Next Rhino.DeleteObjects objPt Rhino.EnableRedraw vbTrue GetObjectsPoints = arrSelected End Function Function InflectObjs(arrObjects, arrAttractors, blnAttr, dblRadius, dblIntensity, arrAllow, ConvertToCurves) InflectObjs = Null Dim strObject, arrCurrentPt, arrInflObjects() Dim arrPoints, strGeom Dim i, j, k ReDim arrInflObjects(Ubound(arrObjects)) Dim arrKnots, arrWeights, intDegree, ptCount, isoCurves i=0 k=0 For Each strObject In arrObjects If Rhino.IsCurve(strObject) Then arrPoints = Rhino.CurvePoints(strObject) strGeom = "Curve" intDegree = Rhino.CurveDegree (strObject) Else arrPoints = rhino.SurfacePoints(strObject) strGeom = "Surface" ptCount = Rhino.SurfacePointCount(strObject) arrKnots = Rhino.SurfaceKnots(strObject) arrWeights = Rhino.SurfaceWeights(strObject) intDegree = Rhino.SurfaceDegree(strObject) End If j=0 For Each arrCurrentPt In arrPoints If arrAllow(k) Then arrPoints(j) = InflectPoint(arrCurrentPt, arrAttractors, blnAttr, dblRadius, dblIntensity) End If k=k+1 j=j+1 Next Select Case UCase(Left(strGeom, 1)) Case "C" arrInflObjects(i) = Rhino.AddCurve (arrPoints , intDegree) Case "S" arrInflObjects(i) = Rhino.AddNurbsSurface(ptCount, arrPoints, arrKnots(0), arrKnots(1), intDegree, arrWeights) End Select i=i+1 Next InflectObjs = arrInflObjects End Function Function InflectPoint(arrCurrentPt, arrAttractors, blnAttr, dblRadius, dblIntensity) InflectPoint = arrCurrentPt Dim dblCurrentDistance, strCurrentAttractor, arrCurrentAttractor, arrCurrentVector, dblParameter, arrParam Dim arrNewPt : arrNewPt = arrCurrentPt Dim arrVector: arrVector = array(0, 0, 0) For Each strCurrentAttractor In arrAttractors If Rhino.IsPoint(strCurrentAttractor) Then arrCurrentAttractor = Rhino.PointCoordinates (strCurrentAttractor) ElseIf Rhino.IsCurve(strCurrentAttractor) Then dblParameter = Rhino.CurveClosestPoint (strCurrentAttractor, arrCurrentPt) arrCurrentAttractor = Rhino.EvaluateCurve (strCurrentAttractor, dblParameter) Else arrParam = Rhino.SurfaceClosestPoint (strCurrentAttractor, arrCurrentPt) arrCurrentAttractor = Rhino.EvaluateSurface(strCurrentAttractor, arrParam) End If dblCurrentDistance = Rhino.Distance (arrCurrentPt, arrCurrentAttractor) If dblCurrentDistance<=dblRadius Then arrCurrentVector = VectorCreate (arrCurrentPt, arrCurrentAttractor) If dblCurrentDistance<>0 Then arrCurrentVector = Rhino.VectorScale (arrCurrentVector, dblIntensity/dblCurrentDistance) End If arrVector = VectorAdd (arrVector, arrCurrentVector) End If Next If blnAttr Then arrNewPt = array((arrCurrentPt(0) - arrVector(0)), _ (arrCurrentPt(1) - arrVector(1)), _ (arrCurrentPt(2) - arrVector(2))) Else arrNewPt = array((arrCurrentPt(0) + arrVector(0)), _ (arrCurrentPt(1) + arrVector(1)), _ (arrCurrentPt(2) + arrVector(2))) End If InflectPoint = arrNewPt End Function Function Bln2Str(blnIn) Bln2Str = "No" If blnIn Then Bln2Str = "Yes" End Function Function Bln2Str2(blnIn) Bln2Str2 = "Attract" If blnIn Then Bln2Str2 = "Repulse" End Function Function VectorCreate(p1, p2) VectorCreate = Null If Not IsArray(p1) Or (UBound(p1) <> 2) Then Exit Function If Not IsArray(p2) Or (UBound(p2) <> 2) Then Exit Function VectorCreate = Array(p2(0) - p1(0), p2(1) - p1(1), p2(2) - p1(2)) End Function Function VectorAdd(v1, v2) VectorAdd = Null If Not IsArray(v1) Or (UBound(v1) <> 2) Then Exit Function If Not IsArray(v2) Or (UBound(v2) <> 2) Then Exit Function VectorAdd = Array(v1(0) + v2(0), v1(1) + v2(1), v1(2) + v2(2)) End Function Function VectorUnitize(v) VectorUnitize = Null If Not IsArray(v) Or (UBound(v) <> 2) Then Exit Function Dim dist, x, y, z, x2, y2, z2 x = v(0) : y = v(1) : z = v(2) x2 = x * x : y2 = y * y : z2 = z * z dist = x2 + y2 + z2 If (dist < 0.01) Then VectorUnitize = Array(0, 0, 0) Exit Function End If dist = sqr(dist) x = x / dist y = y / dist z = z / dist VectorUnitize = Array(x, y, z) End Function