In the file below, there are 6 planes, which started out as copies (no history). Then each one has had its top edge moved in the Y direction a tiny amount as indicated by the dots - to simulate a “just off vertical situation”. The idea was to check at what tolerance the script would detect a non-vertical condition.
Basically what it does is get the surface plane, move its origin to W0, make a point a certain height (roughly the size of the object) along the World Z axis and check the distance from this point to the closest point on the surface plane. Obviously a completely vertical surface will have essentially 0 distance, as the plane is tilted by moving the top edge there should be an increasing distance between the two points, getting greater the more the tilt.
Moving the check point higher along the world Z axis should result in a proportionally larger distance being measured. The script prints out this distance. I compare this to the file tolerance and if it is less than that, I select the object as being ‘vertical within tolerance’.
What I am finding is that the script (just a prototype for something else) is working OK for all except the second object - the one that has had the upper edge moved by only 0.001 (file tolerance). I would expect a distance to be printed out for that one that is smaller than the file tolerance, maybe around 0.0009. Instead it prints 0.0:
Now if I increase the ‘size’ variable by a factor of 10, all the values should be multiplied by 10 proportionally.
Which they do, all except the second one which remains 0.0.
I can increase the size as much as I want - to 1000, 10,000 or more - but the second one stubbornly stays at 0.0. Interestingly if I start decreasing the size value from 100, I start getting more of the planes selected, as one would expect - at 50 I get the third one lighting up, at 30 the fourth one, at 20 the fifth one, and at 10 all of them. So it is working in that direction. So what am I not understanding here?
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def TestPlaneWVertical(o_plane,size,tol):
w0=Rhino.Geometry.Point3d(0,0,0)
chk_pt=Rhino.Geometry.Point3d(0,0,size)
o_plane.Origin=w0
print(abs(o_plane.DistanceTo(chk_pt))) #debug
if abs(o_plane.DistanceTo(chk_pt))<tol: return True
return False
size=100.0 #start value, can change
tol=sc.doc.ModelAbsoluteTolerance
obj_ids=rs.ObjectsByType(8)
breps=[rs.coercebrep(obj_id) for obj_id in obj_ids]
for i,brep in enumerate(breps):
face=brep.Faces[0]
rc,obj_plane=face.TryGetPlane()
if rc:
if TestPlaneWVertical(obj_plane,size,tol):
rs.SelectObject(obj_ids[i])
TestSrfs.3dm (2.9 MB)
EDIT:
OK, I have a possible suspect here -
Looks like moving the edge by only 0.001 (the file tolerance) results in the edge being pulled out of tolerance instead of the underlying surface itself actually getting changed. What shows this:
and I see this if I put a point at 0,0,100 and I zoom way in:
If I look at the next one which has had the edge moved 0.002, I see this:
So it looks like this might actually be a bug in the way moving a surface edge happens when the distances are very small. Not good IMO.
Edit 2:
More or less confirmed, RebuildEdges on that surface makes the edge go back to where it was before nudging.