diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_do_intersect_transform_traits.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_do_intersect_transform_traits.h index e690e003f91..098dd521ef8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_do_intersect_transform_traits.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/AABB_do_intersect_transform_traits.h @@ -1,4 +1,3 @@ - // Copyright (c) 2018 GeometryFactory (France). // All rights reserved. // @@ -19,6 +18,7 @@ // // // Author(s) : Maxime Gimeno +// Sebastien Loriot // #ifndef CGAL_AABB_DO_INTERSECT_TRANSFORM_TRAITS_H @@ -38,204 +38,263 @@ #include #include -/// \file AABB_do_intersect_transform_traits.h - namespace CGAL { -template -class AABB_do_intersect_transform_traits: - public AABB_traits +template +class Traversal_traits_with_transformation_helper { - mutable Aff_transformation_3 m_transfo; - mutable bool has_rotation; - typedef AABB_traits BaseTraits; - typedef AABB_do_intersect_transform_traits Self; - - void set_transformation(const Aff_transformation_3& trans, CGAL::Tag_true) const - { - has_rotation = (trans.m(0,1) != 0 - || trans.m(0,2) != 0 - || trans.m(1,0) != 0 - || trans.m(1,2) != 0 - || trans.m(2,0) != 0 - || trans.m(2,1) !=0); - } - void set_transformation(const Aff_transformation_3& trans, CGAL::Tag_false) const - {} Bbox_3 - compute_transformed_bbox_impl(const Bbox_3& bbox, Tag_true) const + compute_transformed_bbox_impl(const CGAL::Aff_transformation_3& at, + const Bbox_3& bbox, + bool has_rotation, + /*SUPPORTS_ROTATION*/ Tag_true) const { + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_UPWARD); + if(!has_rotation) - return compute_transformed_bbox_impl(bbox, Tag_false()); + return compute_transformed_bbox_impl(at, bbox, has_rotation, Tag_false()); typedef Simple_cartesian AK; typedef Cartesian_converter C2F; C2F c2f; - AK::Aff_transformation_3 af = c2f(m_transfo); + AK::Aff_transformation_3 a_at = c2f(at); AK::FT xtrm[6] = { c2f(bbox.min(0)), c2f(bbox.max(0)), c2f(bbox.min(1)), c2f(bbox.max(1)), c2f(bbox.min(2)), c2f(bbox.max(2)) }; typename AK::Point_3 ps[8]; - ps[0] = af( AK::Point_3(xtrm[0], xtrm[2], xtrm[4]) ); - ps[1] = af( AK::Point_3(xtrm[0], xtrm[2], xtrm[5]) ); - ps[2] = af( AK::Point_3(xtrm[0], xtrm[3], xtrm[4]) ); - ps[3] = af( AK::Point_3(xtrm[0], xtrm[3], xtrm[5]) ); + ps[0] = a_at( AK::Point_3(xtrm[0], xtrm[2], xtrm[4]) ); + ps[1] = a_at( AK::Point_3(xtrm[0], xtrm[2], xtrm[5]) ); + ps[2] = a_at( AK::Point_3(xtrm[0], xtrm[3], xtrm[4]) ); + ps[3] = a_at( AK::Point_3(xtrm[0], xtrm[3], xtrm[5]) ); - ps[4] = af( AK::Point_3(xtrm[1], xtrm[2], xtrm[4]) ); - ps[5] = af( AK::Point_3(xtrm[1], xtrm[2], xtrm[5]) ); - ps[6] = af( AK::Point_3(xtrm[1], xtrm[3], xtrm[4]) ); - ps[7] = af( AK::Point_3(xtrm[1], xtrm[3], xtrm[5]) ); + ps[4] = a_at( AK::Point_3(xtrm[1], xtrm[2], xtrm[4]) ); + ps[5] = a_at( AK::Point_3(xtrm[1], xtrm[2], xtrm[5]) ); + ps[6] = a_at( AK::Point_3(xtrm[1], xtrm[3], xtrm[4]) ); + ps[7] = a_at( AK::Point_3(xtrm[1], xtrm[3], xtrm[5]) ); return bbox_3(ps, ps+8); } Bbox_3 - compute_transformed_bbox_impl(const Bbox_3& bbox, Tag_false) const + compute_transformed_bbox_impl(const CGAL::Aff_transformation_3& at, + const Bbox_3& bbox, + bool, + /*SUPPORTS_ROTATION*/ Tag_false) const { + CGAL_expensive_assertion(FPU_get_cw() == CGAL_FE_UPWARD); + typedef Simple_cartesian AK; typedef Cartesian_converter C2F; C2F c2f; - AK::Aff_transformation_3 af = c2f(m_transfo); + AK::Aff_transformation_3 a_at = c2f(at); AK::FT xtrm[6] = { c2f(bbox.min(0)), c2f(bbox.max(0)), c2f(bbox.min(1)), c2f(bbox.max(1)), c2f(bbox.min(2)), c2f(bbox.max(2)) }; typename AK::Point_3 ps[2]; - ps[0] = af( AK::Point_3(xtrm[0], xtrm[2], xtrm[4]) ); - ps[1] = af( AK::Point_3(xtrm[1], xtrm[3], xtrm[5]) ); + ps[0] = a_at( AK::Point_3(xtrm[0], xtrm[2], xtrm[4]) ); + ps[1] = a_at( AK::Point_3(xtrm[1], xtrm[3], xtrm[5]) ); return bbox_3(ps, ps+2); } + public: - //Constructor - AABB_do_intersect_transform_traits(const Aff_transformation_3& transf = Aff_transformation_3(IDENTITY)) + bool has_rotation(const CGAL::Aff_transformation_3& at) const { - has_rotation = false; - set_transformation(transf, SUPPORTS_ROTATION()); + return ( at.m(0,1) != 0 || at.m(0,2) != 0 || at.m(1,0) != 0 + || at.m(1,2) != 0 || at.m(2,0) != 0 || at.m(2,1) !=0); } - // AABBTraits concept types - typedef typename BaseTraits::Point_3 Point_3; - typedef typename BaseTraits::Primitive Primitive; - typedef typename BaseTraits::Bounding_box Bounding_box; + Bbox_3 + compute_transformed_bbox(const CGAL::Aff_transformation_3& at, + const Bbox_3& bbox, + bool has_rotation) const + { + return compute_transformed_bbox_impl(at, bbox, has_rotation, SUPPORTS_ROTATION()); + } +}; - // helper functions +// traversal traits for a tree vs a primitive +template +class Do_intersect_traversal_traits_with_transformation + : public Traversal_traits_with_transformation_helper +{ + typedef typename AABBTraits::Primitive Primitive; + typedef ::CGAL::AABB_node Node; + typedef Traversal_traits_with_transformation_helper Base; + + void register_transformation(CGAL::Tag_true) + { + m_has_rotation = this->has_rotation(m_transfo); + } + + void register_transformation(CGAL::Tag_false) + {} + +public: + + Do_intersect_traversal_traits_with_transformation(const AABBTraits& traits) + : m_is_found(false), m_traits(traits), m_has_rotation(false) + { + } + + bool go_further() const { return !m_is_found; } + + template + void intersection(const Query& query, const Primitive& primitive) + { + if( CGAL::do_intersect(query, + internal::Primitive_helper::get_datum(primitive, m_traits).transform(m_transfo)) ) + m_is_found = true; + } + + template + bool do_intersect(const Query& query, const Node& node) const + { + return m_traits.do_intersect_object()(query, compute_transformed_bbox(node.bbox())); + } + + bool is_intersection_found() const { return m_is_found; } + + void reset() + { + m_is_found = false; + } + + const Aff_transformation_3& + transformation() const + { + return m_transfo; + } + + void set_transformation(const Aff_transformation_3& transfo) + { + m_transfo = transfo; + register_transformation(SUPPORTS_ROTATION()); + } - Bbox_3 compute_transformed_bbox(const Bbox_3& bbox) const { - return compute_transformed_bbox_impl(bbox, SUPPORTS_ROTATION()); + return Base::compute_transformed_bbox(m_transfo, bbox, m_has_rotation); } - // Do_intersect predicate - class Do_intersect - : BaseTraits::Do_intersect + // helper for Point_inside_vertical_ray_cast + class Transformed_tree_helper { - typedef AABB_do_intersect_transform_traits AABBTraits; - const AABBTraits& m_traits; - typedef typename BaseTraits::Do_intersect Base; + typedef AABB_tree Tree; + typedef CGAL::AABB_node Node; + typedef Do_intersect_traversal_traits_with_transformation Traversal_traits; - Bounding_box - compute_transformed_bbox(const Bounding_box& bbox) const - { - return m_traits.compute_transformed_bbox(bbox); - } + Traversal_traits m_tt; public: - Do_intersect(const AABBTraits& traits) - : Base(static_cast(traits)), - m_traits(traits) + + Transformed_tree_helper(const Traversal_traits& tt) + : m_tt(tt) {} - template - bool operator()(const Query& q, const Bounding_box& bbox) const + Bbox_3 get_tree_bbox(const AABB_tree& tree) const { - return - static_cast(this)->operator()( - q, compute_transformed_bbox(bbox)); + return m_tt.compute_transformed_bbox(tree.bbox()); } - template - bool operator()(const Query& q, const Primitive& pr) const + typename AABBTraits::Primitive::Datum + get_primitive_datum(const typename AABBTraits::Primitive& primitive, const AABBTraits& traits) const { - // transformation is done within Primitive_helper - return do_intersect(q, internal::Primitive_helper::get_datum(pr,m_traits)); + return internal::Primitive_helper::get_datum(primitive, traits).transform(m_tt.transformation()); } - // intersection with AABB-tree - template - bool operator()(const CGAL::AABB_tree& other_tree, const Primitive& pr) const + Bbox_3 get_node_bbox(const Node& node) const { - // transformation is done within Primitive_helper - return other_tree.do_intersect( internal::Primitive_helper::get_datum(pr,m_traits)); - } - - template - bool operator()(const CGAL::AABB_tree& other_tree, const Bounding_box& bbox) const - { - return other_tree.do_intersect(compute_transformed_bbox(bbox)); + return m_tt.compute_transformed_bbox(node.bbox()); } }; - Do_intersect do_intersect_object() const{ - return Do_intersect(*this); - } - - //Specific - void set_transformation(const Aff_transformation_3& trans) const + Transformed_tree_helper get_helper() const { - m_transfo = trans; - set_transformation(trans, SUPPORTS_ROTATION()); + return Transformed_tree_helper(*this); } - const Aff_transformation_3& transformation() const { return m_transfo; } +private: + bool m_is_found; + const AABBTraits& m_traits; + Aff_transformation_3 m_transfo; + bool m_has_rotation; }; -namespace internal { -template -struct Primitive_helper ,true>{ - -typedef AABB_do_intersect_transform_traits Traits; - - -static typename Traits::Primitive::Datum get_datum(const typename Traits::Primitive& p, - const Traits & traits) +// traversal traits for a tree +template +class Do_intersect_traversal_traits_for_two_trees + : public Traversal_traits_with_transformation_helper { - return p.datum(traits.shared_data()).transform(traits.transformation()); -} + typedef typename AABBTraits::Primitive Primitive; + typedef ::CGAL::AABB_node Node; + typedef Traversal_traits_with_transformation_helper Base; -static typename Traits::Point_3 get_reference_point(const typename Traits::Primitive& p,const Traits& traits) { - return p.reference_point(traits.shared_data()).transform(traits.transformation()); -} + void register_transformation(CGAL::Tag_true) + { + m_has_rotation = this->has_rotation(m_transfo); + } + void register_transformation(CGAL::Tag_false) + {} + + Bbox_3 + compute_transformed_bbox(const Bbox_3& bbox) const + { + return Base::compute_transformed_bbox(m_transfo, bbox, m_has_rotation); + } + +public: + Do_intersect_traversal_traits_for_two_trees(const AABBTraits& traits, + const Aff_transformation_3& transfo, + Do_intersect_traversal_traits_with_transformation& query_traversal_traits) + : m_is_found(false) + , m_traits(traits) + , m_transfo(transfo) + , m_has_rotation(false) + , m_query_traversal_traits(query_traversal_traits) + + { + register_transformation(SUPPORTS_ROTATION()); + } + + bool go_further() const { return !m_is_found; } + + void intersection(const AABB_tree& query, const Primitive& primitive) + { + query.traversal( internal::Primitive_helper::get_datum(primitive,m_traits).transform(m_transfo), m_query_traversal_traits ); + m_is_found = m_query_traversal_traits.is_intersection_found(); + m_query_traversal_traits.reset(); + } + + bool do_intersect(const AABB_tree& query, const Node& node) const + { + query.traversal( compute_transformed_bbox(node.bbox()), m_query_traversal_traits ); + bool res = m_query_traversal_traits.is_intersection_found(); + m_query_traversal_traits.reset(); + return res; + } + + bool is_intersection_found() const { return m_is_found; } + +private: + bool m_is_found; + const AABBTraits& m_traits; + const Aff_transformation_3& m_transfo; + bool m_has_rotation; + Do_intersect_traversal_traits_with_transformation& m_query_traversal_traits; }; -template -typename CGAL::AABB_tree >::Bounding_box -get_tree_bbox(const CGAL::AABB_tree >& tree) -{ - return tree.traits().compute_transformed_bbox(tree.bbox()); -} - -template -typename CGAL::AABB_tree >::Bounding_box -get_node_bbox(const CGAL::AABB_node >& node, - const AABB_do_intersect_transform_traits& traits) -{ - return traits.compute_transformed_bbox(node.bbox()); -} - -} // end internal - }//end CGAL #endif //CGAL_AABB_AABB_do_intersect_transform_traits_H diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Point_inside_vertical_ray_cast.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Point_inside_vertical_ray_cast.h index b3d45194891..2bb77654b4b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Point_inside_vertical_ray_cast.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Point_inside_vertical_ray_cast.h @@ -36,24 +36,32 @@ namespace CGAL { namespace internal { -// added for AABB_do_intersect_transform_traits -template -typename AABBTree::Bounding_box -get_tree_bbox(const AABBTree& tree) +template +struct Default_tree_helper { - return tree.bbox(); -} + typedef typename AABBTree::AABB_traits AABB_traits; + typedef typename CGAL::AABB_node Node; -template -typename AABBNode::Bounding_box -get_node_bbox(const AABBNode& node, const AABBTraits&) -{ - return node.bbox(); -} + Bbox_3 get_tree_bbox(const AABBTree& tree) const + { + return tree.bbox(); + } + + typename AABBTree::Primitive::Datum + get_primitive_datum(const typename AABBTree::Primitive& primitive, const AABB_traits& traits) const + { + return internal::Primitive_helper::get_datum(primitive, traits); + } + + Bbox_3 get_node_bbox(const Node& node) const + { + return node.bbox(); + } +}; // internal class for point inside test, using existing AABB tree -template -class Point_inside_vertical_ray_cast +template > +class Point_inside_vertical_ray_cast { typedef typename Kernel::Point_3 Point; typedef typename Kernel::Ray_3 Ray; @@ -61,14 +69,20 @@ class Point_inside_vertical_ray_cast static const unsigned int seed = 1340818006; + Helper m_helper; + public: + Point_inside_vertical_ray_cast(const Helper& h = Helper()) + : m_helper(h) + {} + Bounded_side operator()( const Point& point, const AABBTree& tree, typename Kernel::Construct_ray_3 ray_functor = Kernel().construct_ray_3_object(), typename Kernel::Construct_vector_3 vector_functor = Kernel().construct_vector_3_object() ) const { - typename Traits::Bounding_box bbox = get_tree_bbox(tree); + typename Traits::Bounding_box bbox = m_helper.get_tree_bbox(tree); if( point.x() < bbox.xmin() || point.x() > bbox.xmax() || point.y() < bbox.ymin() || point.y() > bbox.ymax() @@ -103,8 +117,8 @@ private: std::pair status( boost::logic::tribool(boost::logic::indeterminate), 0); - Ray_3_Triangle_3_traversal_traits > - traversal_traits(status, tree.traits()); + Ray_3_Triangle_3_traversal_traits > + traversal_traits(status, tree.traits(), m_helper); tree.traversal(ray, traversal_traits); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Ray_3_Triangle_3_traversal_traits.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Ray_3_Triangle_3_traversal_traits.h index bbd3eda72cc..c4e94d216f2 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Ray_3_Triangle_3_traversal_traits.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Side_of_triangle_mesh/Ray_3_Triangle_3_traversal_traits.h @@ -15,7 +15,7 @@ // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0+ -// +// // // Author(s) : Sebastien Loriot @@ -36,7 +36,7 @@ namespace CGAL { namespace internal { -template +template class Ray_3_Triangle_3_traversal_traits { protected: @@ -46,11 +46,13 @@ protected: const AABBTraits& m_aabb_traits; typedef typename AABBTraits::Primitive Primitive; typedef CGAL::AABB_node Node; + Helper m_helper; public: Ray_3_Triangle_3_traversal_traits(std::pair& status, - const AABBTraits& aabb_traits) - :m_status(status),m_stop(false), m_aabb_traits(aabb_traits) + const AABBTraits& aabb_traits, + const Helper& h) + :m_status(status),m_stop(false), m_aabb_traits(aabb_traits), m_helper(h) {m_status.first=true;} bool go_further() const { return !m_stop; } @@ -60,10 +62,8 @@ public: { internal::r3t3_do_intersect_endpoint_position_visitor visitor; std::pair res= - internal::do_intersect( - (internal::Primitive_helper::get_datum(primitive, m_aabb_traits)), - query,Kernel(),visitor); - + internal::do_intersect(m_helper.get_primitive_datum(primitive, m_aabb_traits), query,Kernel(),visitor); + if (res.first){ switch (res.second){ case internal::R3T3_intersection::CROSS_FACET: @@ -79,40 +79,40 @@ public: } } } - + template bool do_intersect(const Query& query, const Node& node) const { - return m_aabb_traits.do_intersect_object()(query, node.bbox()); + return m_aabb_traits.do_intersect_object()(query, m_helper.get_node_bbox(node)); } }; //specialization for vertical ray -template -class Ray_3_Triangle_3_traversal_traits: - public Ray_3_Triangle_3_traversal_traits +template +class Ray_3_Triangle_3_traversal_traits: + public Ray_3_Triangle_3_traversal_traits { - typedef Ray_3_Triangle_3_traversal_traits Base; + typedef Ray_3_Triangle_3_traversal_traits Base; typedef typename Kernel::Point_3 Point; typedef typename Base::Primitive Primitive; typedef CGAL::AABB_node Node; public: - Ray_3_Triangle_3_traversal_traits(std::pair& status, const AABBTraits& aabb_traits) - :Base(status, aabb_traits){} + Ray_3_Triangle_3_traversal_traits(std::pair& status, const AABBTraits& aabb_traits, const TraversalTraits& tt) + :Base(status, aabb_traits, tt){} template bool do_intersect(const Query& query, const Bbox_3& bbox) const { const Point& source=query.point(0); const Point& target=query.point(1); - + bool inc_z=target.z()>source.z(); - + //the ray does not intersect the z-slab if ( ( inc_z && source.z()>bbox.zmax() )|| (!inc_z && source.z() bbox.xmax() || source.x() bool do_intersect(const Query& query, const Node& node) const { - return do_intersect(query,get_node_bbox(node, this->m_aabb_traits)); + return do_intersect(query,this->m_helper.get_node_bbox(node)); } private: @@ -139,44 +139,42 @@ public: template void intersection(const Query& query, const Primitive& primitive) { - typename Kernel::Triangle_3 t - = (internal::Primitive_helper::get_datum(primitive, this->m_aabb_traits)); + typename Kernel::Triangle_3 t = this->m_helper.get_primitive_datum(primitive, this->m_aabb_traits); if ( !do_intersect(query,t.bbox()) ) return; - + typename Kernel::Point_2 p0=z_project(t[0]); typename Kernel::Point_2 p1=z_project(t[1]); typename Kernel::Point_2 p2=z_project(t[2]); int indices[3]={0,1,2}; //to track whether triangle points have been swapt typename Kernel::Point_2 q=z_project( query.source() ); - + Orientation orient_2=orientation(p0,p1,p2); - + //check whether the face has a normal vector in the xy-plane if (orient_2==COLLINEAR){ //in that case the projection of the triangle along the z-axis is a segment. const typename Kernel::Point_2& other_point = p0!=p1?p1:p2; if ( orientation(p0,other_point,q) != COLLINEAR ) return;///no intersection - - //check if the ray source is above or below the triangle and compare it + + //check if the ray source is above or below the triangle and compare it //with the direction of the ray //TODO and if yes return //this is just an optimisation, the current code is valid - + this->m_status.first=boost::logic::indeterminate; this->m_stop=true; return; } - - + //regular case if (orient_2==NEGATIVE){ std::swap(p1,p2); std::swap(indices[1],indices[2]); } - + //check whether the ray intersect the supporting plane Orientation orient_3 = orientation(t[indices[0]],t[indices[1]],t[indices[2]],query.source()); - if ( orient_3!=COPLANAR && + if ( orient_3!=COPLANAR && ( //indicates whether the ray is oriented toward the positive side of the plane ( POSITIVE == CGAL::sign( query.to_vector().z() ) ) @@ -185,7 +183,6 @@ public: (orient_3==POSITIVE) ) ) return; //no intersection - //position against first segment switch( orientation(p0,p1,q) ){ diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_mesh_collision_detection.h index abd4a9e6991..34ca215a573 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_mesh_collision_detection.h @@ -28,9 +28,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -50,17 +50,16 @@ template class Rigid_mesh_collision_detection { typedef CGAL::AABB_face_graph_triangle_primitive Primitive; - typedef CGAL::AABB_do_intersect_transform_traits Traits; + typedef CGAL::AABB_traits Traits; typedef CGAL::AABB_tree Tree; - typedef Side_of_triangle_mesh Side_of_tm; - + typedef Do_intersect_traversal_traits_with_transformation Traversal_traits; std::vector m_triangle_mesh_ptrs; // TODO: we probably want an option with external trees std::vector m_aabb_trees; std::vector m_is_closed; std::vector< std::vector > m_points_per_cc; - + std::vector m_traversal_traits; #if CGAL_CACHE_BOXES boost::dynamic_bitset<> m_bboxes_is_invalid; std::vector m_bboxes; @@ -108,6 +107,25 @@ class Rigid_mesh_collision_detection m_points_per_cc.back().push_back( get(boost::vertex_point, tm, *boost::begin(vertices(tm))) ); } + // precondition A and B does not intersect + bool does_A_contains_a_CC_of_B(std::size_t id_A, std::size_t id_B) + { + typename Kernel::Construct_ray_3 ray_functor; + typename Kernel::Construct_vector_3 vector_functor; + typedef typename Traversal_traits::Transformed_tree_helper Helper; + + BOOST_FOREACH(const typename Kernel::Point_3& q, m_points_per_cc[id_B]) + { + if( internal::Point_inside_vertical_ray_cast(m_traversal_traits[id_A].get_helper())( + m_traversal_traits[id_B].transformation()( q ), *m_aabb_trees[id_A], + ray_functor, vector_functor) == CGAL::ON_BOUNDED_SIDE) + { + return true; + } + } + return false; + } + public: template Rigid_mesh_collision_detection(const MeshRange& triangle_meshes, bool assume_one_CC_per_mesh = false) @@ -131,6 +149,7 @@ public: m_aabb_trees.reserve(nb_meshes); m_is_closed.clear(); m_is_closed.resize(nb_meshes, false); + m_traversal_traits.reserve(m_aabb_trees.size()); #if CGAL_CACHE_BOXES m_bboxes_is_invalid.clear(); m_bboxes_is_invalid.resize(nb_meshes, true); @@ -144,6 +163,7 @@ public: m_triangle_mesh_ptrs.push_back( &tm ); Tree* t = new Tree(faces(tm).begin(), faces(tm).end(), tm); m_aabb_trees.push_back(t); + m_traversal_traits.push_back( Traversal_traits(m_aabb_trees.back()->traits()) ); add_cc_points(tm, assume_one_CC); } } @@ -154,6 +174,7 @@ public: m_triangle_mesh_ptrs.push_back( &tm ); Tree* t = new Tree(faces(tm).begin(), faces(tm).end(), tm); m_aabb_trees.push_back(t); + m_traversal_traits.push_back( Traversal_traits(m_aabb_trees.back()->traits()) ); #if CGAL_CACHE_BOXES m_bboxes.push_back(Bbox_3()); m_bboxes_is_invalid.resize(m_bboxes_is_invalid.size()+1, true); @@ -169,6 +190,7 @@ public: m_aabb_trees.erase( m_aabb_trees.begin()+mesh_id); m_is_closed.erase(m_is_closed.begin()+mesh_id); m_points_per_cc.erase(m_points_per_cc.begin()+mesh_id); + m_traversal_traits.erase(m_traversal_traits.begin()+mesh_id); #if CGAL_CACHE_BOXES // TODO this is a lazy approach that is not optimal m_bboxes.pop_back(); @@ -179,7 +201,7 @@ public: void set_transformation(std::size_t mesh_id, const Aff_transformation_3& aff_trans) { - m_aabb_trees[mesh_id]->traits().set_transformation(aff_trans); + m_traversal_traits[mesh_id].set_transformation(aff_trans); #if CGAL_CACHE_BOXES m_bboxes_is_invalid.set(mesh_id); #endif @@ -189,11 +211,11 @@ public: void update_bboxes() { // protector is supposed to have been set - for (boost::dynamic_bitset<>::size_type i = m_bboxes.find_first(); + for (boost::dynamic_bitset<>::size_type i = m_bboxes_is_invalid.find_first(); i != m_bboxes_is_invalid.npos; i = m_bboxes_is_invalid.find_next(i)) { - m_bboxes[i]=internal::get_tree_bbox(*m_aabb_trees[i]); + m_bboxes[i]=m_traversal_traits[i].get_helper().get_tree_bbox(*m_aabb_trees[i]); } m_bboxes_is_invalid.reset(); } @@ -261,34 +283,27 @@ public: if (!do_overlap(m_bboxes[k], m_bboxes[mesh_id])) continue; #endif // TODO: think about an alternative that is using a traversal traits - if ( m_aabb_trees[k]->do_intersect( *m_aabb_trees[mesh_id] ) ) + + Do_intersect_traversal_traits_for_two_trees traversal_traits( + m_aabb_trees[k]->traits(), m_traversal_traits[k].transformation(), m_traversal_traits[mesh_id]); + m_aabb_trees[k]->traversal(*m_aabb_trees[mesh_id], traversal_traits); + if (traversal_traits.is_intersection_found()) res.push_back(std::make_pair(k, false)); else{ if (m_is_closed[mesh_id]) { - Side_of_tm side_of_mid(*m_aabb_trees[mesh_id]); - bool stop = false; - BOOST_FOREACH(const typename Kernel::Point_3& q, m_points_per_cc[k]) + if ( does_A_contains_a_CC_of_B(mesh_id, k) ) { - if(side_of_mid(m_aabb_trees[k]->traits().transformation()( q )) == CGAL::ON_BOUNDED_SIDE) - { - res.push_back(std::make_pair(k, true)); - stop=true; - break; - } + res.push_back(std::make_pair(k, true)); + continue; } - if (stop) continue; } if (m_is_closed[k]) { - Side_of_tm side_of_mk(*m_aabb_trees[k]); - BOOST_FOREACH(const typename Kernel::Point_3& q, m_points_per_cc[mesh_id]) + if ( does_A_contains_a_CC_of_B(k, mesh_id) ) { - if(side_of_mk(m_aabb_trees[mesh_id]->traits().transformation()( q )) == CGAL::ON_BOUNDED_SIDE) - { - res.push_back(std::make_pair(k, true)); - break; - } + res.push_back(std::make_pair(k, true)); + continue; } } }