algorithmic modeling for Rhino
Hi all,
I am trying to write a scripting component that determines whether a point is on a surface or outside. It works quite well using standard GH components, but I would like to pack it into a single scripting component.
The weird thing is: the Surface.ClosestPoint method seems to think any point inside the u,v domain is on the surface, so if a point is outside the surface, but inside the surface's u,v domain, the closest point is equal to the original point.
Grasshopper's "Surface CP" component seems to work quite well...
Does anyone have an idea what I am missing here?
My source code is:
private void RunScript(Point3d P, Surface S, double t, ref object PI, ref object PO, ref object ii)
{
double u;
double v;
if (S.ClosestPoint(P, out u, out v))
{
Point3d tP = S.PointAt(u, v);
double d = P.DistanceTo(tP);
if (d <= t)
{
// distance is within tolerance
PI = P;
ii = true;
}
else
{
// distance is larger than tolerance
PO = P;
ii = false;
}
}
}
this is the GH defnition
(there is an old discussion on the forum that seems to end without a real result..., see http://www.grasshopper3d.com/forum/topics/surface-closest-point-and...)
Tags:
What Grasshopper calls a "trimmed surface" is actually a Brep with one face, not a "Surface" data type. Surfaces (in RhinoCommon) are always untrimmed, which would explain your result. Try Brep.ClosestPoint()
Andrew is absolutely right. The Surface Datatype doesn't store trimm curves. Brep which means boundary representation does...it's a Surface with specified boundary also known as a trimmed Surface.
This means for your script, that in RhinoCommon all trimmed Surfaces should be casted as Brep type. See the difference in the pic below:
also the script works a little bit different, cause you have to run trough all faces of the brep...in your case obviously there is just one.
Cheers
FF
hi,
could you explain the line code
double tolerance = (t == 0) ? doc.ModelAbsoluteTolerance : t;
it's shorthand for if-then-else,
see http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.100%29.aspx
written out, it would be something like
double tolerance;
if (t==0)
tolerance=doc.ModelAbsoluteTolerance;
else
tolerance=t;
nice,
thanks
Excellent!
Thanks a lot.
Just for clarification: I was wondering a bit why you used BrepFace.DuplicateFace.
My a assumption is that you did this so you can use the Brep.ClosestPoint method. Is that right? Or is there something else behind it?
Best regards
Stefan
-------------------------------------------------------------
Here is the code including comments to illustrate what I mean:
private void RunScript(Brep B, Point3d P, double t, ref object Pi, ref object Po)
{
double d = double.MaxValue;
double tolerance = (t == 0) ? doc.ModelAbsoluteTolerance : t;
foreach(BrepFace f in B.Faces)
{
// short version:
double dist = f.DuplicateFace(false).ClosestPoint(P).DistanceTo(P);
/*
// long version fo the uninitiated:
// cast BrepFace to Brep because BrepFace has only a method
// public bool ClosestPoint(Point3d testPoint, out double u, out double v)
// which is somewhat cumbersome to use
Brep currentFaceAsBrep = f.DuplicateFace(false);
// with a Brep we can directly use a method
// public Point3d ClosestPoint(Point3d testPoint)
Point3d clPoint = currentFaceAsBrep.ClosestPoint(P);
// now compute the distance
double dist = clPoint.DistanceTo(P);
*/
if(dist < d)
d = dist;
}
if(d <= tolerance)
Pi = P;
else
Po = P;
}
Hi Stefan, actually i didn't have to DuplicateFace...just realized right now. The BrepFace had the same method...this is because i wrote it quickly an didn't take a look at the sdk...happens sometime ;-)
The comments are all right...you got every step of the script.
Have a nice day
FF
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by