@sdmitch said:
It should if "point" is truly inside the solid. If it is a model point then it will need to be transformed by the inverse of the solid's transformation.
Thanks
Yes the point must be in the solid(group) coordinate space.
I've changed the code a bit to allow shell (outer face) testing
Here it is:
Edited:
After some testing still something was not OK.
I realized that when the ray crosses an edge it hits 2 different planes and through a vertice it can hit an unknown number of faces. The solution I came is that the ray crosses the solid in only one point. So instead of keeping track of how many faces it hits, I register all points the ray hits the solid and then perform a uniq-like operation to the array to count the number of points/hits.
I've updated the code.
For the filtering uniq! doesn't work (guessing because it uses eql? and this is not implemented in Point3d)
Also tried
pts.uniq! {|pt| pt.to_a}
but it didn't worked, but since the raycast is parallel to X axis comparing x coordinate does the trick
def point_insidesolid?(point, solid, exclude_surface=false)
vect = Geom;;Vector3d.new(1,0,0)
pts = []
solid.entities.grep(Sketchup;;Face).each do |face|
if(FaceTools.is_pointof_face?(point,face))
return true unless exclude_surface
return false
else
pt = Geom.intersect_line_plane([point,vect], [face.vertices[0].position, face.normal])
if(!pt.nil?)
if(FaceTools.is_pointof_face?(pt,face) && pt.x>point.x)
pts.push pt
end
end
end
end
ptsuniq = pts.uniq {|pt| pt.x}
return ptsuniq.count%2!=0
end
def point_insideface?(point,face)
case(face.classify_point(point))
when Sketchup;;Face;;PointInside, Sketchup;;Face;;PointOnVertex, Sketchup;;Face;;PointOnEdge
return true
end
return false
end