Avoid filter failure in ray shoot facet

This commit is contained in:
Giles Bathgate 2022-03-27 10:17:01 +01:00
parent 0dfa8a4941
commit 04f7b8d7b9
1 changed files with 33 additions and 31 deletions

View File

@ -218,6 +218,22 @@ public:
delete candidate_provider;
}
// We next check if v is a vertex on the face to avoid a geometric test
static inline bool v_vertex_of_f(Vertex_handle v, Halffacet_handle f) {
Halffacet_cycle_iterator fci;
for(fci=f->facet_cycles_begin(); fci!=f->facet_cycles_end(); ++fci) {
if(fci.is_shalfedge()) {
SHalfedge_around_facet_circulator sfc(fci), send(sfc);
CGAL_For_all(sfc,send) {
if(sfc->source()->center_vertex() == v){
return true;
}
}
}
}
return false;
}
virtual Object_handle shoot(const Ray_3& ray, int mask=255) const {
Vertex_handle null_handle;
return this->shoot(ray, null_handle, mask);
@ -282,20 +298,22 @@ public:
Point_3 q;
_CGAL_NEF_TRACEN("trying facet with on plane "<<f->plane()<<
" with point on "<<f->plane().point());
if( SNC_intersection::does_intersect_internally( ray, f, q) ) {
_CGAL_NEF_TRACEN("ray intersects facet on "<<q);
_CGAL_NEF_TRACEN("prev. intersection? "<<hit);
if( hit) { _CGAL_NEF_TRACEN("prev. intersection on "<<eor); }
if( hit && !has_smaller_distance_to_point( ray.source(), q, eor))
continue;
_CGAL_NEF_TRACEN("is the intersection point on the current cell? "<<
candidate_provider->is_point_on_cell( q, objects_iterator));
if( !candidate_provider->is_point_on_cell( q, objects_iterator))
continue;
eor = q;
result = make_object(f);
hit = true;
_CGAL_NEF_TRACEN("the facet becomes the new hit object");
if( (ray_source_vertex == Vertex_handle()) || !v_vertex_of_f(ray_source_vertex,f) ) {
if( SNC_intersection::does_intersect_internally( ray, f, q) ) {
_CGAL_NEF_TRACEN("ray intersects facet on "<<q);
_CGAL_NEF_TRACEN("prev. intersection? "<<hit);
if( hit) { _CGAL_NEF_TRACEN("prev. intersection on "<<eor); }
if( hit && !has_smaller_distance_to_point( ray.source(), q, eor))
continue;
_CGAL_NEF_TRACEN("is the intersection point on the current cell? "<<
candidate_provider->is_point_on_cell( q, objects_iterator));
if( !candidate_provider->is_point_on_cell( q, objects_iterator))
continue;
eor = q;
result = make_object(f);
hit = true;
_CGAL_NEF_TRACEN("the facet becomes the new hit object");
}
}
}
else if((mask&15) == 15)
@ -443,23 +461,7 @@ public:
return make_object(f);
}
// We next check if v is a vertex on the face to avoid a geometric test
bool v_vertex_of_f = false;
Halffacet_cycle_iterator fci;
for(fci=f->facet_cycles_begin(); (! v_vertex_of_f) && (fci!=f->facet_cycles_end()); ++fci) {
if(fci.is_shalfedge()) {
SHalfedge_around_facet_circulator sfc(fci), send(sfc);
CGAL_For_all(sfc,send) {
if(sfc->source()->center_vertex() == v){
v_vertex_of_f = true;
break;
}
}
}
}
if( (! v_vertex_of_f) && SNC_intersection::does_intersect_internally(s,f,ip) ) {
if( !v_vertex_of_f(v,f) && SNC_intersection::does_intersect_internally(s,f,ip) ) {
s = Segment_3(p, normalized(ip));
result = make_object(f);
}