I have been going around with this for an hour or two and I finally gave upā¦
The script below (part of something larger) prompts the user to select a boundary curve and then gets all the other brep objects in the scene. It then tests each object to see if all the eight bbox points are inside the curve, all outside, or some inside and some outside; it classifies the objects into 3 lists, inside, outside and inters based on the result.
What Iām getting is the inverse of what is should be for inside/outside - an object which should have all points inside is reporting as outside and vice versa.
In the file below as is, there is a circle plus two visible surfaces. All the BB points on the pink surface should clearly lie outside the circle, but it gets classified as inside. Inversely, the cyan surface which is entirely inside the circle tests as outsideā¦ There are some hidden surfaces in the file that test as intersect, those are OK.
Iām sure there is something fundamental that Iām missing here, but I canāt see what - Iāve been staring at it too long probably. If you hide the cyan object and run the script with a breakpoint set as in the image below, you will see that the 8 points from the pink surface which should all be outside are all reported as inside (True) by brep.IsPointInside()
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def CheckPointInclusionBase(pts,vol,strict,tol):
"""
Checks for inclusion of all points inside volume(single point or pt list)
Returns:
1 if all points are inside volume
-1 if all points outside volume
0 if at least one point is inside and one is outside.
Strict=True means points that are ON surface are considered outside
"""
if isinstance(pts,Rhino.Geometry.Point3d): pts=[pts]
inside=False
outside=False
# sc.doc.Objects.AddBrep(vol) #debug
# sc.doc.Views.Redraw() #debug
rs.AddPoints(pts) #debug
for pt in pts:
chk=vol.IsPointInside(pt,tol,True)
pass
if chk==True:
inside=True
elif chk==False:
outside=True
else:
#something went wrong
return
if inside==True and outside==False:
#all points have tested inside, none outside
return 1
elif outside==True and inside==False:
#all points have tested outside, none inside
return -1
else:
return 0
def TestPointInclusion():
msg="Select closed curve for inclusion test"
crv_id=rs.GetObject(msg,4,preselect=True)
if not crv_id: return
obj_ids=rs.ObjectsByType(8+16,state=1)
if not obj_ids: return
inside=[]
outside=[]
inters=[]
tol=sc.doc.ModelAbsoluteTolerance
strictly_in=False
plane=Rhino.Geometry.Plane.WorldXY
all_objs_bb=rs.BoundingBox(obj_ids)
#set plane to bottom of all objects bounding box
plane.Origin=all_objs_bb[0]
#get extrusion vector
ex_vec=all_objs_bb[4]-all_objs_bb[0]
if ex_vec.IsTiny(tol): ex_vec=Rhino.Geometry.Vector3d.ZAxis
#create inclusion extrusion (closed brep)
sel_crv=rs.coercecurve(crv_id)
sel_crv.Transform(rs.XformPlanarProjection(plane))
sel_extru=Rhino.Geometry.Extrusion.CreateExtrusion(sel_crv,ex_vec)
sel_extru_brep=sel_extru.ToBrep()
sel_vol=sel_extru_brep.CapPlanarHoles(tol)
for obj_id in obj_ids:
bb=rs.BoundingBox(obj_id)
pts=[rs.coerce3dpoint(pt_id) for pt_id in bb]
test=CheckPointInclusionBase(pts,sel_vol,strictly_in,tol)
if test==1:
#all bb points of object are inside the sel volume
inside.append(obj_id)
elif test==-1:
#all bb points of object are outside the sel volume
outside.append(obj_id)
elif test==0:
#some points inside, some points outside
inters.append(obj_id)
else:
#some error occurred
print("Error!")
rs.SelectObjects(inside)
TestPointInclusion()
SelScriptProblem.3dm (2.2 MB)