[Bug/FR] SectionCut and raytest

bug
featurerequest

#1

In Section&Raytest.skp (113.2 KB) when Scene 2 is activated:

Sketchup.active_model.raytest([Geom::Point3d.new(0, 0, 0), Geom::Vector3d.new(0, 1, 0)])

hits an invisible face that the section-cut has made invisible.
I would expect the box component being returned instead of the currently invisible face.

This prevents a tool that relies on the raytest to reach the visible ComponentInstance. At least it could reach the SectionPlane, but unfortunately it stops on the “optically” invisible face.


#2

You need to set raytest’s second argument, “wysiwyg_flag” to control whether hidden geometry is considered during the test. The Ruby API docs say it defaults to true, meaning ignore hidden geometry, but the docs have been known to contain errors and could have it wrong, or maybe this flag doesn’t work (I am not where I can test this right now).


#3

The doc is correct.

The problem is that even with the visibility flag set to default true it ignores invisible geometry (hidden), but still doesn’t ignore the geometry removed by section planes.


#4

Find the active section-plane - if any.
That active section-plane has a plane [Geom object = [point, vector]].
There is also that section-plane’s normal [second item in its plane array - or reconstructed from the last three ?]

You can then do a raytest.

First determine if the ‘eye’ point for the raytest is behind the section-plane.

You have the raytest’s vector.
If the angle_between the normal and that vector is <90° it might be going to hit something beyond the section-cut.
Otherwise you can assume any ‘hit’ will be behind the plane and therefore should be visible.

But if there is a potential unseen ‘hit’, you can do the following:

Make a line [a Geom object [point.vect] NOT an ‘edge’ !] using the ray’s eye and its vector.
Intersect that line with the section-cut’s plane [Geom method http://ruby.sketchup.com/Geom.html#intersect_line_plane-class_method ].
You should get a point, now get the distance from the eye to that point [let’s call it ‘dsc’].
Get the distance from the eye to the hit’s point.
If it’s < dsc, then it’s hit a visible object.
If it’s > dsc, then it’s beyond the section plane.
If it’s == dsc then you need to do some testing to determine if it’s seen - in my experience the section-cut plane is itself a tiny distance inset from its actual plane…
So perhaps you need a tolerance for ‘on-plane’ hits that are actually [un]seen…

I can’t test this right now… over to you…


#5

Thanks TIG for the idea/workaround.

I think I will go slightly different way. You can always determine whether current ray hit is on the “dark” side of active section cuts by finding a vector perpendicular to the section plane. If hit is “dark” then shoot a ray further until it reaches something on the “bright” side.


#6

I have come up with something like this. It will work in SU2015+.
I do not inspect all the section cuts out there, just check the very first active. It doesn’t dig deeper into entities tree neither.

def isSectionVisible(hit_point)
visible = true
if (Sketchup.active_model.rendering_options["DisplaySectionCuts"])
	ents = Sketchup.active_model.entities
	section = nil
	ents.each do |ent|
		if (ent.class==Sketchup::SectionPlane and ent.active?)
			section=ent
			break
		end
	end
	if (section)
		plane = section.get_plane
		point = hit_point.project_to_plane(plane)
		vector = Geom::Vector3d.new(hit_point.x-point.x,hit_point.y-point.y,hit_point.z-point.z)
		visible = false if (vector.angle_between(Geom::Vector3d.new(plane[0],plane[1],plane[2]))>0.00001)
	end
end
return visible

end


#7

This topic was automatically closed after 91 days. New replies are no longer allowed.