diff --git a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt
index 61027e0f6fc..5b6f978c3b5 100644
--- a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt
+++ b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt
@@ -30,7 +30,6 @@ and faces is much simpler and can be used at runtime and not at compile time.}
## Classes ##
- `CGAL::Surface_mesh
`
-- `CGAL::Property_map`
*/
diff --git a/Surface_mesh/examples/Surface_mesh/sm_memory.cpp b/Surface_mesh/examples/Surface_mesh/sm_memory.cpp
index a29c2ca005c..5bbb1108352 100644
--- a/Surface_mesh/examples/Surface_mesh/sm_memory.cpp
+++ b/Surface_mesh/examples/Surface_mesh/sm_memory.cpp
@@ -33,7 +33,7 @@ int main()
}
// The status of being used or removed is stored in a property map
- CGAL::Property_map removed
+ Mesh::Property_map removed
= m.get_property_map("v:removed");
diff --git a/Surface_mesh/examples/Surface_mesh/sm_properties.cpp b/Surface_mesh/examples/Surface_mesh/sm_properties.cpp
index c1907d2b44a..a327587e6f2 100644
--- a/Surface_mesh/examples/Surface_mesh/sm_properties.cpp
+++ b/Surface_mesh/examples/Surface_mesh/sm_properties.cpp
@@ -27,7 +27,7 @@ int main()
m.add_property_map("f:my_property", false);
// give each vertex a name, the default is empty
- CGAL::Property_map name
+ Mesh::Property_map name
= m.add_property_map("v:name", "noname");
// add some names to the vertices
@@ -35,7 +35,7 @@ int main()
name[v2] = "world";
// retrieve the point property
- CGAL::Property_map location = m.points();
+ Mesh::Property_map location = m.points();
BOOST_FOREACH( vertex_descriptor vd, m.vertices()) {
std::cout << name[vd] << " @ " << location[vd] << std::endl;
}
diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h
index 470a4fdd180..4c86dff317e 100644
--- a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h
+++ b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h
@@ -31,6 +31,8 @@
namespace CGAL {
+#ifndef DOXYGEN_RUNNING
+
/// \addtogroup PkgSurface_mesh
///
/// @{
@@ -470,7 +472,7 @@ private:
///@}
-
+#endif // DOXYGEN_RUNNING
} // CGAL
//=============================================================================
diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h
index d1dcb4051a9..5025ca6f631 100644
--- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h
+++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h
@@ -25,6 +25,9 @@
#include
#include
#include
+#include
+#include
+#include
#include
#include
@@ -33,13 +36,14 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
-#include
+//#include
#include
#include
@@ -65,6 +69,453 @@ class Surface_mesh
template
class Handle_iterator;
public:
+
+
+
+/// \addtogroup PkgSurface_mesh
+///
+/// @{
+
+/// @cond CGAL_DOCUMENT_INTERNALS
+class Base_property_array
+{
+public:
+
+ /// Default constructor
+ Base_property_array(const std::string& name) : name_(name) {}
+
+ /// Destructor.
+ virtual ~Base_property_array() {}
+
+ /// Reserve memory for n elements.
+ virtual void reserve(size_t n) = 0;
+
+ /// Resize storage to hold n elements.
+ virtual void resize(size_t n) = 0;
+
+ /// Free unused memory.
+ virtual void shrink_to_fit() = 0;
+
+ /// Extend the number of elements by one.
+ virtual void push_back() = 0;
+
+ /// Let two elements swap their storage place.
+ virtual void swap(size_t i0, size_t i1) = 0;
+
+ /// Return a deep copy of self.
+ virtual Base_property_array* clone () const = 0;
+
+ /// Return the type_info of the property
+ virtual const std::type_info& type() = 0;
+
+ /// Return the name of the property
+ const std::string& name() const { return name_; }
+
+
+protected:
+
+ std::string name_;
+};
+
+ /// @endcond
+
+
+//== CLASS DEFINITION =========================================================
+
+/// @cond CGAL_DOCUMENT_INTERNALS
+
+template
+class Property_array : public Base_property_array
+{
+public:
+
+ typedef T value_type;
+ typedef std::vector vector_type;
+ typedef typename vector_type::reference reference;
+ typedef typename vector_type::const_reference const_reference;
+
+ Property_array(const std::string& name, T t=T()) : Base_property_array(name), value_(t) {}
+
+public: // virtual interface of Base_property_array
+
+ virtual void reserve(size_t n)
+ {
+ data_.reserve(n);
+ }
+
+ virtual void resize(size_t n)
+ {
+ data_.resize(n, value_);
+ }
+
+ virtual void push_back()
+ {
+ data_.push_back(value_);
+ }
+
+ virtual void shrink_to_fit()
+ {
+ vector_type(data_).swap(data_);
+ }
+
+ virtual void swap(size_t i0, size_t i1)
+ {
+ T d(data_[i0]);
+ data_[i0]=data_[i1];
+ data_[i1]=d;
+ }
+
+ virtual Base_property_array* clone() const
+ {
+ Property_array* p = new Property_array(name_, value_);
+ p->data_ = data_;
+ return p;
+ }
+
+ virtual const std::type_info& type() { return typeid(T); }
+
+
+public:
+
+ /// Get pointer to array (does not work for T==bool)
+ const T* data() const
+ {
+ return &data_[0];
+ }
+
+ /// Access the i'th element. No range check is performed!
+ reference operator[](int _idx)
+ {
+ CGAL_assertion( size_t(_idx) < data_.size() );
+ return data_[_idx];
+ }
+
+ /// Const access to the i'th element. No range check is performed!
+ const_reference operator[](int _idx) const
+ {
+ CGAL_assertion( size_t(_idx) < data_.size());
+ return data_[_idx];
+ }
+
+
+
+private:
+ vector_type data_;
+ value_type value_;
+};
+
+
+
+// specialization for bool properties
+template <>
+inline const bool*
+Property_array::data() const
+{
+ CGAL_assertion(false);
+ return NULL;
+}
+
+ /// @endcond
+
+//== CLASS DEFINITION =========================================================
+
+/// @cond CGAL_DOCUMENT_INTERNALS
+
+template
+class Property_container;
+/// @endcond
+
+
+
+
+//== CLASS DEFINITION =========================================================
+/// @cond CGAL_DOCUMENT_INTERNALS
+
+template
+class Property_map;
+
+template
+class Property_container
+{
+public:
+
+ // default constructor
+ Property_container() : size_(0) {}
+
+ // destructor (deletes all property arrays)
+ virtual ~Property_container() { clear(); }
+
+ // copy constructor: performs deep copy of property arrays
+ Property_container(const Property_container& _rhs) { operator=(_rhs); }
+
+ // assignment: performs deep copy of property arrays
+ Property_container& operator=(const Property_container& _rhs)
+ {
+ if (this != &_rhs)
+ {
+ clear();
+ parrays_.resize(_rhs.n_properties());
+ size_ = _rhs.size();
+ for (unsigned int i=0; iclone();
+ }
+ return *this;
+ }
+
+ // returns the current size of the property arrays
+ size_t size() const { return size_; }
+
+ // returns the number of property arrays
+ size_t n_properties() const { return parrays_.size(); }
+
+ // returns a vector of all property names
+ std::vector properties() const
+ {
+ std::vector names;
+ for (unsigned int i=0; iname());
+ return names;
+ }
+
+ // add a property with name \c name and default value \c t
+ template Property_map add(const std::string& name, const T t=T())
+ {
+ // if a property with this name already exists, return an invalid property
+ for (unsigned int i=0; iname() == name)
+ {
+ return Property_map();
+ }
+ }
+
+ // otherwise add the property
+ Property_array* p = new Property_array(name, t);
+ p->resize(size_);
+ parrays_.push_back(p);
+ return Property_map(p);
+ }
+
+
+ // get a property by its name. returns invalid property if it does not exist.
+ template Property_map get(const std::string& name) const
+ {
+ for (unsigned int i=0; iname() == name)
+ return Property_map(dynamic_cast*>(parrays_[i]));
+ return Property_map();
+ }
+
+
+ // returns a property if it exists, otherwise it creates it first.
+ template Property_map get_or_add(const std::string& name, const T t=T())
+ {
+ Property_map p = get(name);
+ if (!p) p = add(name, t);
+ return p;
+ }
+
+
+ // get the type of property by its name. returns typeid(void) if it does not exist.
+ const std::type_info& get_type(const std::string& name)
+ {
+ for (unsigned int i=0; iname() == name)
+ return parrays_[i]->type();
+ return typeid(void);
+ }
+
+
+ // delete a property
+ template void remove(Property_map& h)
+ {
+ std::vector::iterator it=parrays_.begin(), end=parrays_.end();
+ for (; it!=end; ++it)
+ {
+ if (*it == h.parray_)
+ {
+ delete *it;
+ parrays_.erase(it);
+ h.reset();
+ break;
+ }
+ }
+ }
+
+
+ // delete all properties
+ void clear()
+ {
+ for (unsigned int i=0; ireserve(n);
+ }
+
+ // resize all arrays to size n
+ void resize(size_t n)
+ {
+ for (unsigned int i=0; iresize(n);
+ size_ = n;
+ }
+
+ // free unused space in all arrays
+ void shrink_to_fit() const
+ {
+ for (unsigned int i=0; ishrink_to_fit();
+ }
+
+ // add a new element to each vector
+ void push_back()
+ {
+ for (unsigned int i=0; ipush_back();
+ ++size_;
+ }
+
+ // swap elements i0 and i1 in all arrays
+ void swap(size_t i0, size_t i1) const
+ {
+ for (unsigned int i=0; iswap(i0, i1);
+ }
+
+
+private:
+ std::vector parrays_;
+ size_t size_;
+};
+
+ /// @endcond
+
+#ifndef DOXYGEN_RUNNING
+///
+///
+/// `Property_map` enables to attach properties to the simplices of a
+/// surface mesh.
+///
+/// @tparam Key The key type of the property map. It must be a model of `Index`.
+/// @tparam Value The value type of the property.
+///
+/// \cgalModels `LvaluePropertyMap`
+///
+template
+class Property_map
+/// @cond CGAL_DOCUMENT_INTERNALS
+ : public boost::put_get_helper<
+ typename Property_array::reference,
+ Property_map< I, T > >
+/// @endcond
+{
+ typedef void (Property_map::*bool_type)() const;
+ void this_type_does_not_support_comparisons() const {}
+public:
+ typedef I key_type;
+ typedef T value_type;
+ typedef boost::lvalue_property_map_tag category;
+
+#ifndef DOXYGEN_RUNNING
+
+ typedef typename Property_array::reference reference;
+
+ typedef typename Property_array::const_reference const_reference;
+#else
+ /// A reference to the value type of the property.
+ typedef unspecified_type reference;
+
+ /// A const reference to the value type of the property.
+ typedef unspecified_type const_reference;
+#endif
+
+#ifndef DOXYGEN_RUNNING
+ friend class Property_container;
+
+ template friend class Surface_mesh;
+#endif
+
+public:
+/// @cond CGAL_DOCUMENT_INTERNALS
+ Property_map(Property_array* p=NULL) : parray_(p) {}
+
+ void reset()
+ {
+ parray_ = NULL;
+ }
+ /// @endcond
+
+public:
+ /// \name Accessing Properties
+ //@{
+#ifdef DOXYGEN_RUNNING
+ /// Conversion to a Boolean. It is \c true when the property map
+ /// can be used, and \c false otherwise.
+ operator bool () const;
+#else
+ operator bool_type() const {
+ return parray_ != NULL ?
+ &Property_map::this_type_does_not_support_comparisons : 0;
+ }
+#endif
+ /// Access the property associated with the key \c i.
+ reference operator[](const I& i)
+ {
+ CGAL_assertion(parray_ != NULL);
+ return (*parray_)[i.idx()];
+ }
+
+ /// Access the property associated with the key \c i.
+ reference operator[](const I& i) const
+ {
+ CGAL_assertion(parray_ != NULL);
+ return (*parray_)[i.idx()];
+ }
+
+ /// Allows access to the underlying storage of the property. This
+ /// is useful when the key associated with the properties is
+ /// unimportant and only the properties are of interest
+ /// (e.g. rendering).
+ ///
+ /// \returns a pointer to the underlying storage of the property.
+ const T* data() const
+ {
+ CGAL_assertion(parray_ != NULL);
+ return parray_->data();
+ }
+
+ //@}
+private:
+
+ Property_array& array()
+ {
+ CGAL_assertion(parray_ != NULL);
+ return *parray_;
+ }
+
+ const Property_array& array() const
+ {
+ CGAL_assertion(parray_ != NULL);
+ return *parray_;
+ }
+
+ Property_array* parray_;
+};
+
+#endif // DOXYGEN_RUNNING
+
+///@}
+
+
+
/// \name Basic Types
///
///@{
@@ -1425,6 +1876,16 @@ private: //--------------------------------------------------- property handling
*/
///@{
+ /// Model of `LValuePropertyMap` with `I` as key type and `T` as value type, where `I`
+ /// is either a vertex, halfedge, edge, or face index type.
+#ifdef DOXYGEN_RUNNING
+ template
+ using Property_map = unspecified_type;
+
+#else
+
+
+#endif
/// adds a property map named `name` with value type `T` and default `t`
/// for index type `I`. Returns an invalid property map if a property