Raytest problem

We have a face on a group (face1 & grp) and a point on it (pt). I wish to know raytest point is in opposite side of this group or not. I write following codes.

#find opposite face
ents = grp.entities
face2 = Sketchup::Face.new
ents.grep(Sketchup::Face) do |f|
  face2 = f if f.normal.reverse == face1.normal
end
#find raytest point
mod = Sketchup.active_model
 result = mod.raytest( [pt, face1.normal.reverse ] )
pt2 = result.first
#face2 and pt2 are right and also pt2 is on edge of face2 in my example
#check pt2 is on face2 or not
pt_result = face2.classify_point(pt2)
p pt_result

I assume pt_result will be 1 or 4 (Sketchup::Face::PointInside or Sketchup::Face::PointOnEdge) but it is always 32 (Sketchup::Face::PointNotOnPlane). Can you help me to find problem?
Thank you in advance.

Beside that, you did not mentioned where the pt and face1 are…
It is more than likely that you did not take into consideration the local-global coordinates of the points (transformations of group(s) )

I have never ever seen that someone “pre-define” a face like this: face2 = Sketchup::Face.new. It is not clear for me what it is exactly doing…
I would avoid this line and instead I would check if fece2 got a value inside the grep method.

You are right. I forget coordinate again. Following code works.

#find opposite face
ents = grp.entities
face2 = Sketchup::Face.new
ents.grep(Sketchup::Face) do |f|
  face2 = f if f.normal.reverse == face1.normal
end
#find raytest point
mod = Sketchup.active_model
 result = mod.raytest( [pt, face1.normal.reverse ] )
pt2 = result.first
tr = grp.transformation
pt2.transform! tr.inverse
#face2 and pt2 are right and also pt2 is on edge of face2 in my example
#check pt2 is on face2 or not
pt_result = face2.classify_point(pt2)
p pt_result

It seems we have to keep face2 = Sketchup::Face.new. Please let me know more about it.

As I told you I don’t know what the Sketchup::Face.new is doing. Why do you need to keep it? What happening if you are deleting that line?

If I delete this code following error will happen.
Error: #<NameError: undefined local variable or method `face2’ for #MajidMahmoudi::MajDoorHole::MajDoor:0x000001e253520800>

:235:in `onLButtonDown'

First of all, Sketchup::Face.new returns an invalid face, which makes sense because it has no edges and hasn’t been placed in any Entities collection.

If you are just looking to create a variable so you can use it in the subsequent loop, you could do

face2 = nil

There is a danger that face2 will not get a new value in the grep loop if no face is found that passes the normal vector text. You should test for and manage this situation since otherwise there is an oversight in your code that could some day cause a runtime error in the later line

pt_result = face2.classify_point(pt2)

because you can’t invoke classify_point(pt2) on either an invalid face or nil.

Second, the reason you get an error if you remove that line is that there is no longer anywhere that face2 is defined.

2 Likes

face2 = nil instead of face2 = Sketchup::Face.new also works. Thank you for your information.