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,surface,0.001) self.brepFace = breptrimmed.Faces 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()