// Copyright (c) 2005 Tel-Aviv University (Israel). // All rights reserved. // // This file is part of CGAL (www.cgal.org); you may redistribute it under // the terms of the Q Public License version 1.0. // See the file LICENSE.QPL distributed with CGAL. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $Source: /CVSROOT/CGAL/Packages/Envelope_3/include/CGAL/Envelope_pm_dcel.h,v $ // $Revision$ $Date$ // $Name: $ // // Author(s) : Michal Meyerovitch #ifndef CGAL_ENVELOPE_PM_DCEL_H #define CGAL_ENVELOPE_PM_DCEL_H #include #include #include "CGAL/Envelope_base.h" #include #include #include CGAL_BEGIN_NAMESPACE template class Dcel_data { public: typedef Dcel_data Self; typedef std::list Data_container; typedef typename Data_container::iterator Data_iterator; typedef typename Data_container::const_iterator Data_const_iterator; protected: /*! data container */ Data_container m_data; /*! Indicates that the data (surfaces) have been set already */ bool m_is_set; // the decision that was made Dac_decision m_decision; public: /*! Constructor */ Dcel_data() : m_is_set(false), m_decision(NOT_SET) {} /*! \brief returns true iff data has been set already */ bool get_is_set() const { return m_is_set; } /*! \brief resets the flag */ void set_is_set(bool flag) { m_is_set = flag; } bool is_decision_set() { return (m_decision != NOT_SET); } Dac_decision get_decision() { return m_decision; } void set_decision(Comparison_result comp) { if (comp == SMALLER) m_decision = FIRST; else if (comp == LARGER) m_decision = SECOND; else m_decision = BOTH; } void set_decision(Dac_decision dec) { m_decision = dec; } /*! * Get the number of data objects associated with the face. */ int number_of_data_objects() const { return (m_data.size()); } /*! * check if the data is set to be empty */ bool has_no_data() const { return (m_is_set && number_of_data_objects() == 0); } /*! * Get the first data object associated with the face. * \pre number_of_data_objects() is not 0. */ const Data& get_data() const { CGAL_precondition (m_data.size() > 0); return (m_data.front()); } /*! * Get the data iterators (const version). */ Data_const_iterator begin_data() const { return (m_data.begin()); } Data_const_iterator end_data() const { return (m_data.end()); } /*! * Get the data iterators (non-const version). */ Data_iterator begin_data() { return (m_data.begin()); } Data_iterator end_data() { return (m_data.end()); } /*! * Set a data object to the face. * \param data The data object to set. */ void set_data (const Data & data) { clear_data(); add_data(data); } /*! * Set a range of data objects to the face. * \param begin A begin iterator for the data range. * \param end A past-the-end iterator for the data range. */ template void set_data(const InputIterator & begin, const InputIterator & end) { clear_data(); add_data(begin, end); } /*! * set the data to be empty. */ void set_no_data() { clear_data(); m_is_set = true; } /*! * Add a data object to the face. * \param data The additional data object. */ void add_data (const Data & data) { m_data.push_back(data); m_is_set = true; } /*! * Add a range of data objects to the face. * \param begin A begin iterator for the data range. * \param end A past-the-end iterator for the data range. */ template void add_data (const InputIterator & begin, const InputIterator & end) { InputIterator it; for (it = begin; it != end; it++) m_data.push_back(*it); m_is_set = true; } /*! * Clear the data objects. */ void clear_data () { m_data.clear(); m_is_set = false; } /*! * Check if the set of data objects in the input range is equal to our * set of data objects */ template bool is_equal_data(const InputIterator & begin, const InputIterator & end) const { if (!get_is_set()) return false; // insert the input data objects into a set std::set input_data(begin, end); std::set my_data(begin_data(), end_data()); if (input_data.size() != my_data.size()) return false; return (my_data == input_data); } template bool has_equal_data(const InputIterator & begin, const InputIterator & end) const { if (!get_is_set()) return false; // insert the input data objects into a set std::set input_data(begin, end); std::set my_data(begin_data(), end_data()); std::list intersection; std::set_intersection(my_data.begin(), my_data.end(), input_data.begin(), input_data.end(), std::back_inserter(intersection)); return (intersection.size() > 0); } protected: /*! Place holder for the source of the overlay data */ Object m_aux_source[2]; public: template void set_aux_source(unsigned int id, HandleType h) { CGAL_precondition(id < 2); m_aux_source[id] = make_object(h); } void set_aux_source(unsigned int id, Object o) { CGAL_precondition(id < 2); CGAL_precondition(!o.is_empty()); m_aux_source[id] = o; } Object get_aux_source(unsigned int id) { CGAL_precondition(id < 2); CGAL_precondition (!m_aux_source[id].is_empty()); return m_aux_source[id]; } /*! \brief returns true iff the point has been set already */ bool get_aux_is_set(unsigned int id) const { CGAL_precondition(id < 2); return (!m_aux_source[id].is_empty()); } }; /*! Extend the planar-map vertex */ template class Envelope_pm_vertex : public CGAL::Arr_vertex_base, public Dcel_data { private: // indicate if the edge was added in the decomposition process // and is not part of the arrangement bool m_is_fake; // is this vertex an intersection vertex? // used in the partial vd, to eliminate vertical edges from // intersection points bool m_is_intersection; // indications for the Envelope algorithm (for an isolated vertex only) bool m_is_equal_data_in_face; bool m_has_equal_data_in_face; bool m_is_equal_aux_data_in_face[2]; bool m_has_equal_aux_data_in_face[2]; public: /*! Constructor */ Envelope_pm_vertex() : Dcel_data() , m_is_fake(false) , m_is_intersection(false) , m_is_equal_data_in_face(false) , m_has_equal_data_in_face(false) { m_is_equal_aux_data_in_face[0] = m_is_equal_aux_data_in_face[1] = false; m_has_equal_aux_data_in_face[0] = m_has_equal_aux_data_in_face[1] = false; } void set_is_fake(bool b) { m_is_fake = b; } bool get_is_fake() const { return m_is_fake; } void set_is_intersection(bool b) { m_is_intersection = b; } bool get_is_intersection() const { return m_is_intersection; } void set_is_equal_data_in_face(bool b) { m_is_equal_data_in_face = b; } bool get_is_equal_data_in_face() const { return m_is_equal_data_in_face; } void set_has_equal_data_in_face(bool b) { m_has_equal_data_in_face = b; } bool get_has_equal_data_in_face() const { return m_has_equal_data_in_face; } void set_is_equal_aux_data_in_face(unsigned int id, bool b) { CGAL_assertion(id < 2); m_is_equal_aux_data_in_face[id] = b; } bool get_is_equal_aux_data_in_face(unsigned int id) const { CGAL_assertion(id < 2); return m_is_equal_aux_data_in_face[id]; } void set_has_equal_aux_data_in_face(unsigned int id, bool b) { CGAL_assertion(id < 2); m_has_equal_aux_data_in_face[id] = b; } bool get_has_equal_aux_data_in_face(unsigned int id) const { CGAL_assertion(id < 2); return m_has_equal_aux_data_in_face[id]; } }; /*! Extend the planar-map halfedge */ template class Envelope_pm_halfedge : public CGAL::Arr_halfedge_base, public Dcel_data { private: // indicate if the edge was added in the decomposition process // and is not part of the arrangement bool m_is_fake; // indications for the Envelope algorithm // relation between halfedge and incident face bool m_is_equal_data_in_face; bool m_has_equal_data_in_face; bool m_is_equal_aux_data_in_face[2]; bool m_has_equal_aux_data_in_face[2]; // relation between halfedge and target vertex bool m_is_equal_data_in_target; bool m_has_equal_data_in_target; bool m_is_equal_aux_data_in_target[2]; bool m_has_equal_aux_data_in_target[2]; // relation between target vertex and incident face bool m_has_equal_data_in_target_and_face; bool m_has_equal_aux_data_in_target_and_face[2]; public: Envelope_pm_halfedge() : Dcel_data() , m_is_fake(false) , m_is_equal_data_in_face(false) , m_has_equal_data_in_face(false) , m_is_equal_data_in_target(false) , m_has_equal_data_in_target(false) , m_has_equal_data_in_target_and_face(false) { m_is_equal_aux_data_in_face[0] = m_is_equal_aux_data_in_face[1] = false; m_has_equal_aux_data_in_face[0] = m_has_equal_aux_data_in_face[1] = false; m_is_equal_aux_data_in_target[0] = m_is_equal_aux_data_in_target[1] = false; m_has_equal_aux_data_in_target[0] = m_has_equal_aux_data_in_target[1] = false; m_has_equal_aux_data_in_target_and_face[0] = m_has_equal_aux_data_in_target_and_face[1] = false; } void set_is_fake(bool b) { m_is_fake = b; } bool get_is_fake() const { return m_is_fake; } void set_is_equal_data_in_face(bool b) { m_is_equal_data_in_face = b; } bool get_is_equal_data_in_face() const { return m_is_equal_data_in_face; } void set_has_equal_data_in_face(bool b) { m_has_equal_data_in_face = b; } bool get_has_equal_data_in_face() const { return m_has_equal_data_in_face; } void set_is_equal_aux_data_in_face(unsigned int id, bool b) { CGAL_assertion(id < 2); m_is_equal_aux_data_in_face[id] = b; } bool get_is_equal_aux_data_in_face(unsigned int id) const { CGAL_assertion(id < 2); return m_is_equal_aux_data_in_face[id]; } void set_has_equal_aux_data_in_face(unsigned int id, bool b) { CGAL_assertion(id < 2); m_has_equal_aux_data_in_face[id] = b; } bool get_has_equal_aux_data_in_face(unsigned int id) const { CGAL_assertion(id < 2); return m_has_equal_aux_data_in_face[id]; } void set_is_equal_data_in_target(bool b) { m_is_equal_data_in_target = b; } bool get_is_equal_data_in_target() const { return m_is_equal_data_in_target; } void set_has_equal_data_in_target(bool b) { m_has_equal_data_in_target = b; } bool get_has_equal_data_in_target() const { return m_has_equal_data_in_target; } void set_is_equal_aux_data_in_target(unsigned int id, bool b) { CGAL_assertion(id < 2); m_is_equal_aux_data_in_target[id] = b; } bool get_is_equal_aux_data_in_target(unsigned int id) const { CGAL_assertion(id < 2); return m_is_equal_aux_data_in_target[id]; } void set_has_equal_aux_data_in_target(unsigned int id, bool b) { CGAL_assertion(id < 2); m_has_equal_aux_data_in_target[id] = b; } bool get_has_equal_aux_data_in_target(unsigned int id) const { CGAL_assertion(id < 2); return m_has_equal_aux_data_in_target[id]; } // access to flags that contain relation between target and face void set_has_equal_data_in_target_and_face(bool b) { m_has_equal_data_in_target_and_face = b; } bool get_has_equal_data_in_target_and_face() const { return m_has_equal_data_in_target_and_face; } void set_has_equal_aux_data_in_target_and_face(unsigned int id, bool b) { CGAL_assertion(id < 2); m_has_equal_aux_data_in_target_and_face[id] = b; } bool get_has_equal_aux_data_in_target_and_face(unsigned int id) const { CGAL_assertion(id < 2); return m_has_equal_aux_data_in_target_and_face[id]; } }; /*! Extend the planar-map face */ template class Envelope_pm_face : public CGAL::Arr_face_base, public Dcel_data { public: typedef std::list Data_container; typedef typename Data_container::iterator Data_iterator; typedef typename Data_container::const_iterator Data_const_iterator; /*! Constructor */ Envelope_pm_face() : Dcel_data() {} }; /*! A new dcel builder with full Envelope features */ template class Envelope_pm_dcel : public CGAL::Arr_dcel_base, Envelope_pm_halfedge, Envelope_pm_face > { public: typedef Data Face_data; typedef typename Envelope_pm_face::Data_iterator Face_data_iterator; typedef typename Envelope_pm_face::Data_const_iterator Face_data_const_iterator; typedef Data Edge_data; typedef Face_data_iterator Edge_data_iterator; typedef Face_data_const_iterator Edge_data_const_iterator; typedef Data Vertex_data; typedef Face_data_iterator Vertex_data_iterator; typedef Face_data_const_iterator Vertex_data_const_iterator; typedef Dcel_data Dcel_elem_with_data; typedef Data Dcel_data; typedef Face_data_iterator Dcel_data_iterator; typedef Face_data_const_iterator Dcel_data_const_iterator; /*! Constructor */ Envelope_pm_dcel() {} }; CGAL_END_NAMESPACE #endif