Hi all,
I have been working with this script linked (Rhino V6 version below) to see drainage over a surface, but my issue is it was never designed the trimmed surfaces in mind so I have been trying to add this.
I know I needed to add another elif statement in to stop the loop from running when the point is beyond the trimmed surface but I have not been able to make it work whatever I try.
My esif is called onSurface() and I have also tried to make the trimmed surface a brep.face as that’s what the points in trim wants in the def_init at the top of the code but not getting an output where the drainage crvs do not keep going over the trimmed surface.
I have attached the code in a python component below also with a simple surface example.
Drainage Problem.gh (36.8 KB)
import Rhino
import ghpythonlib.components as ghc
class DrainBoid(object):
def __init__(self, point3d, surface, stepsize=0.5, maxsteps=None, tolerance=0.001):
self.start = point3d
self.pos = self.start
result, self.u, self.v = surface.ClosestPoint(self.pos)
self.surface = surface
self.stepsize = stepsize
self.points = [self.start]
self.state = 'on'
self.tolerance = tolerance
self.maxsteps = maxsteps
brep = surface.ToBrep()
breptrimmed = brep.CopyTrimCurves(brep.Faces[0],surface,0.001)
self.brepFace = breptrimmed.Faces[0]
def makeDrainCurve(self):
i = 0
while self.state == 'on':
i += 1
if self.maxsteps:
if i >= self.maxsteps:
self.state = 'finished'
self.nextStep()
return Rhino.Geometry.Curve.CreateControlPointCurve(self.points, 1)
def nextStep(self):
result, newFrame = self.surface.FrameAt(self.u, self.v)
# create a vector from newFrame XAxis
downVect = newFrame.XAxis
# figure out hw far to rotate it.
deltaAngle = Rhino.Geometry.Vector3d.VectorAngle( downVect, Rhino.Geometry.Vector3d(0.0, 0.0, -1.0), newFrame )
# rotate it in the plane
downVect.Rotate( deltaAngle, newFrame.ZAxis)
# set the length
downVect = downVect.Multiply( self.stepsize, downVect )
spacePoint = Rhino.Geometry.Point3d.Add(self.pos, downVect)
result, self.u, self.v = self.surface.ClosestPoint(spacePoint)
out, newPoint, vects = self.surface.Evaluate(self.u, self.v, 0)
if newPoint.Z >= self.pos.Z: # if higher
self.state = 'finished'
elif not self.checkTolerance(newPoint): # if too close
self.state = 'finished'
elif not self.onSurface():
self.state = 'finished'
else:
self.updatePos(newPoint)
def updatePos(self, newPoint):
self.points.append(newPoint)
self.pos = newPoint
def checkTolerance(self, other):
# checks against another point
# if it is outside of tolerance, returns True
return self.pos.DistanceTo( other ) > self.tolerance
def onSurface(self):
# checks if point is on trimmed surface
# if it is outside returns True
return self.brepFace.IsPointOnFace(self.u,self.v) == Rhino.Geometry.PointFaceRelation.Interior
if terrainSurface:
b = DrainBoid(startPoint, terrainSurface, stepSize, maxSteps, tol)
crv= b.makeDrainCurve()

