From 37f9b70a6bf4d0edee45e137972e92f7330cb6a8 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 17 Jul 2018 12:09:15 +0200 Subject: [PATCH 01/81] Better remove() / is_removed() methods --- Point_set_3/include/CGAL/Point_set_3.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index fa44d2404ee..84aa7ed209a 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -590,7 +590,10 @@ public: */ void remove (const Index& index) { - remove (m_indices.begin() + index); + iterator it = m_indices.begin() + index; + while (*it != index) + it = m_indices.begin() + *it; + remove (it); } @@ -610,6 +613,14 @@ public: return (std::distance (it, garbage_begin()) <= 0); } + bool is_removed (const Index& index) const + { + const_iterator it = m_indices.begin() + index; + while (*it != index) + it = m_indices.begin() + *it; + return is_removed (it); + } + /*! \brief Returns the constant iterator to the first element marked as removed (equal to `garbage_end()` if no elements are marked as removed. From 65672c6ce4958a3375fa36bb29c5f886971f0d1a Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 13 Aug 2018 11:29:13 +0200 Subject: [PATCH 02/81] Unify API of add_normal_map() with add_property_map() --- Point_set_3/include/CGAL/Point_set_3.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 84aa7ed209a..30ffac0d945 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -784,14 +784,15 @@ public: This method adds a property of type `Vector` and named `normal`. - \return `true` if the property was added, `false` if it already - existed. + \return Returns a pair containing the normal map and a Boolean + that is `true` if the property was added and `false` if it already + exists (and was therefore not added but only returned). */ - bool add_normal_map (const Vector& default_value = Vector(0., 0., 0.)) + std::pair add_normal_map (const Vector& default_value = Vector(0., 0., 0.)) { bool out = false; boost::tie (m_normals, out) = this->add_property_map ("normal", default_value); - return out; + return std::make_pair (m_normals, out); } /*! \brief Returns the property map of the normal property. From 5778e974c83b73d5739a206fb701e2dbcb35efde Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 13 Aug 2018 11:29:51 +0200 Subject: [PATCH 03/81] Update selection in demo with latest Point_set_3 improvments --- .../Point_set/Point_set_selection_plugin.cpp | 114 +++++++----------- .../demo/Polyhedron/include/Point_set_3.h | 32 ++--- 2 files changed, 59 insertions(+), 87 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index 9b9c5853770..4e9acfd60a1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp @@ -89,10 +89,9 @@ public: void apply (std::size_t i) const { - Point_set::const_iterator it = point_set->begin() + i; - bool already_selected = point_set->is_selected (it); + Point_set::Index idx = *(point_set->begin() + i); - const Kernel::Point_3& p = point_set->point (*it); + const Kernel::Point_3& p = point_set->point (idx); CGAL::qglviewer::Vec vp (p.x (), p.y (), p.z ()); bool now_selected = false; if(!ui_widget.box->isChecked()) @@ -115,13 +114,17 @@ public: } if (ui_widget.new_selection->isChecked()) - selected[i] = now_selected; - else if (ui_widget.union_selection->isChecked()) - selected[i] = (already_selected || now_selected); - else if (ui_widget.intersection->isChecked()) - selected[i] = (already_selected && now_selected); - else if (ui_widget.diff->isChecked()) - selected[i] = (already_selected && !now_selected); + selected[idx] = now_selected; + else + { + bool already_selected = point_set->is_selected (idx); + if (ui_widget.union_selection->isChecked()) + selected[idx] = (already_selected || now_selected); + else if (ui_widget.intersection->isChecked()) + selected[idx] = (already_selected && now_selected); + else if (ui_widget.diff->isChecked()) + selected[idx] = (already_selected && !now_selected); + } } }; @@ -183,26 +186,13 @@ public: selected_bitmap[nit->first] = true; } - std::vector unselected, selected; - - for(Point_set::iterator it = points_item->point_set()->begin (); - it != points_item->point_set()->end(); ++ it) - if (points_item->point_set()->is_selected(it) || selected_bitmap[*it]) - selected.push_back (*it); - else - unselected.push_back (*it); - - for (std::size_t i = 0; i < unselected.size(); ++ i) - *(points_item->point_set()->begin() + i) = unselected[i]; - for (std::size_t i = 0; i < selected.size(); ++ i) - *(points_item->point_set()->begin() + (unselected.size() + i)) = selected[i]; - - if (selected.empty ()) - points_item->point_set()->unselect_all(); - else + Point_set::iterator it = points_item->point_set()->begin (); + while (it != points_item->point_set()->first_selected()) { - points_item->point_set()->set_first_selected - (points_item->point_set()->begin() + unselected.size()); + if (selected_bitmap[*it]) + points_item->point_set()->select(*it); + else + ++ it; } points_item->invalidateOpenGLBuffers(); @@ -235,29 +225,14 @@ public: } } - std::vector unselected, selected; + Point_set::iterator it = points_item->point_set()->first_selected (); + while (it != points_item->point_set()->end()) + { + if (!selected_bitmap[*it]) + points_item->point_set()->unselect(*it); - for(Point_set::iterator it = points_item->point_set()->begin (); - it != points_item->point_set()->end(); ++ it) - if (points_item->point_set()->is_selected(it) && selected_bitmap[*it]) - selected.push_back (*it); - else - unselected.push_back (*it); - - for (std::size_t i = 0; i < unselected.size(); ++ i) - *(points_item->point_set()->begin() + i) = unselected[i]; - for (std::size_t i = 0; i < selected.size(); ++ i) - *(points_item->point_set()->begin() + (unselected.size() + i)) = selected[i]; - - if (selected.empty ()) - { - points_item->point_set()->unselect_all(); - } - else - { - points_item->point_set()->set_first_selected - (points_item->point_set()->begin() + unselected.size()); - } + ++ it; + } points_item->invalidateOpenGLBuffers(); points_item->itemChanged(); @@ -652,32 +627,25 @@ protected Q_SLOTS: selection_test.apply(i); #endif - std::vector unselected, selected; - for (std::size_t i = 0; i < points->size(); ++ i) + Point_set::iterator it = points->begin (); + Point_set::iterator first_selected = points->first_selected (); + while (it != points->first_selected()) { - Point_set::Index idx = *(points->begin() + i); - if (selected_bitmap[i]) - selected.push_back (idx); + if (selected_bitmap[*it]) + points->select(*it); else - unselected.push_back (idx); + ++ it; + } + + it = first_selected; + while (it != points->end()) + { + if (!selected_bitmap[*it]) + points->unselect(*it); + + ++ it; } - delete[] selected_bitmap; - - for (std::size_t i = 0; i < unselected.size(); ++ i) - *(points->begin() + i) = unselected[i]; - for (std::size_t i = 0; i < selected.size(); ++ i) - *(points->begin() + (unselected.size() + i)) = selected[i]; - if (selected.empty ()) - { - points->unselect_all(); - } - else - { - points->set_first_selected - (points->begin() + unselected.size()); - } - point_set_item->invalidateOpenGLBuffers(); point_set_item->itemChanged(); } diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index 8697f75c2cf..4f992825396 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -333,6 +333,12 @@ public: { return this->is_removed (it); } + + // Test if point is selected + bool is_selected(const Index& idx) const + { + return this->is_removed (idx); + } /// Gets the number of selected points. std::size_t nb_selected_points() const @@ -341,21 +347,19 @@ public: } /// Mark a point as selected/not selected. - void select(iterator it, bool selected = true) + void select(const Index& index) { - bool currently = is_selected (it); - iterator first = this->first_selected(); - --first; - if (currently && !selected) - { - std::swap (*it, *first); - -- this->m_nb_removed; - } - else if (!currently && selected) - { - std::swap (*it, *first); - ++ this->m_nb_removed; - } + this->remove(index); + } + + /// Mark a point as selected/not selected. + void unselect(const Index& index) + { + iterator it = this->m_indices.begin() + index; + while (*it != index) + it = this->m_indices.begin() + *it; + std::iter_swap (it, first_selected()); + this->m_nb_removed --; } void select_all() From 371be5bf84ed190823a0e14ccc9f641333a1b1e7 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 13 Aug 2018 15:48:29 +0200 Subject: [PATCH 04/81] Cleanup: no rearrangement of indices for display, use external vector --- .../Scene_points_with_normal_item.cpp | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index 1bdc1b7058e..bcf4b4c34fa 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -135,6 +135,7 @@ struct Scene_points_with_normal_item_priv class Fill_buffers { Point_set* point_set; + std::vector& indices; std::vector& positions_lines; std::vector& positions_normals; bool has_normals; @@ -145,6 +146,7 @@ class Fill_buffers { public: Fill_buffers(Point_set* point_set, + std::vector& indices, std::vector& positions_lines, std::vector& positions_normals, bool has_normals, @@ -152,6 +154,7 @@ public: double length, std::size_t offset_normal_indices = 0) : point_set (point_set) + , indices (indices) , positions_lines (positions_lines) , positions_normals (positions_normals) , has_normals (has_normals) @@ -175,8 +178,8 @@ public: void apply (std::size_t i) const { - Point_set::const_iterator it = point_set->begin() + i; - const Kernel::Point_3& p = point_set->point(*it); + const Point_set::Index& idx = indices[i]; + const Kernel::Point_3& p = point_set->point(idx); positions_lines[i * size_p ] = p.x() + offset.x; positions_lines[i * size_p + 1] = p.y() + offset.y; @@ -184,7 +187,7 @@ public: if(has_normals) { - const Kernel::Vector_3& n = point_set->normal(*it); + const Kernel::Vector_3& n = point_set->normal(idx); Point_set_3::Point q = p + length * n; positions_lines[i * size_p + 3] = q.x() + offset.x; positions_lines[i * size_p + 4] = q.y() + offset.y; @@ -413,9 +416,14 @@ void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const colors_points.resize(0); //Shuffle container to allow quick display random points - CGAL::cpp98::random_shuffle (m_points->begin(), m_points->first_selected()); + std::vector indices; + indices.reserve (m_points->size()); + std::copy (m_points->begin(), m_points->end(), std::back_inserter(indices)); + + CGAL::cpp98::random_shuffle (indices.begin(), indices.end() - m_points->nb_selected_points()); if (m_points->nb_selected_points() != 0) - CGAL::cpp98::random_shuffle (m_points->first_selected(), m_points->end()); + CGAL::cpp98::random_shuffle (indices.end() - m_points->nb_selected_points(), indices.end()); + //if item has normals, points will be one point out of two in the lines data. //else points will be lines and lines discarded. double average_spacing = 0; @@ -439,24 +447,24 @@ void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const positions_lines.resize(m_points->size() * 3); } - Fill_buffers fill_buffers (m_points, positions_lines, positions_normals, + Fill_buffers fill_buffers (m_points, indices, positions_lines, positions_normals, item->has_normals(), offset, normal_length * length_factor); - Fill_buffers fill_buffers_2 (m_points, positions_lines, positions_selected_normals, + Fill_buffers fill_buffers_2 (m_points, indices, positions_lines, positions_selected_normals, item->has_normals(), offset, normal_length * length_factor, m_points->first_selected() - m_points->begin()); #ifdef CGAL_LINKED_WITH_TBB tbb::parallel_for(tbb::blocked_range(0, - m_points->first_selected() - m_points->begin()), + m_points->size() - m_points->nb_selected_points()), fill_buffers); - tbb::parallel_for(tbb::blocked_range(m_points->first_selected() - m_points->begin(), + tbb::parallel_for(tbb::blocked_range(m_points->size() - m_points->nb_selected_points(), m_points->size()), fill_buffers_2); #else - for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->first_selected(); ++it) - fill_buffers.apply (it - m_points->begin()); - for (Point_set_3::const_iterator it = m_points->first_selected(); it != m_points->end(); ++it) - fill_buffers_2.apply (it - m_points->begin()); + for (std::size_t i = 0; i < indices.size() - m_points->nb_selected_points(); ++ i) + fill_buffers.apply (i); + for (std::size_t i = indices.size() - m_points->nb_selected_points(); i < indices.size(); ++ i) + fill_buffers_2.apply (i); #endif //The colors @@ -464,15 +472,15 @@ void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const { colors_points.reserve((m_points->size() - m_points->nb_selected_points()) * 6); - for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); ++it) - { - colors_points.push_back (m_points->red(*it)); - colors_points.push_back (m_points->green(*it)); - colors_points.push_back (m_points->blue(*it)); - colors_points.push_back (m_points->red(*it)); - colors_points.push_back (m_points->green(*it)); - colors_points.push_back (m_points->blue(*it)); - } + for (std::size_t i = 0; i < indices.size() - m_points->nb_selected_points(); ++ i) + { + colors_points.push_back (m_points->red(indices[i])); + colors_points.push_back (m_points->green(indices[i])); + colors_points.push_back (m_points->blue(indices[i])); + colors_points.push_back (m_points->red(indices[i])); + colors_points.push_back (m_points->green(indices[i])); + colors_points.push_back (m_points->blue(indices[i])); + } } QApplication::restoreOverrideCursor(); From 6e4815064ef87a2c9f34ff74327353d8e9f8185d Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 12:21:43 +0200 Subject: [PATCH 05/81] Add methods to easily transfer properties from one point set to another --- Point_set_3/include/CGAL/Point_set_3.h | 28 +++++--- .../include/CGAL/Surface_mesh/Properties.h | 71 +++++++++++++++++-- 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 30ffac0d945..0f2b7a3a695 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -238,15 +238,6 @@ public: return *this; } - /// \cond SKIP_IN_MANUAL - Point_set_3 (const Point_set_3& ps) - { - *this = ps; - } - - /// \endcond - - /// @} /// \cond SKIP_IN_MANUAL @@ -476,6 +467,15 @@ public: return out; } + iterator insert (const Point_set_3& other, const Index& idx) + { + iterator out = insert(); + Index new_idx = *out; + m_base.transfer(other.base(), idx, new_idx); + *out = new_idx; // Do not copy index from other point set + return out; + } + /// @} /// \name Accessors and Iterators @@ -840,6 +840,16 @@ public: return m_points; } + /// \cond SKIP_IN_MANUAL + void copy_properties (const Point_set_3& other) + { + m_base.copy_properties (other.base()); + + m_normals = this->property_map ("normal").first; // In case normal was added + } + /// \endcond + + /*! \brief Returns a vector with all strings that describe properties. */ diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h index c0b53cd8e23..640c7221585 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h @@ -70,6 +70,7 @@ public: virtual void reset(size_t idx) = 0; virtual bool transfer(const Base_property_array& other) = 0; + virtual bool transfer(const Base_property_array& other, std::size_t from, std::size_t to) = 0; /// Let two elements swap their storage place. virtual void swap(size_t i0, size_t i1) = 0; @@ -77,12 +78,19 @@ public: /// Return a deep copy of self. virtual Base_property_array* clone () const = 0; + /// Return a empty copy of self. + virtual Base_property_array* empty_clone () const = 0; + /// Return the type_info of the property - virtual const std::type_info& type() = 0; + virtual const std::type_info& type() const = 0; /// Return the name of the property const std::string& name() const { return name_; } + bool is_same (const Base_property_array& other) + { + return (name() == other.name() && type() == other.type()); + } protected: @@ -142,6 +150,18 @@ public: // virtual interface of Base_property_array return false; } + bool transfer(const Base_property_array& other, std::size_t from, std::size_t to) + { + const Property_array* pa = dynamic_cast(&other); + if (pa != NULL) + { + data_[to] = (*pa)[from]; + return true; + } + + return false; + } + virtual void shrink_to_fit() { vector_type(data_).swap(data_); @@ -161,7 +181,13 @@ public: // virtual interface of Base_property_array return p; } - virtual const std::type_info& type() { return typeid(T); } + virtual Base_property_array* empty_clone() const + { + Property_array* p = new Property_array(this->name_, this->value_); + return p; + } + + virtual const std::type_info& type() const { return typeid(T); } public: @@ -241,11 +267,11 @@ public: return *this; } - void transfer(const Property_container& _rhs) + bool transfer(const Property_container& _rhs) { for(std::size_t i=0; iname() == _rhs.parrays_[j]->name()){ + if(parrays_[i]->is_same (*(_rhs.parrays_[j]))){ parrays_[i]->transfer(* _rhs.parrays_[j]); break; } @@ -253,6 +279,38 @@ public: } } + // Copy properties that don't already exist from another container + void copy_properties (const Property_container& _rhs) + { + for (std::size_t i = 0; i < _rhs.parrays_.size(); ++ i) + { + bool property_already_exists = false; + for (std::size_t j = 0; j < parrays_.size(); ++ j) + if (_rhs.parrays_[i]->is_same (*(parrays_[j]))) + { + property_already_exists = true; + break; + } + + if (property_already_exists) + continue; + + parrays_.push_back (_rhs.parrays_[i]->empty_clone()); + parrays_.back()->resize(size_); + } + } + + // Transfer one element with all properties + // WARNING: properties must be the same in the two containers + bool transfer(const Property_container& _rhs, std::size_t from, std::size_t to) + { + bool out = true; + for(std::size_t i=0; itransfer(* _rhs.parrays_[i], from, to))) + out = false; + return out; + } + // returns the current size of the property arrays size_t size() const { return size_; } @@ -529,6 +587,11 @@ public: return parray_->transfer(*(other.parray_)); } + bool transfer (const Property_map_base& other, std::size_t from, std::size_t to) + { + return parray_->transfer(*(other.parray_), from, to); + } + /// 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 From 65f7ed1534bcc4d88e56e0a2044c0170956a0c6b Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 12:22:14 +0200 Subject: [PATCH 06/81] Bug fix: stop losing properties when creating point item from selection --- .../Point_set/Point_set_selection_plugin.cpp | 54 ++++--------------- 1 file changed, 11 insertions(+), 43 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index 4e9acfd60a1..699dc433230 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp @@ -753,57 +753,25 @@ public Q_SLOTS: return; } QApplication::setOverrideCursor(Qt::WaitCursor); - Scene_points_with_normal_item* new_item = new Scene_points_with_normal_item(); + Scene_points_with_normal_item* new_item = new Scene_points_with_normal_item; + new_item->point_set()->copy_properties (*(point_set_item->point_set())); + new_item->point_set()->check_colors(); + new_item->setName(QString("%1 (selected points)").arg(point_set_item->name())); - if (point_set_item->has_normals()) - new_item->point_set()->add_normal_map(); - Point_set::Byte_map red, green, blue; - Point_set::Double_map fred, fgreen, fblue; - if (point_set_item->point_set()->has_colors()) - { - if (point_set_item->point_set()->has_byte_colors()) - { - red = new_item->point_set()->add_property_map("red", 0).first; - green = new_item->point_set()->add_property_map("green", 0).first; - blue = new_item->point_set()->add_property_map("blue", 0).first; - } - else - { - fred = new_item->point_set()->add_property_map("red", 0).first; - fgreen = new_item->point_set()->add_property_map("green", 0).first; - fblue = new_item->point_set()->add_property_map("blue", 0).first; - } - new_item->point_set()->check_colors(); - } new_item->setColor(point_set_item->color()); new_item->setRenderingMode(point_set_item->renderingMode()); new_item->setVisible(point_set_item->visible()); + + std::cerr << point_set_item->point_set()->info() << std::endl; + std::cerr << new_item->point_set()->info() << std::endl; typedef Point_set_3 Point_set; for(Point_set::iterator it = point_set_item->point_set()->first_selected (); - it != point_set_item->point_set()->end(); ++ it) - { - Point_set::iterator new_point = - new_item->point_set()->insert(point_set_item->point_set()->point(*it)); - if (point_set_item->has_normals()) - new_item->point_set()->normal(*new_point) = point_set_item->point_set()->normal(*it); - if (point_set_item->point_set()->has_colors()) - { - if (point_set_item->point_set()->has_byte_colors()) - { - red[*new_point] = (unsigned char)(255. * point_set_item->point_set()->red(*it)); - green[*new_point] = (unsigned char)(255. * point_set_item->point_set()->green(*it)); - blue[*new_point] = (unsigned char)(255. * point_set_item->point_set()->blue(*it)); - } - else - { - fred[*new_point] = point_set_item->point_set()->red(*it); - fgreen[*new_point] = point_set_item->point_set()->green(*it); - fblue[*new_point] = point_set_item->point_set()->blue(*it); - } - } - } + it != point_set_item->point_set()->end(); ++ it) + { + new_item->point_set()->insert (*(point_set_item->point_set()), *it); + } new_item->resetSelection(); new_item->invalidateOpenGLBuffers(); From 14091145de1ad3609c6fd309bb86fa14db84d44d Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 12:22:33 +0200 Subject: [PATCH 07/81] Add method to get properties and types as string --- Point_set_3/include/CGAL/Point_set_3.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 0f2b7a3a695..c86e5251b7d 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -861,6 +861,19 @@ public: return out; } + std::vector > properties_and_types() const + { + std::vector prop = m_base.properties(); + prop.erase (prop.begin()); // remove "index" + prop.erase (prop.begin()); // remove "point" + + std::vector > out; out.reserve (prop.size()); + for (std::size_t i = 0; i < prop.size(); ++ i) + out.push_back (std::make_pair (prop[i], m_base.get_type(prop[i]))); + return out; + } + + /*! \brief Returns a sequence of \ref psp_namedparameters "Named Parameters" for Point Set Processing algorithms. From 17792e53b8c903c7fb114c3d8120c985075455f9 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:18:24 +0200 Subject: [PATCH 08/81] Fix return type --- Surface_mesh/include/CGAL/Surface_mesh/Properties.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h index 640c7221585..98d4f69184c 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h @@ -267,7 +267,7 @@ public: return *this; } - bool transfer(const Property_container& _rhs) + void transfer(const Property_container& _rhs) { for(std::size_t i=0; i Date: Tue, 14 Aug 2018 14:18:45 +0200 Subject: [PATCH 09/81] Update test with latest methods --- .../test/Point_set_3/point_set_test_join.cpp | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/Point_set_3/test/Point_set_3/point_set_test_join.cpp b/Point_set_3/test/Point_set_3/point_set_test_join.cpp index 78f6e3ee6c8..ab8d3b9da6b 100644 --- a/Point_set_3/test/Point_set_3/point_set_test_join.cpp +++ b/Point_set_3/test/Point_set_3/point_set_test_join.cpp @@ -29,15 +29,23 @@ void test (bool expr, const char* msg) } void print_point_set (const Point_set& ps, const char* msg) + { + Point_set::Property_map intensity; + bool has_intensity; + boost::tie (intensity, has_intensity) + = ps.property_map("intensity"); + std::cerr << msg << std::endl; - if (ps.has_normal_map()) - for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it) - std::cerr << *it << ": " << ps.point(*it) - << ", normal " << ps.normal(*it) << std::endl; - else - for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it) - std::cerr << *it << ": " << ps.point(*it) << std::endl; + for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it) + { + std::cerr << *it << ": " << ps.point(*it); + if (ps.has_normal_map()) + std::cerr << ", normal " << ps.normal(*it); + if (has_intensity) + std::cerr << ", intensity " << intensity[*it]; + std::cerr << std::endl; + } } @@ -62,5 +70,25 @@ int main (int, char**) ps1 += ps2; print_point_set (ps1, "JOINT PS1 = "); + Point_set ps3; + ps3.add_normal_map(); + + Point_set::Property_map intensity; + bool okay; + + boost::tie (intensity, okay) = ps3.add_property_map("intensity", 0); + assert (okay); + + Point_set::iterator it = ps3.insert (Point (double(0), double(1), double(2)), + Vector (double(3), double(4), double(5))); + intensity[*it] = 42; + + print_point_set (ps3, "PS3 = "); + ps1.copy_properties (ps3); + + print_point_set (ps1, "PS1 with PS3 properties = "); + ps1.insert (ps3, *it); + print_point_set (ps1, "PS1 with PS3 properties + PS3 item copied = "); + return EXIT_SUCCESS; }; From aece13c60958ec9dcf799dd7c42c117eb877e41c Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:30:14 +0200 Subject: [PATCH 10/81] Update user manual --- Point_set_3/include/CGAL/Point_set_3.h | 113 +++++++++++++++++++------ 1 file changed, 88 insertions(+), 25 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index c86e5251b7d..2bedb4166e5 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -55,10 +55,10 @@ namespace CGAL { The coordinates of a point can be access using the index of the point and the member function `point()`. This property is always present. The normal vector of a point can be accessed using the - index of the point and the `normal()` function. This property must + index of the point and the `normal()` method. This property must be explicitly created. - All properties can be accessed as a range using the functions + All properties can be accessed as a range using the methods `points()`, `normals()`, and `range()` for points coordinates, normal vectors, and other properties respectively. @@ -67,9 +67,9 @@ namespace CGAL { removed elements. A garbage collection method must be called to really remove it from memory. - For convenience, all functions of the package \ref PkgPointSetProcessing3Ref - are provided with an overload that takes a Point_set_3 - object as an argument. + For convenience, all functions of the package \ref + PkgPointSetProcessing automatically creates the right named + parameters if called with a `CGAL::Point_set_3` object as argument. \tparam Point Point type. @@ -286,7 +286,11 @@ public: the point set and `other`. Property maps which are only in `other` are ignored. - \note Garbage is collected in both point sets when calling this function. + \note If `copy_properties()` with `other` as argument is called + before calling this method, then all the content of `other` will + be copied and no property will be lost in the process. + + \note Garbage is collected in both point sets when calling this method. */ bool join (Point_set_3& other) { @@ -305,7 +309,7 @@ public: /*! \brief Clears the point set properties and content. - After calling this function, the object is the same as a newly + After calling this method, the object is the same as a newly constructed object. The additional properties (such as normal vectors) are also removed and must thus be re-added if needed. */ @@ -320,8 +324,8 @@ public: /*! \brief Clears all properties created. - After calling this function, all properties are removed. The - points are left unchanged. + After calling this method, all properties are removed. The points + are left unchanged. */ void clear_properties() { @@ -440,7 +444,7 @@ public: } /*! - \brief Convenience function to add a point with a normal vector. + \brief Convenience method to add a point with a normal vector. \param p Point to insert \param n Associated normal vector @@ -467,6 +471,29 @@ public: return out; } + /*! + \brief Convenience method to copy a point with all its properties + from another point set. + + In the case where two point sets have the same properties, this + method allows the user to easily copy one point (along with the + values of all its properties) from one point set to another. + + \param other Point set to which the point to copy belongs + \param idx Index of the point to copy in `other` + + \warning This point set and `other` must have the exact same + properties, with the exact same names and types in the exact same + order. + + \note If a reallocation happens, all iterators, pointers and + references related to the container are invalidated. Otherwise, + only the end iterator is invalidated, and all iterators, pointers + and references to elements are guaranteed to keep referring to the + same elements they were referring to before the call. + + \return The iterator on the newly added element. + */ iterator insert (const Point_set_3& other, const Index& idx) { iterator out = insert(); @@ -524,7 +551,7 @@ public: /// @} - /// \name Removal Functions + /// \name Removal Methods /// @{ /*! @@ -532,7 +559,8 @@ public: \note The elements are just marked as removed and are not erased from the memory. `collect_garbage()` should be called if the - memory needs to be disallocated. + memory needs to be disallocated. Elements can be recovered with + `cancel_removal()`. \note All iterators, pointers and references related to the container are invalidated. */ @@ -569,7 +597,8 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory - needs to be freed. + needs to be freed. The element can be recovered with + `cancel_removal()`. \note All iterators, pointers and references related to the container are invalidated. */ @@ -584,7 +613,8 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory - needs to be freed. + needs to be freed. The element can be recovered with + `cancel_removal()`. \note All iterators, pointers and references related to the container are invalidated. */ @@ -601,6 +631,7 @@ public: /// \name Garbage Management /// @{ + /*! \brief Returns `true` if the element is marked as removed, `false` otherwise. @@ -613,6 +644,13 @@ public: return (std::distance (it, garbage_begin()) <= 0); } + /*! + \brief Returns `true` if the element is marked as removed, `false` + otherwise. + + \note When iterating between `begin()` and `end()`, no element + marked as removed can be found. + */ bool is_removed (const Index& index) const { const_iterator it = m_indices.begin() + index; @@ -632,11 +670,15 @@ public: const_iterator garbage_end () const { return m_indices.end(); } /*! \brief Number of removed points. + + \note The method `garbage_size()` is also available and does the + same thing. */ std::size_t number_of_removed_points () const { return m_nb_removed; } /// \cond SKIP_IN_MANUAL std::size_t garbage_size () const { return number_of_removed_points(); } /// \endcond + /*! \brief Returns `true` if there are elements marked as removed, `false` otherwise. */ @@ -656,22 +698,35 @@ public: for (std::size_t i = 0; i < m_base.size(); ++ i) m_indices[i] = indices[i]; - // for (std::size_t i = 0; i < 10; ++ i) - // std::cerr << m_indices[i] << " "; - // std::cerr << std::endl; - // Sorting based on the indices reorders the point set correctly quick_sort_on_indices ((std::ptrdiff_t)0, (std::ptrdiff_t)(m_base.size() - 1)); - // for (std::size_t i = 0; i < 10; ++ i) - // std::cerr << m_indices[i] << " "; - // std::cerr << std::endl; - m_base.resize (size ()); m_base.shrink_to_fit (); m_nb_removed = 0; } + /*! + \brief Restores all removed points. + + After removing one or several points, calling this method restores + the point set to its initial state: points that were removed (and + their associated properties) are restored. + + \note This method is only guaranteed to work if no point was + inserted after the removal: otherwise, some points might not be + restored. + + \note If `collect_garbage()` was called after removal, the points + are irremediably lost and nothing will be restored. + */ + void cancel_removal() + { + m_nb_removed = 0; + for (std::size_t i = 0; i < this->m_base.size(); ++ i) + this->m_indices[i] = i; + } + /// @} @@ -840,14 +895,19 @@ public: return m_points; } - /// \cond SKIP_IN_MANUAL + /*! + \brief Copies the properties from another point set. + + All properties from `other` that do not already exist in this + point set are added and filled to their default values. Properties + that exist in both point sets are left unchanged. + */ void copy_properties (const Point_set_3& other) { m_base.copy_properties (other.base()); m_normals = this->property_map ("normal").first; // In case normal was added } - /// \endcond /*! @@ -861,6 +921,9 @@ public: return out; } + /*! + \brief Returns a vector of pairs that describe properties and associated types. + */ std::vector > properties_and_types() const { std::vector prop = m_base.properties(); @@ -1201,7 +1264,7 @@ private: Copies entries of all property maps which have the same name in `ps` and `other`. Property maps which are only in `other` are ignored. - \note Garbage is collected in both point sets when calling this function. + \note Garbage is collected in both point sets when calling this method. */ template From 7919f523ade9bd61ded995762e67e1575d9c79d5 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:30:47 +0200 Subject: [PATCH 11/81] Use new method --- Polyhedron/demo/Polyhedron/include/Point_set_3.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index 4f992825396..7afa0c01877 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -138,10 +138,7 @@ public: void reset_indices() { - unselect_all(); - - for (std::size_t i = 0; i < this->m_base.size(); ++ i) - this->m_indices[i] = i; + this->cancel_removal(); } bool add_radius() From d8854192a45556f0478c2e678a2165be6416ed75 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:45:19 +0200 Subject: [PATCH 12/81] Fix doc note about iterator invalidations --- Point_set_3/include/CGAL/Point_set_3.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 2bedb4166e5..cfc6a260b23 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -562,7 +562,8 @@ public: memory needs to be disallocated. Elements can be recovered with `cancel_removal()`. - \note All iterators, pointers and references related to the container are invalidated. + \note All iterators, pointers and references related to the + container are invalidated. */ void remove (iterator first, iterator last) { @@ -600,7 +601,8 @@ public: needs to be freed. The element can be recovered with `cancel_removal()`. - \note All iterators, pointers and references related to the container are invalidated. + \note The `end()` iterator is invalidated, `it` dereferences to a + different element. */ void remove (iterator it) { @@ -616,7 +618,8 @@ public: needs to be freed. The element can be recovered with `cancel_removal()`. - \note All iterators, pointers and references related to the container are invalidated. + \note The `end()` iterator is invalidated, `it` dereferences to a + different element. */ void remove (const Index& index) { From 797f47d68c46cf1e8f85eeab16ef02762f687de7 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 19 Sep 2018 14:34:48 +0200 Subject: [PATCH 13/81] Add useful typedefs of templates of Point_set_3 --- Point_set_3/include/CGAL/Point_set_3.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index cfc6a260b23..052363498b8 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -148,7 +148,9 @@ public: Index operator-- (int) { Index tmp(*this); -- value; return tmp; } /// \endcond }; - + + typedef Point Point_3; ///< The point type + typedef Vector Vector_3; ///< The vector type #ifdef DOXYGEN_RUNNING typedef unspecified_type iterator; ///< Iterator type of the point set with value type `Index` \cgalModels RandomAccessIterator From 7a2d545a8b08628995df949f8d40ce51b9083588 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 12 Dec 2018 10:42:31 +0100 Subject: [PATCH 14/81] Replace cancel_removal() by cancel_removals() --- Point_set_3/include/CGAL/Point_set_3.h | 8 ++++---- Polyhedron/demo/Polyhedron/include/Point_set_3.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 052363498b8..edef837243c 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -562,7 +562,7 @@ public: \note The elements are just marked as removed and are not erased from the memory. `collect_garbage()` should be called if the memory needs to be disallocated. Elements can be recovered with - `cancel_removal()`. + `cancel_removals()`. \note All iterators, pointers and references related to the container are invalidated. @@ -601,7 +601,7 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory needs to be freed. The element can be recovered with - `cancel_removal()`. + `cancel_removals()`. \note The `end()` iterator is invalidated, `it` dereferences to a different element. @@ -618,7 +618,7 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory needs to be freed. The element can be recovered with - `cancel_removal()`. + `cancel_removals()`. \note The `end()` iterator is invalidated, `it` dereferences to a different element. @@ -725,7 +725,7 @@ public: \note If `collect_garbage()` was called after removal, the points are irremediably lost and nothing will be restored. */ - void cancel_removal() + void cancel_removals() { m_nb_removed = 0; for (std::size_t i = 0; i < this->m_base.size(); ++ i) diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index 7afa0c01877..6b950dff12a 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -138,7 +138,7 @@ public: void reset_indices() { - this->cancel_removal(); + this->cancel_removals(); } bool add_radius() From 5474615dc30c2019933c5576561ca21cf0214a3b Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 13 Dec 2018 14:43:46 +0100 Subject: [PATCH 15/81] Document garbage_size() properly --- Point_set_3/include/CGAL/Point_set_3.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index edef837243c..63969ab6100 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -675,12 +675,13 @@ public: const_iterator garbage_end () const { return m_indices.end(); } /*! \brief Number of removed points. - - \note The method `garbage_size()` is also available and does the - same thing. + \sa `garbage_size()` */ std::size_t number_of_removed_points () const { return m_nb_removed; } - /// \cond SKIP_IN_MANUAL + /*! + \brief Number of removed points. + \sa `number_of_removed_points()` + */ std::size_t garbage_size () const { return number_of_removed_points(); } /// \endcond From 5ccbfdc2f313ae0b2b92099fecaf7dacdd5afd58 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 14 Dec 2018 15:10:48 +0100 Subject: [PATCH 16/81] Fix another float/double bug in Point_set_3 IO --- Point_set_3/include/CGAL/Point_set_3/IO.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 93117799195..59e46ed41ae 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -464,9 +464,18 @@ write_ply_point_set( if (prop[i] == "point") { - stream << "property double x" << std::endl - << "property double y" << std::endl - << "property double z" << std::endl; + if (boost::is_same::type, float>::value) + { + stream << "property float x" << std::endl + << "property float y" << std::endl + << "property float z" << std::endl; + } + else + { + stream << "property double x" << std::endl + << "property double y" << std::endl + << "property double z" << std::endl; + } printers.push_back (new internal::Property_printer(point_set.point_map())); continue; } From 7f7840137ac733c77286c6873fcd3d4d693a9da6 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 11 Jan 2019 10:02:39 +0100 Subject: [PATCH 17/81] Update with change of ref tag --- Point_set_3/include/CGAL/Point_set_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 63969ab6100..172c0a996b7 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -68,7 +68,7 @@ namespace CGAL { really remove it from memory. For convenience, all functions of the package \ref - PkgPointSetProcessing automatically creates the right named + PkgPointSetProcessing3 automatically creates the right named parameters if called with a `CGAL::Point_set_3` object as argument. From dd954f479c1eb92a3c8da09e40ebcdcaa14e407f Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 11 Jan 2019 13:26:10 +0100 Subject: [PATCH 18/81] Propagate API change to Point_inside_polyhedron_plugin --- .../Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp index 9625fc02fc4..ea5b0937d00 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp @@ -164,7 +164,7 @@ public Q_SLOTS: (on_boundary && res == CGAL::ON_BOUNDARY) || (outside && res == CGAL::ON_UNBOUNDED_SIDE) ) { - point_set->select(point_it); ++nb_selected; + point_set->select(*point_it); ++nb_selected; -- pt; // Selection replaces current point with unselected one selected = true; break;//loop on i From f9767943985cd896c0db086c0f3b6ef3f2998ca7 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 11 Jan 2019 13:29:48 +0100 Subject: [PATCH 19/81] Propagate API change to classification test --- .../test/Classification/test_classification_point_set.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classification/test/Classification/test_classification_point_set.cpp b/Classification/test/Classification/test_classification_point_set.cpp index f7092478a70..b444a6bbe71 100644 --- a/Classification/test/Classification/test_classification_point_set.cpp +++ b/Classification/test/Classification/test_classification_point_set.cpp @@ -50,7 +50,7 @@ int main (int, char**) Size_t_map echo_map; Color_map color_map; - map_added = pts.add_normal_map(); + map_added = pts.add_normal_map().second; assert (map_added); normal_map = pts.normal_map(); boost::tie (echo_map, map_added) = pts.add_property_map ("echo"); From 1667de6ecfb7b9771b00d933ba4dc3ed8c7abc0c Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 15 Jan 2019 10:04:54 +0100 Subject: [PATCH 20/81] Propagate API to Point Set To Distance Plugin --- .../Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp index 582335319fd..c523882f4b3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp @@ -194,7 +194,7 @@ private Q_SLOTS: it != item->point_set()->end(); ++ it) { if(distance <= distance_map[*it]) - item->point_set()->select(it); + item->point_set()->select(*it); } item->invalidateOpenGLBuffers(); item->itemChanged(); From 12dfbd635360a6562284bbca136c696f3e075bb9 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 22 Jan 2019 10:00:23 +0100 Subject: [PATCH 21/81] Reorganize PLY IO functions/files --- Point_set_3/include/CGAL/Point_set_3/IO.h | 3 +- .../include/CGAL/IO/read_ply_points.h | 620 +----------- .../include/CGAL/IO/write_ply_points.h | 245 +---- Polyhedron_IO/include/CGAL/IO/PLY_reader.h | 2 +- Polyhedron_IO/include/CGAL/IO/PLY_writer.h | 2 +- Stream_support/include/CGAL/IO/PLY.h | 891 ++++++++++++++++++ 6 files changed, 903 insertions(+), 860 deletions(-) create mode 100644 Stream_support/include/CGAL/IO/PLY.h diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 35560d89027..e3d319ac997 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -36,8 +36,7 @@ #include #include #endif // LAS -#include -#include +#include #endif // CXX11 namespace CGAL { diff --git a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h index 1dd14548a94..10abdc961a0 100644 --- a/Point_set_processing_3/include/CGAL/IO/read_ply_points.h +++ b/Point_set_processing_3/include/CGAL/IO/read_ply_points.h @@ -30,6 +30,7 @@ #include +#include #include #include #include @@ -46,36 +47,9 @@ #include #include -#define TRY_TO_GENERATE_PROPERTY(STD_TYPE, T_TYPE, TYPE) \ - if (type == STD_TYPE || type == T_TYPE) \ - m_elements.back().add_property (new PLY_read_typed_number< TYPE > (name, format)) - -#define TRY_TO_GENERATE_SIZED_LIST_PROPERTY(STD_SIZE_TYPE, T_SIZE_TYPE, SIZE_TYPE, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \ - if ((size_type == STD_SIZE_TYPE || size_type == T_SIZE_TYPE) && \ - (index_type == STD_INDEX_TYPE || index_type == T_INDEX_TYPE)) \ - m_elements.back().add_property (new PLY_read_typed_list_with_typed_size< SIZE_TYPE , INDEX_TYPE > (name, format)) - -#define TRY_TO_GENERATE_LIST_PROPERTY(STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \ - TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uchar", "uint8", boost::uint8_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \ - else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("ushort", "uint16", boost::uint16_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \ - else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uint", "uint32", boost::uint32_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) - - namespace CGAL { - -// PLY types: -// name type number of bytes -// --------------------------------------- -// char character 1 -// uchar unsigned character 1 -// short short integer 2 -// ushort unsigned short integer 2 -// int integer 4 -// uint unsigned integer 4 -// float single-precision float 4 -// double double-precision float 8 - +#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience /** \ingroup PkgPointSetProcessing3IOPly @@ -91,14 +65,6 @@ namespace CGAL { PLY_property (const char* name) : name (name) { } }; - /// \cond SKIP_IN_MANUAL - template - struct GetFTFromMap - { - typedef typename Kernel_traits::value_type>::Kernel::FT type; - }; - /// \endcond - /** \ingroup PkgPointSetProcessing3IOPly @@ -112,24 +78,10 @@ namespace CGAL { \tparam PointMap the property map used to store points. */ template -#ifdef DOXYGEN_RUNNING std::tuple::Kernel::Construct_point_3, PLY_property, PLY_property, PLY_property > -#else - std::tuple::Kernel::Construct_point_3, - PLY_property::type>, - PLY_property::type>, - PLY_property::type> > -#endif - make_ply_point_reader(PointMap point_map) - { - return std::make_tuple (point_map, typename Kernel_traits::Kernel::Construct_point_3(), - PLY_property::type>("x"), - PLY_property::type>("y"), - PLY_property::type>("z")); - } + make_ply_point_reader(PointMap point_map); /** \ingroup PkgPointSetProcessing3IOPly @@ -145,573 +97,11 @@ namespace CGAL { \tparam VectorMap the property map used to store vectors. */ template -#ifdef DOXYGEN_RUNNING std::tuple::Kernel::Construct_vector_3, PLY_property, PLY_property, PLY_property > -#else - std::tuple::Kernel::Construct_vector_3, - PLY_property::type>, - PLY_property::type>, - PLY_property::type> > -#endif - make_ply_normal_reader(VectorMap normal_map) - { - return std::make_tuple (normal_map, typename Kernel_traits::Kernel::Construct_vector_3(), - PLY_property::type>("nx"), - PLY_property::type>("ny"), - PLY_property::type>("nz")); - } - - /// \cond SKIP_IN_MANUAL - -namespace internal { - - namespace PLY { - - class PLY_read_number - { - protected: - std::string m_name; - std::size_t m_format; - - public: - PLY_read_number (std::string name, std::size_t format) - : m_name (name), m_format (format) { } - virtual ~PLY_read_number() { } - - const std::string& name () const { return m_name; } - - virtual void get (std::istream& stream) const = 0; - - // The two following functions prevent the stream to only extract - // ONE character (= what the types char imply) by requiring - // explicitely an integer object when reading the stream - void read_ascii (std::istream& stream, char& c) const - { - short s; - stream >> s; - c = static_cast(s); - } - void read_ascii (std::istream& stream, signed char& c) const - { - short s; - stream >> s; - c = static_cast(s); - } - void read_ascii (std::istream& stream, unsigned char& c) const - { - unsigned short s; - stream >> s; - c = static_cast(s); - } - - void read_ascii (std::istream& stream, float& t) const - { - stream >> iformat(t); - } - - void read_ascii (std::istream& stream, double& t) const - { - stream >> iformat(t); - } - - // Default template when Type is not a char type - template - void read_ascii (std::istream& stream, Type& t) const - { - stream >> t; - } - - - template - Type read (std::istream& stream) const - { - if (m_format == 0) // Ascii - { - Type t; - read_ascii (stream, t); - return t; - } - else // Binary (2 = little endian) - { - union - { - char uChar[sizeof (Type)]; - Type type; - } buffer; - - std::size_t size = sizeof (Type); - - stream.read(buffer.uChar, size); - - if (m_format == 2) // Big endian - { - for (std::size_t i = 0; i < size / 2; ++ i) - { - unsigned char tmp = buffer.uChar[i]; - buffer.uChar[i] = buffer.uChar[size - 1 - i]; - buffer.uChar[size - 1 - i] = tmp; - } - } - return buffer.type; - } - return Type(); - } - }; - - template - class PLY_read_typed_number : public PLY_read_number - { - mutable Type m_buffer; - public: - PLY_read_typed_number (std::string name, std::size_t format) - : PLY_read_number (name, format) - { - } - void get (std::istream& stream) const - { - m_buffer = (this->read (stream)); - } - const Type& buffer() const - { - return m_buffer; - } - }; - - template - class PLY_read_typed_list : public PLY_read_number - { - protected: - mutable std::vector m_buffer; - public: - PLY_read_typed_list (std::string name, std::size_t format) - : PLY_read_number (name, format) - { - } - virtual void get (std::istream& stream) const = 0; - - const std::vector& buffer() const - { - return m_buffer; - } - }; - - template - class PLY_read_typed_list_with_typed_size - : public PLY_read_typed_list - { - - public: - PLY_read_typed_list_with_typed_size (std::string name, std::size_t format) - : PLY_read_typed_list (name, format) - { - } - void get (std::istream& stream) const - { - std::size_t size = static_cast(this->template read(stream)); - this->m_buffer.resize (size); - for (std::size_t i = 0; i < size; ++ i) - this->m_buffer[i] = this->template read (stream); - } - }; - - class PLY_element - { - std::string m_name; - std::size_t m_number; - - std::vector m_properties; - public: - - PLY_element (const std::string& name, std::size_t number) - : m_name (name), m_number (number) - { } - - PLY_element (const PLY_element& other) - : m_name (other.m_name), m_number (other.m_number), m_properties (other.m_properties) - { - const_cast(other).m_properties.clear(); - } - - PLY_element& operator= (const PLY_element& other) - { - m_name = other.m_name; - m_number = other.m_number; - m_properties = other.m_properties; - const_cast(other).m_properties.clear(); - return *this; - } - - ~PLY_element() - { - for (std::size_t i = 0; i < m_properties.size(); ++ i) - delete m_properties[i]; - } - - const std::string& name() const { return m_name; } - std::size_t number_of_items() const { return m_number; } - std::size_t number_of_properties() const { return m_properties.size(); } - - PLY_read_number* property (std::size_t idx) { return m_properties[idx]; } - - void add_property (PLY_read_number* read_number) - { - m_properties.push_back (read_number); - } - - template - bool has_property (const char* tag) - { - return has_property (tag, Type()); - } - template - bool has_property (const char* tag, const std::vector&) - { - for (std::size_t i = 0; i < number_of_properties(); ++ i) - if (m_properties[i]->name () == tag) - return (dynamic_cast*>(m_properties[i]) != NULL); - return false; - } - - template - bool has_property (const char* tag, Type) - { - for (std::size_t i = 0; i < number_of_properties(); ++ i) - if (m_properties[i]->name () == tag) - return (dynamic_cast*>(m_properties[i]) != NULL); - return false; - } - bool has_property (const char* tag, double) - { - for (std::size_t i = 0; i < number_of_properties(); ++ i) - if (m_properties[i]->name () == tag) - return (dynamic_cast*>(m_properties[i]) != NULL - || dynamic_cast*>(m_properties[i]) != NULL); - - return false; - } - - template - void assign (Type& t, const char* tag) - { - for (std::size_t i = 0; i < number_of_properties (); ++ i) - if (m_properties[i]->name () == tag) - { - PLY_read_typed_number* - property = dynamic_cast*>(m_properties[i]); - CGAL_assertion (property != NULL); - t = property->buffer(); - return; - } - } - - template - void assign (std::vector& t, const char* tag) - { - for (std::size_t i = 0; i < number_of_properties (); ++ i) - if (m_properties[i]->name () == tag) - { - PLY_read_typed_list* - property = dynamic_cast*>(m_properties[i]); - CGAL_assertion (property != NULL); - t = property->buffer(); - return; - } - } - - void assign (double& t, const char* tag) - { - for (std::size_t i = 0; i < number_of_properties (); ++ i) - if (m_properties[i]->name () == tag) - { - PLY_read_typed_number* - property_double = dynamic_cast*>(m_properties[i]); - if (property_double == NULL) - { - PLY_read_typed_number* - property_float = dynamic_cast*>(m_properties[i]); - CGAL_assertion (property_float != NULL); - t = property_float->buffer(); - } - else - t = property_double->buffer(); - - return; - } - } - - }; - - class PLY_reader - { - std::vector m_elements; - std::string m_comments; - - public: - PLY_reader () { } - - std::size_t number_of_elements() const { return m_elements.size(); } - PLY_element& element (std::size_t idx) - { - return m_elements[idx]; - } - - const std::string& comments() const { return m_comments; } - - template - bool init (Stream& stream) - { - std::size_t lineNumber = 0; // current line number - enum Format { ASCII = 0, BINARY_LITTLE_ENDIAN = 1, BINARY_BIG_ENDIAN = 2}; - Format format = ASCII; - - std::string line; - std::istringstream iss; - - while (getline (stream,line)) - { - iss.clear(); - iss.str (line); - ++ lineNumber; - - // Reads file signature on first line - if (lineNumber == 1) - { - std::string signature; - if (!(iss >> signature) || (signature != "ply")) - { - // if wrong file format - std::cerr << "Error: incorrect file format line " << lineNumber << " of file" << std::endl; - return false; - } - } - - // Reads format on 2nd line - else if (lineNumber == 2) - { - std::string tag, format_string, version; - if ( !(iss >> tag >> format_string >> version) ) - { - std::cerr << "Error line " << lineNumber << " of file" << std::endl; - return false; - } - if (format_string == "ascii") format = ASCII; - else if (format_string == "binary_little_endian") format = BINARY_LITTLE_ENDIAN; - else if (format_string == "binary_big_endian") format = BINARY_BIG_ENDIAN; - else - { - std::cerr << "Error: unknown file format \"" << format_string << "\" line " << lineNumber << std::endl; - return false; - } - } - - // Comments and vertex properties - else - { - std::string keyword; - if (!(iss >> keyword)) - { - std::cerr << "Error line " << lineNumber << " of file" << std::endl; - return false; - } - - if (keyword == "property") - { - std::string type, name; - if (!(iss >> type >> name)) - { - std::cerr << "Error line " << lineNumber << " of file" << std::endl; - return false; - } - - - if (type == "list") // Special case - { - std::string size_type = name; - std::string index_type; - name.clear(); - if (!(iss >> index_type >> name)) - { - std::cerr << "Error line " << lineNumber << " of file" << std::endl; - return false; - } - - TRY_TO_GENERATE_LIST_PROPERTY ("char", "int8", boost::int8_t); - else TRY_TO_GENERATE_LIST_PROPERTY ("uchar", "uint8", boost::uint8_t); - else TRY_TO_GENERATE_LIST_PROPERTY ("short", "int16", boost::int16_t); - else TRY_TO_GENERATE_LIST_PROPERTY ("ushort", "uint16", boost::uint16_t); - else TRY_TO_GENERATE_LIST_PROPERTY ("int", "int32", boost::int32_t); - else TRY_TO_GENERATE_LIST_PROPERTY ("uint", "uint32", boost::uint32_t); - else TRY_TO_GENERATE_LIST_PROPERTY ("float", "float32", float); - else TRY_TO_GENERATE_LIST_PROPERTY ("double", "float64", double); - } - else - { - TRY_TO_GENERATE_PROPERTY ("char", "int8", boost::int8_t); - else TRY_TO_GENERATE_PROPERTY ("uchar", "uint8", boost::uint8_t); - else TRY_TO_GENERATE_PROPERTY ("short", "int16", boost::int16_t); - else TRY_TO_GENERATE_PROPERTY ("ushort", "uint16", boost::uint16_t); - else TRY_TO_GENERATE_PROPERTY ("int", "int32", boost::int32_t); - else TRY_TO_GENERATE_PROPERTY ("uint", "uint32", boost::uint32_t); - else TRY_TO_GENERATE_PROPERTY ("float", "float32", float); - else TRY_TO_GENERATE_PROPERTY ("double", "float64", double); - } - - continue; - } - else if (keyword == "comment") - { - std::string str = iss.str(); - if (str.size() > 8) - { - std::copy (str.begin() + 8, str.end(), std::back_inserter (m_comments)); - m_comments += "\n"; - } - } - else if (keyword == "element") - { - std::string type; - std::size_t number; - if (!(iss >> type >> number)) - { - std::cerr << "Error line " << lineNumber << " of file" << std::endl; - return false; - } - - m_elements.push_back (PLY_element(type, number)); - } - // When end_header is reached, stop loop and begin reading points - else if (keyword == "end_header") - break; - } - } - return true; - } - - ~PLY_reader () - { - } - - }; - - template - void get_value(Reader& r, T& v, PLY_property& wrapper) - { - return r.assign(v, wrapper.name); - } - - - template - struct Filler - { - template - static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers) - { - get_value(r, std::get(values), std::get(wrappers)); - Filler::fill(r, values, wrappers); - } - }; - - template - struct seq { }; - - template - struct gens : gens { }; - - template - struct gens<0, S...> { - typedef seq type; - }; - - template - ValueType call_functor(Functor f, Tuple t, seq) { - return f(std::get(t) ...); - } - - template - ValueType call_functor(Functor f, std::tuple& t) - { - return call_functor(f, t, typename gens::type()); - } - - template<> - struct Filler<0> - { - template - static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers) - { - get_value(r, std::get<0>(values), std::get<2>(wrappers)); - } - }; - - template - void process_properties (PLY_element& element, OutputValueType& new_element, - std::tuple...>&& current) - { - typedef typename PropertyMap::value_type PmapValueType; - std::tuple values; - Filler::fill(element, values, current); - PmapValueType new_value = call_functor(std::get<1>(current), values); - put (std::get<0>(current), new_element, new_value); - } - - template - void process_properties (PLY_element& element, OutputValueType& new_element, - std::tuple...>&& current, - NextPropertyBinder&& next, - PropertyMapBinders&& ... properties) - { - typedef typename PropertyMap::value_type PmapValueType; - std::tuple values; - Filler::fill(element, values, current); - PmapValueType new_value = call_functor(std::get<1>(current), values); - put (std::get<0>(current), new_element, new_value); - - process_properties (element, new_element, std::forward(next), - std::forward(properties)...); - } - - - template - void process_properties (PLY_element& element, OutputValueType& new_element, - std::pair >&& current) - { - T new_value = T(); - element.assign (new_value, current.second.name); - put (current.first, new_element, new_value); - } - - template - void process_properties (PLY_element& element, OutputValueType& new_element, - std::pair >&& current, - NextPropertyBinder&& next, - PropertyMapBinders&& ... properties) - { - T new_value = T(); - element.assign (new_value, current.second.name); - put (current.first, new_element, new_value); - process_properties (element, new_element, std::forward(next), - std::forward(properties)...); - } - - } // namespace PLY - -} // namespace internal - - - /// \endcond - + make_ply_normal_reader(VectorMap normal_map); +#endif // DOXYGEN_RUNNING /* \ingroup PkgPointSetProcessing3IOPly diff --git a/Point_set_processing_3/include/CGAL/IO/write_ply_points.h b/Point_set_processing_3/include/CGAL/IO/write_ply_points.h index 7d9886858b9..adcb8729794 100644 --- a/Point_set_processing_3/include/CGAL/IO/write_ply_points.h +++ b/Point_set_processing_3/include/CGAL/IO/write_ply_points.h @@ -30,9 +30,9 @@ #include +#include #include #include -#include #include #include @@ -45,6 +45,7 @@ namespace CGAL { +#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience /** \ingroup PkgPointSetProcessing3IOPly @@ -58,21 +59,8 @@ namespace CGAL { \tparam PointMap the property map used to store points. */ template -#ifdef DOXYGEN_RUNNING std::tuple, PLY_property, PLY_property > -#else - std::tuple::type>, - PLY_property::type>, - PLY_property::type> > -#endif - make_ply_point_writer(PointMap point_map) - { - return std::make_tuple (point_map, - PLY_property::type>("x"), - PLY_property::type>("y"), - PLY_property::type>("z")); - } + make_ply_point_writer(PointMap point_map); /** \ingroup PkgPointSetProcessing3IOPly @@ -87,21 +75,9 @@ namespace CGAL { \tparam VectorMap the property map used to store vectors. */ template -#ifdef DOXYGEN_RUNNING std::tuple, PLY_property, PLY_property > -#else - std::tuple::type>, - PLY_property::type>, - PLY_property::type> > + make_ply_normal_writer(VectorMap normal_map); #endif - make_ply_normal_writer(VectorMap normal_map) - { - return std::make_tuple (normal_map, - PLY_property::type>("nx"), - PLY_property::type>("ny"), - PLY_property::type>("nz")); - } /// \cond SKIP_IN_MANUAL @@ -109,219 +85,6 @@ namespace internal { namespace PLY { - template void property_header_type (std::ostream& stream) - { - CGAL_assertion_msg (false, "Unknown PLY type"); - stream << "undefined_type"; - } - - template <> void property_header_type (std::ostream& stream) { stream << "char"; } - template <> void property_header_type (std::ostream& stream) { stream << "char"; } - template <> void property_header_type (std::ostream& stream) { stream << "uchar"; } - template <> void property_header_type (std::ostream& stream) { stream << "short"; } - template <> void property_header_type (std::ostream& stream) { stream << "ushort"; } - template <> void property_header_type (std::ostream& stream) { stream << "int"; } - template <> void property_header_type (std::ostream& stream) { stream << "uint"; } - template <> void property_header_type (std::ostream& stream) { stream << "float"; } - template <> void property_header_type (std::ostream& stream) { stream << "double"; } - - template - void property_header (std::ostream& stream, const PLY_property& prop) - { - stream << "property "; - property_header_type(stream); - stream << " " << prop.name << std::endl; - } - - template - void property_header (std::ostream& stream, const PLY_property >& prop) - { - stream << "property list uchar "; - property_header_type(stream); - stream << " " << prop.name << std::endl; - } - - - template - struct Properties_header - { - template - static void write(std::ostream& stream, PLY_property_tuple& wrappers) - { - Properties_header::write(stream, wrappers); - property_header (stream, std::get(wrappers)); - } - }; - template <> - struct Properties_header<0> - { - template - static void write(std::ostream& stream, PLY_property_tuple& wrappers) - { - property_header (stream, std::get<1>(wrappers)); - } - }; - - template - void output_property_header (std::ostream& stream, - std::tuple... >&& current) - { - Properties_header::write(stream, current); - } - - - template - void output_property_header (std::ostream& stream, - std::pair >&& current) - { - property_header (stream, current.second); - } - - template - void output_property_header (std::ostream& stream, - std::pair >&& current, - NextPropertyHandler&& next, - PropertyHandler&& ... properties) - { - property_header (stream, current.second); - output_property_header (stream, std::forward(next), - std::forward(properties)...); - } - template - void output_property_header (std::ostream& stream, - std::tuple... >&& current, - NextPropertyHandler&& next, - PropertyHandler&& ... properties) - { - Properties_header::write(stream, current); - output_property_header (stream, std::forward(next), - std::forward(properties)...); - } - - - template - void property_write (std::ostream& stream, ForwardIterator it, PropertyMap map) - { - stream << CGAL::oformat(get (map, *it)); - } - - template - T no_char_character (const T& t) { return t; } - int no_char_character (const char& t) { return int(t); } - int no_char_character (const signed char& t) { return int(t); } - int no_char_character (const unsigned char& t) { return int(t); } - - template - void simple_property_write (std::ostream& stream, ForwardIterator it, - std::pair > map) - { - if (CGAL::get_mode(stream) == IO::ASCII) - stream << no_char_character(get (map.first, *it)); - else - { - typename PropertyMap::value_type value = get(map.first, *it); - stream.write (reinterpret_cast(&value), sizeof(value)); - } - } - - template - void simple_property_write (std::ostream& stream, ForwardIterator it, - std::pair > > map) - { - const typename PropertyMap::reference value = get(map.first, *it); - - if (CGAL::get_mode(stream) == IO::ASCII) - { - stream << value.size(); - for (std::size_t i = 0; i < value.size(); ++ i) - stream << " " << no_char_character(value[i]); - } - else - { - unsigned char size = static_cast(value.size()); - stream.write (reinterpret_cast(&size), sizeof(size)); - for (std::size_t i = 0; i < value.size(); ++ i) - { - T t = T(value[i]); - stream.write (reinterpret_cast(&t), sizeof(t)); - } - } - } - - - template - void output_properties (std::ostream& stream, - ForwardIterator it, - std::tuple... >&& current) - { - property_write (stream, it, std::get<0>(current)); - if (get_mode(stream) == IO::ASCII) - stream << std::endl; - } - - - template - void output_properties (std::ostream& stream, - ForwardIterator it, - std::pair >&& current) - { - simple_property_write (stream, it, std::forward > >(current)); - if (get_mode(stream) == IO::ASCII) - stream << std::endl; - } - - template - void output_properties (std::ostream& stream, - ForwardIterator it, - std::pair >&& current, - NextPropertyHandler&& next, - PropertyHandler&& ... properties) - { - simple_property_write (stream, it, current); - if (get_mode(stream) == IO::ASCII) - stream << " "; - output_properties (stream, it, std::forward(next), - std::forward(properties)...); - } - - template - void output_properties (std::ostream& stream, - ForwardIterator it, - std::tuple... >&& current, - NextPropertyHandler&& next, - PropertyHandler&& ... properties) - { - property_write (stream, it, std::get<0>(current)); - if (get_mode(stream) == IO::ASCII) - stream << " "; - output_properties (stream, it, std::forward(next), - std::forward(properties)...); - } } // namespace PLY diff --git a/Polyhedron_IO/include/CGAL/IO/PLY_reader.h b/Polyhedron_IO/include/CGAL/IO/PLY_reader.h index 2f7522c36fd..077a89fc374 100644 --- a/Polyhedron_IO/include/CGAL/IO/PLY_reader.h +++ b/Polyhedron_IO/include/CGAL/IO/PLY_reader.h @@ -20,7 +20,7 @@ #ifndef CGAL_IO_PLY_READER_H #define CGAL_IO_PLY_READER_H -#include +#include namespace CGAL{ diff --git a/Polyhedron_IO/include/CGAL/IO/PLY_writer.h b/Polyhedron_IO/include/CGAL/IO/PLY_writer.h index b177d071fcd..8b6f92eb4a4 100644 --- a/Polyhedron_IO/include/CGAL/IO/PLY_writer.h +++ b/Polyhedron_IO/include/CGAL/IO/PLY_writer.h @@ -20,7 +20,7 @@ #ifndef CGAL_IO_PLY_WRITER_H #define CGAL_IO_PLY_WRITER_H -#include +#include namespace CGAL{ diff --git a/Stream_support/include/CGAL/IO/PLY.h b/Stream_support/include/CGAL/IO/PLY.h new file mode 100644 index 00000000000..e907c35bb45 --- /dev/null +++ b/Stream_support/include/CGAL/IO/PLY.h @@ -0,0 +1,891 @@ +// Copyright (c) 2015 Geometry Factory +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_IO_PLY_H +#define CGAL_IO_PLY_H + +#include +#include + +#include +#include +#include +#include + +#define TRY_TO_GENERATE_PROPERTY(STD_TYPE, T_TYPE, TYPE) \ + if (type == STD_TYPE || type == T_TYPE) \ + m_elements.back().add_property (new PLY_read_typed_number< TYPE > (name, format)) + +#define TRY_TO_GENERATE_SIZED_LIST_PROPERTY(STD_SIZE_TYPE, T_SIZE_TYPE, SIZE_TYPE, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \ + if ((size_type == STD_SIZE_TYPE || size_type == T_SIZE_TYPE) && \ + (index_type == STD_INDEX_TYPE || index_type == T_INDEX_TYPE)) \ + m_elements.back().add_property (new PLY_read_typed_list_with_typed_size< SIZE_TYPE , INDEX_TYPE > (name, format)) + +#define TRY_TO_GENERATE_LIST_PROPERTY(STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \ + TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uchar", "uint8", boost::uint8_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \ + else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("ushort", "uint16", boost::uint16_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \ + else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uint", "uint32", boost::uint32_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) + + +/// \cond SKIP_IN_MANUAL + +namespace CGAL { + +// PLY types: +// name type number of bytes +// --------------------------------------- +// char character 1 +// uchar unsigned character 1 +// short short integer 2 +// ushort unsigned short integer 2 +// int integer 4 +// uint unsigned integer 4 +// float single-precision float 4 +// double double-precision float 8 + +template +struct PLY_property +{ + typedef T type; + const char* name; + PLY_property (const char* name) : name (name) { } +}; + +template +struct Get_FT_from_map +{ + typedef typename Kernel_traits::value_type>::Kernel::FT type; +}; + +template +std::tuple::Kernel::Construct_point_3, + PLY_property::type>, + PLY_property::type>, + PLY_property::type> > +make_ply_point_reader(PointMap point_map) +{ + return std::make_tuple (point_map, typename Kernel_traits::Kernel::Construct_point_3(), + PLY_property::type>("x"), + PLY_property::type>("y"), + PLY_property::type>("z")); +} + +template +std::tuple::Kernel::Construct_vector_3, + PLY_property::type>, + PLY_property::type>, + PLY_property::type> > +make_ply_normal_reader(VectorMap normal_map) +{ + return std::make_tuple (normal_map, typename Kernel_traits::Kernel::Construct_vector_3(), + PLY_property::type>("nx"), + PLY_property::type>("ny"), + PLY_property::type>("nz")); +} + +template +std::tuple::type>, + PLY_property::type>, + PLY_property::type> > +make_ply_point_writer(PointMap point_map) +{ + return std::make_tuple (point_map, + PLY_property::type>("x"), + PLY_property::type>("y"), + PLY_property::type>("z")); +} + +template +std::tuple::type>, + PLY_property::type>, + PLY_property::type> > +make_ply_normal_writer(VectorMap normal_map) +{ + return std::make_tuple (normal_map, + PLY_property::type>("nx"), + PLY_property::type>("ny"), + PLY_property::type>("nz")); +} + +namespace internal { + +namespace PLY { + +class PLY_read_number +{ +protected: + std::string m_name; + std::size_t m_format; + +public: + PLY_read_number (std::string name, std::size_t format) + : m_name (name), m_format (format) { } + virtual ~PLY_read_number() { } + + const std::string& name () const { return m_name; } + + virtual void get (std::istream& stream) const = 0; + + // The two following functions prevent the stream to only extract + // ONE character (= what the types char imply) by requiring + // explicitely an integer object when reading the stream + void read_ascii (std::istream& stream, char& c) const + { + short s; + stream >> s; + c = static_cast(s); + } + void read_ascii (std::istream& stream, signed char& c) const + { + short s; + stream >> s; + c = static_cast(s); + } + void read_ascii (std::istream& stream, unsigned char& c) const + { + unsigned short s; + stream >> s; + c = static_cast(s); + } + + void read_ascii (std::istream& stream, float& t) const + { + stream >> iformat(t); + } + + void read_ascii (std::istream& stream, double& t) const + { + stream >> iformat(t); + } + + // Default template when Type is not a char type + template + void read_ascii (std::istream& stream, Type& t) const + { + stream >> t; + } + + + template + Type read (std::istream& stream) const + { + if (m_format == 0) // Ascii + { + Type t; + read_ascii (stream, t); + return t; + } + else // Binary (2 = little endian) + { + union + { + char uChar[sizeof (Type)]; + Type type; + } buffer; + + std::size_t size = sizeof (Type); + + stream.read(buffer.uChar, size); + + if (m_format == 2) // Big endian + { + for (std::size_t i = 0; i < size / 2; ++ i) + { + unsigned char tmp = buffer.uChar[i]; + buffer.uChar[i] = buffer.uChar[size - 1 - i]; + buffer.uChar[size - 1 - i] = tmp; + } + } + return buffer.type; + } + return Type(); + } +}; + +template +class PLY_read_typed_number : public PLY_read_number +{ + mutable Type m_buffer; +public: + PLY_read_typed_number (std::string name, std::size_t format) + : PLY_read_number (name, format) + { + } + void get (std::istream& stream) const + { + m_buffer = (this->read (stream)); + } + const Type& buffer() const + { + return m_buffer; + } +}; + +template +class PLY_read_typed_list : public PLY_read_number +{ +protected: + mutable std::vector m_buffer; +public: + PLY_read_typed_list (std::string name, std::size_t format) + : PLY_read_number (name, format) + { + } + virtual void get (std::istream& stream) const = 0; + + const std::vector& buffer() const + { + return m_buffer; + } +}; + +template +class PLY_read_typed_list_with_typed_size + : public PLY_read_typed_list +{ + +public: + PLY_read_typed_list_with_typed_size (std::string name, std::size_t format) + : PLY_read_typed_list (name, format) + { + } + void get (std::istream& stream) const + { + std::size_t size = static_cast(this->template read(stream)); + this->m_buffer.resize (size); + for (std::size_t i = 0; i < size; ++ i) + this->m_buffer[i] = this->template read (stream); + } +}; + +class PLY_element +{ + std::string m_name; + std::size_t m_number; + + std::vector m_properties; +public: + + PLY_element (const std::string& name, std::size_t number) + : m_name (name), m_number (number) + { } + + PLY_element (const PLY_element& other) + : m_name (other.m_name), m_number (other.m_number), m_properties (other.m_properties) + { + const_cast(other).m_properties.clear(); + } + + PLY_element& operator= (const PLY_element& other) + { + m_name = other.m_name; + m_number = other.m_number; + m_properties = other.m_properties; + const_cast(other).m_properties.clear(); + return *this; + } + + ~PLY_element() + { + for (std::size_t i = 0; i < m_properties.size(); ++ i) + delete m_properties[i]; + } + + const std::string& name() const { return m_name; } + std::size_t number_of_items() const { return m_number; } + std::size_t number_of_properties() const { return m_properties.size(); } + + PLY_read_number* property (std::size_t idx) { return m_properties[idx]; } + + void add_property (PLY_read_number* read_number) + { + m_properties.push_back (read_number); + } + + template + bool has_property (const char* tag) + { + return has_property (tag, Type()); + } + template + bool has_property (const char* tag, const std::vector&) + { + for (std::size_t i = 0; i < number_of_properties(); ++ i) + if (m_properties[i]->name () == tag) + return (dynamic_cast*>(m_properties[i]) != NULL); + return false; + } + + template + bool has_property (const char* tag, Type) + { + for (std::size_t i = 0; i < number_of_properties(); ++ i) + if (m_properties[i]->name () == tag) + return (dynamic_cast*>(m_properties[i]) != NULL); + return false; + } + bool has_property (const char* tag, double) + { + for (std::size_t i = 0; i < number_of_properties(); ++ i) + if (m_properties[i]->name () == tag) + return (dynamic_cast*>(m_properties[i]) != NULL + || dynamic_cast*>(m_properties[i]) != NULL); + + return false; + } + + template + void assign (Type& t, const char* tag) + { + for (std::size_t i = 0; i < number_of_properties (); ++ i) + if (m_properties[i]->name () == tag) + { + PLY_read_typed_number* + property = dynamic_cast*>(m_properties[i]); + CGAL_assertion (property != NULL); + t = property->buffer(); + return; + } + } + + template + void assign (std::vector& t, const char* tag) + { + for (std::size_t i = 0; i < number_of_properties (); ++ i) + if (m_properties[i]->name () == tag) + { + PLY_read_typed_list* + property = dynamic_cast*>(m_properties[i]); + CGAL_assertion (property != NULL); + t = property->buffer(); + return; + } + } + + void assign (double& t, const char* tag) + { + for (std::size_t i = 0; i < number_of_properties (); ++ i) + if (m_properties[i]->name () == tag) + { + PLY_read_typed_number* + property_double = dynamic_cast*>(m_properties[i]); + if (property_double == NULL) + { + PLY_read_typed_number* + property_float = dynamic_cast*>(m_properties[i]); + CGAL_assertion (property_float != NULL); + t = property_float->buffer(); + } + else + t = property_double->buffer(); + + return; + } + } + +}; + +class PLY_reader +{ + std::vector m_elements; + std::string m_comments; + +public: + PLY_reader () { } + + std::size_t number_of_elements() const { return m_elements.size(); } + PLY_element& element (std::size_t idx) + { + return m_elements[idx]; + } + + const std::string& comments() const { return m_comments; } + + template + bool init (Stream& stream) + { + std::size_t lineNumber = 0; // current line number + enum Format { ASCII = 0, BINARY_LITTLE_ENDIAN = 1, BINARY_BIG_ENDIAN = 2}; + Format format = ASCII; + + std::string line; + std::istringstream iss; + + while (getline (stream,line)) + { + iss.clear(); + iss.str (line); + ++ lineNumber; + + // Reads file signature on first line + if (lineNumber == 1) + { + std::string signature; + if (!(iss >> signature) || (signature != "ply")) + { + // if wrong file format + std::cerr << "Error: incorrect file format line " << lineNumber << " of file" << std::endl; + return false; + } + } + + // Reads format on 2nd line + else if (lineNumber == 2) + { + std::string tag, format_string, version; + if ( !(iss >> tag >> format_string >> version) ) + { + std::cerr << "Error line " << lineNumber << " of file" << std::endl; + return false; + } + if (format_string == "ascii") format = ASCII; + else if (format_string == "binary_little_endian") format = BINARY_LITTLE_ENDIAN; + else if (format_string == "binary_big_endian") format = BINARY_BIG_ENDIAN; + else + { + std::cerr << "Error: unknown file format \"" << format_string << "\" line " << lineNumber << std::endl; + return false; + } + } + + // Comments and vertex properties + else + { + std::string keyword; + if (!(iss >> keyword)) + { + std::cerr << "Error line " << lineNumber << " of file" << std::endl; + return false; + } + + if (keyword == "property") + { + std::string type, name; + if (!(iss >> type >> name)) + { + std::cerr << "Error line " << lineNumber << " of file" << std::endl; + return false; + } + + + if (type == "list") // Special case + { + std::string size_type = name; + std::string index_type; + name.clear(); + if (!(iss >> index_type >> name)) + { + std::cerr << "Error line " << lineNumber << " of file" << std::endl; + return false; + } + + TRY_TO_GENERATE_LIST_PROPERTY ("char", "int8", boost::int8_t); + else TRY_TO_GENERATE_LIST_PROPERTY ("uchar", "uint8", boost::uint8_t); + else TRY_TO_GENERATE_LIST_PROPERTY ("short", "int16", boost::int16_t); + else TRY_TO_GENERATE_LIST_PROPERTY ("ushort", "uint16", boost::uint16_t); + else TRY_TO_GENERATE_LIST_PROPERTY ("int", "int32", boost::int32_t); + else TRY_TO_GENERATE_LIST_PROPERTY ("uint", "uint32", boost::uint32_t); + else TRY_TO_GENERATE_LIST_PROPERTY ("float", "float32", float); + else TRY_TO_GENERATE_LIST_PROPERTY ("double", "float64", double); + } + else + { + TRY_TO_GENERATE_PROPERTY ("char", "int8", boost::int8_t); + else TRY_TO_GENERATE_PROPERTY ("uchar", "uint8", boost::uint8_t); + else TRY_TO_GENERATE_PROPERTY ("short", "int16", boost::int16_t); + else TRY_TO_GENERATE_PROPERTY ("ushort", "uint16", boost::uint16_t); + else TRY_TO_GENERATE_PROPERTY ("int", "int32", boost::int32_t); + else TRY_TO_GENERATE_PROPERTY ("uint", "uint32", boost::uint32_t); + else TRY_TO_GENERATE_PROPERTY ("float", "float32", float); + else TRY_TO_GENERATE_PROPERTY ("double", "float64", double); + } + + continue; + } + else if (keyword == "comment") + { + std::string str = iss.str(); + if (str.size() > 8) + { + std::copy (str.begin() + 8, str.end(), std::back_inserter (m_comments)); + m_comments += "\n"; + } + } + else if (keyword == "element") + { + std::string type; + std::size_t number; + if (!(iss >> type >> number)) + { + std::cerr << "Error line " << lineNumber << " of file" << std::endl; + return false; + } + + m_elements.push_back (PLY_element(type, number)); + } + // When end_header is reached, stop loop and begin reading points + else if (keyword == "end_header") + break; + } + } + return true; + } + + ~PLY_reader () + { + } + +}; + +template +void get_value(Reader& r, T& v, PLY_property& wrapper) +{ + return r.assign(v, wrapper.name); +} + + +template +struct Filler +{ + template + static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers) + { + get_value(r, std::get(values), std::get(wrappers)); + Filler::fill(r, values, wrappers); + } +}; + +template +struct seq { }; + +template +struct gens : gens { }; + +template +struct gens<0, S...> { + typedef seq type; +}; + +template +ValueType call_functor(Functor f, Tuple t, seq) { + return f(std::get(t) ...); +} + +template +ValueType call_functor(Functor f, std::tuple& t) +{ + return call_functor(f, t, typename gens::type()); +} + +template<> +struct Filler<0> +{ + template + static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers) + { + get_value(r, std::get<0>(values), std::get<2>(wrappers)); + } +}; + +template +void process_properties (PLY_element& element, OutputValueType& new_element, + std::tuple...>&& current) +{ + typedef typename PropertyMap::value_type PmapValueType; + std::tuple values; + Filler::fill(element, values, current); + PmapValueType new_value = call_functor(std::get<1>(current), values); + put (std::get<0>(current), new_element, new_value); +} + +template +void process_properties (PLY_element& element, OutputValueType& new_element, + std::tuple...>&& current, + NextPropertyBinder&& next, + PropertyMapBinders&& ... properties) +{ + typedef typename PropertyMap::value_type PmapValueType; + std::tuple values; + Filler::fill(element, values, current); + PmapValueType new_value = call_functor(std::get<1>(current), values); + put (std::get<0>(current), new_element, new_value); + + process_properties (element, new_element, std::forward(next), + std::forward(properties)...); +} + + +template +void process_properties (PLY_element& element, OutputValueType& new_element, + std::pair >&& current) +{ + T new_value = T(); + element.assign (new_value, current.second.name); + put (current.first, new_element, new_value); +} + +template +void process_properties (PLY_element& element, OutputValueType& new_element, + std::pair >&& current, + NextPropertyBinder&& next, + PropertyMapBinders&& ... properties) +{ + T new_value = T(); + element.assign (new_value, current.second.name); + put (current.first, new_element, new_value); + process_properties (element, new_element, std::forward(next), + std::forward(properties)...); +} + +template void property_header_type (std::ostream& stream) +{ + CGAL_assertion_msg (false, "Unknown PLY type"); + stream << "undefined_type"; +} + +template <> void property_header_type (std::ostream& stream) { stream << "char"; } +template <> void property_header_type (std::ostream& stream) { stream << "char"; } +template <> void property_header_type (std::ostream& stream) { stream << "uchar"; } +template <> void property_header_type (std::ostream& stream) { stream << "short"; } +template <> void property_header_type (std::ostream& stream) { stream << "ushort"; } +template <> void property_header_type (std::ostream& stream) { stream << "int"; } +template <> void property_header_type (std::ostream& stream) { stream << "uint"; } +template <> void property_header_type (std::ostream& stream) { stream << "float"; } +template <> void property_header_type (std::ostream& stream) { stream << "double"; } + +template +void property_header (std::ostream& stream, const PLY_property& prop) +{ + stream << "property "; + property_header_type(stream); + stream << " " << prop.name << std::endl; +} + +template +void property_header (std::ostream& stream, const PLY_property >& prop) +{ + stream << "property list uchar "; + property_header_type(stream); + stream << " " << prop.name << std::endl; +} + + +template +struct Properties_header +{ + template + static void write(std::ostream& stream, PLY_property_tuple& wrappers) + { + Properties_header::write(stream, wrappers); + property_header (stream, std::get(wrappers)); + } +}; +template <> +struct Properties_header<0> +{ + template + static void write(std::ostream& stream, PLY_property_tuple& wrappers) + { + property_header (stream, std::get<1>(wrappers)); + } +}; + +template +void output_property_header (std::ostream& stream, + std::tuple... >&& current) +{ + Properties_header::write(stream, current); +} + + +template +void output_property_header (std::ostream& stream, + std::pair >&& current) +{ + property_header (stream, current.second); +} + +template +void output_property_header (std::ostream& stream, + std::pair >&& current, + NextPropertyHandler&& next, + PropertyHandler&& ... properties) +{ + property_header (stream, current.second); + output_property_header (stream, std::forward(next), + std::forward(properties)...); +} +template +void output_property_header (std::ostream& stream, + std::tuple... >&& current, + NextPropertyHandler&& next, + PropertyHandler&& ... properties) +{ + Properties_header::write(stream, current); + output_property_header (stream, std::forward(next), + std::forward(properties)...); +} + + +template +void property_write (std::ostream& stream, ForwardIterator it, PropertyMap map) +{ + stream << CGAL::oformat(get (map, *it)); +} + +template +T no_char_character (const T& t) { return t; } +int no_char_character (const char& t) { return int(t); } +int no_char_character (const signed char& t) { return int(t); } +int no_char_character (const unsigned char& t) { return int(t); } + +template +void simple_property_write (std::ostream& stream, ForwardIterator it, + std::pair > map) +{ + if (CGAL::get_mode(stream) == IO::ASCII) + stream << no_char_character(get (map.first, *it)); + else + { + typename PropertyMap::value_type value = get(map.first, *it); + stream.write (reinterpret_cast(&value), sizeof(value)); + } +} + +template +void simple_property_write (std::ostream& stream, ForwardIterator it, + std::pair > > map) +{ + const typename PropertyMap::reference value = get(map.first, *it); + + if (CGAL::get_mode(stream) == IO::ASCII) + { + stream << value.size(); + for (std::size_t i = 0; i < value.size(); ++ i) + stream << " " << no_char_character(value[i]); + } + else + { + unsigned char size = static_cast(value.size()); + stream.write (reinterpret_cast(&size), sizeof(size)); + for (std::size_t i = 0; i < value.size(); ++ i) + { + T t = T(value[i]); + stream.write (reinterpret_cast(&t), sizeof(t)); + } + } +} + + +template +void output_properties (std::ostream& stream, + ForwardIterator it, + std::tuple... >&& current) +{ + property_write (stream, it, std::get<0>(current)); + if (get_mode(stream) == IO::ASCII) + stream << std::endl; +} + + +template +void output_properties (std::ostream& stream, + ForwardIterator it, + std::pair >&& current) +{ + simple_property_write (stream, it, std::forward > >(current)); + if (get_mode(stream) == IO::ASCII) + stream << std::endl; +} + +template +void output_properties (std::ostream& stream, + ForwardIterator it, + std::pair >&& current, + NextPropertyHandler&& next, + PropertyHandler&& ... properties) +{ + simple_property_write (stream, it, current); + if (get_mode(stream) == IO::ASCII) + stream << " "; + output_properties (stream, it, std::forward(next), + std::forward(properties)...); +} + +template +void output_properties (std::ostream& stream, + ForwardIterator it, + std::tuple... >&& current, + NextPropertyHandler&& next, + PropertyHandler&& ... properties) +{ + property_write (stream, it, std::get<0>(current)); + if (get_mode(stream) == IO::ASCII) + stream << " "; + output_properties (stream, it, std::forward(next), + std::forward(properties)...); +} + +} // namespace PLY + +} // namespace internal + +} // namespace CGAL + + +#endif // CGAL_IO_PLY_H From 6789ca1c41542545893a512d5774bd3b6fbf01f5 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 23 Jan 2019 11:25:35 +0100 Subject: [PATCH 22/81] Some more modifications of the PLY interface --- Point_set_3/include/CGAL/Point_set_3/IO.h | 123 ++++++---------------- Stream_support/include/CGAL/IO/PLY.h | 102 +++++++++++++++--- 2 files changed, 118 insertions(+), 107 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index e3d319ac997..f21ff38cd9e 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -43,80 +43,6 @@ namespace CGAL { namespace internal { - - template - class Abstract_property_printer - { - public: - virtual ~Abstract_property_printer() { } - virtual void print (std::ostream& stream, const typename CGAL::Point_set_3::Index& index) = 0; - }; - - template - class Property_printer : public Abstract_property_printer - { - typedef typename CGAL::Point_set_3 Point_set; - typedef typename Point_set::template Property_map Pmap; - Pmap m_pmap; - public: - Property_printer (const Pmap& pmap) : m_pmap (pmap) - { - - } - - virtual void print(std::ostream& stream, const typename CGAL::Point_set_3::Index& index) - { - stream << get(m_pmap, index); - } - }; - - template - class Simple_property_printer : public Abstract_property_printer - { - typedef typename CGAL::Point_set_3 Point_set; - typedef typename Point_set::template Property_map Pmap; - Pmap m_pmap; - public: - Simple_property_printer (const Pmap& pmap) : m_pmap (pmap) - { - - } - - virtual void print(std::ostream& stream, const typename CGAL::Point_set_3::Index& index) - { - if (get_mode(stream) == IO::ASCII) - stream << get(m_pmap, index); - else - { - Type t = get (m_pmap, index); - stream.write (reinterpret_cast(&t), sizeof(t)); - } - } - }; - - template - class Char_property_printer : public Abstract_property_printer - { - typedef typename CGAL::Point_set_3 Point_set; - typedef typename Point_set::template Property_map Pmap; - Pmap m_pmap; - public: - Char_property_printer (const Pmap& pmap) : m_pmap (pmap) - { - - } - - virtual void print(std::ostream& stream, const typename CGAL::Point_set_3::Index& index) - { - if (get_mode(stream) == IO::ASCII) - stream << int(get(m_pmap, index)); - else - { - Type t = get (m_pmap, index); - stream.write (reinterpret_cast(&t), sizeof(t)); - } - } - }; #if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) namespace PLY @@ -405,7 +331,8 @@ read_ply_point_set( { internal::PLY::PLY_element& element = reader.element(i); - if (element.name() == "vertex" || element.name() == "vertices") + bool is_vertex = (element.name() == "vertex" || element.name() == "vertices"); + if (is_vertex) { point_set.reserve (element.number_of_items()); filler.instantiate_properties (element); @@ -421,7 +348,7 @@ read_ply_point_set( return false; } - if (element.name() == "vertex" || element.name() == "vertices") + if (is_vertex) filler.process_line (element); } } @@ -444,6 +371,16 @@ write_ply_point_set( #endif { typedef CGAL::Point_set_3 Point_set; + typedef typename Point_set::Index Index; + typedef typename Point_set::Point_map Point_map; + typedef typename Point_set::Vector_map Vector_map; + typedef typename Point_set::template Property_map Int8_map; + typedef typename Point_set::template Property_map Uint8_map; + typedef typename Point_set::template Property_map Int16_map; + typedef typename Point_set::template Property_map Uint16_map; + typedef typename Point_set::template Property_map Int32_map; + typedef typename Point_set::template Property_map Float_map; + typedef typename Point_set::template Property_map Double_map; stream << "ply" << std::endl << ((get_mode(stream) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl @@ -463,7 +400,7 @@ write_ply_point_set( stream << "element vertex " << point_set.number_of_points() << std::endl; std::vector prop = point_set.base().properties(); - std::vector*> printers; + std::vector*> printers; for (std::size_t i = 0; i < prop.size(); ++ i) { @@ -475,7 +412,7 @@ write_ply_point_set( stream << "property double x" << std::endl << "property double y" << std::endl << "property double z" << std::endl; - printers.push_back (new internal::Property_printer(point_set.point_map())); + printers.push_back (new internal::PLY::Property_printer(point_set.point_map())); continue; } if (prop[i] == "normal") @@ -483,78 +420,78 @@ write_ply_point_set( stream << "property double nx" << std::endl << "property double ny" << std::endl << "property double nz" << std::endl; - printers.push_back (new internal::Property_printer(point_set.normal_map())); + printers.push_back (new internal::PLY::Property_printer(point_set.normal_map())); continue; } bool okay = false; { - typename Point_set::template Property_map pmap; + Int8_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); if (okay) { stream << "property char " << prop[i] << std::endl; - printers.push_back (new internal::Char_property_printer(pmap)); + printers.push_back (new internal::PLY::Char_property_printer(pmap)); continue; } } { - typename Point_set::template Property_map pmap; + Uint8_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); if (okay) { stream << "property uchar " << prop[i] << std::endl; - printers.push_back (new internal::Char_property_printer(pmap)); + printers.push_back (new internal::PLY::Char_property_printer(pmap)); continue; } } { - typename Point_set::template Property_map pmap; + Int16_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); if (okay) { stream << "property short " << prop[i] << std::endl; - printers.push_back (new internal::Simple_property_printer(pmap)); + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } } { - typename Point_set::template Property_map pmap; + Uint16_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); if (okay) { stream << "property ushort " << prop[i] << std::endl; - printers.push_back (new internal::Simple_property_printer(pmap)); + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } } { - typename Point_set::template Property_map pmap; + Int32_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); if (okay) { stream << "property int " << prop[i] << std::endl; - printers.push_back (new internal::Simple_property_printer(pmap)); + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } } { - typename Point_set::template Property_map pmap; + Float_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); if (okay) { stream << "property float " << prop[i] << std::endl; - printers.push_back (new internal::Simple_property_printer(pmap)); + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } } { - typename Point_set::template Property_map pmap; + Double_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); if (okay) { stream << "property double " << prop[i] << std::endl; - printers.push_back (new internal::Simple_property_printer(pmap)); + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } } diff --git a/Stream_support/include/CGAL/IO/PLY.h b/Stream_support/include/CGAL/IO/PLY.h index e907c35bb45..32eab0d9011 100644 --- a/Stream_support/include/CGAL/IO/PLY.h +++ b/Stream_support/include/CGAL/IO/PLY.h @@ -667,21 +667,21 @@ void process_properties (PLY_element& element, OutputValueType& new_element, std::forward(properties)...); } -template void property_header_type (std::ostream& stream) +template inline void property_header_type (std::ostream& stream) { CGAL_assertion_msg (false, "Unknown PLY type"); stream << "undefined_type"; } -template <> void property_header_type (std::ostream& stream) { stream << "char"; } -template <> void property_header_type (std::ostream& stream) { stream << "char"; } -template <> void property_header_type (std::ostream& stream) { stream << "uchar"; } -template <> void property_header_type (std::ostream& stream) { stream << "short"; } -template <> void property_header_type (std::ostream& stream) { stream << "ushort"; } -template <> void property_header_type (std::ostream& stream) { stream << "int"; } -template <> void property_header_type (std::ostream& stream) { stream << "uint"; } -template <> void property_header_type (std::ostream& stream) { stream << "float"; } -template <> void property_header_type (std::ostream& stream) { stream << "double"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "char"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "char"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "uchar"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "short"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "ushort"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "int"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "uint"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "float"; } +template <> inline void property_header_type (std::ostream& stream) { stream << "double"; } template void property_header (std::ostream& stream, const PLY_property& prop) @@ -773,10 +773,10 @@ void property_write (std::ostream& stream, ForwardIterator it, PropertyMap map) } template -T no_char_character (const T& t) { return t; } -int no_char_character (const char& t) { return int(t); } -int no_char_character (const signed char& t) { return int(t); } -int no_char_character (const unsigned char& t) { return int(t); } +inline T no_char_character (const T& t) { return t; } +inline int no_char_character (const char& t) { return int(t); } +inline int no_char_character (const signed char& t) { return int(t); } +inline int no_char_character (const unsigned char& t) { return int(t); } template (properties)...); } + +// Printer classes used by Point_set_3 and Surface_mesh (translate a +// property map to a PLY property) + +template +class Abstract_property_printer +{ +public: + virtual ~Abstract_property_printer() { } + virtual void print (std::ostream& stream, const Index& index) = 0; +}; + +template +class Property_printer : public Abstract_property_printer +{ + PropertyMap m_pmap; +public: + Property_printer (const PropertyMap& pmap) : m_pmap (pmap) + { + + } + + virtual void print(std::ostream& stream, const Index& index) + { + stream << get(m_pmap, index); + } +}; + +template +class Simple_property_printer : public Abstract_property_printer +{ + typedef typename PropertyMap::value_type Type; + PropertyMap m_pmap; +public: + Simple_property_printer (const PropertyMap& pmap) : m_pmap (pmap) + { + + } + + virtual void print(std::ostream& stream, const Index& index) + { + if (get_mode(stream) == IO::ASCII) + stream << get(m_pmap, index); + else + { + Type t = get (m_pmap, index); + stream.write (reinterpret_cast(&t), sizeof(t)); + } + } +}; + +template +class Char_property_printer : public Abstract_property_printer +{ + typedef typename PropertyMap::value_type Type; + PropertyMap m_pmap; +public: + Char_property_printer (const PropertyMap& pmap) : m_pmap (pmap) + { + + } + + virtual void print(std::ostream& stream, const Index& index) + { + if (get_mode(stream) == IO::ASCII) + stream << int(get(m_pmap, index)); + else + { + Type t = get (m_pmap, index); + stream.write (reinterpret_cast(&t), sizeof(t)); + } + } +}; + } // namespace PLY } // namespace internal From a15b4cdf4af1ad0b0588d3b088f7464d6cea1a0e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 23 Jan 2019 11:26:07 +0100 Subject: [PATCH 23/81] Add PLY IO functions for Surface_mesh + test --- .../include/CGAL/Surface_mesh/IO/PLY.h | 260 +++++++++++++ .../include/CGAL/Surface_mesh/Surface_mesh.h | 348 ++++++++++++++++++ .../test/Surface_mesh/colored_tetra.ply | 20 + Surface_mesh/test/Surface_mesh/sm_ply_io.cpp | 39 ++ 4 files changed, 667 insertions(+) create mode 100644 Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h create mode 100644 Surface_mesh/test/Surface_mesh/colored_tetra.ply create mode 100644 Surface_mesh/test/Surface_mesh/sm_ply_io.cpp diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h new file mode 100644 index 00000000000..b472a24cb49 --- /dev/null +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h @@ -0,0 +1,260 @@ +// Copyright (c) 2018 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Simon Giraudot + +#ifndef CGAL_SURFACE_MESH_IO_PLY +#define CGAL_SURFACE_MESH_IO_PLY + +#include + +namespace CGAL { + +namespace internal { + +#if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) +namespace PLY { + +template +class Surface_mesh_filler +{ +public: + typedef Surface_mesh Surface_mesh; + typedef typename Surface_mesh::Vertex_index Vertex_index; + typedef typename Surface_mesh::Face_index Face_index; + +private: + + struct Abstract_ply_property_to_surface_mesh_property + { + virtual ~Abstract_ply_property_to_surface_mesh_property() { } + virtual void assign (PLY_element& element, std::size_t index) = 0; + }; + + template + class PLY_property_to_surface_mesh_property : public Abstract_ply_property_to_surface_mesh_property + { + typedef typename Surface_mesh::template Property_map Map; + Map m_map; + std::string m_name; + public: + PLY_property_to_surface_mesh_property (Surface_mesh& sm, const std::string& name) + : m_name (name) + { + m_map = sm.template add_property_map(name).first; + } + + virtual void assign (PLY_element& element, std::size_t index) + { + Type t{}; + element.assign (t, m_name.c_str()); + put(m_map, Simplex(index), t); + } + }; + + Surface_mesh& m_mesh; + bool m_use_floats; + bool m_use_int32_t; + std::string m_index_tag; + std::vector m_vertex_properties; + std::vector m_face_properties; + +public: + + Surface_mesh_filler (Surface_mesh& mesh) + : m_mesh (mesh), m_use_floats (false) + { } + + ~Surface_mesh_filler() + { + for (std::size_t i = 0; i < m_vertex_properties.size(); ++ i) + delete m_vertex_properties[i]; + for (std::size_t i = 0; i < m_face_properties.size(); ++ i) + delete m_face_properties[i]; + } + + bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Vertex_index) + { + const std::string& name = property->name(); + if (name == "x" || + name == "y" || + name == "z") + { + if (dynamic_cast*>(property)) + m_use_floats = true; + return true; + } + return false; + } + + bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Face_index) + { + const std::string& name = property->name(); + if (name == "vertex_indices" || name == "vertex_index") + { + m_index_tag = name; + m_use_int32_t = dynamic_cast*>(property); + CGAL_assertion (dynamic_cast*>(property)); + return true; + } + + return false; + } + + void instantiate_vertex_properties (PLY_element& element) + { + instantiate_properties (element, m_vertex_properties); + } + + void instantiate_face_properties (PLY_element& element) + { + instantiate_properties (element, m_face_properties); + } + + template + void instantiate_properties (PLY_element& element, + std::vector& properties) + { + for (std::size_t j = 0; j < element.number_of_properties(); ++ j) + { + internal::PLY::PLY_read_number* property = element.property(j); + + if (has_simplex_specific_property (property, Simplex())) + continue; + + const std::string& name = property->name(); + + if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + else if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + else if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + else if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + else if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + else if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + else if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + else if (dynamic_cast*>(property)) + { + properties.push_back + (new PLY_property_to_surface_mesh_property(m_mesh, + name)); + } + } + } + + void process_vertex_line (PLY_element& element) + { + Vertex_index vi; + + if (m_use_floats) + process_line(element, vi); + else + process_line(element, vi); + + for (std::size_t i = 0; i < m_vertex_properties.size(); ++ i) + m_vertex_properties[i]->assign (element, vi); + } + + template + void process_line (PLY_element& element, Vertex_index& vi) + { + FT x = (FT)0.,y = (FT)0., z = (FT)0.; + element.assign (x, "x"); + element.assign (y, "y"); + element.assign (z, "z"); + Point point (x, y, z); + vi = m_mesh.add_vertex(point); + } + + bool process_face_line (PLY_element& element) + { + Face_index fi; + + if (m_use_int32_t) + process_line(element, fi); + else + process_line(element, fi); + + if (fi == Surface_mesh::null_face()) + return false; + + for (std::size_t i = 0; i < m_face_properties.size(); ++ i) + m_face_properties[i]->assign (element, fi); + + return true; + } + + template + void process_line (PLY_element& element, Face_index& fi) + { + std::vector indices; + element.assign (indices, m_index_tag.c_str()); + std::vector vertices; + vertices.reserve(indices.size()); + for (std::size_t i = 0; i < indices.size(); ++ i) + vertices.push_back (Vertex_index (indices[i])); + + fi = m_mesh.add_face(vertices); + } + +}; + + +} // namespace PLY +#endif + +} // namespace internal + +} // namespace CGAL + + +#endif // CGAL_SURFACE_MESH_IO_PLY diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index f702688ff08..ba81637e146 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -2156,6 +2157,286 @@ private: //------------------------------------------------------- private data return os; } +#if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) + template +#ifdef DOXYGEN_RUNNING + bool write_ply(std::ostream& os, const Surface_mesh

& sm) +#else + bool write_ply(std::ostream& os, const Surface_mesh

& sm, std::string* comments = NULL) +#endif + { + typedef Surface_mesh

SMesh; + typedef typename SMesh::Vertex_index VIndex; + typedef typename SMesh::Face_index FIndex; + typedef typename SMesh::Halfedge_index HIndex; + typedef typename SMesh::template Property_map Point_map; + + typedef typename SMesh::template Property_map Int8_map_v; + typedef typename SMesh::template Property_map Uint8_map_v; + typedef typename SMesh::template Property_map Int16_map_v; + typedef typename SMesh::template Property_map Uint16_map_v; + typedef typename SMesh::template Property_map Int32_map_v; + typedef typename SMesh::template Property_map Float_map_v; + typedef typename SMesh::template Property_map Double_map_v; + + typedef typename SMesh::template Property_map Int8_map_f; + typedef typename SMesh::template Property_map Uint8_map_f; + typedef typename SMesh::template Property_map Int16_map_f; + typedef typename SMesh::template Property_map Uint16_map_f; + typedef typename SMesh::template Property_map Int32_map_f; + typedef typename SMesh::template Property_map Float_map_f; + typedef typename SMesh::template Property_map Double_map_f; + + os << "ply" << std::endl + << ((get_mode(os) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl + << "comment Generated by the CGAL library" << std::endl; + + if (comments != NULL) + { + std::istringstream iss (*comments); + std::string line; + while (getline(iss, line)) + { + if (line != "Generated by the CGAL library") // Avoid repeating the line if multiple savings + os << "comment " << line << std::endl; + } + } + + os << "element vertex " << sm.number_of_vertices() << std::endl; + std::vector vprop = sm.template properties(); + std::vector*> vprinters; + + for (std::size_t i = 0; i < vprop.size(); ++ i) + { + if (vprop[i] == "v:connectivity" || + vprop[i] == "v:removed") + continue; + + if (vprop[i] == "v:point") + { + os << "property double x" << std::endl + << "property double y" << std::endl + << "property double z" << std::endl; + vprinters.push_back (new internal::PLY::Property_printer(sm.points())); + continue; + } + + bool okay = false; + { + Int8_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property char " << vprop[i] << std::endl; + vprinters.push_back (new internal::PLY::Char_property_printer(pmap)); + continue; + } + } + { + Uint8_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property uchar " << vprop[i] << std::endl; + vprinters.push_back (new internal::PLY::Char_property_printer(pmap)); + continue; + } + } + { + Int16_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property short " << vprop[i] << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint16_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property ushort " << vprop[i] << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Int32_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property int " << vprop[i] << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Float_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property float " << vprop[i] << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Double_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property double " << vprop[i] << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + } + + os << "element face " << sm.number_of_faces() << std::endl; + os << "property list uchar int vertex_indices" << std::endl; + std::vector fprop = sm.template properties(); + std::vector*> fprinters; + + for (std::size_t i = 0; i < fprop.size(); ++ i) + { + if (fprop[i] == "f:connectivity" || + fprop[i] == "f:removed") + continue; + + bool okay = false; + { + Int8_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property char " << fprop[i] << std::endl; + fprinters.push_back (new internal::PLY::Char_property_printer(pmap)); + continue; + } + } + { + Uint8_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property uchar " << fprop[i] << std::endl; + fprinters.push_back (new internal::PLY::Char_property_printer(pmap)); + continue; + } + } + { + Int16_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property short " << fprop[i] << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint16_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property ushort " << fprop[i] << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Int32_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property int " << fprop[i] << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Float_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property float " << fprop[i] << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Double_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property double " << fprop[i] << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + } + + os << "end_header" << std::endl; + + BOOST_FOREACH(VIndex vi, sm.vertices()) + { + for (std::size_t i = 0; i < vprinters.size(); ++ i) + { + vprinters[i]->print(os, vi); + if (get_mode (os) == IO::ASCII) + os << " "; + } + if (get_mode (os) == IO::ASCII) + os << std::endl; + } + + std::vector polygon; + + BOOST_FOREACH(FIndex fi, sm.faces()) + { + // Get list of vertex indices + polygon.clear(); + BOOST_FOREACH(HIndex hi, halfedges_around_face(halfedge(fi, sm), sm)) + polygon.push_back (sm.target(hi)); + + if (get_mode (os) == IO::ASCII) + { + os << polygon.size() << " "; + for (std::size_t i = 0; i < polygon.size(); ++ i) + os << int(polygon[i]) << " "; + } + else + { + unsigned char size = (unsigned char)(polygon.size()); + os.write (reinterpret_cast(&size), sizeof(size)); + for (std::size_t i = 0; i < polygon.size(); ++ i) + { + int idx = int(polygon[i]); + os.write (reinterpret_cast(&idx), sizeof(idx)); + } + } + + for (std::size_t i = 0; i < fprinters.size(); ++ i) + { + fprinters[i]->print(os, fi); + if (get_mode (os) == IO::ASCII) + os << " "; + } + + if (get_mode (os) == IO::ASCII) + os << std::endl; + } + + for (std::size_t i = 0; i < vprinters.size(); ++ i) + delete vprinters[i]; + for (std::size_t i = 0; i < fprinters.size(); ++ i) + delete fprinters[i]; + + return true; + } +#endif /// @cond CGAL_DOCUMENT_INTERNALS @@ -2316,6 +2597,73 @@ private: //------------------------------------------------------- private data return read_off(is, sm, parameters::all_default()); } +#if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) + template +#ifdef DOXYGEN_RUNNING + bool read_ply(std::istream& is, Surface_mesh

& sm) +#else + bool read_ply(std::istream& is, Surface_mesh

& sm, std::string* comments = NULL) +#endif + { + if(!is) + { + std::cerr << "Error: cannot open file" << std::endl; + return false; + } + + internal::PLY::PLY_reader reader; + internal::PLY::Surface_mesh_filler

filler(sm); + + if (!(reader.init (is))) + { + is.setstate(std::ios::failbit); + return false; + } + + if (comments != NULL) + *comments = reader.comments(); + + for (std::size_t i = 0; i < reader.number_of_elements(); ++ i) + { + internal::PLY::PLY_element& element = reader.element(i); + + bool is_vertex = (element.name() == "vertex" || element.name() == "vertices"); + bool is_face = false; + if (is_vertex) + filler.instantiate_vertex_properties (element); + else + is_face = (element.name() == "face" || element.name() == "faces"); + + if (is_face) + filler.instantiate_face_properties (element); + + for (std::size_t j = 0; j < element.number_of_items(); ++ j) + { + for (std::size_t k = 0; k < element.number_of_properties(); ++ k) + { + internal::PLY::PLY_read_number* property = element.property(k); + property->get (is); + if (is.fail()) + return false; + } + + if (is_vertex) + filler.process_vertex_line (element); + else if (is_face) + { + if (!filler.process_face_line (element)) + { + is.setstate(std::ios::failbit); + return false; + } + } + } + } + + return true; + } +#endif + /// \relates Surface_mesh /// This operator calls `read_off(std::istream& is, CGAL::Surface_mesh& sm)`. /// \attention Up to %CGAL 4.10 this operator called `sm.clear()`. diff --git a/Surface_mesh/test/Surface_mesh/colored_tetra.ply b/Surface_mesh/test/Surface_mesh/colored_tetra.ply new file mode 100644 index 00000000000..a13165c80e2 --- /dev/null +++ b/Surface_mesh/test/Surface_mesh/colored_tetra.ply @@ -0,0 +1,20 @@ +ply +format ascii 1.0 +element vertex 4 +property double x +property double y +property double z +element face 4 +property list uchar int vertex_indices +property uchar red +property uchar green +property uchar blue +end_header +0 0 0 +0 0 1 +0 1 0 +1 0 0 +3 0 1 2 255 0 0 +3 0 3 1 0 255 0 +3 1 3 2 0 0 255 +3 0 2 3 255 0 255 diff --git a/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp b/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp new file mode 100644 index 00000000000..2b846cc7f7b --- /dev/null +++ b/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh SMesh; +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + + +int main() +{ + std::ifstream in ("colored_tetra.ply"); + SMesh mesh; + CGAL::read_ply (in, mesh); + + std::cerr << "Read mesh with " << mesh.number_of_vertices() << " vertices and " + << mesh.number_of_faces() << " faces" << std::endl; + + std::cerr << "Properties associated with vertices:" << std::endl; + std::vector properties = mesh.properties(); + for (std::size_t i = 0; i < properties.size(); ++ i) + std::cerr << " * " << properties[i] << std::endl; + + std::cerr << "Properties associated with faces:" << std::endl; + properties = mesh.properties(); + for (std::size_t i = 0; i < properties.size(); ++ i) + std::cerr << " * " << properties[i] << std::endl; + + + std::ofstream out ("out.ply"); + CGAL::set_binary_mode(out); + CGAL::write_ply (out, mesh); + + return 0; +} From cf1fb8c3b085f257e7913381185759d8c5a0ed3e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 23 Jan 2019 12:25:41 +0100 Subject: [PATCH 24/81] Handle float Kernel --- .../include/CGAL/Surface_mesh/Surface_mesh.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index ba81637e146..e9e082df793 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2214,9 +2214,18 @@ private: //------------------------------------------------------- private data if (vprop[i] == "v:point") { - os << "property double x" << std::endl - << "property double y" << std::endl - << "property double z" << std::endl; + if (boost::is_same::type, float>::value) + { + os << "property float x" << std::endl + << "property float y" << std::endl + << "property float z" << std::endl; + } + else + { + os << "property double x" << std::endl + << "property double y" << std::endl + << "property double z" << std::endl; + } vprinters.push_back (new internal::PLY::Property_printer(sm.points())); continue; } From 0d2f06d8a951615241b1b4ca4f084ba4a4df77d4 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 23 Jan 2019 13:52:12 +0100 Subject: [PATCH 25/81] Update PLY plugin with new Surface_mesh PLY IO functions --- .../Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 174 +++++++++++++----- 1 file changed, 130 insertions(+), 44 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index 0a57fac8fee..34256cc9aeb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -37,32 +37,112 @@ public: bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); private: - void set_vcolors(SMesh* smesh, const std::vector& colors) + void set_vcolors(SMesh* smesh) { - typedef SMesh SMesh; typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - SMesh::Property_map vcolors = - smesh->property_map("v:color").first; - bool created; - boost::tie(vcolors, created) = smesh->add_property_map("v:color",CGAL::Color(0,0,0)); - assert(colors.size()==smesh->number_of_vertices()); - int color_id = 0; + typedef SMesh::Property_map Color_map; + typedef SMesh::Property_map Uchar_map; + + Uchar_map r, g, b; + bool okay = false; + boost::tie (r, okay) = smesh->property_map("red"); + if (!okay) + return; + boost::tie (g, okay) = smesh->property_map("green"); + if (!okay) + return; + boost::tie (b, okay) = smesh->property_map("blue"); + if (!okay) + return; + + SMesh::Property_map vcolors + = smesh->add_property_map("v:color",CGAL::Color(0,0,0)).first; + BOOST_FOREACH(vertex_descriptor vd, vertices(*smesh)) - vcolors[vd] = colors[color_id++]; + vcolors[vd] = CGAL::Color (r[vd], g[vd], b[vd]); + + smesh->remove_property_map(r); + smesh->remove_property_map(g); + smesh->remove_property_map(b); } - void set_fcolors(SMesh* smesh, const std::vector& colors) + void set_fcolors(SMesh* smesh) { - typedef SMesh SMesh; typedef boost::graph_traits::face_descriptor face_descriptor; - SMesh::Property_map fcolors = - smesh->property_map("f:color").first; - bool created; - boost::tie(fcolors, created) = smesh->add_property_map("f:color",CGAL::Color(0,0,0)); - assert(colors.size()==smesh->number_of_faces()); - int color_id = 0; + typedef SMesh::Property_map Color_map; + typedef SMesh::Property_map Uchar_map; + + Uchar_map r, g, b; + bool okay = false; + boost::tie (r, okay) = smesh->property_map("red"); + if (!okay) + return; + boost::tie (g, okay) = smesh->property_map("green"); + if (!okay) + return; + boost::tie (b, okay) = smesh->property_map("blue"); + if (!okay) + return; + + SMesh::Property_map fcolors + = smesh->add_property_map("f:color",CGAL::Color(0,0,0)).first; + BOOST_FOREACH(face_descriptor fd, faces(*smesh)) - fcolors[fd] = colors[color_id++]; + fcolors[fd] = CGAL::Color (r[fd], g[fd], b[fd]); + + smesh->remove_property_map(r); + smesh->remove_property_map(g); + smesh->remove_property_map(b); + } + + void set_vrgb(SMesh* smesh) + { + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef SMesh::Property_map Color_map; + typedef SMesh::Property_map Uchar_map; + + SMesh::Property_map vcolors; + bool okay = false; + boost::tie (vcolors, okay) = smesh->property_map("v:color"); + if (!okay) + return; + + Uchar_map r, g, b; + r = smesh->add_property_map("red").first; + g = smesh->add_property_map("green").first; + b = smesh->add_property_map("blue").first; + + BOOST_FOREACH(vertex_descriptor vd, vertices(*smesh)) + { + r[vd] = vcolors[vd].red(); + g[vd] = vcolors[vd].green(); + b[vd] = vcolors[vd].blue(); + } + } + + void set_frgb(SMesh* smesh) + { + typedef boost::graph_traits::face_descriptor face_descriptor; + typedef SMesh::Property_map Color_map; + typedef SMesh::Property_map Uchar_map; + + SMesh::Property_map fcolors; + bool okay = false; + boost::tie (fcolors, okay) = smesh->property_map("f:color"); + if (!okay) + return; + + Uchar_map r, g, b; + r = smesh->add_property_map("red").first; + g = smesh->add_property_map("green").first; + b = smesh->add_property_map("blue").first; + + BOOST_FOREACH(face_descriptor fd, faces(*smesh)) + { + r[fd] = fcolors[fd].red(); + g[fd] = fcolors[fd].green(); + b[fd] = fcolors[fd].blue(); + } } }; @@ -110,6 +190,23 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { if (input_is_mesh) // Open mesh or polygon soup { + // First try mesh + SMesh *surface_mesh = new SMesh(); + + if (CGAL::read_ply (in, *surface_mesh)) + { + set_vcolors(surface_mesh); + set_fcolors(surface_mesh); + + Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh); + sm_item->setName(fileinfo.completeBaseName()); + QApplication::restoreOverrideCursor(); + return sm_item; + } + + in.seekg(0); + + // else try polygon soup std::vector points; std::vector > polygons; std::vector fcolors; @@ -121,29 +218,11 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { return NULL; } - if (CGAL::Polygon_mesh_processing::is_polygon_soup_a_polygon_mesh (polygons)) - { - SMesh *surface_mesh = new SMesh(); - CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh (points, polygons, - *surface_mesh); - if(!(vcolors.empty())) - set_vcolors(surface_mesh, vcolors); - if(!(fcolors.empty())) - set_fcolors(surface_mesh, fcolors); - - Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh); - sm_item->setName(fileinfo.completeBaseName()); - QApplication::restoreOverrideCursor(); - return sm_item; - } - else - { - Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item; - soup_item->setName(fileinfo.completeBaseName()); - soup_item->load (points, polygons, fcolors, vcolors); - QApplication::restoreOverrideCursor(); - return soup_item; - } + Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item; + soup_item->setName(fileinfo.completeBaseName()); + soup_item->load (points, polygons, fcolors, vcolors); + QApplication::restoreOverrideCursor(); + return soup_item; } else // Open point set { @@ -206,10 +285,17 @@ bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFile return CGAL::write_PLY (out, soup_item->points(), soup_item->polygons()); // This plugin supports surface meshes - const Scene_surface_mesh_item* sm_item = - qobject_cast(item); + Scene_surface_mesh_item* sm_item = + const_cast(qobject_cast(item)); if (sm_item) - return CGAL::write_PLY (out, *(sm_item->polyhedron())); + { + set_vrgb (sm_item->polyhedron()); + set_frgb (sm_item->polyhedron()); + bool success = CGAL::write_ply (out, *(sm_item->polyhedron())); + set_vcolors (sm_item->polyhedron()); + set_fcolors (sm_item->polyhedron()); + return success; + } return false; } From 2e13c549136b3fd2fbc69d62f442f9434fc87db3 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 23 Jan 2019 14:43:21 +0100 Subject: [PATCH 26/81] Documentation + better comment parameter --- .../include/CGAL/Surface_mesh/Surface_mesh.h | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index e9e082df793..24cb74fa0e4 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2158,12 +2158,12 @@ private: //------------------------------------------------------- private data } #if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) + + /// \relates Surface_mesh + /// Inserts the surface mesh in an output stream in PLY format. + /// All vertex and face properties with simple types are inserted in the stream. template -#ifdef DOXYGEN_RUNNING - bool write_ply(std::ostream& os, const Surface_mesh

& sm) -#else - bool write_ply(std::ostream& os, const Surface_mesh

& sm, std::string* comments = NULL) -#endif + bool write_ply(std::ostream& os, const Surface_mesh

& sm, const std::string& comments = std::string()) { typedef Surface_mesh

SMesh; typedef typename SMesh::Vertex_index VIndex; @@ -2191,9 +2191,9 @@ private: //------------------------------------------------------- private data << ((get_mode(os) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl << "comment Generated by the CGAL library" << std::endl; - if (comments != NULL) + if (comments != std::string()) { - std::istringstream iss (*comments); + std::istringstream iss (comments); std::string line; while (getline(iss, line)) { @@ -2607,12 +2607,26 @@ private: //------------------------------------------------------- private data } #if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) + + /// \cond SKIP_IN_MANUAL template -#ifdef DOXYGEN_RUNNING bool read_ply(std::istream& is, Surface_mesh

& sm) -#else - bool read_ply(std::istream& is, Surface_mesh

& sm, std::string* comments = NULL) -#endif + { + std::string dummy; + return read_ply (is, sm, dummy); + } + /// \endcond + + /// \relates Surface_mesh + /// Extracts the surface mesh from an input stream in Ascii or + /// Binary PLY format and appends it to the surface mesh `sm`. The + /// operator reads all properties for vertices and faces found in + /// the PLY input. + /// \pre The data in the stream must represent a two-manifold. If this is not the case + /// the `failbit` of `is` is set and the mesh cleared. + + template + bool read_ply(std::istream& is, Surface_mesh

& sm, std::string& comments) { if(!is) { @@ -2629,8 +2643,7 @@ private: //------------------------------------------------------- private data return false; } - if (comments != NULL) - *comments = reader.comments(); + comments = reader.comments(); for (std::size_t i = 0; i < reader.number_of_elements(); ++ i) { From 011f919ce6fbd664d5a364a27ad0a6586b9a27e5 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 10:58:34 +0100 Subject: [PATCH 27/81] Fix color binary alignment when writing 3 chars --- Stream_support/include/CGAL/IO/io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Stream_support/include/CGAL/IO/io.h b/Stream_support/include/CGAL/IO/io.h index 679565c8480..04c3e989d45 100644 --- a/Stream_support/include/CGAL/IO/io.h +++ b/Stream_support/include/CGAL/IO/io.h @@ -396,9 +396,9 @@ std::ostream& operator<<( std::ostream& out, const Color& col) << static_cast(col.green()) << ' ' << static_cast(col.blue()); case IO::BINARY : - write(out, static_cast(col.red())); - write(out, static_cast(col.green())); - write(out, static_cast(col.blue())); + write(out, col.red()); + write(out, col.green()); + write(out, col.blue()); return out; default: return out << "Color(" << static_cast(col.red()) << ", " From 37a8f12f0573c62de4c555aa1b0e347b459d8a91 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 10:58:57 +0100 Subject: [PATCH 28/81] Handle more types --- Stream_support/include/CGAL/IO/PLY.h | 6 +- .../include/CGAL/Surface_mesh/IO/PLY.h | 72 +++++++- .../include/CGAL/Surface_mesh/Surface_mesh.h | 165 ++++++++++++++++-- .../test/Surface_mesh/colored_tetra.ply | 24 ++- 4 files changed, 238 insertions(+), 29 deletions(-) diff --git a/Stream_support/include/CGAL/IO/PLY.h b/Stream_support/include/CGAL/IO/PLY.h index 32eab0d9011..85f14b97b91 100644 --- a/Stream_support/include/CGAL/IO/PLY.h +++ b/Stream_support/include/CGAL/IO/PLY.h @@ -909,10 +909,10 @@ public: } }; -template +template class Simple_property_printer : public Abstract_property_printer { - typedef typename PropertyMap::value_type Type; PropertyMap m_pmap; public: Simple_property_printer (const PropertyMap& pmap) : m_pmap (pmap) @@ -926,7 +926,7 @@ public: stream << get(m_pmap, index); else { - Type t = get (m_pmap, index); + Type t = Type(get (m_pmap, index)); stream.write (reinterpret_cast(&t), sizeof(t)); } } diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h index b472a24cb49..1aeb21e5a52 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h @@ -35,6 +35,8 @@ template class Surface_mesh_filler { public: + typedef typename Kernel_traits::Kernel Kernel; + typedef typename Kernel::Vector_3 Vector; typedef Surface_mesh Surface_mesh; typedef typename Surface_mesh::Vertex_index Vertex_index; typedef typename Surface_mesh::Face_index Face_index; @@ -57,7 +59,7 @@ private: PLY_property_to_surface_mesh_property (Surface_mesh& sm, const std::string& name) : m_name (name) { - m_map = sm.template add_property_map(name).first; + m_map = sm.template add_property_map(prefix(Simplex()) + name).first; } virtual void assign (PLY_element& element, std::size_t index) @@ -66,10 +68,19 @@ private: element.assign (t, m_name.c_str()); put(m_map, Simplex(index), t); } + + std::string prefix(Vertex_index) const { return "v:"; } + std::string prefix(Face_index) const { return "f:"; } }; Surface_mesh& m_mesh; bool m_use_floats; + int m_normals; + typename Surface_mesh::template Property_map m_normal_map; + int m_vcolors; + typename Surface_mesh::template Property_map m_vcolor_map; + int m_fcolors; + typename Surface_mesh::template Property_map m_fcolor_map; bool m_use_int32_t; std::string m_index_tag; std::vector m_vertex_properties; @@ -78,7 +89,7 @@ private: public: Surface_mesh_filler (Surface_mesh& mesh) - : m_mesh (mesh), m_use_floats (false) + : m_mesh (mesh), m_use_floats (false), m_normals(0), m_vcolors(0), m_fcolors(0) { } ~Surface_mesh_filler() @@ -100,6 +111,24 @@ public: m_use_floats = true; return true; } + if (name == "nx" || + name == "ny" || + name == "nz") + { + ++ m_normals; + if (m_normals == 3) + m_normal_map = m_mesh.template add_property_map("v:normal").first; + return true; + } + if (name == "red" || + name == "green" || + name == "blue") + { + ++ m_vcolors; + if (m_vcolors == 3) + m_vcolor_map = m_mesh.template add_property_map("v:color").first; + return true; + } return false; } @@ -113,6 +142,15 @@ public: CGAL_assertion (dynamic_cast*>(property)); return true; } + if (name == "red" || + name == "green" || + name == "blue") + { + ++ m_fcolors; + if (m_fcolors == 3) + m_fcolor_map = m_mesh.template add_property_map("f:color").first; + return true; + } return false; } @@ -207,12 +245,31 @@ public: template void process_line (PLY_element& element, Vertex_index& vi) { - FT x = (FT)0.,y = (FT)0., z = (FT)0.; + FT x = (FT)0.,y = (FT)0., z = (FT)0., + nx = (FT)0., ny = (FT)0., nz = (FT)0.; element.assign (x, "x"); element.assign (y, "y"); element.assign (z, "z"); Point point (x, y, z); vi = m_mesh.add_vertex(point); + + if (m_normals == 3) + { + element.assign (nx, "nx"); + element.assign (ny, "ny"); + element.assign (nz, "nz"); + Vector normal (nx, ny, nz); + m_normal_map[vi] = normal; + } + + if (m_vcolors == 3) + { + unsigned char r, g, b; + element.assign (r, "red"); + element.assign (g, "green"); + element.assign (b, "blue"); + m_vcolor_map[vi] = CGAL::Color (r, g, b); + } } bool process_face_line (PLY_element& element) @@ -244,6 +301,15 @@ public: vertices.push_back (Vertex_index (indices[i])); fi = m_mesh.add_face(vertices); + + if (m_fcolors == 3) + { + unsigned char r, g, b; + element.assign (r, "red"); + element.assign (g, "green"); + element.assign (b, "blue"); + m_fcolor_map[fi] = CGAL::Color (r, g, b); + } } }; diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 24cb74fa0e4..dd62434e350 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2166,24 +2166,37 @@ private: //------------------------------------------------------- private data bool write_ply(std::ostream& os, const Surface_mesh

& sm, const std::string& comments = std::string()) { typedef Surface_mesh

SMesh; + typedef typename Kernel_traits

::Kernel K; + typedef typename K::Vector_3 Vector; typedef typename SMesh::Vertex_index VIndex; typedef typename SMesh::Face_index FIndex; typedef typename SMesh::Halfedge_index HIndex; - typedef typename SMesh::template Property_map Point_map; + typedef typename SMesh::template Property_map Point_map; + typedef typename SMesh::template Property_map Vector_map; + typedef typename SMesh::template Property_map Vcolor_map; + typedef typename SMesh::template Property_map Int8_map_v; typedef typename SMesh::template Property_map Uint8_map_v; typedef typename SMesh::template Property_map Int16_map_v; typedef typename SMesh::template Property_map Uint16_map_v; typedef typename SMesh::template Property_map Int32_map_v; + typedef typename SMesh::template Property_map Uint32_map_v; + typedef typename SMesh::template Property_map Int64_map_v; + typedef typename SMesh::template Property_map Uint64_map_v; typedef typename SMesh::template Property_map Float_map_v; typedef typename SMesh::template Property_map Double_map_v; + typedef typename SMesh::template Property_map Fcolor_map; + typedef typename SMesh::template Property_map Int8_map_f; typedef typename SMesh::template Property_map Uint8_map_f; typedef typename SMesh::template Property_map Int16_map_f; typedef typename SMesh::template Property_map Uint16_map_f; typedef typename SMesh::template Property_map Int32_map_f; + typedef typename SMesh::template Property_map Uint32_map_f; + typedef typename SMesh::template Property_map Int64_map_f; + typedef typename SMesh::template Property_map Uint64_map_f; typedef typename SMesh::template Property_map Float_map_f; typedef typename SMesh::template Property_map Double_map_f; @@ -2231,12 +2244,55 @@ private: //------------------------------------------------------- private data } bool okay = false; + if (vprop[i] == "v:normal") + { + Vector_map pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + if (boost::is_same::type, float>::value) + { + os << "property float nx" << std::endl + << "property float ny" << std::endl + << "property float nz" << std::endl; + } + else + { + os << "property double nx" << std::endl + << "property double ny" << std::endl + << "property double nz" << std::endl; + } + vprinters.push_back (new internal::PLY::Property_printer(pmap)); + continue; + } + } + + if (vprop[i] == "v:color") + { + Vcolor_map pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property uchar red" << std::endl + << "property uchar green" << std::endl + << "property uchar blue" << std::endl; + + vprinters.push_back (new internal::PLY::Property_printer(pmap)); + continue; + } + } + + // Cut the "v:" prefix + std::string name = vprop[i]; + if (name.rfind("v:",0) == 0) + name = std::string (vprop[i].begin() + 2, vprop[i].end()); + { Int8_map_v pmap; boost::tie (pmap, okay) = sm.template property_map(vprop[i]); if (okay) { - os << "property char " << vprop[i] << std::endl; + os << "property char " << name << std::endl; vprinters.push_back (new internal::PLY::Char_property_printer(pmap)); continue; } @@ -2246,7 +2302,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(vprop[i]); if (okay) { - os << "property uchar " << vprop[i] << std::endl; + os << "property uchar " << name << std::endl; vprinters.push_back (new internal::PLY::Char_property_printer(pmap)); continue; } @@ -2256,7 +2312,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(vprop[i]); if (okay) { - os << "property short " << vprop[i] << std::endl; + os << "property short " << name << std::endl; vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } @@ -2266,7 +2322,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(vprop[i]); if (okay) { - os << "property ushort " << vprop[i] << std::endl; + os << "property ushort " << name << std::endl; vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } @@ -2276,17 +2332,47 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(vprop[i]); if (okay) { - os << "property int " << vprop[i] << std::endl; + os << "property int " << name << std::endl; vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } } + { + Uint32_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property uint " << name << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Int64_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property int " << name << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint64_map_v pmap; + boost::tie (pmap, okay) = sm.template property_map(vprop[i]); + if (okay) + { + os << "property uint " << name << std::endl; + vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } { Float_map_v pmap; boost::tie (pmap, okay) = sm.template property_map(vprop[i]); if (okay) { - os << "property float " << vprop[i] << std::endl; + os << "property float " << name << std::endl; vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } @@ -2296,7 +2382,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(vprop[i]); if (okay) { - os << "property double " << vprop[i] << std::endl; + os << "property double " << name << std::endl; vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } @@ -2315,12 +2401,31 @@ private: //------------------------------------------------------- private data continue; bool okay = false; + if (fprop[i] == "f:color") + { + Fcolor_map pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property uchar red" << std::endl + << "property uchar green" << std::endl + << "property uchar blue" << std::endl; + + fprinters.push_back (new internal::PLY::Property_printer(pmap)); + continue; + } + } + + // Cut the "f:" prefix + std::string name = fprop[i]; + if (name.rfind("f:",0) == 0) + name = std::string (fprop[i].begin() + 2, fprop[i].end()); { Int8_map_f pmap; boost::tie (pmap, okay) = sm.template property_map(fprop[i]); if (okay) { - os << "property char " << fprop[i] << std::endl; + os << "property char " << name << std::endl; fprinters.push_back (new internal::PLY::Char_property_printer(pmap)); continue; } @@ -2330,7 +2435,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(fprop[i]); if (okay) { - os << "property uchar " << fprop[i] << std::endl; + os << "property uchar " << name << std::endl; fprinters.push_back (new internal::PLY::Char_property_printer(pmap)); continue; } @@ -2340,7 +2445,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(fprop[i]); if (okay) { - os << "property short " << fprop[i] << std::endl; + os << "property short " << name << std::endl; fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } @@ -2350,7 +2455,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(fprop[i]); if (okay) { - os << "property ushort " << fprop[i] << std::endl; + os << "property ushort " << name << std::endl; fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } @@ -2360,17 +2465,47 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(fprop[i]); if (okay) { - os << "property int " << fprop[i] << std::endl; + os << "property int " << name << std::endl; fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } } + { + Uint32_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property uint " << name << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Int64_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property int " << name << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint64_map_f pmap; + boost::tie (pmap, okay) = sm.template property_map(fprop[i]); + if (okay) + { + os << "property uint " << name << std::endl; + fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } { Float_map_f pmap; boost::tie (pmap, okay) = sm.template property_map(fprop[i]); if (okay) { - os << "property float " << fprop[i] << std::endl; + os << "property float " << name << std::endl; fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } @@ -2380,7 +2515,7 @@ private: //------------------------------------------------------- private data boost::tie (pmap, okay) = sm.template property_map(fprop[i]); if (okay) { - os << "property double " << fprop[i] << std::endl; + os << "property double " << name << std::endl; fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); continue; } diff --git a/Surface_mesh/test/Surface_mesh/colored_tetra.ply b/Surface_mesh/test/Surface_mesh/colored_tetra.ply index a13165c80e2..281a182a55e 100644 --- a/Surface_mesh/test/Surface_mesh/colored_tetra.ply +++ b/Surface_mesh/test/Surface_mesh/colored_tetra.ply @@ -4,17 +4,25 @@ element vertex 4 property double x property double y property double z +property double nx +property double ny +property double nz +property uchar red +property uchar green +property uchar blue +property int id element face 4 property list uchar int vertex_indices property uchar red property uchar green property uchar blue +property int label end_header -0 0 0 -0 0 1 -0 1 0 -1 0 0 -3 0 1 2 255 0 0 -3 0 3 1 0 255 0 -3 1 3 2 0 0 255 -3 0 2 3 255 0 255 +0 0 0 -0.5 -0.5 -0.5 255 255 0 0 +0 0 1 -0.5 -0.5 0 0 255 255 1 +0 1 0 -0.5 0 -0.5 128 0 255 2 +1 0 0 0 -0.5 -0.5 255 128 0 3 +3 0 1 2 255 0 0 -1 +3 0 3 1 0 255 0 1 +3 1 3 2 0 0 255 -1 +3 0 2 3 255 0 255 0 From c8672335499023d116ad7fd027469c38cefc2470 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 10:59:11 +0100 Subject: [PATCH 29/81] Update plugin, colors are directly handled now --- .../Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 120 +----------------- 1 file changed, 2 insertions(+), 118 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index 34256cc9aeb..72dc665b19f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -37,113 +37,6 @@ public: bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); private: - void set_vcolors(SMesh* smesh) - { - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef SMesh::Property_map Color_map; - typedef SMesh::Property_map Uchar_map; - - Uchar_map r, g, b; - bool okay = false; - boost::tie (r, okay) = smesh->property_map("red"); - if (!okay) - return; - boost::tie (g, okay) = smesh->property_map("green"); - if (!okay) - return; - boost::tie (b, okay) = smesh->property_map("blue"); - if (!okay) - return; - - SMesh::Property_map vcolors - = smesh->add_property_map("v:color",CGAL::Color(0,0,0)).first; - - BOOST_FOREACH(vertex_descriptor vd, vertices(*smesh)) - vcolors[vd] = CGAL::Color (r[vd], g[vd], b[vd]); - - smesh->remove_property_map(r); - smesh->remove_property_map(g); - smesh->remove_property_map(b); - } - - void set_fcolors(SMesh* smesh) - { - typedef boost::graph_traits::face_descriptor face_descriptor; - typedef SMesh::Property_map Color_map; - typedef SMesh::Property_map Uchar_map; - - Uchar_map r, g, b; - bool okay = false; - boost::tie (r, okay) = smesh->property_map("red"); - if (!okay) - return; - boost::tie (g, okay) = smesh->property_map("green"); - if (!okay) - return; - boost::tie (b, okay) = smesh->property_map("blue"); - if (!okay) - return; - - SMesh::Property_map fcolors - = smesh->add_property_map("f:color",CGAL::Color(0,0,0)).first; - - BOOST_FOREACH(face_descriptor fd, faces(*smesh)) - fcolors[fd] = CGAL::Color (r[fd], g[fd], b[fd]); - - smesh->remove_property_map(r); - smesh->remove_property_map(g); - smesh->remove_property_map(b); - } - - void set_vrgb(SMesh* smesh) - { - typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef SMesh::Property_map Color_map; - typedef SMesh::Property_map Uchar_map; - - SMesh::Property_map vcolors; - bool okay = false; - boost::tie (vcolors, okay) = smesh->property_map("v:color"); - if (!okay) - return; - - Uchar_map r, g, b; - r = smesh->add_property_map("red").first; - g = smesh->add_property_map("green").first; - b = smesh->add_property_map("blue").first; - - BOOST_FOREACH(vertex_descriptor vd, vertices(*smesh)) - { - r[vd] = vcolors[vd].red(); - g[vd] = vcolors[vd].green(); - b[vd] = vcolors[vd].blue(); - } - } - - void set_frgb(SMesh* smesh) - { - typedef boost::graph_traits::face_descriptor face_descriptor; - typedef SMesh::Property_map Color_map; - typedef SMesh::Property_map Uchar_map; - - SMesh::Property_map fcolors; - bool okay = false; - boost::tie (fcolors, okay) = smesh->property_map("f:color"); - if (!okay) - return; - - Uchar_map r, g, b; - r = smesh->add_property_map("red").first; - g = smesh->add_property_map("green").first; - b = smesh->add_property_map("blue").first; - - BOOST_FOREACH(face_descriptor fd, faces(*smesh)) - { - r[fd] = fcolors[fd].red(); - g[fd] = fcolors[fd].green(); - b[fd] = fcolors[fd].blue(); - } - } }; bool Polyhedron_demo_ply_plugin::canLoad() const { @@ -195,9 +88,6 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { if (CGAL::read_ply (in, *surface_mesh)) { - set_vcolors(surface_mesh); - set_fcolors(surface_mesh); - Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh); sm_item->setName(fileinfo.completeBaseName()); QApplication::restoreOverrideCursor(); @@ -288,14 +178,8 @@ bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFile Scene_surface_mesh_item* sm_item = const_cast(qobject_cast(item)); if (sm_item) - { - set_vrgb (sm_item->polyhedron()); - set_frgb (sm_item->polyhedron()); - bool success = CGAL::write_ply (out, *(sm_item->polyhedron())); - set_vcolors (sm_item->polyhedron()); - set_fcolors (sm_item->polyhedron()); - return success; - } + return CGAL::write_ply (out, *(sm_item->polyhedron())); + return false; } From b3baaf7e92540163464e2455e14d00c5ce8f6f7a Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 13:36:36 +0100 Subject: [PATCH 30/81] Move doc of CGAL::Color to header and rewrite class --- .../doc/Stream_support/CGAL/IO/Color.h | 107 ----- Stream_support/doc/Stream_support/Doxyfile.in | 1 + Stream_support/include/CGAL/IO/Color.h | 365 +++++++++++++++--- 3 files changed, 303 insertions(+), 170 deletions(-) delete mode 100644 Stream_support/doc/Stream_support/CGAL/IO/Color.h diff --git a/Stream_support/doc/Stream_support/CGAL/IO/Color.h b/Stream_support/doc/Stream_support/CGAL/IO/Color.h deleted file mode 100644 index bf800b4a7a4..00000000000 --- a/Stream_support/doc/Stream_support/CGAL/IO/Color.h +++ /dev/null @@ -1,107 +0,0 @@ - -namespace CGAL { - -/*! -\ingroup PkgStreamSupportRef - -An object of the class `Color` is a color available -for drawing operations in many \cgal output streams. -Each color is defined by a triple of unsigned chars `(r,g,b)` with -0 \f$\le\f$ r,g,b \f$ \le \f$ 255, the so-called rgb-value of the color. - -\sa `CGAL::Geomview_stream` - -*/ - -class Color { -public: - -/// \name Creation -/// @{ - -/*! -creates a color with rgb-value `(0,0,0)`, i.e.\ black. -*/ -Color(); - -/*! -creates a color with rgb-value `(red,green,blue)`. -*/ -Color(unsigned char red, unsigned char green, unsigned char blue); - -/// @} - -/// \name Operations -/// @{ - -/*! -Test for equality: Two colors are equal, iff their -rgb-values are equal. -*/ -bool operator==(const Color &q) const; - -/*! -Test for inequality. -*/ -bool operator!=(const Color &q) const; - -/*! -returns the red component of `c`. -*/ -unsigned char red() const; - -/*! -returns the green component of `c`. -*/ -unsigned char green() const; - -/*! -returns the blue component of `c`. -*/ -unsigned char blue() const; - -/// @} - -/// \name Constants -/// The following constants are predefined: -/// @{ - -/*! -Black. -*/ -const Color BLACK = Color(0, 0, 0); - -/*! -White. -*/ -const Color WHITE = Color(255, 255, 255); - -/*! -Red. -*/ -const Color RED = Color(255, 0, 0); - -/*! -Green. -*/ -const Color GREEN = Color(0, 255, 0); - -/*! -Blue. -*/ -const Color BLUE = Color(0, 0, 255); - -/*! -Violet. -*/ -const Color VIOLET = Color(255, 0, 255); - -/*! -Orange. -*/ -const Color ORANGE = Color(255, 170, 0); - -/// @} - -}; /* end Color */ -} /* end namespace CGAL */ diff --git a/Stream_support/doc/Stream_support/Doxyfile.in b/Stream_support/doc/Stream_support/Doxyfile.in index 1f49650958f..f742dc367d0 100644 --- a/Stream_support/doc/Stream_support/Doxyfile.in +++ b/Stream_support/doc/Stream_support/Doxyfile.in @@ -1,4 +1,5 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - IO Streams" +INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/IO/Color.h diff --git a/Stream_support/include/CGAL/IO/Color.h b/Stream_support/include/CGAL/IO/Color.h index a6797a71cf7..05119dc6220 100644 --- a/Stream_support/include/CGAL/IO/Color.h +++ b/Stream_support/include/CGAL/IO/Color.h @@ -23,83 +23,322 @@ // // Author(s) : Andreas Fabri -#include - #ifndef CGAL_COLOR_H #define CGAL_COLOR_H +#include +#include + namespace CGAL { -class Color { -public: - Color(): _red(120), _green(120), _blue(120), _alpha(120) {} - Color(unsigned char red, - unsigned char green, - unsigned char blue, - unsigned char alpha = 120) - : _red(red), _green(green), _blue(blue), _alpha(alpha) - {} - unsigned char r() const {return _red;} - unsigned char g() const {return _green;} - unsigned char b() const {return _blue;} +/*! + \ingroup PkgStreamSupportRef - unsigned char red() const {return _red;} - unsigned char green() const {return _green;} - unsigned char blue() const {return _blue;} - unsigned char alpha() const {return _alpha;} - void set_alpha(unsigned char a) {_alpha=a;} - bool operator==(const Color &c) const - { - return ( (red() == c.red()) && - (green() == c.green()) && - (blue() == c.blue()) ); - } + An object of the class `Color` is a color available for drawing + operations in many \cgal output streams. Each color is defined by a + 4 unsigned chars `(r,g,b,a)` with 0 \f$\le\f$ r,g,b,a \f$ \le \f$ + 255, the so-called rgba-value of the color. - bool operator!=(const Color &c) const - { - return !( (*this) == c); - } + The alpha parameter (representing transparency) is often ignored and + left to its default value (255 = no transparency), which is why we + often refer to the rgb-value of the color. - Color& operator=(const Color &c) - { - _red = c.red(); - _green = c.green(); - _blue = c.blue(); - _alpha = c.alpha(); - return *this; - } + \sa `CGAL::Geomview_stream` +*/ + +class Color +{ private: - unsigned char _red; - unsigned char _green; - unsigned char _blue; - unsigned char _alpha; + + cpp11::array m_data; + +public: + + /// \name Creation + /// @{ + + /*! + creates a color with rgba-value `(0,0,0,255)`, i.e.\ black. + */ + Color() + { + set_rgb (0, 0, 0, 255); + } + + /*! + creates a color with rgba-value `(red,green,blue,alpha)`. + */ + Color(unsigned char red, + unsigned char green, + unsigned char blue, + unsigned char alpha = 255) + { + set_rgb (red, green, blue, alpha); + } + + /// @} + + /// \name Component Access + /// @{ + + /*! + returns the red component. + */ + unsigned char red() const { return m_data[0]; } + + /*! + returns a reference on the red component. + */ + unsigned char& red() { return m_data[0]; } + + /*! + returns the green component. + */ + unsigned char green() const { return m_data[1]; } + + /*! + returns a reference on the green component. + */ + unsigned char& green() { return m_data[1]; } + + /*! + returns the blue component. + */ + unsigned char blue() const { return m_data[2]; } + + /*! + returns a reference on the blue component. + */ + unsigned char& blue() { return m_data[2]; } + + /*! + returns the alpha component. + */ + unsigned char alpha() const { return m_data[3]; } + + /*! + returns a reference on the alpha component. + */ + unsigned char& alpha() { return m_data[3]; } + + /// @} + + /// \name Array Access + /// @{ + + /*! + returns the i^{th} component of the rgb color (the 0^{th} is red, + the 1^{st} is blue, etc.). + */ + unsigned char operator[] (std::size_t i) const { return m_data[i]; } + + /*! + returns a reference on the i^{th} component of `c` (the 0^{th} is + red, the 1^{st} is blue, etc.). + */ + unsigned char& operator[] (std::size_t i) { return m_data[i]; } + + /*! + returns the array with rgba values. + */ + const cpp11::array& to_rgba() const { return m_data; } + + /*! + returns the array with rgb values. + */ + const cpp11::array& to_rgb() const + { + return reinterpret_cast&>(m_data); + } + + /*! + computes the hsv (hue, saturation, value) values and returns an + array representing them as float values between 0 and 1. + */ + cpp11::array to_hsv() const + { + double r = (double)(m_data[0]) / 255.; + double g = (double)(m_data[1]) / 255.; + double b = (double)(m_data[2]) / 255.; + double Cmax = (std::max) (r, (std::max) (g, b)); + double Cmin = (std::min) (r, (std::min) (g, b)); + double delta = Cmax - Cmin; + double H = 0.; + + if (delta != 0.) + { + if (Cmax == r) + H = 60. * ((g - b) / delta); + else if (Cmax == g) + H = 60. * (((b - r) / delta) + 2.); + else + H = 60. * (((r - g) / delta) + 4.); + } + + if (H < 0.) H += 360.; + + double S = (Cmax == 0. ? 0. : 100. * (delta / Cmax)); + double V = 100. * Cmax; + + return make_array(H,S,V); + } + + /// \name Modification + /// @{ + + /*! + replaces the rgb values of the colors by the one given as parameters. + */ + void set_rgb (unsigned char red, + unsigned char green, + unsigned char blue, + unsigned char alpha = 255) + { + m_data[0] = red; + m_data[1] = green; + m_data[2] = blue; + m_data[3] = alpha; + } + + /*! + replaces the rgb values of the colors by the conversion to rgb of + the hsv values given as parameters. + + Double values given as parameters should take range between 0 and 1. + */ + void set_hsv (double hue, + double saturation, + double value, + unsigned char alpha = 255) + { + saturation /= 100.; + value /= 100.; + double C = value*saturation; + int hh = (int)(hue/60.); + double X = C * (1-std::abs (hh % 2 - 1)); + double r = 0, g = 0, b = 0; + + if( hh>=0 && hh<1 ) + { + r = C; + g = X; + } + else if( hh>=1 && hh<2 ) + { + r = X; + g = C; + } + else if( hh>=2 && hh<3 ) + { + g = C; + b = X; + } + else if( hh>=3 && hh<4 ) + { + g = X; + b = C; + } + else if( hh>=4 && hh<5 ) + { + r = X; + b = C; + } + else + { + r = C; + b = X; + } + double m = value-C; + r += m; + g += m; + b += m; + r *= 255.0; + g *= 255.0; + b *= 255.0; + + m_data[0] = (unsigned char)r; + m_data[1] = (unsigned char)g; + m_data[2] = (unsigned char)b; + m_data[3] = alpha; + } + + /// @} + +}; + + +/*! + Constructs Color(0,0,0). + \relates Color +*/ +inline Color black() { return Color(0,0,0); } + +/*! + Constructs Color(0,0,255). + \relates Color +*/ +inline Color blue() { return Color(0,0,255); } + +/*! + Constructs Color(10,0,100). + \relates Color +*/ +inline Color deep_blue() { return Color(10,0,100); } + +/*! + Constructs Color(100,100,100). + \relates Color +*/ +inline Color gray() { return Color(100,100,100); } + +/*! + Constructs Color(0,255,0). + \relates Color +*/ +inline Color green() { return Color(0,255,0); } + +/*! + Constructs Color(235,150,0). + \relates Color +*/ +inline Color orange() { return Color(235,150,0); } + +/*! + Constructs Color(100,0,70). + \relates Color +*/ +inline Color purple() { return Color(100,0,70); } + +/*! + Constructs Color(255,0,0). + \relates Color +*/ +inline Color red() { return Color(255,0,0); } + +/*! + Constructs Color(255,0,255). + \relates Color +*/ +inline Color violet() { return Color(255,0,255); } + +/*! + Constructs Color(255,255,255). + \relates Color +*/ +inline Color white() { return Color(255,255,255); } + +/*! + Constructs Color(255,255,0). + \relates Color +*/ +inline Color yellow() { return Color(255,255,0); } + + }; -#ifndef CGAL_HEADER_ONLY - -CGAL_EXPORT extern const Color BLACK ; -CGAL_EXPORT extern const Color WHITE ; -CGAL_EXPORT extern const Color GRAY ; - -CGAL_EXPORT extern const Color RED ; -CGAL_EXPORT extern const Color GREEN ; - -CGAL_EXPORT extern const Color DEEPBLUE; -CGAL_EXPORT extern const Color BLUE ; -CGAL_EXPORT extern const Color PURPLE ; -CGAL_EXPORT extern const Color VIOLET ; - -CGAL_EXPORT extern const Color ORANGE ; -CGAL_EXPORT extern const Color YELLOW ; - -#endif // CGAL_HEADER_ONLY } //namespace CGAL -#ifdef CGAL_HEADER_ONLY -#include -#endif // CGAL_HEADER_ONLY - #endif // CGAL_COLOR_H From 59a169a3000f4ff50925dd1458473032766d888e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:16:35 +0100 Subject: [PATCH 31/81] Replace link test using Random instead of Color --- Installation/test/Installation/link_to_CGAL.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Installation/test/Installation/link_to_CGAL.cpp b/Installation/test/Installation/link_to_CGAL.cpp index 0638aa6db6e..3cb2755535d 100644 --- a/Installation/test/Installation/link_to_CGAL.cpp +++ b/Installation/test/Installation/link_to_CGAL.cpp @@ -1,10 +1,9 @@ // Use something defined not in headers but in the CGAL library to test that is was indeed properly built and linked to, -#include +#include int main() { - volatile const CGAL::Color* c = &CGAL::BLACK; - - return (c != 0) ? 0 : 1; + volatile const CGAL::Random* r = &CGAL::get_default_random(); + return int(r != 0); } From e3e0efb4f8bf22f2e6f65f680025a2104316df5a Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:18:49 +0100 Subject: [PATCH 32/81] Replace old color API using global const variable with new one using functions --- .../xalci/misc.cpp | 2 +- .../Arrangement_on_surface_2/arr_bench.cpp | 10 ++++----- .../demo/Convex_hull_3/quickhull_3_demo.cpp | 4 ++-- Geomview/demo/Geomview/gv_terrain.cpp | 4 ++-- Geomview/demo/Geomview/kernel.cpp | 16 +++++++------- .../Qt/SegmentDelaunayGraphGraphicsItem.h | 4 ++-- .../Qt/SegmentDelaunayGraphLinfGraphicsItem.h | 4 ++-- .../examples/HalfedgeDS/hds_prog_color.cpp | 6 ++--- .../Interpolation/interpolation_2_demo.cpp | 4 ++-- .../demo/Interpolation/surface_voronoi.cpp | 10 ++++----- .../applications/display_distribution.cpp | 6 ++--- Mesh_3/archive/applications/distribution.cpp | 4 ++-- .../applications/lanteri_process_results.cpp | 2 +- .../output_distribution_to_stdout.cpp | 6 ++--- Nef_3/include/CGAL/Nef_3/SM_visualizor.h | 6 ++--- Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h | 6 ++--- Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h | 6 ++--- .../include/CGAL/Nef_S2/Sphere_geometry_OGL.h | 22 +++++++++---------- .../p2t2_colored_vertices.cpp | 2 +- .../colored_vertices.cpp | 2 +- .../Polyhedron/polyhedron_prog_color.cpp | 2 +- .../polyhedron_prog_vertex_color.cpp | 2 +- .../demo/Polyhedron_IO/geomview_demo.cpp | 2 +- .../examples/Triangulation_2/colored_face.cpp | 4 ++-- .../Triangulation_3_color_demo.cpp | 2 +- .../Triangulation_3_demo.cpp | 4 ++-- .../Triangulation_3_voronoi_demo.cpp | 2 +- .../examples/Triangulation_3/color.cpp | 2 +- 28 files changed, 73 insertions(+), 73 deletions(-) diff --git a/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp b/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp index 5641b3e6296..453a43b5e6a 100644 --- a/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp +++ b/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp @@ -479,7 +479,7 @@ void xAlci_main_window::setup(int w, int h) tab_widget->addTab(cad_tab,"cad"); tab_widget->addTab(arr_tab,"arrangement"); - *widget << CGAL::LineWidth(2) << CGAL::BackgroundColor(CGAL::WHITE); + *widget << CGAL::LineWidth(2) << CGAL::BackgroundColor(CGAL::white()); resize(w,h); double ratio = 1.0;//(double)h/w; widget->set_window(-1, 1, -ratio, ratio, true); diff --git a/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp b/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp index 86e299c27ad..903fc5a1b90 100644 --- a/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp +++ b/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp @@ -277,11 +277,11 @@ inline std::ostream & operator<<(std::ostream & os, const Arr::Vertex & vertex) inline Window_stream & operator<<(Window_stream & ws, Arr & arr) { Arr::Edge_iterator ei; - ws << CGAL::BLUE; + ws << CGAL::blue(); for (ei = arr.edges_begin(); ei != arr.edges_end(); ++ei) ws << (*ei).curve(); Arr::Vertex_iterator vi; - ws << CGAL::RED; + ws << CGAL::red(); for (vi = arr.vertices_begin(); vi != arr.vertices_end(); ++vi) ws << (*vi).point(); return ws; @@ -474,7 +474,7 @@ public: m_window->flush(); #else m_window->lock(); - *m_window << CGAL::BackgroundColor(CGAL::WHITE) << CGAL::RED; + *m_window << CGAL::BackgroundColor(CGAL::white()) << CGAL::red(); (*m_window) << arr; m_window->unlock(); App->flush(); @@ -490,9 +490,9 @@ public: ps_stream.set_line_width(1); CGAL::Arr_drawer drawer(ps_stream); // drawer.draw_faces(arr.faces_begin(), arr.faces_end()); - ps_stream << CGAL::BLUE; + ps_stream << CGAL::blue(); drawer.draw_halfedges(arr.halfedges_begin(), arr.halfedges_end()); - ps_stream << CGAL::RED; + ps_stream << CGAL::red(); drawer.draw_vertices(arr.vertices_begin(), arr.vertices_end()); // draw_arr(arr, drawer, ps_stream); diff --git a/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp b/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp index d50f0faef09..786598fb80b 100644 --- a/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp +++ b/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp @@ -67,7 +67,7 @@ void draw_points_and_hull(const std::vector& points, std::vector::const_iterator p_it; CGAL::Geomview_stream geomview; - geomview << CGAL::RED; + geomview << CGAL::red(); for (p_it = points.begin(); p_it != points.end(); p_it++) { geomview << *p_it; @@ -78,7 +78,7 @@ void draw_points_and_hull(const std::vector& points, Point_3 point; Polyhedron_3 polyhedron; - geomview << CGAL::BLUE; + geomview << CGAL::blue(); if ( CGAL::assign(point, object) ) geomview << point; else if ( CGAL::assign(segment, object) ) diff --git a/Geomview/demo/Geomview/gv_terrain.cpp b/Geomview/demo/Geomview/gv_terrain.cpp index 27ce828d30c..bed8f15171a 100644 --- a/Geomview/demo/Geomview/gv_terrain.cpp +++ b/Geomview/demo/Geomview/gv_terrain.cpp @@ -57,13 +57,13 @@ int main() // use different colors, and put a few sleeps/clear. - gv << CGAL::BLUE; + gv << CGAL::blue(); std::cout << "Drawing 2D Delaunay triangulation in wired mode.\n"; gv.set_wired(true); gv << D; #if 1 // It's too slow ! Needs to use OFF for that. - gv << CGAL::RED; + gv << CGAL::red(); std::cout << "Drawing its Voronoi diagram.\n"; gv.set_wired(true); D.draw_dual(gv); diff --git a/Geomview/demo/Geomview/kernel.cpp b/Geomview/demo/Geomview/kernel.cpp index e496e59a311..0fe909a05fc 100644 --- a/Geomview/demo/Geomview/kernel.cpp +++ b/Geomview/demo/Geomview/kernel.cpp @@ -50,25 +50,25 @@ int main() gv.clear(); // remove the pickplane. gv << K::Point_2 (200, 100); - gv << CGAL::BLUE; + gv << CGAL::blue(); gv << K::Point_3 (200, 100, 100); - gv << CGAL::RED; + gv << CGAL::red(); gv << K::Segment_2 (K::Point_2(200, 100), K::Point_2(300, 100)); - gv << CGAL::GREEN; + gv << CGAL::green(); gv << K::Segment_3 (K::Point_3(200, 100, 100), K::Point_3(300, 100, 200)); - gv << CGAL::DEEPBLUE; + gv << CGAL::deep_blue(); gv << K::Sphere_3 (K::Point_3(100, 100, 100), 1000); - gv << CGAL::VIOLET; + gv << CGAL::violet(); gv << K::Triangle_2 (K::Point_2(200, 200), K::Point_2(220, 220), K::Point_2(180, 220)); - gv << CGAL::ORANGE; + gv << CGAL::orange(); gv << K::Triangle_3 (K::Point_3(200, 200, 50), K::Point_3(220, 220, 80), K::Point_3(180, 220, 100)); - gv << CGAL::PURPLE; + gv << CGAL::purple(); gv << K::Tetrahedron_3 (K::Point_3(100, 100, 180), K::Point_3(120, 70, 220), K::Point_3(100, 100, 220), @@ -76,7 +76,7 @@ int main() gv << CGAL::Bbox_2(10, 10, 30, 30); gv << CGAL::Bbox_3(10, 10, 10, 30, 30, 30); - gv << CGAL::RED; + gv << CGAL::red(); gv << K::Ray_2(K::Point_2(205,205), K::Point_2(500,500)); gv << K::Ray_3(K::Point_3(250,250,250), K::Point_3(500,500,500)); gv << K::Line_2(K::Point_2(195,195), K::Point_2(500,500)); diff --git a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h index d9fb9e6b5e0..71a52459805 100644 --- a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h +++ b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h @@ -173,9 +173,9 @@ SegmentDelaunayGraphGraphicsItem::drawAll(QPainter *painter, const QStyleOpti vit != t->finite_vertices_end(); ++vit) { typename T::Site_2 s = vit->site(); if ( s.is_input() ) { - //*widget << CGAL::RED; + //*widget << CGAL::red(); } else { - //*widget << CGAL::YELLOW; + //*widget << CGAL::yellow(); } if ( s.is_point() ) { QPointF point = matrix.map(convert(s.point())); diff --git a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h index 43ba00ccbf6..1542ff69acf 100644 --- a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h +++ b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h @@ -208,9 +208,9 @@ SegmentDelaunayGraphLinfGraphicsItem::drawAll(QPainter *painter, const QStyle vit != t->finite_vertices_end(); ++vit) { typename T::Site_2 s = vit->site(); if ( s.is_input() ) { - //*widget << CGAL::RED; + //*widget << CGAL::red(); } else { - //*widget << CGAL::YELLOW; + //*widget << CGAL::yellow(); } if ( s.is_point() ) { QPointF point = matrix.map(convert(s.point())); diff --git a/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp b/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp index 35300c92bab..6b294fefe5c 100644 --- a/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp +++ b/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp @@ -28,8 +28,8 @@ typedef HDS::Face_handle Face_handle; int main() { HDS hds; - Face_handle f = hds.faces_push_back( Face( CGAL::RED)); - f->color = CGAL::BLUE; - CGAL_assertion( f->color == CGAL::BLUE); + Face_handle f = hds.faces_push_back( Face( CGAL::red())); + f->color = CGAL::blue(); + CGAL_assertion( f->color == CGAL::blue()); return 0; } diff --git a/Interpolation/demo/Interpolation/interpolation_2_demo.cpp b/Interpolation/demo/Interpolation/interpolation_2_demo.cpp index 2ed7aa06b07..d3d0a5136e6 100644 --- a/Interpolation/demo/Interpolation/interpolation_2_demo.cpp +++ b/Interpolation/demo/Interpolation/interpolation_2_demo.cpp @@ -287,14 +287,14 @@ int main(int , char** ) std::cout << "The data points are displayed in blue in the geomview" << " application." << std::endl; - gv << CGAL::BLUE; + gv << CGAL::blue(); visu_points(gv,sample_3); //show the gradients if(method>0){ std::cout << "The function gradients are displayed by red lines " <<" in the geomview application." << std::endl; - gv <> ch; diff --git a/Mesh_3/archive/applications/display_distribution.cpp b/Mesh_3/archive/applications/display_distribution.cpp index 838b3bb595a..547ff00693e 100644 --- a/Mesh_3/archive/applications/display_distribution.cpp +++ b/Mesh_3/archive/applications/display_distribution.cpp @@ -174,7 +174,7 @@ void output_distribution_to_png(std::vector& elements, const double scale = double_options["scale"]; - *widget << CGAL::FillColor(CGAL::BLACK); + *widget << CGAL::FillColor(CGAL::black()); // *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.)); for(int k=0;k0) @@ -184,12 +184,12 @@ void output_distribution_to_png(std::vector& elements, height = ( (distribution[k]+0.)/number_of_cells ) * scale; else height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale); - *widget << CGAL::BLACK + *widget << CGAL::black() << Rectangle_2(Point_2(k*width, 0), Point_2((k+1)*width, height)); } else - *widget << CGAL::RED << Segment_2(Point_2(k*width, 0), + *widget << CGAL::red() << Segment_2(Point_2(k*width, 0), Point_2((k+1)*width, 0)); widget->unlock(); diff --git a/Mesh_3/archive/applications/distribution.cpp b/Mesh_3/archive/applications/distribution.cpp index 42fb5678dde..4a7d44f780e 100644 --- a/Mesh_3/archive/applications/distribution.cpp +++ b/Mesh_3/archive/applications/distribution.cpp @@ -34,10 +34,10 @@ void display_distribution(Distribution_displayer* display, const double height = ( distribution[k]+0. ) * echelle; display->fill_rectangle(k * width, 0, (k+1)* width, height, - CGAL::BLACK); + CGAL::black()); } else display->segment(k * width, 0., (k+1) * width, 0., - CGAL::RED); + CGAL::red()); } diff --git a/Mesh_3/archive/applications/lanteri_process_results.cpp b/Mesh_3/archive/applications/lanteri_process_results.cpp index 982e18c5201..b7403c49f09 100644 --- a/Mesh_3/archive/applications/lanteri_process_results.cpp +++ b/Mesh_3/archive/applications/lanteri_process_results.cpp @@ -99,7 +99,7 @@ bool process_aux_2(const std::vector& qualities, displays[i]->segment(x_position_of_length_bound, 0.0, x_position_of_length_bound, -0.05, - CGAL::BLUE); + CGAL::blue()); } *out_stream << "saving " << filename.c_str() << "...\n"; diff --git a/Mesh_3/archive/applications/output_distribution_to_stdout.cpp b/Mesh_3/archive/applications/output_distribution_to_stdout.cpp index 4b7a586eba6..6ceef9c3ca0 100644 --- a/Mesh_3/archive/applications/output_distribution_to_stdout.cpp +++ b/Mesh_3/archive/applications/output_distribution_to_stdout.cpp @@ -180,7 +180,7 @@ void parse_argv(int argc, char** argv, int extra_args = 0) // // const double scale = double_options["scale"]; // -//// *widget << CGAL::FillColor(CGAL::BLACK); +//// *widget << CGAL::FillColor(CGAL::black()); // // *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.)); // for(int k=0;k0) @@ -190,12 +190,12 @@ void parse_argv(int argc, char** argv, int extra_args = 0) // height = ( (distribution[k]+0.)/number_of_cells ) * scale; // else // height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale); -//// *widget << CGAL::BLACK +//// *widget << CGAL::black() //// << Rectangle_2(Point_2(k*width, 0), //// Point_2((k+1)*width, height)); // } // else -//// *widget << CGAL::RED << Segment_2(Point_2(k*width, 0), +//// *widget << CGAL::red() << Segment_2(Point_2(k*width, 0), //// Point_2((k+1)*width, 0)); // // // widget->unlock(); diff --git a/Nef_3/include/CGAL/Nef_3/SM_visualizor.h b/Nef_3/include/CGAL/Nef_3/SM_visualizor.h index a8c6c67512b..0423db7b476 100644 --- a/Nef_3/include/CGAL/Nef_3/SM_visualizor.h +++ b/Nef_3/include/CGAL/Nef_3/SM_visualizor.h @@ -48,11 +48,11 @@ class SNC_SM_BooleColor typedef typename Refs_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF3_DGREY : CGAL_NEF3_LGREY ); } }; diff --git a/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h b/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h index 25330ad7501..b2d18c43130 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h @@ -48,11 +48,11 @@ class SNC_SM_BooleColor typedef typename Map_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); } }; diff --git a/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h b/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h index 51ee7fe9917..a007e6a9338 100644 --- a/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h +++ b/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h @@ -44,11 +44,11 @@ class SM_BooleColor typedef typename Map_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); } }; diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h index f0527bb932b..34fecb1aa9f 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h @@ -254,7 +254,7 @@ class Sphere_point : public VPoint, public Gen_object { public: Sphere_point() {} Sphere_point(const CGAL::Sphere_point& p, - CGAL::Color c = CGAL::BLACK, unsigned w = 10) : + CGAL::Color c = CGAL::black(), unsigned w = 10) : VPoint(Approximator::approximate(p)), p_(p), c_(c), w_(w) {} Sphere_point(const Sphere_point& p) : VPoint(p), Gen_object() { p_ = p.p_; c_ = p.c_; w_ = p.w_; } @@ -297,7 +297,7 @@ class Sphere_segment : public VSegment, public Gen_object { public: Sphere_segment() {} Sphere_segment(const CGAL::Sphere_segment& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 2) + CGAL::Color c = CGAL::black(), unsigned w = 2) : VSegment(Approximator::approximate(s)), s_(s), c_(c), w_(w) {} Sphere_segment(const Sphere_segment& s) : VSegment(s), Gen_object() { s_ = s.s_; c_ = s.c_; w_ = s.w_; } @@ -350,7 +350,7 @@ class Sphere_circle : public VSegment, public Gen_object { public: Sphere_circle() {} Sphere_circle(const CGAL::Sphere_circle& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 2) + CGAL::Color c = CGAL::black(), unsigned w = 2) : VSegment(Approximator::approximate(s)), s_(s), c_(c), w_(w) {} Sphere_circle(const Sphere_circle& s) : VSegment(s), Gen_object() { s_ = s.s_; c_ = s.c_; w_ = s.w_; } @@ -539,27 +539,27 @@ Unit_sphere& operator=(const Unit_sphere& S) template void push_back(const CGAL::Sphere_point& p, - CGAL::Color c = CGAL::YELLOW, unsigned w = 5) + CGAL::Color c = CGAL::yellow(), unsigned w = 5) { objects_.push_back(new Sphere_point(p,c,w)); } template void push_back(const CGAL::Sphere_segment& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 1) + CGAL::Color c = CGAL::black(), unsigned w = 1) { objects_.push_back(new Sphere_segment(s,c,w)); } template void push_back(const CGAL::Sphere_circle& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 1) + CGAL::Color c = CGAL::black(), unsigned w = 1) { objects_.push_back(new Sphere_circle(s,c,w)); } template void push_back(const CGAL::Sphere_triangle& t, - CGAL::Color c = CGAL::WHITE) + CGAL::Color c = CGAL::white()) { triangles_.push_back(new Sphere_triangle(t,c)); } template void push_back_triangle_edge(const CGAL::Sphere_segment& s, - CGAL::Color c = CGAL::BLUE, unsigned w = 1) + CGAL::Color c = CGAL::blue(), unsigned w = 1) { triangle_edges_.push_back(new Sphere_segment(s,c,w)); } void set_style(int style) { @@ -718,11 +718,11 @@ class SM_BooleColor typedef typename Map_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); } }; diff --git a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp index 63097b27e00..aeed55bfdd3 100644 --- a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp +++ b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp @@ -32,7 +32,7 @@ int main() PDT::Vertex_iterator vit; for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit) if (T.degree(vit) == 6) - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); return 0; } diff --git a/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp b/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp index aa9cd4e4225..989b702679a 100644 --- a/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp +++ b/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp @@ -36,7 +36,7 @@ int main(int, char**) P3DT3::Vertex_iterator vit; for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit) { if (T.degree(vit) == 16) { - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); } } diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp index 57fba3f5d8e..13a5569c3d0 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp @@ -23,6 +23,6 @@ typedef Polyhedron::Halfedge_handle Halfedge_handle; int main() { Polyhedron P; Halfedge_handle h = P.make_tetrahedron(); - h->facet()->color = CGAL::RED; + h->facet()->color = CGAL::red(); return 0; } diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp index 1a29a2674e9..63abfbc9b2a 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp @@ -29,6 +29,6 @@ typedef Polyhedron::Halfedge_handle Halfedge_handle; int main() { Polyhedron P; Halfedge_handle h = P.make_tetrahedron(); - h->vertex()->color = CGAL::RED; + h->vertex()->color = CGAL::red(); return 0; } diff --git a/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp b/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp index 1b806c21fa4..7ab19eccca2 100644 --- a/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp +++ b/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp @@ -47,7 +47,7 @@ int main() { Polyhedron P; P.make_tetrahedron( p,q,r,s); CGAL::Geomview_stream geo; - geo << CGAL::GREEN << P; + geo << CGAL::green() << P; // wait for a mouse click. Point click; diff --git a/Triangulation_2/examples/Triangulation_2/colored_face.cpp b/Triangulation_2/examples/Triangulation_2/colored_face.cpp index cbee32c63ed..84392cd820b 100644 --- a/Triangulation_2/examples/Triangulation_2/colored_face.cpp +++ b/Triangulation_2/examples/Triangulation_2/colored_face.cpp @@ -22,11 +22,11 @@ int main() { t.insert(Point(2,2)); Finite_faces_iterator fc = t.finite_faces_begin(); - for( ; fc != t.finite_faces_end(); ++fc) fc->info() = CGAL::BLUE; + for( ; fc != t.finite_faces_end(); ++fc) fc->info() = CGAL::blue(); Point p(0.5,0.5); Face_handle fh = t.locate(p); - fh->info() = CGAL::RED; + fh->info() = CGAL::red(); return 0; } diff --git a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp index c718b0bb087..8d3615ad60b 100644 --- a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp +++ b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp @@ -66,7 +66,7 @@ int main() Delaunay::Finite_vertices_iterator vit; for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) if (T.degree(vit) == 6) - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); std::cout << " Visualization of T" << std::endl; gv.set_wired(true); diff --git a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp index b7f14bf3808..206531e09c2 100644 --- a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp +++ b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp @@ -136,7 +136,7 @@ int main() std::cout <<" Locating point (1,1,1) :" << std::endl; Point p(1,1,1); - gv.set_vertex_color(CGAL::ORANGE); + gv.set_vertex_color(CGAL::orange()); gv << p; Locate_type lt; int li, lj; @@ -144,7 +144,7 @@ int main() sleep(3); - gv << CGAL::VIOLET; + gv << CGAL::violet(); if ( lt == Triangulation::CELL ) { std::cout <<" CELL" << std::endl; visu_cell(gv,T,c); diff --git a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp index e3fe523bcb2..383285ab01a 100644 --- a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp +++ b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp @@ -74,7 +74,7 @@ int main() gv << T; std::cout <<" Visualizing the Voronoi edges" << std::endl; - gv << CGAL::RED; + gv << CGAL::red(); T.draw_dual(gv); char ch; diff --git a/Triangulation_3/examples/Triangulation_3/color.cpp b/Triangulation_3/examples/Triangulation_3/color.cpp index c1e769c8875..1dbd7bdeb75 100644 --- a/Triangulation_3/examples/Triangulation_3/color.cpp +++ b/Triangulation_3/examples/Triangulation_3/color.cpp @@ -30,7 +30,7 @@ int main() Delaunay::Finite_vertices_iterator vit; for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) if (T.degree(vit) == 6) - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); return 0; } From 9672358b949a07d9795fdf95c55da39dd70e944e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:46:22 +0100 Subject: [PATCH 33/81] Fix missing bracket and add undocumented functions r,g,b,a --- Stream_support/include/CGAL/IO/Color.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Stream_support/include/CGAL/IO/Color.h b/Stream_support/include/CGAL/IO/Color.h index 05119dc6220..cfaa585043d 100644 --- a/Stream_support/include/CGAL/IO/Color.h +++ b/Stream_support/include/CGAL/IO/Color.h @@ -123,7 +123,14 @@ public: */ unsigned char& alpha() { return m_data[3]; } - /// @} + /// \cond SKIP_IN_MANUAL + unsigned char r() const { return red(); } + unsigned char g() const { return green(); } + unsigned char b() const { return blue(); } + unsigned char a() const { return alpha(); } + /// \endcond + + /// @} /// \name Array Access /// @{ @@ -336,9 +343,6 @@ inline Color white() { return Color(255,255,255); } inline Color yellow() { return Color(255,255,0); } -}; - - } //namespace CGAL #endif // CGAL_COLOR_H From 3a941f3f8fc8c39289b1dc6601e40979ecae1b9c Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:46:39 +0100 Subject: [PATCH 34/81] Remove CGAL::Classification::RGB_Color and HSV_Color and just use CGAL::Color everywhere --- Classification/include/CGAL/Classification.h | 1 - .../include/CGAL/Classification/Color.h | 140 ------------------ .../Classification/Feature/Color_channel.h | 10 +- .../Classification/Mesh_feature_generator.h | 2 - .../Point_set_feature_generator.h | 8 +- .../test_classification_point_set.cpp | 10 +- .../Classification/Cluster_classification.cpp | 14 +- .../Classification/Cluster_classification.h | 3 +- .../Point_set_item_classification.cpp | 14 +- .../Point_set_item_classification.h | 3 +- 10 files changed, 27 insertions(+), 178 deletions(-) delete mode 100644 Classification/include/CGAL/Classification/Color.h diff --git a/Classification/include/CGAL/Classification.h b/Classification/include/CGAL/Classification.h index 654aa185cd3..04b3146d322 100644 --- a/Classification/include/CGAL/Classification.h +++ b/Classification/include/CGAL/Classification.h @@ -32,7 +32,6 @@ #endif #include -#include #include #include #include diff --git a/Classification/include/CGAL/Classification/Color.h b/Classification/include/CGAL/Classification/Color.h deleted file mode 100644 index 8b619b9c497..00000000000 --- a/Classification/include/CGAL/Classification/Color.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2017 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_CLASSIFICATION_COLOR_H -#define CGAL_CLASSIFICATION_COLOR_H - -#include -#include -#include -#include - -namespace CGAL { -namespace Classification { - - /*! - \ingroup PkgClassificationColor - - %Color described in red/green/blue space. Each component is stored - as an unsigned char ranging from 0 (no color) to 255 (full color). - */ -typedef CGAL::cpp11::array RGB_Color; - /*! - \ingroup PkgClassificationColor - - %Color described in hue/saturation/value space. Each component is stored - as a float: - - - `hue` ranges from 0° to 360° (corresponding to the color tint) - - `saturation` ranges from 0.0 (gray) to 100.0 (full saturation) - - `value` ranges from 0.0 (black) to 100.0 (white) - */ -typedef CGAL::cpp11::array HSV_Color; - - - /// \cond SKIP_IN_MANUAL -inline HSV_Color rgb_to_hsv (const RGB_Color& c) -{ - double r = (double)(c[0]) / 255.; - double g = (double)(c[1]) / 255.; - double b = (double)(c[2]) / 255.; - double Cmax = (std::max) (r, (std::max) (g, b)); - double Cmin = (std::min) (r, (std::min) (g, b)); - double delta = Cmax - Cmin; - double H = 0.; - - if (delta != 0.) - { - if (Cmax == r) - H = 60. * ((g - b) / delta); - else if (Cmax == g) - H = 60. * (((b - r) / delta) + 2.); - else - H = 60. * (((r - g) / delta) + 4.); - } - if (H < 0.) H += 360.; - double S = (Cmax == 0. ? 0. : 100. * (delta / Cmax)); - double V = 100. * Cmax; - HSV_Color out = {{ float(H), float(S), float(V) }}; - return out; -} - -inline RGB_Color hsv_to_rgb (const HSV_Color& c) -{ - double h = c[0]; - double s = c[1]; - double v = c[2]; - - s /= 100.; - v /= 100.; - double C = v*s; - int hh = (int)(h/60.); - double X = C * (1-CGAL::abs (hh % 2 - 1)); - double r = 0, g = 0, b = 0; - - if( hh>=0 && hh<1 ) - { - r = C; - g = X; - } - else if( hh>=1 && hh<2 ) - { - r = X; - g = C; - } - else if( hh>=2 && hh<3 ) - { - g = C; - b = X; - } - else if( hh>=3 && hh<4 ) - { - g = X; - b = C; - } - else if( hh>=4 && hh<5 ) - { - r = X; - b = C; - } - else - { - r = C; - b = X; - } - double m = v-C; - r += m; - g += m; - b += m; - r *= 255.0; - g *= 255.0; - b *= 255.0; - - RGB_Color out = {{ (unsigned char)r, (unsigned char)g, (unsigned char)b }}; - return out; -} - /// \endcond - -} // namespace Classification -} // namespace CGAL - - - -#endif // CGAL_CLASSIFICATION_COLOR_H diff --git a/Classification/include/CGAL/Classification/Feature/Color_channel.h b/Classification/include/CGAL/Classification/Feature/Color_channel.h index 73ff155f5b8..4d3ecea6459 100644 --- a/Classification/include/CGAL/Classification/Feature/Color_channel.h +++ b/Classification/include/CGAL/Classification/Feature/Color_channel.h @@ -25,7 +25,6 @@ #include -#include #include namespace CGAL { @@ -65,7 +64,7 @@ namespace Feature { `ColorMap`. \tparam ColorMap model of `ReadablePropertyMap` whose key type is the value type of the iterator of `PointRange` and value type - is `CGAL::Classification::RGB_Color`. + is `CGAL::Color`. */ template class Color_channel : public Feature_base @@ -82,9 +81,6 @@ public: private: - typedef typename Classification::RGB_Color RGB_Color; - typedef typename Classification::HSV_Color HSV_Color; - const PointRange& input; ColorMap color_map; Channel m_channel; @@ -111,8 +107,8 @@ public: /// \cond SKIP_IN_MANUAL virtual float value (std::size_t pt_index) { - HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index))); - return c[std::size_t(m_channel)]; + cpp11::array c = get(color_map, *(input.begin()+pt_index)).to_hsv(); + return float(c[std::size_t(m_channel)]); } /// \endcond }; diff --git a/Classification/include/CGAL/Classification/Mesh_feature_generator.h b/Classification/include/CGAL/Classification/Mesh_feature_generator.h index 935abc76a1e..39a7861bb84 100644 --- a/Classification/include/CGAL/Classification/Mesh_feature_generator.h +++ b/Classification/include/CGAL/Classification/Mesh_feature_generator.h @@ -139,8 +139,6 @@ public: typedef Classification::Feature::Verticality Verticality; typedef Classification::Feature::Eigenvalue Eigenvalue; - - typedef typename Classification::RGB_Color RGB_Color; /// \endcond private: diff --git a/Classification/include/CGAL/Classification/Point_set_feature_generator.h b/Classification/include/CGAL/Classification/Point_set_feature_generator.h index 9063d094afb..73ace682780 100644 --- a/Classification/include/CGAL/Classification/Point_set_feature_generator.h +++ b/Classification/include/CGAL/Classification/Point_set_feature_generator.h @@ -140,8 +140,6 @@ public: typedef Classification::Feature::Gradient_of_feature Gradient_of_feature; #endif - - typedef typename Classification::RGB_Color RGB_Color; /// \endcond private: @@ -322,7 +320,7 @@ public: typedef typename Default::Get::type Vmap; - typedef typename Default::Get::type + typedef typename Default::Get::type Cmap; typedef typename Default::Get::type Emap; @@ -335,7 +333,7 @@ public: // Functions to remove when deprecated constructor is removed void generate_normal_based_features(const CGAL::Constant_property_map&) { } - void generate_color_based_features(const CGAL::Constant_property_map&) { } + void generate_color_based_features(const CGAL::Constant_property_map&) { } void generate_echo_based_features(const CGAL::Constant_property_map&) { } #endif @@ -412,7 +410,7 @@ public: \tparam ColorMap model of `ReadablePropertyMap` whose key type is the value type of the iterator of `PointRange` and value type is - `CGAL::Classification::RGB_Color`. + `CGAL::Color`. \param features the feature set where the features are instantiated. \param color_map property map to access the colors of the input points (if any). diff --git a/Classification/test/Classification/test_classification_point_set.cpp b/Classification/test/Classification/test_classification_point_set.cpp index f7092478a70..a8f87b7fd7e 100644 --- a/Classification/test/Classification/test_classification_point_set.cpp +++ b/Classification/test/Classification/test_classification_point_set.cpp @@ -37,7 +37,7 @@ typedef Classification::Point_set_feature_generator Size_t_map; -typedef Point_set::Property_map Color_map; +typedef Point_set::Property_map Color_map; @@ -55,7 +55,7 @@ int main (int, char**) normal_map = pts.normal_map(); boost::tie (echo_map, map_added) = pts.add_property_map ("echo"); assert (map_added); - boost::tie (color_map, map_added) = pts.add_property_map ("color"); + boost::tie (color_map, map_added) = pts.add_property_map ("color"); assert (map_added); for (std::size_t i = 0; i < 1000; ++ i) @@ -68,9 +68,9 @@ int main (int, char**) CGAL::get_default_random().get_double(), CGAL::get_default_random().get_double())); echo_map[*it] = std::size_t(CGAL::get_default_random().get_int(0, 4)); - color_map[*it] = CGAL::make_array ((unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255))); + color_map[*it] = CGAL::Color ((unsigned char)(CGAL::get_default_random().get_int(0, 255)), + (unsigned char)(CGAL::get_default_random().get_int(0, 255)), + (unsigned char)(CGAL::get_default_random().get_int(0, 255))); } Feature_set features; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp index d8e20fd778f..33f4bca43a1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp @@ -303,12 +303,12 @@ void Cluster_classification::backup_existing_colors_and_add_new() { if (m_points->point_set()->has_colors()) { - m_color = m_points->point_set()->add_property_map("real_color").first; + m_color = m_points->point_set()->add_property_map("real_color").first; for (Point_set::const_iterator it = m_points->point_set()->begin(); it != m_points->point_set()->first_selected(); ++ it) - m_color[*it] = {{ (unsigned char)(255 * m_points->point_set()->red(*it)), - (unsigned char)(255 * m_points->point_set()->green(*it)), - (unsigned char)(255 * m_points->point_set()->blue(*it)) }}; + m_color[*it] = CGAL::Color ((unsigned char)(255 * m_points->point_set()->red(*it)), + (unsigned char)(255 * m_points->point_set()->green(*it)), + (unsigned char)(255 * m_points->point_set()->blue(*it))); m_points->point_set()->remove_colors(); } @@ -328,7 +328,7 @@ void Cluster_classification::backup_existing_colors_and_add_new() void Cluster_classification::reset_colors() { - if (m_color == Point_set::Property_map()) + if (m_color == Point_set::Property_map()) m_points->point_set()->remove_colors(); else { @@ -515,7 +515,7 @@ int Cluster_classification::real_index_color() const { int out = m_index_color; - if (out == 0 && m_color == Point_set::Property_map()) + if (out == 0 && m_color == Point_set::Property_map()) out = -1; return out; } @@ -546,7 +546,7 @@ void Cluster_classification::compute_features (std::size_t nb_scales) if (normals) normal_map = m_points->point_set()->normal_map(); - bool colors = (m_color != Point_set::Property_map()); + bool colors = (m_color != Point_set::Property_map()); Point_set::Property_map echo_map; bool echo; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h index 190692f07c4..452346d97b4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h @@ -27,7 +27,6 @@ class Cluster_classification : public Item_classification_base public: typedef Kernel::Point_3 Point_3; typedef Kernel::Vector_3 Vector_3; - typedef CGAL::Classification::RGB_Color Color; typedef Point_set::Point_map Point_map; typedef Point_set::Vector_map Vector_map; @@ -394,7 +393,7 @@ class Cluster_classification : public Item_classification_base Point_set::Property_map m_red; Point_set::Property_map m_green; Point_set::Property_map m_blue; - Point_set::Property_map m_color; + Point_set::Property_map m_color; Point_set::Property_map m_cluster_id; Point_set::Property_map m_training; Point_set::Property_map m_classif; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp index 1096fe5d067..5bde75b7733 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp @@ -247,12 +247,12 @@ void Point_set_item_classification::backup_existing_colors_and_add_new() { if (m_points->point_set()->has_colors()) { - m_color = m_points->point_set()->add_property_map("real_color").first; + m_color = m_points->point_set()->add_property_map("real_color").first; for (Point_set::const_iterator it = m_points->point_set()->begin(); it != m_points->point_set()->first_selected(); ++ it) - m_color[*it] = {{ (unsigned char)(255 * m_points->point_set()->red(*it)), - (unsigned char)(255 * m_points->point_set()->green(*it)), - (unsigned char)(255 * m_points->point_set()->blue(*it)) }}; + m_color[*it] = CGAL::Color((unsigned char)(255 * m_points->point_set()->red(*it)), + (unsigned char)(255 * m_points->point_set()->green(*it)), + (unsigned char)(255 * m_points->point_set()->blue(*it))); m_points->point_set()->remove_colors(); } @@ -272,7 +272,7 @@ void Point_set_item_classification::backup_existing_colors_and_add_new() void Point_set_item_classification::reset_colors() { - if (m_color == Point_set::Property_map()) + if (m_color == Point_set::Property_map()) m_points->point_set()->remove_colors(); else { @@ -413,7 +413,7 @@ int Point_set_item_classification::real_index_color() const { int out = m_index_color; - if (out == 0 && m_color == Point_set::Property_map()) + if (out == 0 && m_color == Point_set::Property_map()) out = -1; return out; } @@ -447,7 +447,7 @@ void Point_set_item_classification::compute_features (std::size_t nb_scales) if (normals) normal_map = m_points->point_set()->normal_map(); - bool colors = (m_color != Point_set::Property_map()); + bool colors = (m_color != Point_set::Property_map()); Point_set::Property_map echo_map; bool echo; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h index 7390bd3a8e3..76f19de0921 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h @@ -29,7 +29,6 @@ class Point_set_item_classification : public Item_classification_base public: typedef Kernel::Point_3 Point_3; typedef Kernel::Vector_3 Vector_3; - typedef CGAL::Classification::RGB_Color Color; typedef Point_set::Point_map Point_map; typedef Point_set::Vector_map Vector_map; @@ -370,7 +369,7 @@ class Point_set_item_classification : public Item_classification_base Point_set::Property_map m_red; Point_set::Property_map m_green; Point_set::Property_map m_blue; - Point_set::Property_map m_color; + Point_set::Property_map m_color; Point_set::Property_map m_training; Point_set::Property_map m_classif; From f0a798719ded739f4689efc632dfd3710a986455 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:50:48 +0100 Subject: [PATCH 35/81] Remove deprecated parts of Classification --- .../CGAL/Classification/Feature/Eigen.h | 431 ------------------ .../include/CGAL/Classification/Feature/Hsv.h | 175 ------- .../Point_set_feature_generator.h | 58 --- .../test/Classification/CMakeLists.txt | 8 - ...precated_test_classification_point_set.cpp | 136 ------ 5 files changed, 808 deletions(-) delete mode 100644 Classification/include/CGAL/Classification/Feature/Eigen.h delete mode 100644 Classification/include/CGAL/Classification/Feature/Hsv.h delete mode 100644 Classification/test/Classification/deprecated_test_classification_point_set.cpp diff --git a/Classification/include/CGAL/Classification/Feature/Eigen.h b/Classification/include/CGAL/Classification/Feature/Eigen.h deleted file mode 100644 index 793e3433449..00000000000 --- a/Classification/include/CGAL/Classification/Feature/Eigen.h +++ /dev/null @@ -1,431 +0,0 @@ -// Copyright (c) 2017 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_CLASSIFICATION_FEATURES_EIGEN_H -#define CGAL_CLASSIFICATION_FEATURES_EIGEN_H - -#include - -#include -#include -#include - -/// \cond SKIP_IN_MANUAL -#ifndef CGAL_NO_DEPRECATED_CODE - -namespace CGAL { - -namespace Classification { - -namespace Feature { - -class Eigen_feature : public Feature_base -{ -protected: -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - std::vector attrib; -#else - const Classification::Local_eigen_analysis& eigen; -#endif - -public: - template - Eigen_feature (const InputRange&, - const Classification::Local_eigen_analysis& eigen) -#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - : eigen (eigen) -#endif - { - } - -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - virtual void init (std::size_t size, const Classification::Local_eigen_analysis& eigen) - { - attrib.reserve (size); - for (std::size_t i = 0; i < size; ++ i) - attrib.push_back (get_value (eigen, i)); - } -#else - virtual void init (std::size_t, const Classification::Local_eigen_analysis&) - { - } -#endif - - virtual float get_value (const Classification::Local_eigen_analysis& eigen, std::size_t i) = 0; - virtual float value (std::size_t pt_index) - { -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - return attrib[pt_index]; -#else - return get_value(eigen, pt_index); -#endif - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Linearity is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_1 - \lambda_2}{\lambda_1} - \f] - - Its default name is "linearity". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Linearity, please update your code with Eigenvalue instead") -class Linearity -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \tparam Input model of `ConstRange`. Its iterator type - is `RandomAccessIterator`. - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Linearity (const InputRange& input, - const Local_eigen_analysis& eigen) : Eigen_feature (input, eigen) - { - this->set_name("linearity"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return ((ev[2] - ev[1]) / ev[2]); - } -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Planarity is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_2 - \lambda_3}{\lambda_1} - \f] - - Its default name is "planarity". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Planarity, please update your code with Eigenvalue instead") -class Planarity -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Planarity (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("planarity"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return ((ev[1] - ev[0]) / ev[2]); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Sphericity is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_3}{\lambda_1} - \f] - - Its default name is "sphericity". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Sphericity, please update your code with Eigenvalue instead") -class Sphericity -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Sphericity (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("sphericity"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return (ev[0] / ev[2]); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Omnivariance is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - (\lambda_1 \times \lambda_2 \times \lambda_3)^{\frac{1}{3}} - \f] - - Its default name is "omnivariance". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Omnivariance, please update your code with Eigenvalue instead") -class Omnivariance -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Omnivariance (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("omnivariance"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - return (std::pow (CGAL::abs(ev[0] * ev[1] * ev[2]), 0.333333333f)); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Anisotropy is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_1 - \lambda_3}{\lambda_1} - \f] - - Its default name is "anisotropy". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Anisotropy, please update your code with Eigenvalue instead") -class Anisotropy -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Anisotropy (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("anisotropy"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return ((ev[2] - ev[0]) / ev[2]); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Eigentropy is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - - \sum_{i=1}^3 \lambda_i \times \log{\lambda_i} - \f] - - Its default name is "eigentropy". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Eigentropy, please update your code with Eigenvalue instead") -class Eigentropy -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Eigentropy (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("eigentropy"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[0] < 1e-15 - || ev[1] < 1e-15 - || ev[2] < 1e-15) - return 0.; - else - return (- ev[0] * std::log(ev[0]) - - ev[1] * std::log(ev[1]) - - ev[2] * std::log(ev[2])); - } - -}; - - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance - matrix of a local neighborhood. Surface variation is defined, for - the 3 eigenvalues \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge - 0\f$, as: - - \f[ - \frac{\lambda_3}{\lambda_1 + \lambda_2 + \lambda_3} - \f] - - Its default name is "surface_variation". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Surface_variation, please update your code with Eigenvalue instead") -class Surface_variation -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Surface_variation (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("surface_variation"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[0] + ev[1] + ev[2] < 1e-15) - return 0.; - else - return (ev[0] / (ev[0] + ev[1] + ev[2])); - } - -}; - -} // namespace Feature - -} // namespace Classification - -} // namespace CGAL - -#endif -/// \endcond - -#endif // CGAL_CLASSIFICATION_FEATURES_EIGEN_H diff --git a/Classification/include/CGAL/Classification/Feature/Hsv.h b/Classification/include/CGAL/Classification/Feature/Hsv.h deleted file mode 100644 index 536d6aaa5b0..00000000000 --- a/Classification/include/CGAL/Classification/Feature/Hsv.h +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2017 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_CLASSIFICATION_FEATURE_HSV_H -#define CGAL_CLASSIFICATION_FEATURE_HSV_H - -#include - -#include - -#include -#include - -/// \cond SKIP_IN_MANUAL -#ifndef CGAL_NO_DEPRECATED_CODE - -namespace CGAL { - -namespace Classification { - -namespace Feature { - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on HSV colorimetric information. If the input - point cloud has colorimetric information, it can be used for - classification purposes. This feature is based on a Gaussian - probabilistic model on one of the three HSV channels (hue, - saturation or value). It computes the probability of the color of - the input point to match this specific color channel defined by a - mean and a standard deviation. - - The HSV channels are defined this way: - - - Hue ranges from 0 to 360 and measures the general "tint" of the - color (green, blue, pink, etc.) - - - Saturation ranges from 0 to 100 and measures the "strength" of the - color (0 is gray and 100 is the fully saturated color) - - - Value ranges from 0 to 100 and measures the "brightness" of the - color (0 is black and 100 is the fully bright color) - - For example, such an feature using the channel 0 (hue) with a - mean of 90 (which corresponds to a green hue) can help to identify - trees. - - \image html trees.png - -

Left: input point set with colors. Right: HSV feature on hue with - a mean of 90 (from low values in white to high values in dark - red).
- - Its default name is the channel followed by the mean value (for - example: "hue_180", "saturation_20" or "value_98"). - - \note The user only needs to provide a map to standard (and more common) - RGB colors, the conversion to HSV is done internally. - - \tparam GeomTraits model of \cgal Kernel. - \tparam PointRange model of `ConstRange`. Its iterator type - is `RandomAccessIterator` and its value type is the key type of - `ColorMap`. - \tparam ColorMap model of `ReadablePropertyMap` whose key - type is the value type of the iterator of `PointRange` and value type - is `CGAL::Classification::RGB_Color`. - */ -template -CGAL_DEPRECATED_MSG("you are using the deprecated feature Hsv, please update your code with Color_channel instead") -class Hsv : public Feature_base -{ -public: - - /// Selected channel. - enum Channel - { - HUE = 0, ///< 0 - SATURATION = 1, ///< 1 - VALUE = 2 ///< 2 - }; - -private: - - typedef typename Classification::RGB_Color RGB_Color; - typedef typename Classification::HSV_Color HSV_Color; - -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - std::vector color_feature; -#else - const PointRange& input; - ColorMap color_map; - Channel m_channel; - float m_mean; - float m_sd; -#endif - -public: - - /*! - - \brief Constructs a feature based on the given color channel, - mean and standard deviation. - - \param input point range. - \param color_map property map to access the colors of the input points. - \param channel chosen HSV channel. - \param mean mean value of the specified channel. - \param sd standard deviation of the specified channel. - */ - Hsv (const PointRange& input, - ColorMap color_map, - Channel channel, - float mean, float sd) -#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - : input(input), color_map(color_map), m_channel(channel), m_mean(mean), m_sd(sd) -#endif - { - -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - for(std::size_t i = 0; i < input.size();i++) - { - HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+i))); - color_feature.push_back (std::exp (-(c[std::size_t(channel)] - mean) - * (c[std::size_t(channel)] - mean) / (2. * sd * sd))); - } -#endif - std::ostringstream oss; - if (channel == HUE) oss << "hue"; - else if (channel == SATURATION) oss << "saturation"; - else if (channel == VALUE) oss << "value"; - oss << "_" << mean; - this->set_name (oss.str()); - } - - virtual float value (std::size_t pt_index) - { -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - return color_feature[pt_index]; -#else - HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index))); - return std::exp (-(c[std::size_t(m_channel)] - m_mean) - * (c[std::size_t(m_channel)] - m_mean) / (2.f * m_sd * m_sd)); -#endif - } - -}; - -} // namespace Feature - -} // namespace Classification - -} // namespace CGAL - -#endif -/// \endcond - -#endif // CGAL_CLASSIFICATION_FEATURE_HSV_H diff --git a/Classification/include/CGAL/Classification/Point_set_feature_generator.h b/Classification/include/CGAL/Classification/Point_set_feature_generator.h index 73ace682780..3cb6f05dc5f 100644 --- a/Classification/include/CGAL/Classification/Point_set_feature_generator.h +++ b/Classification/include/CGAL/Classification/Point_set_feature_generator.h @@ -279,64 +279,6 @@ public: /// @} /// \cond SKIP_IN_MANUAL - -#ifndef CGAL_NO_DEPRECATED_CODE - // deprecated - template - CGAL_DEPRECATED_MSG("you are using a deprecated constructor of CGAL::Classification::Point_set_feature_generator, please update your code") - Point_set_feature_generator(Feature_set& features, - const PointRange& input, - PointMap point_map, - std::size_t nb_scales, - VectorMap normal_map = VectorMap(), - ColorMap color_map = ColorMap(), - EchoMap echo_map = EchoMap(), - float voxel_size = -1.f) - : m_input (input), m_point_map (point_map) - { - m_bbox = CGAL::bounding_box - (boost::make_transform_iterator (m_input.begin(), CGAL::Property_map_to_unary_function(m_point_map)), - boost::make_transform_iterator (m_input.end(), CGAL::Property_map_to_unary_function(m_point_map))); - - CGAL::Real_timer t; t.start(); - - m_scales.reserve (nb_scales); - - m_scales.push_back (new Scale (m_input, m_point_map, m_bbox, voxel_size)); - - if (voxel_size == -1.f) - voxel_size = m_scales[0]->grid_resolution(); - - for (std::size_t i = 1; i < nb_scales; ++ i) - { - voxel_size *= 2; - m_scales.push_back (new Scale (m_input, m_point_map, m_bbox, voxel_size, m_scales[i-1]->grid)); - } - t.stop(); - CGAL_CLASSIFICATION_CERR << "Scales computed in " << t.time() << " second(s)" << std::endl; - t.reset(); - - typedef typename Default::Get::type - Vmap; - typedef typename Default::Get::type - Cmap; - typedef typename Default::Get::type - Emap; - - generate_point_based_features (features); - generate_normal_based_features (features, get_parameter(normal_map)); - generate_color_based_features (features, get_parameter(color_map)); - generate_echo_based_features (features, get_parameter(echo_map)); - } - - // Functions to remove when deprecated constructor is removed - void generate_normal_based_features(const CGAL::Constant_property_map&) { } - void generate_color_based_features(const CGAL::Constant_property_map&) { } - void generate_echo_based_features(const CGAL::Constant_property_map&) { } -#endif - virtual ~Point_set_feature_generator() { clear(); diff --git a/Classification/test/Classification/CMakeLists.txt b/Classification/test/Classification/CMakeLists.txt index fd5d89785b2..f6967a11db1 100644 --- a/Classification/test/Classification/CMakeLists.txt +++ b/Classification/test/Classification/CMakeLists.txt @@ -89,14 +89,6 @@ if(TARGET test_classification_point_set) endif() endif() -create_single_source_cgal_program( "deprecated_test_classification_point_set.cpp" CXX_FEATURES ${needed_cxx_features} ) -if(TARGET deprecated_test_classification_point_set) - target_link_libraries(deprecated_test_classification_point_set PUBLIC ${classification_linked_libraries}) - if (TBB_FOUND) - CGAL_target_use_TBB( deprecated_test_classification_point_set ) - endif() -endif() - create_single_source_cgal_program( "test_classification_io.cpp" CXX_FEATURES ${needed_cxx_features} ) if(TARGET test_classification_io) target_link_libraries(test_classification_io PUBLIC ${classification_linked_libraries}) diff --git a/Classification/test/Classification/deprecated_test_classification_point_set.cpp b/Classification/test/Classification/deprecated_test_classification_point_set.cpp deleted file mode 100644 index 45f5a92fdc3..00000000000 --- a/Classification/test/Classification/deprecated_test_classification_point_set.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include - -#if defined (_MSC_VER) && !defined (_WIN64) -#pragma warning(disable:4244) // boost::number_distance::distance() - // converts 64 to 32 bits integers -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include - -typedef CGAL::Simple_cartesian Kernel; -typedef Kernel::Point_3 Point; -typedef Kernel::Vector_3 Vector; - -typedef CGAL::Point_set_3 Point_set; -typedef Point_set::Point_map Point_map; - -typedef Kernel::Iso_cuboid_3 Iso_cuboid_3; - -namespace Classification = CGAL::Classification; - -typedef Classification::Label_handle Label_handle; -typedef Classification::Feature_handle Feature_handle; -typedef Classification::Label_set Label_set; -typedef Classification::Feature_set Feature_set; - -typedef Classification::Sum_of_weighted_features_classifier Classifier; - -typedef Classification::Point_set_feature_generator Feature_generator; - -typedef Point_set::Property_map Size_t_map; -typedef Point_set::Property_map Color_map; - - - -int main (int, char**) -{ - Point_set pts; - - pts.add_normal_map(); - - bool map_added = false; - Size_t_map echo_map; - Color_map color_map; - - boost::tie (echo_map, map_added) = pts.add_property_map ("echo"); - assert (map_added); - boost::tie (color_map, map_added) = pts.add_property_map ("color"); - assert (map_added); - - for (std::size_t i = 0; i < 1000; ++ i) - { - Point_set::iterator it - = pts.insert (Point (CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double()), - Vector (CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double())); - echo_map[*it] = std::size_t(CGAL::get_default_random().get_int(0, 4)); - color_map[*it] = CGAL::make_array ((unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255))); - } - - Feature_set features; - Feature_generator generator (features, pts, pts.point_map(), - 5, // using 5 scales - pts.normal_map(), - color_map, echo_map); - - assert (generator.number_of_scales() == 5); - assert (features.size() == 44); - - Label_set labels; - - std::vector training_set (pts.size(), -1); - for (std::size_t i = 0; i < 20; ++ i) - { - std::ostringstream oss; - oss << "label_" << i; - Label_handle lh = labels.add(oss.str().c_str()); - - for (std::size_t j = 0; j < 10; ++ j) - training_set[std::size_t(CGAL::get_default_random().get_int(0, int(training_set.size())))] = int(i); - } - assert (labels.size() == 20); - - Classifier classifier (labels, features); - - classifier.train (training_set, 800); -#ifdef CGAL_LINKED_WITH_TBB - classifier.train (training_set, 800); -#endif - - std::vector label_indices(pts.size(), -1); - - Classification::classify - (pts, labels, classifier, label_indices); - - Classification::classify_with_local_smoothing - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().sphere_neighbor_query(0.01f), - label_indices); - - Classification::classify_with_graphcut - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().k_neighbor_query(12), - 0.2f, 10, label_indices); - -#ifdef CGAL_LINKED_WITH_TBB - Classification::classify - (pts, labels, classifier, label_indices); - - Classification::classify_with_local_smoothing - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().sphere_neighbor_query(0.01f), - label_indices); - - Classification::classify_with_graphcut - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().k_neighbor_query(12), - 0.2f, 10, label_indices); -#endif - - Classification::Evaluation evaluation (labels, training_set, label_indices); - - return EXIT_SUCCESS; -} From 2d7ed851a1cb3a856b75cc0b6bc8d90b9940bd94 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 15:21:09 +0100 Subject: [PATCH 36/81] Fix Color IO in binary + handle alpha --- Stream_support/include/CGAL/IO/io.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Stream_support/include/CGAL/IO/io.h b/Stream_support/include/CGAL/IO/io.h index 679565c8480..eb67fd391aa 100644 --- a/Stream_support/include/CGAL/IO/io.h +++ b/Stream_support/include/CGAL/IO/io.h @@ -393,39 +393,45 @@ std::ostream& operator<<( std::ostream& out, const Color& col) switch(get_mode(out)) { case IO::ASCII : return out << static_cast(col.red()) << ' ' - << static_cast(col.green()) << ' ' - << static_cast(col.blue()); + << static_cast(col.green()) << ' ' + << static_cast(col.blue()) << ' ' + << static_cast(col.alpha()); case IO::BINARY : - write(out, static_cast(col.red())); - write(out, static_cast(col.green())); - write(out, static_cast(col.blue())); + out.write(reinterpret_cast(col.to_rgba().data()), 4); return out; default: return out << "Color(" << static_cast(col.red()) << ", " - << static_cast(col.green()) << ", " - << static_cast(col.blue()) << ')'; + << static_cast(col.green()) << ", " + << static_cast(col.blue()) << ", " + << static_cast(col.alpha()) << ")"; } } inline std::istream &operator>>(std::istream &is, Color& col) { - int r = 0, g = 0, b = 0; + unsigned char r = 0, g = 0, b = 0, a = 0; + int ir = 0, ig = 0, ib = 0, ia = 0; switch(get_mode(is)) { case IO::ASCII : - is >> r >> g >> b; + is >> ir >> ig >> ib >> ia; + r = (unsigned char)ir; + g = (unsigned char)ig; + b = (unsigned char)ib; + a = (unsigned char)ia; break; case IO::BINARY : read(is, r); read(is, g); read(is, b); + read(is, a); break; default: std::cerr << "" << std::endl; std::cerr << "Stream must be in ascii or binary mode" << std::endl; break; } - col = Color((unsigned char)r,(unsigned char)g,(unsigned char)b); + col = Color(r,g,b,a); return is; } From 3e8810f1814709901ab3a7794d46e82c783f2a5f Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 15:51:53 +0100 Subject: [PATCH 37/81] Remove now useless Color_impl.h file --- Stream_support/include/CGAL/IO/Color_impl.h | 43 --------------------- 1 file changed, 43 deletions(-) delete mode 100644 Stream_support/include/CGAL/IO/Color_impl.h diff --git a/Stream_support/include/CGAL/IO/Color_impl.h b/Stream_support/include/CGAL/IO/Color_impl.h deleted file mode 100644 index 340facebed0..00000000000 --- a/Stream_support/include/CGAL/IO/Color_impl.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 1997 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// -// Author(s) : Andreas Fabri, Hervé Brönnimann - -namespace CGAL { - -const Color BLACK = Color(0, 0, 0); -const Color WHITE = Color(255, 255, 255); -const Color GRAY = Color(100,100,100); - -const Color GREEN = Color(0, 255, 0); - -const Color DEEPBLUE = Color(10, 0, 100); -const Color BLUE = Color(0, 0, 255); -const Color VIOLET = Color(255, 0, 255); -const Color PURPLE = Color(100, 0, 70); - -const Color RED = Color(255, 0, 0); -const Color ORANGE = Color(235, 150, 0); -const Color YELLOW = Color(255, 255, 0); - -} //namespace CGAL From ce125cf020f781e19a10fae3644353e40554d16e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 16:09:45 +0100 Subject: [PATCH 38/81] Better documentation and handling alpha in colors --- .../include/CGAL/Surface_mesh/Surface_mesh.h | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index dd62434e350..beccbfdedff 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2161,7 +2161,9 @@ private: //------------------------------------------------------- private data /// \relates Surface_mesh /// Inserts the surface mesh in an output stream in PLY format. - /// All vertex and face properties with simple types are inserted in the stream. + /// If found, "v:normal", "v:color" and "f:color" are inserted in the stream. + /// All other vertex and face properties with simple types are inserted in the stream. + /// \relates Surface_mesh template bool write_ply(std::ostream& os, const Surface_mesh

& sm, const std::string& comments = std::string()) { @@ -2275,7 +2277,8 @@ private: //------------------------------------------------------- private data { os << "property uchar red" << std::endl << "property uchar green" << std::endl - << "property uchar blue" << std::endl; + << "property uchar blue" << std::endl + << "property uchar alpha" << std::endl; vprinters.push_back (new internal::PLY::Property_printer(pmap)); continue; @@ -2409,7 +2412,8 @@ private: //------------------------------------------------------- private data { os << "property uchar red" << std::endl << "property uchar green" << std::endl - << "property uchar blue" << std::endl; + << "property uchar blue" << std::endl + << "property uchar alpha" << std::endl; fprinters.push_back (new internal::PLY::Property_printer(pmap)); continue; @@ -2754,11 +2758,26 @@ private: //------------------------------------------------------- private data /// \relates Surface_mesh /// Extracts the surface mesh from an input stream in Ascii or - /// Binary PLY format and appends it to the surface mesh `sm`. The - /// operator reads all properties for vertices and faces found in - /// the PLY input. + /// Binary PLY format and appends it to the surface mesh `sm`. + /// + /// - the operator reads the vertex `point` property and the face + /// `vertex_index` (or `vertex_indices`) property; + /// - if three PLY properties `nx`, `ny` and `nz` with type `float` + /// or `double` are found for vertices, a "v:normal" vertex + /// property map is added; + /// - if three PLY properties `red`, `green` and `blue` with type + /// `uchar` are found for vertices, a "v:color" vertex property + /// map is added; + /// - if three PLY properties `red`, `green` and `blue` with type + /// `uchar` are found for faces, a "f:color" face property map is + /// added; + /// - if any other PLY property is found, a "[s]:[name]" property map is + /// added, where `[s]` is `v` for vertex and `f` for face, and + /// `[name]` is the name of PLY property. + /// /// \pre The data in the stream must represent a two-manifold. If this is not the case /// the `failbit` of `is` is set and the mesh cleared. + /// \relates Surface_mesh template bool read_ply(std::istream& is, Surface_mesh

& sm, std::string& comments) From 8a4f4bb0e72bcafa379a4a85d5e3302170c1b3b2 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 17 Jul 2018 12:09:15 +0200 Subject: [PATCH 39/81] Better remove() / is_removed() methods --- Point_set_3/include/CGAL/Point_set_3.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index fa44d2404ee..84aa7ed209a 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -590,7 +590,10 @@ public: */ void remove (const Index& index) { - remove (m_indices.begin() + index); + iterator it = m_indices.begin() + index; + while (*it != index) + it = m_indices.begin() + *it; + remove (it); } @@ -610,6 +613,14 @@ public: return (std::distance (it, garbage_begin()) <= 0); } + bool is_removed (const Index& index) const + { + const_iterator it = m_indices.begin() + index; + while (*it != index) + it = m_indices.begin() + *it; + return is_removed (it); + } + /*! \brief Returns the constant iterator to the first element marked as removed (equal to `garbage_end()` if no elements are marked as removed. From f852b73ae7668587441857e6176eba858c63168e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 13 Aug 2018 11:29:13 +0200 Subject: [PATCH 40/81] Unify API of add_normal_map() with add_property_map() --- Point_set_3/include/CGAL/Point_set_3.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 84aa7ed209a..30ffac0d945 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -784,14 +784,15 @@ public: This method adds a property of type `Vector` and named `normal`. - \return `true` if the property was added, `false` if it already - existed. + \return Returns a pair containing the normal map and a Boolean + that is `true` if the property was added and `false` if it already + exists (and was therefore not added but only returned). */ - bool add_normal_map (const Vector& default_value = Vector(0., 0., 0.)) + std::pair add_normal_map (const Vector& default_value = Vector(0., 0., 0.)) { bool out = false; boost::tie (m_normals, out) = this->add_property_map ("normal", default_value); - return out; + return std::make_pair (m_normals, out); } /*! \brief Returns the property map of the normal property. From ba1a1963ec98207ae7f8f21744852bea283d2524 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 13 Aug 2018 11:29:51 +0200 Subject: [PATCH 41/81] Update selection in demo with latest Point_set_3 improvments --- .../Point_set/Point_set_selection_plugin.cpp | 114 +++++++----------- .../demo/Polyhedron/include/Point_set_3.h | 32 ++--- 2 files changed, 59 insertions(+), 87 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index 9b9c5853770..4e9acfd60a1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp @@ -89,10 +89,9 @@ public: void apply (std::size_t i) const { - Point_set::const_iterator it = point_set->begin() + i; - bool already_selected = point_set->is_selected (it); + Point_set::Index idx = *(point_set->begin() + i); - const Kernel::Point_3& p = point_set->point (*it); + const Kernel::Point_3& p = point_set->point (idx); CGAL::qglviewer::Vec vp (p.x (), p.y (), p.z ()); bool now_selected = false; if(!ui_widget.box->isChecked()) @@ -115,13 +114,17 @@ public: } if (ui_widget.new_selection->isChecked()) - selected[i] = now_selected; - else if (ui_widget.union_selection->isChecked()) - selected[i] = (already_selected || now_selected); - else if (ui_widget.intersection->isChecked()) - selected[i] = (already_selected && now_selected); - else if (ui_widget.diff->isChecked()) - selected[i] = (already_selected && !now_selected); + selected[idx] = now_selected; + else + { + bool already_selected = point_set->is_selected (idx); + if (ui_widget.union_selection->isChecked()) + selected[idx] = (already_selected || now_selected); + else if (ui_widget.intersection->isChecked()) + selected[idx] = (already_selected && now_selected); + else if (ui_widget.diff->isChecked()) + selected[idx] = (already_selected && !now_selected); + } } }; @@ -183,26 +186,13 @@ public: selected_bitmap[nit->first] = true; } - std::vector unselected, selected; - - for(Point_set::iterator it = points_item->point_set()->begin (); - it != points_item->point_set()->end(); ++ it) - if (points_item->point_set()->is_selected(it) || selected_bitmap[*it]) - selected.push_back (*it); - else - unselected.push_back (*it); - - for (std::size_t i = 0; i < unselected.size(); ++ i) - *(points_item->point_set()->begin() + i) = unselected[i]; - for (std::size_t i = 0; i < selected.size(); ++ i) - *(points_item->point_set()->begin() + (unselected.size() + i)) = selected[i]; - - if (selected.empty ()) - points_item->point_set()->unselect_all(); - else + Point_set::iterator it = points_item->point_set()->begin (); + while (it != points_item->point_set()->first_selected()) { - points_item->point_set()->set_first_selected - (points_item->point_set()->begin() + unselected.size()); + if (selected_bitmap[*it]) + points_item->point_set()->select(*it); + else + ++ it; } points_item->invalidateOpenGLBuffers(); @@ -235,29 +225,14 @@ public: } } - std::vector unselected, selected; + Point_set::iterator it = points_item->point_set()->first_selected (); + while (it != points_item->point_set()->end()) + { + if (!selected_bitmap[*it]) + points_item->point_set()->unselect(*it); - for(Point_set::iterator it = points_item->point_set()->begin (); - it != points_item->point_set()->end(); ++ it) - if (points_item->point_set()->is_selected(it) && selected_bitmap[*it]) - selected.push_back (*it); - else - unselected.push_back (*it); - - for (std::size_t i = 0; i < unselected.size(); ++ i) - *(points_item->point_set()->begin() + i) = unselected[i]; - for (std::size_t i = 0; i < selected.size(); ++ i) - *(points_item->point_set()->begin() + (unselected.size() + i)) = selected[i]; - - if (selected.empty ()) - { - points_item->point_set()->unselect_all(); - } - else - { - points_item->point_set()->set_first_selected - (points_item->point_set()->begin() + unselected.size()); - } + ++ it; + } points_item->invalidateOpenGLBuffers(); points_item->itemChanged(); @@ -652,32 +627,25 @@ protected Q_SLOTS: selection_test.apply(i); #endif - std::vector unselected, selected; - for (std::size_t i = 0; i < points->size(); ++ i) + Point_set::iterator it = points->begin (); + Point_set::iterator first_selected = points->first_selected (); + while (it != points->first_selected()) { - Point_set::Index idx = *(points->begin() + i); - if (selected_bitmap[i]) - selected.push_back (idx); + if (selected_bitmap[*it]) + points->select(*it); else - unselected.push_back (idx); + ++ it; + } + + it = first_selected; + while (it != points->end()) + { + if (!selected_bitmap[*it]) + points->unselect(*it); + + ++ it; } - delete[] selected_bitmap; - - for (std::size_t i = 0; i < unselected.size(); ++ i) - *(points->begin() + i) = unselected[i]; - for (std::size_t i = 0; i < selected.size(); ++ i) - *(points->begin() + (unselected.size() + i)) = selected[i]; - if (selected.empty ()) - { - points->unselect_all(); - } - else - { - points->set_first_selected - (points->begin() + unselected.size()); - } - point_set_item->invalidateOpenGLBuffers(); point_set_item->itemChanged(); } diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index 8697f75c2cf..4f992825396 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -333,6 +333,12 @@ public: { return this->is_removed (it); } + + // Test if point is selected + bool is_selected(const Index& idx) const + { + return this->is_removed (idx); + } /// Gets the number of selected points. std::size_t nb_selected_points() const @@ -341,21 +347,19 @@ public: } /// Mark a point as selected/not selected. - void select(iterator it, bool selected = true) + void select(const Index& index) { - bool currently = is_selected (it); - iterator first = this->first_selected(); - --first; - if (currently && !selected) - { - std::swap (*it, *first); - -- this->m_nb_removed; - } - else if (!currently && selected) - { - std::swap (*it, *first); - ++ this->m_nb_removed; - } + this->remove(index); + } + + /// Mark a point as selected/not selected. + void unselect(const Index& index) + { + iterator it = this->m_indices.begin() + index; + while (*it != index) + it = this->m_indices.begin() + *it; + std::iter_swap (it, first_selected()); + this->m_nb_removed --; } void select_all() From ae2b9c15b16d677370552a78f9e576f8f8c6c8f2 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 13 Aug 2018 15:48:29 +0200 Subject: [PATCH 42/81] Cleanup: no rearrangement of indices for display, use external vector --- .../Scene_points_with_normal_item.cpp | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index 1bdc1b7058e..bcf4b4c34fa 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -135,6 +135,7 @@ struct Scene_points_with_normal_item_priv class Fill_buffers { Point_set* point_set; + std::vector& indices; std::vector& positions_lines; std::vector& positions_normals; bool has_normals; @@ -145,6 +146,7 @@ class Fill_buffers { public: Fill_buffers(Point_set* point_set, + std::vector& indices, std::vector& positions_lines, std::vector& positions_normals, bool has_normals, @@ -152,6 +154,7 @@ public: double length, std::size_t offset_normal_indices = 0) : point_set (point_set) + , indices (indices) , positions_lines (positions_lines) , positions_normals (positions_normals) , has_normals (has_normals) @@ -175,8 +178,8 @@ public: void apply (std::size_t i) const { - Point_set::const_iterator it = point_set->begin() + i; - const Kernel::Point_3& p = point_set->point(*it); + const Point_set::Index& idx = indices[i]; + const Kernel::Point_3& p = point_set->point(idx); positions_lines[i * size_p ] = p.x() + offset.x; positions_lines[i * size_p + 1] = p.y() + offset.y; @@ -184,7 +187,7 @@ public: if(has_normals) { - const Kernel::Vector_3& n = point_set->normal(*it); + const Kernel::Vector_3& n = point_set->normal(idx); Point_set_3::Point q = p + length * n; positions_lines[i * size_p + 3] = q.x() + offset.x; positions_lines[i * size_p + 4] = q.y() + offset.y; @@ -413,9 +416,14 @@ void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const colors_points.resize(0); //Shuffle container to allow quick display random points - CGAL::cpp98::random_shuffle (m_points->begin(), m_points->first_selected()); + std::vector indices; + indices.reserve (m_points->size()); + std::copy (m_points->begin(), m_points->end(), std::back_inserter(indices)); + + CGAL::cpp98::random_shuffle (indices.begin(), indices.end() - m_points->nb_selected_points()); if (m_points->nb_selected_points() != 0) - CGAL::cpp98::random_shuffle (m_points->first_selected(), m_points->end()); + CGAL::cpp98::random_shuffle (indices.end() - m_points->nb_selected_points(), indices.end()); + //if item has normals, points will be one point out of two in the lines data. //else points will be lines and lines discarded. double average_spacing = 0; @@ -439,24 +447,24 @@ void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const positions_lines.resize(m_points->size() * 3); } - Fill_buffers fill_buffers (m_points, positions_lines, positions_normals, + Fill_buffers fill_buffers (m_points, indices, positions_lines, positions_normals, item->has_normals(), offset, normal_length * length_factor); - Fill_buffers fill_buffers_2 (m_points, positions_lines, positions_selected_normals, + Fill_buffers fill_buffers_2 (m_points, indices, positions_lines, positions_selected_normals, item->has_normals(), offset, normal_length * length_factor, m_points->first_selected() - m_points->begin()); #ifdef CGAL_LINKED_WITH_TBB tbb::parallel_for(tbb::blocked_range(0, - m_points->first_selected() - m_points->begin()), + m_points->size() - m_points->nb_selected_points()), fill_buffers); - tbb::parallel_for(tbb::blocked_range(m_points->first_selected() - m_points->begin(), + tbb::parallel_for(tbb::blocked_range(m_points->size() - m_points->nb_selected_points(), m_points->size()), fill_buffers_2); #else - for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->first_selected(); ++it) - fill_buffers.apply (it - m_points->begin()); - for (Point_set_3::const_iterator it = m_points->first_selected(); it != m_points->end(); ++it) - fill_buffers_2.apply (it - m_points->begin()); + for (std::size_t i = 0; i < indices.size() - m_points->nb_selected_points(); ++ i) + fill_buffers.apply (i); + for (std::size_t i = indices.size() - m_points->nb_selected_points(); i < indices.size(); ++ i) + fill_buffers_2.apply (i); #endif //The colors @@ -464,15 +472,15 @@ void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const { colors_points.reserve((m_points->size() - m_points->nb_selected_points()) * 6); - for (Point_set_3::const_iterator it = m_points->begin(); it != m_points->end(); ++it) - { - colors_points.push_back (m_points->red(*it)); - colors_points.push_back (m_points->green(*it)); - colors_points.push_back (m_points->blue(*it)); - colors_points.push_back (m_points->red(*it)); - colors_points.push_back (m_points->green(*it)); - colors_points.push_back (m_points->blue(*it)); - } + for (std::size_t i = 0; i < indices.size() - m_points->nb_selected_points(); ++ i) + { + colors_points.push_back (m_points->red(indices[i])); + colors_points.push_back (m_points->green(indices[i])); + colors_points.push_back (m_points->blue(indices[i])); + colors_points.push_back (m_points->red(indices[i])); + colors_points.push_back (m_points->green(indices[i])); + colors_points.push_back (m_points->blue(indices[i])); + } } QApplication::restoreOverrideCursor(); From 2294a0ceec115d01c5cd7bc41444a0fb96807784 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 12:21:43 +0200 Subject: [PATCH 43/81] Add methods to easily transfer properties from one point set to another --- Point_set_3/include/CGAL/Point_set_3.h | 28 +++++--- .../include/CGAL/Surface_mesh/Properties.h | 71 +++++++++++++++++-- 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 30ffac0d945..0f2b7a3a695 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -238,15 +238,6 @@ public: return *this; } - /// \cond SKIP_IN_MANUAL - Point_set_3 (const Point_set_3& ps) - { - *this = ps; - } - - /// \endcond - - /// @} /// \cond SKIP_IN_MANUAL @@ -476,6 +467,15 @@ public: return out; } + iterator insert (const Point_set_3& other, const Index& idx) + { + iterator out = insert(); + Index new_idx = *out; + m_base.transfer(other.base(), idx, new_idx); + *out = new_idx; // Do not copy index from other point set + return out; + } + /// @} /// \name Accessors and Iterators @@ -840,6 +840,16 @@ public: return m_points; } + /// \cond SKIP_IN_MANUAL + void copy_properties (const Point_set_3& other) + { + m_base.copy_properties (other.base()); + + m_normals = this->property_map ("normal").first; // In case normal was added + } + /// \endcond + + /*! \brief Returns a vector with all strings that describe properties. */ diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h index c0b53cd8e23..640c7221585 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h @@ -70,6 +70,7 @@ public: virtual void reset(size_t idx) = 0; virtual bool transfer(const Base_property_array& other) = 0; + virtual bool transfer(const Base_property_array& other, std::size_t from, std::size_t to) = 0; /// Let two elements swap their storage place. virtual void swap(size_t i0, size_t i1) = 0; @@ -77,12 +78,19 @@ public: /// Return a deep copy of self. virtual Base_property_array* clone () const = 0; + /// Return a empty copy of self. + virtual Base_property_array* empty_clone () const = 0; + /// Return the type_info of the property - virtual const std::type_info& type() = 0; + virtual const std::type_info& type() const = 0; /// Return the name of the property const std::string& name() const { return name_; } + bool is_same (const Base_property_array& other) + { + return (name() == other.name() && type() == other.type()); + } protected: @@ -142,6 +150,18 @@ public: // virtual interface of Base_property_array return false; } + bool transfer(const Base_property_array& other, std::size_t from, std::size_t to) + { + const Property_array* pa = dynamic_cast(&other); + if (pa != NULL) + { + data_[to] = (*pa)[from]; + return true; + } + + return false; + } + virtual void shrink_to_fit() { vector_type(data_).swap(data_); @@ -161,7 +181,13 @@ public: // virtual interface of Base_property_array return p; } - virtual const std::type_info& type() { return typeid(T); } + virtual Base_property_array* empty_clone() const + { + Property_array* p = new Property_array(this->name_, this->value_); + return p; + } + + virtual const std::type_info& type() const { return typeid(T); } public: @@ -241,11 +267,11 @@ public: return *this; } - void transfer(const Property_container& _rhs) + bool transfer(const Property_container& _rhs) { for(std::size_t i=0; iname() == _rhs.parrays_[j]->name()){ + if(parrays_[i]->is_same (*(_rhs.parrays_[j]))){ parrays_[i]->transfer(* _rhs.parrays_[j]); break; } @@ -253,6 +279,38 @@ public: } } + // Copy properties that don't already exist from another container + void copy_properties (const Property_container& _rhs) + { + for (std::size_t i = 0; i < _rhs.parrays_.size(); ++ i) + { + bool property_already_exists = false; + for (std::size_t j = 0; j < parrays_.size(); ++ j) + if (_rhs.parrays_[i]->is_same (*(parrays_[j]))) + { + property_already_exists = true; + break; + } + + if (property_already_exists) + continue; + + parrays_.push_back (_rhs.parrays_[i]->empty_clone()); + parrays_.back()->resize(size_); + } + } + + // Transfer one element with all properties + // WARNING: properties must be the same in the two containers + bool transfer(const Property_container& _rhs, std::size_t from, std::size_t to) + { + bool out = true; + for(std::size_t i=0; itransfer(* _rhs.parrays_[i], from, to))) + out = false; + return out; + } + // returns the current size of the property arrays size_t size() const { return size_; } @@ -529,6 +587,11 @@ public: return parray_->transfer(*(other.parray_)); } + bool transfer (const Property_map_base& other, std::size_t from, std::size_t to) + { + return parray_->transfer(*(other.parray_), from, to); + } + /// 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 From e29f6d7e8d7b72705f92df212b075d4b30bd39b3 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 12:22:14 +0200 Subject: [PATCH 44/81] Bug fix: stop losing properties when creating point item from selection --- .../Point_set/Point_set_selection_plugin.cpp | 54 ++++--------------- 1 file changed, 11 insertions(+), 43 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index 4e9acfd60a1..699dc433230 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp @@ -753,57 +753,25 @@ public Q_SLOTS: return; } QApplication::setOverrideCursor(Qt::WaitCursor); - Scene_points_with_normal_item* new_item = new Scene_points_with_normal_item(); + Scene_points_with_normal_item* new_item = new Scene_points_with_normal_item; + new_item->point_set()->copy_properties (*(point_set_item->point_set())); + new_item->point_set()->check_colors(); + new_item->setName(QString("%1 (selected points)").arg(point_set_item->name())); - if (point_set_item->has_normals()) - new_item->point_set()->add_normal_map(); - Point_set::Byte_map red, green, blue; - Point_set::Double_map fred, fgreen, fblue; - if (point_set_item->point_set()->has_colors()) - { - if (point_set_item->point_set()->has_byte_colors()) - { - red = new_item->point_set()->add_property_map("red", 0).first; - green = new_item->point_set()->add_property_map("green", 0).first; - blue = new_item->point_set()->add_property_map("blue", 0).first; - } - else - { - fred = new_item->point_set()->add_property_map("red", 0).first; - fgreen = new_item->point_set()->add_property_map("green", 0).first; - fblue = new_item->point_set()->add_property_map("blue", 0).first; - } - new_item->point_set()->check_colors(); - } new_item->setColor(point_set_item->color()); new_item->setRenderingMode(point_set_item->renderingMode()); new_item->setVisible(point_set_item->visible()); + + std::cerr << point_set_item->point_set()->info() << std::endl; + std::cerr << new_item->point_set()->info() << std::endl; typedef Point_set_3 Point_set; for(Point_set::iterator it = point_set_item->point_set()->first_selected (); - it != point_set_item->point_set()->end(); ++ it) - { - Point_set::iterator new_point = - new_item->point_set()->insert(point_set_item->point_set()->point(*it)); - if (point_set_item->has_normals()) - new_item->point_set()->normal(*new_point) = point_set_item->point_set()->normal(*it); - if (point_set_item->point_set()->has_colors()) - { - if (point_set_item->point_set()->has_byte_colors()) - { - red[*new_point] = (unsigned char)(255. * point_set_item->point_set()->red(*it)); - green[*new_point] = (unsigned char)(255. * point_set_item->point_set()->green(*it)); - blue[*new_point] = (unsigned char)(255. * point_set_item->point_set()->blue(*it)); - } - else - { - fred[*new_point] = point_set_item->point_set()->red(*it); - fgreen[*new_point] = point_set_item->point_set()->green(*it); - fblue[*new_point] = point_set_item->point_set()->blue(*it); - } - } - } + it != point_set_item->point_set()->end(); ++ it) + { + new_item->point_set()->insert (*(point_set_item->point_set()), *it); + } new_item->resetSelection(); new_item->invalidateOpenGLBuffers(); From 5635780b8587e56aed0a5b12b229d05ecdde8862 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 12:22:33 +0200 Subject: [PATCH 45/81] Add method to get properties and types as string --- Point_set_3/include/CGAL/Point_set_3.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 0f2b7a3a695..c86e5251b7d 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -861,6 +861,19 @@ public: return out; } + std::vector > properties_and_types() const + { + std::vector prop = m_base.properties(); + prop.erase (prop.begin()); // remove "index" + prop.erase (prop.begin()); // remove "point" + + std::vector > out; out.reserve (prop.size()); + for (std::size_t i = 0; i < prop.size(); ++ i) + out.push_back (std::make_pair (prop[i], m_base.get_type(prop[i]))); + return out; + } + + /*! \brief Returns a sequence of \ref psp_namedparameters "Named Parameters" for Point Set Processing algorithms. From 8e72f6fdf339c2fa1a4f333550883e6355a432ac Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:18:24 +0200 Subject: [PATCH 46/81] Fix return type --- Surface_mesh/include/CGAL/Surface_mesh/Properties.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h index 640c7221585..98d4f69184c 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Properties.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Properties.h @@ -267,7 +267,7 @@ public: return *this; } - bool transfer(const Property_container& _rhs) + void transfer(const Property_container& _rhs) { for(std::size_t i=0; i Date: Tue, 14 Aug 2018 14:18:45 +0200 Subject: [PATCH 47/81] Update test with latest methods --- .../test/Point_set_3/point_set_test_join.cpp | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/Point_set_3/test/Point_set_3/point_set_test_join.cpp b/Point_set_3/test/Point_set_3/point_set_test_join.cpp index 78f6e3ee6c8..ab8d3b9da6b 100644 --- a/Point_set_3/test/Point_set_3/point_set_test_join.cpp +++ b/Point_set_3/test/Point_set_3/point_set_test_join.cpp @@ -29,15 +29,23 @@ void test (bool expr, const char* msg) } void print_point_set (const Point_set& ps, const char* msg) + { + Point_set::Property_map intensity; + bool has_intensity; + boost::tie (intensity, has_intensity) + = ps.property_map("intensity"); + std::cerr << msg << std::endl; - if (ps.has_normal_map()) - for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it) - std::cerr << *it << ": " << ps.point(*it) - << ", normal " << ps.normal(*it) << std::endl; - else - for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it) - std::cerr << *it << ": " << ps.point(*it) << std::endl; + for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it) + { + std::cerr << *it << ": " << ps.point(*it); + if (ps.has_normal_map()) + std::cerr << ", normal " << ps.normal(*it); + if (has_intensity) + std::cerr << ", intensity " << intensity[*it]; + std::cerr << std::endl; + } } @@ -62,5 +70,25 @@ int main (int, char**) ps1 += ps2; print_point_set (ps1, "JOINT PS1 = "); + Point_set ps3; + ps3.add_normal_map(); + + Point_set::Property_map intensity; + bool okay; + + boost::tie (intensity, okay) = ps3.add_property_map("intensity", 0); + assert (okay); + + Point_set::iterator it = ps3.insert (Point (double(0), double(1), double(2)), + Vector (double(3), double(4), double(5))); + intensity[*it] = 42; + + print_point_set (ps3, "PS3 = "); + ps1.copy_properties (ps3); + + print_point_set (ps1, "PS1 with PS3 properties = "); + ps1.insert (ps3, *it); + print_point_set (ps1, "PS1 with PS3 properties + PS3 item copied = "); + return EXIT_SUCCESS; }; From 5ee7da0e8f9e58f814d476d642c4db80adfd61de Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:30:14 +0200 Subject: [PATCH 48/81] Update user manual --- Point_set_3/include/CGAL/Point_set_3.h | 113 +++++++++++++++++++------ 1 file changed, 88 insertions(+), 25 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index c86e5251b7d..2bedb4166e5 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -55,10 +55,10 @@ namespace CGAL { The coordinates of a point can be access using the index of the point and the member function `point()`. This property is always present. The normal vector of a point can be accessed using the - index of the point and the `normal()` function. This property must + index of the point and the `normal()` method. This property must be explicitly created. - All properties can be accessed as a range using the functions + All properties can be accessed as a range using the methods `points()`, `normals()`, and `range()` for points coordinates, normal vectors, and other properties respectively. @@ -67,9 +67,9 @@ namespace CGAL { removed elements. A garbage collection method must be called to really remove it from memory. - For convenience, all functions of the package \ref PkgPointSetProcessing3Ref - are provided with an overload that takes a Point_set_3 - object as an argument. + For convenience, all functions of the package \ref + PkgPointSetProcessing automatically creates the right named + parameters if called with a `CGAL::Point_set_3` object as argument. \tparam Point Point type. @@ -286,7 +286,11 @@ public: the point set and `other`. Property maps which are only in `other` are ignored. - \note Garbage is collected in both point sets when calling this function. + \note If `copy_properties()` with `other` as argument is called + before calling this method, then all the content of `other` will + be copied and no property will be lost in the process. + + \note Garbage is collected in both point sets when calling this method. */ bool join (Point_set_3& other) { @@ -305,7 +309,7 @@ public: /*! \brief Clears the point set properties and content. - After calling this function, the object is the same as a newly + After calling this method, the object is the same as a newly constructed object. The additional properties (such as normal vectors) are also removed and must thus be re-added if needed. */ @@ -320,8 +324,8 @@ public: /*! \brief Clears all properties created. - After calling this function, all properties are removed. The - points are left unchanged. + After calling this method, all properties are removed. The points + are left unchanged. */ void clear_properties() { @@ -440,7 +444,7 @@ public: } /*! - \brief Convenience function to add a point with a normal vector. + \brief Convenience method to add a point with a normal vector. \param p Point to insert \param n Associated normal vector @@ -467,6 +471,29 @@ public: return out; } + /*! + \brief Convenience method to copy a point with all its properties + from another point set. + + In the case where two point sets have the same properties, this + method allows the user to easily copy one point (along with the + values of all its properties) from one point set to another. + + \param other Point set to which the point to copy belongs + \param idx Index of the point to copy in `other` + + \warning This point set and `other` must have the exact same + properties, with the exact same names and types in the exact same + order. + + \note If a reallocation happens, all iterators, pointers and + references related to the container are invalidated. Otherwise, + only the end iterator is invalidated, and all iterators, pointers + and references to elements are guaranteed to keep referring to the + same elements they were referring to before the call. + + \return The iterator on the newly added element. + */ iterator insert (const Point_set_3& other, const Index& idx) { iterator out = insert(); @@ -524,7 +551,7 @@ public: /// @} - /// \name Removal Functions + /// \name Removal Methods /// @{ /*! @@ -532,7 +559,8 @@ public: \note The elements are just marked as removed and are not erased from the memory. `collect_garbage()` should be called if the - memory needs to be disallocated. + memory needs to be disallocated. Elements can be recovered with + `cancel_removal()`. \note All iterators, pointers and references related to the container are invalidated. */ @@ -569,7 +597,8 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory - needs to be freed. + needs to be freed. The element can be recovered with + `cancel_removal()`. \note All iterators, pointers and references related to the container are invalidated. */ @@ -584,7 +613,8 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory - needs to be freed. + needs to be freed. The element can be recovered with + `cancel_removal()`. \note All iterators, pointers and references related to the container are invalidated. */ @@ -601,6 +631,7 @@ public: /// \name Garbage Management /// @{ + /*! \brief Returns `true` if the element is marked as removed, `false` otherwise. @@ -613,6 +644,13 @@ public: return (std::distance (it, garbage_begin()) <= 0); } + /*! + \brief Returns `true` if the element is marked as removed, `false` + otherwise. + + \note When iterating between `begin()` and `end()`, no element + marked as removed can be found. + */ bool is_removed (const Index& index) const { const_iterator it = m_indices.begin() + index; @@ -632,11 +670,15 @@ public: const_iterator garbage_end () const { return m_indices.end(); } /*! \brief Number of removed points. + + \note The method `garbage_size()` is also available and does the + same thing. */ std::size_t number_of_removed_points () const { return m_nb_removed; } /// \cond SKIP_IN_MANUAL std::size_t garbage_size () const { return number_of_removed_points(); } /// \endcond + /*! \brief Returns `true` if there are elements marked as removed, `false` otherwise. */ @@ -656,22 +698,35 @@ public: for (std::size_t i = 0; i < m_base.size(); ++ i) m_indices[i] = indices[i]; - // for (std::size_t i = 0; i < 10; ++ i) - // std::cerr << m_indices[i] << " "; - // std::cerr << std::endl; - // Sorting based on the indices reorders the point set correctly quick_sort_on_indices ((std::ptrdiff_t)0, (std::ptrdiff_t)(m_base.size() - 1)); - // for (std::size_t i = 0; i < 10; ++ i) - // std::cerr << m_indices[i] << " "; - // std::cerr << std::endl; - m_base.resize (size ()); m_base.shrink_to_fit (); m_nb_removed = 0; } + /*! + \brief Restores all removed points. + + After removing one or several points, calling this method restores + the point set to its initial state: points that were removed (and + their associated properties) are restored. + + \note This method is only guaranteed to work if no point was + inserted after the removal: otherwise, some points might not be + restored. + + \note If `collect_garbage()` was called after removal, the points + are irremediably lost and nothing will be restored. + */ + void cancel_removal() + { + m_nb_removed = 0; + for (std::size_t i = 0; i < this->m_base.size(); ++ i) + this->m_indices[i] = i; + } + /// @} @@ -840,14 +895,19 @@ public: return m_points; } - /// \cond SKIP_IN_MANUAL + /*! + \brief Copies the properties from another point set. + + All properties from `other` that do not already exist in this + point set are added and filled to their default values. Properties + that exist in both point sets are left unchanged. + */ void copy_properties (const Point_set_3& other) { m_base.copy_properties (other.base()); m_normals = this->property_map ("normal").first; // In case normal was added } - /// \endcond /*! @@ -861,6 +921,9 @@ public: return out; } + /*! + \brief Returns a vector of pairs that describe properties and associated types. + */ std::vector > properties_and_types() const { std::vector prop = m_base.properties(); @@ -1201,7 +1264,7 @@ private: Copies entries of all property maps which have the same name in `ps` and `other`. Property maps which are only in `other` are ignored. - \note Garbage is collected in both point sets when calling this function. + \note Garbage is collected in both point sets when calling this method. */ template From 68a8d6a60d44f9ac6be566e78b1848a9d3bd0bce Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:30:47 +0200 Subject: [PATCH 49/81] Use new method --- Polyhedron/demo/Polyhedron/include/Point_set_3.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index 4f992825396..7afa0c01877 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -138,10 +138,7 @@ public: void reset_indices() { - unselect_all(); - - for (std::size_t i = 0; i < this->m_base.size(); ++ i) - this->m_indices[i] = i; + this->cancel_removal(); } bool add_radius() From e01eaa9660201fe3b7d24beb394d86991f871ee8 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 14 Aug 2018 14:45:19 +0200 Subject: [PATCH 50/81] Fix doc note about iterator invalidations --- Point_set_3/include/CGAL/Point_set_3.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 2bedb4166e5..cfc6a260b23 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -562,7 +562,8 @@ public: memory needs to be disallocated. Elements can be recovered with `cancel_removal()`. - \note All iterators, pointers and references related to the container are invalidated. + \note All iterators, pointers and references related to the + container are invalidated. */ void remove (iterator first, iterator last) { @@ -600,7 +601,8 @@ public: needs to be freed. The element can be recovered with `cancel_removal()`. - \note All iterators, pointers and references related to the container are invalidated. + \note The `end()` iterator is invalidated, `it` dereferences to a + different element. */ void remove (iterator it) { @@ -616,7 +618,8 @@ public: needs to be freed. The element can be recovered with `cancel_removal()`. - \note All iterators, pointers and references related to the container are invalidated. + \note The `end()` iterator is invalidated, `it` dereferences to a + different element. */ void remove (const Index& index) { From 3614f542f238d75a39821008625cd49710c71bb0 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 19 Sep 2018 14:34:48 +0200 Subject: [PATCH 51/81] Add useful typedefs of templates of Point_set_3 --- Point_set_3/include/CGAL/Point_set_3.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index cfc6a260b23..052363498b8 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -148,7 +148,9 @@ public: Index operator-- (int) { Index tmp(*this); -- value; return tmp; } /// \endcond }; - + + typedef Point Point_3; ///< The point type + typedef Vector Vector_3; ///< The vector type #ifdef DOXYGEN_RUNNING typedef unspecified_type iterator; ///< Iterator type of the point set with value type `Index` \cgalModels RandomAccessIterator From 7af06bdf5d8d61b9f683ac0830410a772ca210b4 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Wed, 12 Dec 2018 10:42:31 +0100 Subject: [PATCH 52/81] Replace cancel_removal() by cancel_removals() --- Point_set_3/include/CGAL/Point_set_3.h | 8 ++++---- Polyhedron/demo/Polyhedron/include/Point_set_3.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 052363498b8..edef837243c 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -562,7 +562,7 @@ public: \note The elements are just marked as removed and are not erased from the memory. `collect_garbage()` should be called if the memory needs to be disallocated. Elements can be recovered with - `cancel_removal()`. + `cancel_removals()`. \note All iterators, pointers and references related to the container are invalidated. @@ -601,7 +601,7 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory needs to be freed. The element can be recovered with - `cancel_removal()`. + `cancel_removals()`. \note The `end()` iterator is invalidated, `it` dereferences to a different element. @@ -618,7 +618,7 @@ public: \note The element is just marked as removed and is not erased from the memory. `collect_garbage()` should be called if the memory needs to be freed. The element can be recovered with - `cancel_removal()`. + `cancel_removals()`. \note The `end()` iterator is invalidated, `it` dereferences to a different element. @@ -725,7 +725,7 @@ public: \note If `collect_garbage()` was called after removal, the points are irremediably lost and nothing will be restored. */ - void cancel_removal() + void cancel_removals() { m_nb_removed = 0; for (std::size_t i = 0; i < this->m_base.size(); ++ i) diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index 7afa0c01877..6b950dff12a 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -138,7 +138,7 @@ public: void reset_indices() { - this->cancel_removal(); + this->cancel_removals(); } bool add_radius() From 5a21255e54f705a300183f24e4acc2e619d71b52 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 13 Dec 2018 14:43:46 +0100 Subject: [PATCH 53/81] Document garbage_size() properly --- Point_set_3/include/CGAL/Point_set_3.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index edef837243c..63969ab6100 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -675,12 +675,13 @@ public: const_iterator garbage_end () const { return m_indices.end(); } /*! \brief Number of removed points. - - \note The method `garbage_size()` is also available and does the - same thing. + \sa `garbage_size()` */ std::size_t number_of_removed_points () const { return m_nb_removed; } - /// \cond SKIP_IN_MANUAL + /*! + \brief Number of removed points. + \sa `number_of_removed_points()` + */ std::size_t garbage_size () const { return number_of_removed_points(); } /// \endcond From 998925b6218d17586c29f7ef403f0cca8289f727 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 14 Dec 2018 15:10:48 +0100 Subject: [PATCH 54/81] Fix another float/double bug in Point_set_3 IO --- Point_set_3/include/CGAL/Point_set_3/IO.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 35560d89027..456763083e4 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -473,9 +473,18 @@ write_ply_point_set( if (prop[i] == "point") { - stream << "property double x" << std::endl - << "property double y" << std::endl - << "property double z" << std::endl; + if (boost::is_same::type, float>::value) + { + stream << "property float x" << std::endl + << "property float y" << std::endl + << "property float z" << std::endl; + } + else + { + stream << "property double x" << std::endl + << "property double y" << std::endl + << "property double z" << std::endl; + } printers.push_back (new internal::Property_printer(point_set.point_map())); continue; } From 55d9539dff51b8568e7f3ab05b2354f5185a4d74 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 11 Jan 2019 10:02:39 +0100 Subject: [PATCH 55/81] Update with change of ref tag --- Point_set_3/include/CGAL/Point_set_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Point_set_3/include/CGAL/Point_set_3.h b/Point_set_3/include/CGAL/Point_set_3.h index 63969ab6100..172c0a996b7 100644 --- a/Point_set_3/include/CGAL/Point_set_3.h +++ b/Point_set_3/include/CGAL/Point_set_3.h @@ -68,7 +68,7 @@ namespace CGAL { really remove it from memory. For convenience, all functions of the package \ref - PkgPointSetProcessing automatically creates the right named + PkgPointSetProcessing3 automatically creates the right named parameters if called with a `CGAL::Point_set_3` object as argument. From 11269119d1853c60243df4c77d20c2156b2e9957 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 11 Jan 2019 13:26:10 +0100 Subject: [PATCH 56/81] Propagate API change to Point_inside_polyhedron_plugin --- .../Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp index 9625fc02fc4..ea5b0937d00 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Point_inside_polyhedron_plugin.cpp @@ -164,7 +164,7 @@ public Q_SLOTS: (on_boundary && res == CGAL::ON_BOUNDARY) || (outside && res == CGAL::ON_UNBOUNDED_SIDE) ) { - point_set->select(point_it); ++nb_selected; + point_set->select(*point_it); ++nb_selected; -- pt; // Selection replaces current point with unselected one selected = true; break;//loop on i From 3b00d0f867c2ec85c1d5924c7d11618f8a788670 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 11 Jan 2019 13:29:48 +0100 Subject: [PATCH 57/81] Propagate API change to classification test --- .../test/Classification/test_classification_point_set.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classification/test/Classification/test_classification_point_set.cpp b/Classification/test/Classification/test_classification_point_set.cpp index f7092478a70..b444a6bbe71 100644 --- a/Classification/test/Classification/test_classification_point_set.cpp +++ b/Classification/test/Classification/test_classification_point_set.cpp @@ -50,7 +50,7 @@ int main (int, char**) Size_t_map echo_map; Color_map color_map; - map_added = pts.add_normal_map(); + map_added = pts.add_normal_map().second; assert (map_added); normal_map = pts.normal_map(); boost::tie (echo_map, map_added) = pts.add_property_map ("echo"); From 505946cb22ab6ffc220c1b2bec8ffe0e670583bc Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 15 Jan 2019 10:04:54 +0100 Subject: [PATCH 58/81] Propagate API to Point Set To Distance Plugin --- .../Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp index 582335319fd..c523882f4b3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_to_mesh_distance_plugin.cpp @@ -194,7 +194,7 @@ private Q_SLOTS: it != item->point_set()->end(); ++ it) { if(distance <= distance_map[*it]) - item->point_set()->select(it); + item->point_set()->select(*it); } item->invalidateOpenGLBuffers(); item->itemChanged(); From 12450650682068367bcad6bc90a817fb58af2fb4 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 25 Jan 2019 08:15:16 +0100 Subject: [PATCH 59/81] Update CHANGES.md --- Installation/CHANGES.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 839fe0848cc..a0e278a01a8 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -79,6 +79,33 @@ Release date: March 2019 reduced-convolution method. In particular, correctly handled the case where one of the summands does not have an outer boundaey. +### 3D Point Set + +- Added a method `copy_properties()` that allows to copy the + properties from a point set to another one (without copying the + content); + +- Added a method `insert(const Point_set&, const Index&)` to copy a + point along with all its associated properties from another point + set; + +- `remove()` methods now only invalidate the `end()` iterator + instead of invalidating all iterators; + +- Added a method `is_removed()` that takes an index as argument; + +- Added a method `cancel_removals()` to restore removed points (if + no point was inserted since then an garbage was not collected); + +- **Breaking change:** unified API of method `add_normal_map()` with + `add_property_map()`: it now returns a pair of property map + bool + (that tells if the property was added) instead of just the + property map; + +- Added a method `properties_and_types()` in addition to + `properties()`: this new one returns pairs of `std::string` + + `std::type_info` in order to also know the type of each property. + ### CGAL and the Boost Graph Library (BGL) - Add function `write_wrl()` for writing into VRML 2.0 format. From b206e04c58c98b023ff5c2c86a971940346d8976 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 25 Jan 2019 11:03:24 +0100 Subject: [PATCH 60/81] Handle edge/halfedge properties in PLY IO --- .../include/CGAL/Surface_mesh/IO/PLY.h | 399 ++++++++++++++++- .../include/CGAL/Surface_mesh/Surface_mesh.h | 413 ++++-------------- .../test/Surface_mesh/colored_tetra.ply | 10 + Surface_mesh/test/Surface_mesh/sm_ply_io.cpp | 5 +- 4 files changed, 509 insertions(+), 318 deletions(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h index 1aeb21e5a52..c2b603451f5 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h @@ -40,6 +40,8 @@ public: typedef Surface_mesh Surface_mesh; typedef typename Surface_mesh::Vertex_index Vertex_index; typedef typename Surface_mesh::Face_index Face_index; + typedef typename Surface_mesh::Edge_index Edge_index; + typedef typename Surface_mesh::Halfedge_index Halfedge_index; private: @@ -71,6 +73,8 @@ private: std::string prefix(Vertex_index) const { return "v:"; } std::string prefix(Face_index) const { return "f:"; } + std::string prefix(Edge_index) const { return "e:"; } + std::string prefix(Halfedge_index) const { return "h:"; } }; Surface_mesh& m_mesh; @@ -85,6 +89,8 @@ private: std::string m_index_tag; std::vector m_vertex_properties; std::vector m_face_properties; + std::vector m_edge_properties; + std::vector m_halfedge_properties; public: @@ -98,6 +104,10 @@ public: delete m_vertex_properties[i]; for (std::size_t i = 0; i < m_face_properties.size(); ++ i) delete m_face_properties[i]; + for (std::size_t i = 0; i < m_edge_properties.size(); ++ i) + delete m_edge_properties[i]; + for (std::size_t i = 0; i < m_halfedge_properties.size(); ++ i) + delete m_halfedge_properties[i]; } bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Vertex_index) @@ -155,6 +165,22 @@ public: return false; } + bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Edge_index) + { + const std::string& name = property->name(); + if (name == "v0" || name == "v1") + return true; + return false; + } + + bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Halfedge_index) + { + const std::string& name = property->name(); + if (name == "source" || name == "target") + return true; + return false; + } + void instantiate_vertex_properties (PLY_element& element) { instantiate_properties (element, m_vertex_properties); @@ -165,6 +191,16 @@ public: instantiate_properties (element, m_face_properties); } + void instantiate_edge_properties (PLY_element& element) + { + instantiate_properties (element, m_edge_properties); + } + + void instantiate_halfedge_properties (PLY_element& element) + { + instantiate_properties (element, m_halfedge_properties); + } + template void instantiate_properties (PLY_element& element, std::vector& properties) @@ -274,7 +310,7 @@ public: bool process_face_line (PLY_element& element) { - Face_index fi; + Face_index fi = m_mesh.null_face(); if (m_use_int32_t) process_line(element, fi); @@ -301,6 +337,8 @@ public: vertices.push_back (Vertex_index (indices[i])); fi = m_mesh.add_face(vertices); + if (fi == m_mesh.null_face()) + return; if (m_fcolors == 3) { @@ -312,9 +350,368 @@ public: } } + bool process_edge_line (PLY_element& element) + { + Edge_index ei = m_mesh.null_edge(); + + if (m_use_int32_t) + process_line(element, ei); + else + process_line(element, ei); + + if (ei == Surface_mesh::null_edge()) + return false; + + for (std::size_t i = 0; i < m_edge_properties.size(); ++ i) + m_edge_properties[i]->assign (element, ei); + + return true; + } + + template + void process_line (PLY_element& element, Edge_index& ei) + { + IntType v0, v1; + element.assign (v0, "v0"); + element.assign (v1, "v1"); + + Halfedge_index hi = m_mesh.halfedge(Vertex_index(v0), Vertex_index(v1)); + if (hi == m_mesh.null_halfedge()) + return; + + ei = m_mesh.edge (hi); + } + + bool process_halfedge_line (PLY_element& element) + { + Halfedge_index hi = m_mesh.null_halfedge(); + + if (m_use_int32_t) + process_line(element, hi); + else + process_line(element, hi); + + if (hi == Surface_mesh::null_halfedge()) + return false; + + for (std::size_t i = 0; i < m_halfedge_properties.size(); ++ i) + m_halfedge_properties[i]->assign (element, hi); + + return true; + } + + template + void process_line (PLY_element& element, Halfedge_index& hi) + { + IntType source, target; + element.assign (source, "source"); + element.assign (target, "target"); + hi = m_mesh.halfedge(Vertex_index(source), Vertex_index(target)); + } + }; +template +bool fill_simplex_specific_header +(std::ostream& os, const Surface_mesh& sm, + std::vector::Vertex_index>*>& printers, + const std::string& prop) +{ + typedef Surface_mesh SMesh; + typedef typename SMesh::Vertex_index VIndex; + typedef typename Kernel_traits::Kernel Kernel; + typedef typename Kernel::FT FT; + typedef typename Kernel::Vector_3 Vector; + typedef typename SMesh::template Property_map Point_map; + typedef typename SMesh::template Property_map Vector_map; + typedef typename SMesh::template Property_map Vcolor_map; + + if (prop == "v:connectivity" || + prop == "v:removed") + return true; + + if (prop == "v:point") + { + if (boost::is_same::value) + { + os << "property float x" << std::endl + << "property float y" << std::endl + << "property float z" << std::endl; + } + else + { + os << "property double x" << std::endl + << "property double y" << std::endl + << "property double z" << std::endl; + } + printers.push_back (new Property_printer(sm.points())); + return true; + } + + bool okay = false; + if (prop == "v:normal") + { + Vector_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop); + if (okay) + { + if (boost::is_same::value) + { + os << "property float nx" << std::endl + << "property float ny" << std::endl + << "property float nz" << std::endl; + } + else + { + os << "property double nx" << std::endl + << "property double ny" << std::endl + << "property double nz" << std::endl; + } + printers.push_back (new Property_printer(pmap)); + return true; + } + } + + if (prop == "v:color") + { + Vcolor_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop); + if (okay) + { + os << "property uchar red" << std::endl + << "property uchar green" << std::endl + << "property uchar blue" << std::endl + << "property uchar alpha" << std::endl; + + printers.push_back (new Property_printer(pmap)); + return true; + } + } + + return false; +} + +template +bool fill_simplex_specific_header +(std::ostream& os, const Surface_mesh& sm, + std::vector::Face_index>*>& printers, + const std::string& prop) +{ + typedef Surface_mesh SMesh; + typedef typename SMesh::Face_index FIndex; + typedef typename SMesh::template Property_map Fcolor_map; + + if (prop == "f:connectivity" || + prop == "f:removed") + return true; + + bool okay = false; + if (prop == "f:color") + { + Fcolor_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop); + if (okay) + { + os << "property uchar red" << std::endl + << "property uchar green" << std::endl + << "property uchar blue" << std::endl + << "property uchar alpha" << std::endl; + + printers.push_back (new Property_printer(pmap)); + return true; + } + } + return false; +} + +template +bool fill_simplex_specific_header +(std::ostream& , const Surface_mesh& , + std::vector::Edge_index>*>& , + const std::string& prop) +{ + if (prop == "e:removed") + return true; + return false; +} + +template +bool fill_simplex_specific_header +(std::ostream& , const Surface_mesh& , + std::vector::Halfedge_index>*>& , + const std::string& prop) +{ + if (prop == "h:connectivity") + return true; + return false; +} + +template +std::string get_property_raw_name (const std::string& prop, typename Surface_mesh::Vertex_index) +{ + std::string name = prop; + if (name.rfind("v:",0) == 0) + name = std::string (prop.begin() + 2, prop.end()); + return name; +} + +template +std::string get_property_raw_name (const std::string& prop, typename Surface_mesh::Face_index) +{ + std::string name = prop; + if (name.rfind("f:",0) == 0) + name = std::string (prop.begin() + 2, prop.end()); + return name; +} + +template +std::string get_property_raw_name (const std::string& prop, typename Surface_mesh::Edge_index) +{ + std::string name = prop; + if (name.rfind("e:",0) == 0) + name = std::string (prop.begin() + 2, prop.end()); + return name; +} + +template +std::string get_property_raw_name (const std::string& prop, typename Surface_mesh::Halfedge_index) +{ + std::string name = prop; + if (name.rfind("h:",0) == 0) + name = std::string (prop.begin() + 2, prop.end()); + return name; +} + +template +void fill_header (std::ostream& os, const Surface_mesh& sm, + std::vector*>& printers) +{ + typedef Surface_mesh SMesh; + typedef typename SMesh::template Property_map Int8_map; + typedef typename SMesh::template Property_map Uint8_map; + typedef typename SMesh::template Property_map Int16_map; + typedef typename SMesh::template Property_map Uint16_map; + typedef typename SMesh::template Property_map Int32_map; + typedef typename SMesh::template Property_map Uint32_map; + typedef typename SMesh::template Property_map Int64_map; + typedef typename SMesh::template Property_map Uint64_map; + typedef typename SMesh::template Property_map Float_map; + typedef typename SMesh::template Property_map Double_map; + std::vector prop = sm.template properties(); + + for (std::size_t i = 0; i < prop.size(); ++ i) + { + if (fill_simplex_specific_header(os, sm, printers, prop[i])) + continue; + + // Cut the "v:" prefix + std::string name = get_property_raw_name (prop[i], Simplex()); + + bool okay = false; + { + Int8_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property char " << name << std::endl; + printers.push_back (new internal::PLY::Char_property_printer(pmap)); + continue; + } + } + { + Uint8_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property uchar " << name << std::endl; + printers.push_back (new internal::PLY::Char_property_printer(pmap)); + continue; + } + } + { + Int16_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property short " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint16_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property ushort " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Int32_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property int " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint32_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property uint " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Int64_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property int " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint64_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property uint " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Float_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property float " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Double_map pmap; + boost::tie (pmap, okay) = sm.template property_map(prop[i]); + if (okay) + { + os << "property double " << name << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + } +} + } // namespace PLY #endif diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index beccbfdedff..690a8818886 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2163,6 +2163,10 @@ private: //------------------------------------------------------- private data /// Inserts the surface mesh in an output stream in PLY format. /// If found, "v:normal", "v:color" and "f:color" are inserted in the stream. /// All other vertex and face properties with simple types are inserted in the stream. + /// Edges are only inserted in the stream if they have at least one + /// property with simple type: if they do, all edge properties with + /// simple types are inserted in the stream. The halfedges follow + /// the same behavior. /// \relates Surface_mesh template bool write_ply(std::ostream& os, const Surface_mesh

& sm, const std::string& comments = std::string()) @@ -2172,23 +2176,9 @@ private: //------------------------------------------------------- private data typedef typename K::Vector_3 Vector; typedef typename SMesh::Vertex_index VIndex; typedef typename SMesh::Face_index FIndex; + typedef typename SMesh::Edge_index EIndex; typedef typename SMesh::Halfedge_index HIndex; - typedef typename SMesh::template Property_map Point_map; - typedef typename SMesh::template Property_map Vector_map; - typedef typename SMesh::template Property_map Vcolor_map; - - typedef typename SMesh::template Property_map Int8_map_v; - typedef typename SMesh::template Property_map Uint8_map_v; - typedef typename SMesh::template Property_map Int16_map_v; - typedef typename SMesh::template Property_map Uint16_map_v; - typedef typename SMesh::template Property_map Int32_map_v; - typedef typename SMesh::template Property_map Uint32_map_v; - typedef typename SMesh::template Property_map Int64_map_v; - typedef typename SMesh::template Property_map Uint64_map_v; - typedef typename SMesh::template Property_map Float_map_v; - typedef typename SMesh::template Property_map Double_map_v; - typedef typename SMesh::template Property_map Fcolor_map; typedef typename SMesh::template Property_map Int8_map_f; @@ -2218,314 +2208,33 @@ private: //------------------------------------------------------- private data } os << "element vertex " << sm.number_of_vertices() << std::endl; - std::vector vprop = sm.template properties(); + std::vector*> vprinters; - - for (std::size_t i = 0; i < vprop.size(); ++ i) - { - if (vprop[i] == "v:connectivity" || - vprop[i] == "v:removed") - continue; - - if (vprop[i] == "v:point") - { - if (boost::is_same::type, float>::value) - { - os << "property float x" << std::endl - << "property float y" << std::endl - << "property float z" << std::endl; - } - else - { - os << "property double x" << std::endl - << "property double y" << std::endl - << "property double z" << std::endl; - } - vprinters.push_back (new internal::PLY::Property_printer(sm.points())); - continue; - } - - bool okay = false; - if (vprop[i] == "v:normal") - { - Vector_map pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - if (boost::is_same::type, float>::value) - { - os << "property float nx" << std::endl - << "property float ny" << std::endl - << "property float nz" << std::endl; - } - else - { - os << "property double nx" << std::endl - << "property double ny" << std::endl - << "property double nz" << std::endl; - } - vprinters.push_back (new internal::PLY::Property_printer(pmap)); - continue; - } - } - - if (vprop[i] == "v:color") - { - Vcolor_map pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property uchar red" << std::endl - << "property uchar green" << std::endl - << "property uchar blue" << std::endl - << "property uchar alpha" << std::endl; - - vprinters.push_back (new internal::PLY::Property_printer(pmap)); - continue; - } - } - - // Cut the "v:" prefix - std::string name = vprop[i]; - if (name.rfind("v:",0) == 0) - name = std::string (vprop[i].begin() + 2, vprop[i].end()); - - { - Int8_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property char " << name << std::endl; - vprinters.push_back (new internal::PLY::Char_property_printer(pmap)); - continue; - } - } - { - Uint8_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property uchar " << name << std::endl; - vprinters.push_back (new internal::PLY::Char_property_printer(pmap)); - continue; - } - } - { - Int16_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property short " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Uint16_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property ushort " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Int32_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property int " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Uint32_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property uint " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Int64_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property int " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Uint64_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property uint " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Float_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property float " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Double_map_v pmap; - boost::tie (pmap, okay) = sm.template property_map(vprop[i]); - if (okay) - { - os << "property double " << name << std::endl; - vprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - } + internal::PLY::fill_header (os, sm, vprinters); os << "element face " << sm.number_of_faces() << std::endl; os << "property list uchar int vertex_indices" << std::endl; - std::vector fprop = sm.template properties(); std::vector*> fprinters; - - for (std::size_t i = 0; i < fprop.size(); ++ i) - { - if (fprop[i] == "f:connectivity" || - fprop[i] == "f:removed") - continue; - - bool okay = false; - if (fprop[i] == "f:color") - { - Fcolor_map pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property uchar red" << std::endl - << "property uchar green" << std::endl - << "property uchar blue" << std::endl - << "property uchar alpha" << std::endl; + internal::PLY::fill_header (os, sm, fprinters); - fprinters.push_back (new internal::PLY::Property_printer(pmap)); - continue; - } - } - - // Cut the "f:" prefix - std::string name = fprop[i]; - if (name.rfind("f:",0) == 0) - name = std::string (fprop[i].begin() + 2, fprop[i].end()); - { - Int8_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property char " << name << std::endl; - fprinters.push_back (new internal::PLY::Char_property_printer(pmap)); - continue; - } - } - { - Uint8_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property uchar " << name << std::endl; - fprinters.push_back (new internal::PLY::Char_property_printer(pmap)); - continue; - } - } - { - Int16_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property short " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Uint16_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property ushort " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Int32_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property int " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Uint32_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property uint " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Int64_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property int " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Uint64_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property uint " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Float_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property float " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } - { - Double_map_f pmap; - boost::tie (pmap, okay) = sm.template property_map(fprop[i]); - if (okay) - { - os << "property double " << name << std::endl; - fprinters.push_back (new internal::PLY::Simple_property_printer(pmap)); - continue; - } - } + std::vector*> eprinters; + if (sm.template properties().size() > 1) + { + os << "element edge " << sm.number_of_edges() << std::endl; + os << "property int v0" << std::endl; + os << "property int v1" << std::endl; + internal::PLY::fill_header (os, sm, eprinters); } - + + std::vector*> hprinters; + if (sm.template properties().size() > 1) + { + os << "element halfedge " << sm.number_of_halfedges() << std::endl; + os << "property int source" << std::endl; + os << "property int target" << std::endl; + internal::PLY::fill_header (os, sm, hprinters); + } + os << "end_header" << std::endl; BOOST_FOREACH(VIndex vi, sm.vertices()) @@ -2577,10 +2286,66 @@ private: //------------------------------------------------------- private data os << std::endl; } + if (!eprinters.empty()) + { + BOOST_FOREACH(EIndex ei, sm.edges()) + { + if (get_mode (os) == IO::ASCII) + os << int(sm.vertex(ei,0)) << " " << int(sm.vertex(ei,1)) << " "; + else + { + int v0 = int(sm.vertex(ei,0)); + int v1 = int(sm.vertex(ei,1)); + os.write (reinterpret_cast(&v0), sizeof(v0)); + os.write (reinterpret_cast(&v1), sizeof(v1)); + } + + for (std::size_t i = 0; i < eprinters.size(); ++ i) + { + eprinters[i]->print(os, ei); + if (get_mode (os) == IO::ASCII) + os << " "; + } + + if (get_mode (os) == IO::ASCII) + os << std::endl; + } + } + + if (!hprinters.empty()) + { + BOOST_FOREACH(HIndex hi, sm.halfedges()) + { + if (get_mode (os) == IO::ASCII) + os << int(sm.source(hi)) << " " << int(sm.target(hi)) << " "; + else + { + int source = int(sm.source(hi)); + int target = int(sm.target(hi)); + os.write (reinterpret_cast(&source), sizeof(source)); + os.write (reinterpret_cast(&target), sizeof(target)); + } + + for (std::size_t i = 0; i < hprinters.size(); ++ i) + { + hprinters[i]->print(os, hi); + if (get_mode (os) == IO::ASCII) + os << " "; + } + + if (get_mode (os) == IO::ASCII) + os << std::endl; + } + } + for (std::size_t i = 0; i < vprinters.size(); ++ i) delete vprinters[i]; for (std::size_t i = 0; i < fprinters.size(); ++ i) delete fprinters[i]; + for (std::size_t i = 0; i < eprinters.size(); ++ i) + delete eprinters[i]; + for (std::size_t i = 0; i < hprinters.size(); ++ i) + delete hprinters[i]; return true; } @@ -2805,6 +2570,8 @@ private: //------------------------------------------------------- private data bool is_vertex = (element.name() == "vertex" || element.name() == "vertices"); bool is_face = false; + bool is_edge = false; + bool is_halfedge = false; if (is_vertex) filler.instantiate_vertex_properties (element); else @@ -2812,6 +2579,16 @@ private: //------------------------------------------------------- private data if (is_face) filler.instantiate_face_properties (element); + else + is_edge = (element.name() == "edge"); + + if (is_edge) + filler.instantiate_edge_properties (element); + else + is_halfedge = (element.name() == "halfedge"); + + if (is_halfedge) + filler.instantiate_halfedge_properties (element); for (std::size_t j = 0; j < element.number_of_items(); ++ j) { @@ -2833,6 +2610,10 @@ private: //------------------------------------------------------- private data return false; } } + else if (is_edge) + filler.process_edge_line (element); + else if (is_halfedge) + filler.process_halfedge_line (element); } } diff --git a/Surface_mesh/test/Surface_mesh/colored_tetra.ply b/Surface_mesh/test/Surface_mesh/colored_tetra.ply index 281a182a55e..7ec622125d1 100644 --- a/Surface_mesh/test/Surface_mesh/colored_tetra.ply +++ b/Surface_mesh/test/Surface_mesh/colored_tetra.ply @@ -17,6 +17,10 @@ property uchar red property uchar green property uchar blue property int label +element edge 6 +property int v0 +property int v1 +property float confidence end_header 0 0 0 -0.5 -0.5 -0.5 255 255 0 0 0 0 1 -0.5 -0.5 0 0 255 255 1 @@ -26,3 +30,9 @@ end_header 3 0 3 1 0 255 0 1 3 1 3 2 0 0 255 -1 3 0 2 3 255 0 255 0 +0 1 0.1 +0 2 0.2 +0 3 0.3 +1 2 0.4 +1 3 0.5 +2 3 0.6 diff --git a/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp b/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp index 2b846cc7f7b..8dcf801a16e 100644 --- a/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp +++ b/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp @@ -30,9 +30,12 @@ int main() for (std::size_t i = 0; i < properties.size(); ++ i) std::cerr << " * " << properties[i] << std::endl; + mesh.add_property_map("id", 42); + mesh.add_property_map("u", 13.f); + mesh.add_property_map("v", 37.f); std::ofstream out ("out.ply"); - CGAL::set_binary_mode(out); +// CGAL::set_binary_mode(out); CGAL::write_ply (out, mesh); return 0; From a1bee88b4dbe452363056ab0dd5ebae21d9b6af5 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 25 Jan 2019 14:23:52 +0100 Subject: [PATCH 61/81] Add missing types to Point_set_3 PLY writer --- Point_set_3/include/CGAL/Point_set_3/IO.h | 33 +++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index ec5f9f6858a..c84d91c8477 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -379,6 +379,9 @@ write_ply_point_set( typedef typename Point_set::template Property_map Int16_map; typedef typename Point_set::template Property_map Uint16_map; typedef typename Point_set::template Property_map Int32_map; + typedef typename Point_set::template Property_map Uint32_map; + typedef typename Point_set::template Property_map Int64_map; + typedef typename Point_set::template Property_map Uint64_map; typedef typename Point_set::template Property_map Float_map; typedef typename Point_set::template Property_map Double_map; @@ -493,6 +496,36 @@ write_ply_point_set( continue; } } + { + Uint32_map pmap; + boost::tie (pmap, okay) = point_set.template property_map(prop[i]); + if (okay) + { + stream << "property uint " << prop[i] << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Int64_map pmap; + boost::tie (pmap, okay) = point_set.template property_map(prop[i]); + if (okay) + { + stream << "property int " << prop[i] << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } + { + Uint64_map pmap; + boost::tie (pmap, okay) = point_set.template property_map(prop[i]); + if (okay) + { + stream << "property uint " << prop[i] << std::endl; + printers.push_back (new internal::PLY::Simple_property_printer(pmap)); + continue; + } + } { Float_map pmap; boost::tie (pmap, okay) = point_set.template property_map(prop[i]); From a352fe8a0de9b08de2fb2df2f3c86f99f9bf84f1 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 25 Jan 2019 14:24:07 +0100 Subject: [PATCH 62/81] Document how to recover/write PLY comments --- Point_set_3/include/CGAL/Point_set_3/IO.h | 42 ++++++++++++------- .../Scene_points_with_normal_item.cpp | 4 +- .../include/CGAL/Surface_mesh/Surface_mesh.h | 11 ++++- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index c84d91c8477..735eb6f5116 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -295,19 +295,32 @@ read_off_point_set( #if (!defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES)) || defined(DOXYGEN_RUNNING) +/// \cond SKIP_IN_MANUAL +template +bool +read_ply_point_set( + std::istream& stream, ///< input stream. + CGAL::Point_set_3& point_set) ///< point set +{ + std::string dummy; + return read_ply_point_set (stream, point_set, dummy); +} + +/// \endcond /*! \ingroup PkgPointSet3IO + + The `comments` parameter can be omitted. If provided, it will be + used to store the potential comments found in the PLY + header. Each line starting by "comment " in the header is + appended to the `comments` string (without the "comment " word). */ template bool read_ply_point_set( std::istream& stream, ///< input stream. -#ifdef DOXYGEN_RUNNING - CGAL::Point_set_3& point_set) ///< point set -#else CGAL::Point_set_3& point_set, ///< point set - std::string* comments = NULL) ///< recover PLY comments -#endif + std::string& comments) ///< PLY comments. { if(!stream) { @@ -324,8 +337,7 @@ read_ply_point_set( return false; } - if (comments != NULL) - *comments = reader.comments(); + comments = reader.comments(); for (std::size_t i = 0; i < reader.number_of_elements(); ++ i) { @@ -358,17 +370,17 @@ read_ply_point_set( /*! \ingroup PkgPointSet3IO + + If provided, the `comments` string is included line by line in + the header of the PLY stream (each line will be precedeed by + "comment "). */ template bool write_ply_point_set( std::ostream& stream, ///< output stream. -#ifdef DOXYGEN_RUNNING - const CGAL::Point_set_3& point_set) ///< point set -#else - const CGAL::Point_set_3& point_set, ///< point set - std::string* comments = NULL) ///< write PLY comments -#endif + const CGAL::Point_set_3& point_set, ///< point set. + const std::string& comments = std::string()) ///< PLY comments. { typedef CGAL::Point_set_3 Point_set; typedef typename Point_set::Index Index; @@ -389,9 +401,9 @@ write_ply_point_set( << ((get_mode(stream) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl << "comment Generated by the CGAL library" << std::endl; - if (comments != NULL) + if (comments != std::string()) { - std::istringstream iss (*comments); + std::istringstream iss (comments); std::string line; while (getline(iss, line)) { diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index bcf4b4c34fa..8c4c3484567 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -619,7 +619,7 @@ bool Scene_points_with_normal_item::read_ply_point_set(std::istream& stream) d->m_points->clear(); bool ok = stream && - CGAL::read_ply_point_set (stream, *(d->m_points), &(d->m_comments)) && + CGAL::read_ply_point_set (stream, *(d->m_points), d->m_comments) && !isEmpty(); d->point_Slider->setValue(CGAL::Three::Three::getDefaultPointSize()); std::cerr << d->m_points->info(); @@ -653,7 +653,7 @@ bool Scene_points_with_normal_item::write_ply_point_set(std::ostream& stream, bo if (binary) CGAL::set_binary_mode (stream); - CGAL::write_ply_point_set (stream, *(d->m_points), &(d->m_comments)); + CGAL::write_ply_point_set (stream, *(d->m_points), d->m_comments); return true; } diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 690a8818886..873d03929fd 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2167,6 +2167,11 @@ private: //------------------------------------------------------- private data /// property with simple type: if they do, all edge properties with /// simple types are inserted in the stream. The halfedges follow /// the same behavior. + /// + /// If provided, the `comments` string is included line by line in + /// the header of the PLY stream (each line will be precedeed by + /// "comment "). + /// /// \relates Surface_mesh template bool write_ply(std::ostream& os, const Surface_mesh

& sm, const std::string& comments = std::string()) @@ -2521,7 +2526,6 @@ private: //------------------------------------------------------- private data } /// \endcond - /// \relates Surface_mesh /// Extracts the surface mesh from an input stream in Ascii or /// Binary PLY format and appends it to the surface mesh `sm`. /// @@ -2540,6 +2544,11 @@ private: //------------------------------------------------------- private data /// added, where `[s]` is `v` for vertex and `f` for face, and /// `[name]` is the name of PLY property. /// + /// The `comments` parameter can be omitted. If provided, it will be + /// used to store the potential comments found in the PLY + /// header. Each line starting by "comment " in the header is + /// appended to the `comments` string (without the "comment " word). + /// /// \pre The data in the stream must represent a two-manifold. If this is not the case /// the `failbit` of `is` is set and the mesh cleared. /// \relates Surface_mesh From ca748364c6d923daa47573c6f7b477597a25e50d Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 25 Jan 2019 15:09:29 +0100 Subject: [PATCH 63/81] Add reserve() where needed, fix a bug in read_off() and handle mesh-appending --- Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h | 10 +++++++--- .../include/CGAL/Surface_mesh/Surface_mesh.h | 12 +++++++++++- Surface_mesh/test/Surface_mesh/sm_ply_io.cpp | 4 ++++ Surface_mesh/test/Surface_mesh/tetra.ply | 14 ++++++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 Surface_mesh/test/Surface_mesh/tetra.ply diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h index c2b603451f5..f4a9cb8bb63 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h @@ -78,6 +78,7 @@ private: }; Surface_mesh& m_mesh; + std::vector m_map_v2v; bool m_use_floats; int m_normals; typename Surface_mesh::template Property_map m_normal_map; @@ -183,6 +184,7 @@ public: void instantiate_vertex_properties (PLY_element& element) { + m_map_v2v.reserve(element.number_of_items()); instantiate_properties (element, m_vertex_properties); } @@ -288,6 +290,7 @@ public: element.assign (z, "z"); Point point (x, y, z); vi = m_mesh.add_vertex(point); + m_map_v2v.push_back(vi); if (m_normals == 3) { @@ -334,7 +337,7 @@ public: std::vector vertices; vertices.reserve(indices.size()); for (std::size_t i = 0; i < indices.size(); ++ i) - vertices.push_back (Vertex_index (indices[i])); + vertices.push_back (m_map_v2v[std::size_t(indices[i])]); fi = m_mesh.add_face(vertices); if (fi == m_mesh.null_face()) @@ -375,7 +378,8 @@ public: element.assign (v0, "v0"); element.assign (v1, "v1"); - Halfedge_index hi = m_mesh.halfedge(Vertex_index(v0), Vertex_index(v1)); + Halfedge_index hi = m_mesh.halfedge(m_map_v2v[std::size_t(v0)], + m_map_v2v[std::size_t(v1)]); if (hi == m_mesh.null_halfedge()) return; @@ -406,7 +410,7 @@ public: IntType source, target; element.assign (source, "source"); element.assign (target, "target"); - hi = m_mesh.halfedge(Vertex_index(source), Vertex_index(target)); + hi = m_mesh.halfedge(m_map_v2v[std::size_t(source)], m_map_v2v[std::size_t(target)]); } }; diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 873d03929fd..046d14d9cf3 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2413,7 +2413,7 @@ private: //------------------------------------------------------- private data if(!is){ return false; } - sm.reserve(sm.num_vertices()+n, sm.num_faces()+2*f, sm.num_edges()+e); + sm.reserve(sm.num_vertices()+n, sm.num_edges()+e, sm.num_faces()+f); std::vector vertexmap(n); P p; Vector_3 v; @@ -2582,12 +2582,22 @@ private: //------------------------------------------------------- private data bool is_edge = false; bool is_halfedge = false; if (is_vertex) + { + sm.reserve(sm.number_of_vertices() + element.number_of_items(), + sm.number_of_edges(), + sm.number_of_faces()); filler.instantiate_vertex_properties (element); + } else is_face = (element.name() == "face" || element.name() == "faces"); if (is_face) + { + sm.reserve(sm.number_of_vertices(), + sm.number_of_edges(), + sm.number_of_faces() + element.number_of_items()); filler.instantiate_face_properties (element); + } else is_edge = (element.name() == "edge"); diff --git a/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp b/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp index 8dcf801a16e..c18b6523b74 100644 --- a/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp +++ b/Surface_mesh/test/Surface_mesh/sm_ply_io.cpp @@ -34,6 +34,10 @@ int main() mesh.add_property_map("u", 13.f); mesh.add_property_map("v", 37.f); + // Append second mesh + std::ifstream in2 ("tetra.ply"); + CGAL::read_ply (in2, mesh); + std::ofstream out ("out.ply"); // CGAL::set_binary_mode(out); CGAL::write_ply (out, mesh); diff --git a/Surface_mesh/test/Surface_mesh/tetra.ply b/Surface_mesh/test/Surface_mesh/tetra.ply new file mode 100644 index 00000000000..6b2a697893f --- /dev/null +++ b/Surface_mesh/test/Surface_mesh/tetra.ply @@ -0,0 +1,14 @@ +ply +format ascii 1.0 +element vertex 3 +property double x +property double y +property double z +property int blabla +element face 1 +property list uchar int vertex_indices +end_header +0 0 2 1000 +0 1 2 200 +1 0 2 30 +3 0 1 2 From 6b4bb9bba26f92980bdb6ed5d2ba0b8285f1020b Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Mon, 28 Jan 2019 10:09:06 +0100 Subject: [PATCH 64/81] Update doc --- Point_set_3/include/CGAL/Point_set_3/IO.h | 15 +++++++++++++++ .../include/CGAL/Surface_mesh/Surface_mesh.h | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Point_set_3/include/CGAL/Point_set_3/IO.h b/Point_set_3/include/CGAL/Point_set_3/IO.h index 735eb6f5116..04db58d4f3c 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO.h @@ -310,6 +310,15 @@ read_ply_point_set( /*! \ingroup PkgPointSet3IO + Reads a point set with properties from an input stream in Ascii or + Binary PLY format. + + - the operator reads the vertex `point` property; + - if three PLY properties `nx`, `ny` and `nz` with type `float` + or `double` are found, the normal map is added; + - if any other PLY property is found, a "[name]" property map is + added, where `[name]` is the name of the PLY property. + The `comments` parameter can be omitted. If provided, it will be used to store the potential comments found in the PLY header. Each line starting by "comment " in the header is @@ -371,6 +380,12 @@ read_ply_point_set( /*! \ingroup PkgPointSet3IO + Writes a point set with properties in an output stream in PLY + format. + + If found, the normal map is inserted to the stream. All other + properties with simple types are inserted in the stream. + If provided, the `comments` string is included line by line in the header of the PLY stream (each line will be precedeed by "comment "). diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index 046d14d9cf3..5e298acc519 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2542,7 +2542,7 @@ private: //------------------------------------------------------- private data /// added; /// - if any other PLY property is found, a "[s]:[name]" property map is /// added, where `[s]` is `v` for vertex and `f` for face, and - /// `[name]` is the name of PLY property. + /// `[name]` is the name of the PLY property. /// /// The `comments` parameter can be omitted. If provided, it will be /// used to store the potential comments found in the PLY From 07bd0765f2ecb2a71ecb44f8e646a01c1e55d09d Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Fri, 22 Feb 2019 16:42:40 +0100 Subject: [PATCH 65/81] Fix FT type detection --- Stream_support/include/CGAL/IO/PLY.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Stream_support/include/CGAL/IO/PLY.h b/Stream_support/include/CGAL/IO/PLY.h index 85f14b97b91..926ee1a314e 100644 --- a/Stream_support/include/CGAL/IO/PLY.h +++ b/Stream_support/include/CGAL/IO/PLY.h @@ -68,10 +68,18 @@ struct PLY_property PLY_property (const char* name) : name (name) { } }; +// Use a double property for all kernels... +template struct Convert_FT { typedef double type; }; +// ...except if kernel uses type float +template <> struct Convert_FT { typedef float type; }; + template struct Get_FT_from_map { - typedef typename Kernel_traits::value_type>::Kernel::FT type; + typedef typename + ::value_type>::Kernel::FT>::type type; }; template From 3fb713de13236e3663d62e145ba16143014ee6ca Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 13:36:36 +0100 Subject: [PATCH 66/81] Move doc of CGAL::Color to header and rewrite class --- .../doc/Stream_support/CGAL/IO/Color.h | 107 ------ Stream_support/doc/Stream_support/Doxyfile.in | 1 + Stream_support/include/CGAL/IO/Color.h | 358 +++++++++++++++--- 3 files changed, 304 insertions(+), 162 deletions(-) delete mode 100644 Stream_support/doc/Stream_support/CGAL/IO/Color.h diff --git a/Stream_support/doc/Stream_support/CGAL/IO/Color.h b/Stream_support/doc/Stream_support/CGAL/IO/Color.h deleted file mode 100644 index bf800b4a7a4..00000000000 --- a/Stream_support/doc/Stream_support/CGAL/IO/Color.h +++ /dev/null @@ -1,107 +0,0 @@ - -namespace CGAL { - -/*! -\ingroup PkgStreamSupportRef - -An object of the class `Color` is a color available -for drawing operations in many \cgal output streams. -Each color is defined by a triple of unsigned chars `(r,g,b)` with -0 \f$\le\f$ r,g,b \f$ \le \f$ 255, the so-called rgb-value of the color. - -\sa `CGAL::Geomview_stream` - -*/ - -class Color { -public: - -/// \name Creation -/// @{ - -/*! -creates a color with rgb-value `(0,0,0)`, i.e.\ black. -*/ -Color(); - -/*! -creates a color with rgb-value `(red,green,blue)`. -*/ -Color(unsigned char red, unsigned char green, unsigned char blue); - -/// @} - -/// \name Operations -/// @{ - -/*! -Test for equality: Two colors are equal, iff their -rgb-values are equal. -*/ -bool operator==(const Color &q) const; - -/*! -Test for inequality. -*/ -bool operator!=(const Color &q) const; - -/*! -returns the red component of `c`. -*/ -unsigned char red() const; - -/*! -returns the green component of `c`. -*/ -unsigned char green() const; - -/*! -returns the blue component of `c`. -*/ -unsigned char blue() const; - -/// @} - -/// \name Constants -/// The following constants are predefined: -/// @{ - -/*! -Black. -*/ -const Color BLACK = Color(0, 0, 0); - -/*! -White. -*/ -const Color WHITE = Color(255, 255, 255); - -/*! -Red. -*/ -const Color RED = Color(255, 0, 0); - -/*! -Green. -*/ -const Color GREEN = Color(0, 255, 0); - -/*! -Blue. -*/ -const Color BLUE = Color(0, 0, 255); - -/*! -Violet. -*/ -const Color VIOLET = Color(255, 0, 255); - -/*! -Orange. -*/ -const Color ORANGE = Color(255, 170, 0); - -/// @} - -}; /* end Color */ -} /* end namespace CGAL */ diff --git a/Stream_support/doc/Stream_support/Doxyfile.in b/Stream_support/doc/Stream_support/Doxyfile.in index 1f49650958f..f742dc367d0 100644 --- a/Stream_support/doc/Stream_support/Doxyfile.in +++ b/Stream_support/doc/Stream_support/Doxyfile.in @@ -1,4 +1,5 @@ @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - IO Streams" +INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/IO/Color.h diff --git a/Stream_support/include/CGAL/IO/Color.h b/Stream_support/include/CGAL/IO/Color.h index a9cfdb57f25..05119dc6220 100644 --- a/Stream_support/include/CGAL/IO/Color.h +++ b/Stream_support/include/CGAL/IO/Color.h @@ -23,74 +23,322 @@ // // Author(s) : Andreas Fabri -#include - #ifndef CGAL_COLOR_H #define CGAL_COLOR_H +#include +#include + namespace CGAL { -class Color { -public: - Color(): _red(120), _green(120), _blue(120), _alpha(120) {} - Color(unsigned char red, - unsigned char green, - unsigned char blue, - unsigned char alpha = 120) - : _red(red), _green(green), _blue(blue), _alpha(alpha) - {} - unsigned char r() const {return _red;} - unsigned char g() const {return _green;} - unsigned char b() const {return _blue;} +/*! + \ingroup PkgStreamSupportRef - unsigned char red() const {return _red;} - unsigned char green() const {return _green;} - unsigned char blue() const {return _blue;} - unsigned char alpha() const {return _alpha;} - void set_alpha(unsigned char a) {_alpha=a;} - bool operator==(const Color &c) const - { - return ( (red() == c.red()) && - (green() == c.green()) && - (blue() == c.blue()) ); - } + An object of the class `Color` is a color available for drawing + operations in many \cgal output streams. Each color is defined by a + 4 unsigned chars `(r,g,b,a)` with 0 \f$\le\f$ r,g,b,a \f$ \le \f$ + 255, the so-called rgba-value of the color. - bool operator!=(const Color &c) const - { - return !( (*this) == c); - } + The alpha parameter (representing transparency) is often ignored and + left to its default value (255 = no transparency), which is why we + often refer to the rgb-value of the color. + \sa `CGAL::Geomview_stream` + +*/ + +class Color +{ private: - unsigned char _red; - unsigned char _green; - unsigned char _blue; - unsigned char _alpha; + + cpp11::array m_data; + +public: + + /// \name Creation + /// @{ + + /*! + creates a color with rgba-value `(0,0,0,255)`, i.e.\ black. + */ + Color() + { + set_rgb (0, 0, 0, 255); + } + + /*! + creates a color with rgba-value `(red,green,blue,alpha)`. + */ + Color(unsigned char red, + unsigned char green, + unsigned char blue, + unsigned char alpha = 255) + { + set_rgb (red, green, blue, alpha); + } + + /// @} + + /// \name Component Access + /// @{ + + /*! + returns the red component. + */ + unsigned char red() const { return m_data[0]; } + + /*! + returns a reference on the red component. + */ + unsigned char& red() { return m_data[0]; } + + /*! + returns the green component. + */ + unsigned char green() const { return m_data[1]; } + + /*! + returns a reference on the green component. + */ + unsigned char& green() { return m_data[1]; } + + /*! + returns the blue component. + */ + unsigned char blue() const { return m_data[2]; } + + /*! + returns a reference on the blue component. + */ + unsigned char& blue() { return m_data[2]; } + + /*! + returns the alpha component. + */ + unsigned char alpha() const { return m_data[3]; } + + /*! + returns a reference on the alpha component. + */ + unsigned char& alpha() { return m_data[3]; } + + /// @} + + /// \name Array Access + /// @{ + + /*! + returns the i^{th} component of the rgb color (the 0^{th} is red, + the 1^{st} is blue, etc.). + */ + unsigned char operator[] (std::size_t i) const { return m_data[i]; } + + /*! + returns a reference on the i^{th} component of `c` (the 0^{th} is + red, the 1^{st} is blue, etc.). + */ + unsigned char& operator[] (std::size_t i) { return m_data[i]; } + + /*! + returns the array with rgba values. + */ + const cpp11::array& to_rgba() const { return m_data; } + + /*! + returns the array with rgb values. + */ + const cpp11::array& to_rgb() const + { + return reinterpret_cast&>(m_data); + } + + /*! + computes the hsv (hue, saturation, value) values and returns an + array representing them as float values between 0 and 1. + */ + cpp11::array to_hsv() const + { + double r = (double)(m_data[0]) / 255.; + double g = (double)(m_data[1]) / 255.; + double b = (double)(m_data[2]) / 255.; + double Cmax = (std::max) (r, (std::max) (g, b)); + double Cmin = (std::min) (r, (std::min) (g, b)); + double delta = Cmax - Cmin; + double H = 0.; + + if (delta != 0.) + { + if (Cmax == r) + H = 60. * ((g - b) / delta); + else if (Cmax == g) + H = 60. * (((b - r) / delta) + 2.); + else + H = 60. * (((r - g) / delta) + 4.); + } + + if (H < 0.) H += 360.; + + double S = (Cmax == 0. ? 0. : 100. * (delta / Cmax)); + double V = 100. * Cmax; + + return make_array(H,S,V); + } + + /// \name Modification + /// @{ + + /*! + replaces the rgb values of the colors by the one given as parameters. + */ + void set_rgb (unsigned char red, + unsigned char green, + unsigned char blue, + unsigned char alpha = 255) + { + m_data[0] = red; + m_data[1] = green; + m_data[2] = blue; + m_data[3] = alpha; + } + + /*! + replaces the rgb values of the colors by the conversion to rgb of + the hsv values given as parameters. + + Double values given as parameters should take range between 0 and 1. + */ + void set_hsv (double hue, + double saturation, + double value, + unsigned char alpha = 255) + { + saturation /= 100.; + value /= 100.; + double C = value*saturation; + int hh = (int)(hue/60.); + double X = C * (1-std::abs (hh % 2 - 1)); + double r = 0, g = 0, b = 0; + + if( hh>=0 && hh<1 ) + { + r = C; + g = X; + } + else if( hh>=1 && hh<2 ) + { + r = X; + g = C; + } + else if( hh>=2 && hh<3 ) + { + g = C; + b = X; + } + else if( hh>=3 && hh<4 ) + { + g = X; + b = C; + } + else if( hh>=4 && hh<5 ) + { + r = X; + b = C; + } + else + { + r = C; + b = X; + } + double m = value-C; + r += m; + g += m; + b += m; + r *= 255.0; + g *= 255.0; + b *= 255.0; + + m_data[0] = (unsigned char)r; + m_data[1] = (unsigned char)g; + m_data[2] = (unsigned char)b; + m_data[3] = alpha; + } + + /// @} + +}; + + +/*! + Constructs Color(0,0,0). + \relates Color +*/ +inline Color black() { return Color(0,0,0); } + +/*! + Constructs Color(0,0,255). + \relates Color +*/ +inline Color blue() { return Color(0,0,255); } + +/*! + Constructs Color(10,0,100). + \relates Color +*/ +inline Color deep_blue() { return Color(10,0,100); } + +/*! + Constructs Color(100,100,100). + \relates Color +*/ +inline Color gray() { return Color(100,100,100); } + +/*! + Constructs Color(0,255,0). + \relates Color +*/ +inline Color green() { return Color(0,255,0); } + +/*! + Constructs Color(235,150,0). + \relates Color +*/ +inline Color orange() { return Color(235,150,0); } + +/*! + Constructs Color(100,0,70). + \relates Color +*/ +inline Color purple() { return Color(100,0,70); } + +/*! + Constructs Color(255,0,0). + \relates Color +*/ +inline Color red() { return Color(255,0,0); } + +/*! + Constructs Color(255,0,255). + \relates Color +*/ +inline Color violet() { return Color(255,0,255); } + +/*! + Constructs Color(255,255,255). + \relates Color +*/ +inline Color white() { return Color(255,255,255); } + +/*! + Constructs Color(255,255,0). + \relates Color +*/ +inline Color yellow() { return Color(255,255,0); } + + }; -#ifndef CGAL_HEADER_ONLY - -CGAL_EXPORT extern const Color BLACK ; -CGAL_EXPORT extern const Color WHITE ; -CGAL_EXPORT extern const Color GRAY ; - -CGAL_EXPORT extern const Color RED ; -CGAL_EXPORT extern const Color GREEN ; - -CGAL_EXPORT extern const Color DEEPBLUE; -CGAL_EXPORT extern const Color BLUE ; -CGAL_EXPORT extern const Color PURPLE ; -CGAL_EXPORT extern const Color VIOLET ; - -CGAL_EXPORT extern const Color ORANGE ; -CGAL_EXPORT extern const Color YELLOW ; - -#endif // CGAL_HEADER_ONLY } //namespace CGAL -#ifdef CGAL_HEADER_ONLY -#include -#endif // CGAL_HEADER_ONLY - #endif // CGAL_COLOR_H From 19a66fbd4f4cc5718d0391f4452e2a23b229a44a Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:16:35 +0100 Subject: [PATCH 67/81] Replace link test using Random instead of Color --- Installation/test/Installation/link_to_CGAL.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Installation/test/Installation/link_to_CGAL.cpp b/Installation/test/Installation/link_to_CGAL.cpp index 0638aa6db6e..3cb2755535d 100644 --- a/Installation/test/Installation/link_to_CGAL.cpp +++ b/Installation/test/Installation/link_to_CGAL.cpp @@ -1,10 +1,9 @@ // Use something defined not in headers but in the CGAL library to test that is was indeed properly built and linked to, -#include +#include int main() { - volatile const CGAL::Color* c = &CGAL::BLACK; - - return (c != 0) ? 0 : 1; + volatile const CGAL::Random* r = &CGAL::get_default_random(); + return int(r != 0); } From 9256c04157306f2494e05131745247d78a6acf87 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:18:49 +0100 Subject: [PATCH 68/81] Replace old color API using global const variable with new one using functions --- .../xalci/misc.cpp | 2 +- .../Arrangement_on_surface_2/arr_bench.cpp | 10 ++++----- .../demo/Convex_hull_3/quickhull_3_demo.cpp | 4 ++-- Geomview/demo/Geomview/gv_terrain.cpp | 4 ++-- Geomview/demo/Geomview/kernel.cpp | 16 +++++++------- .../Qt/SegmentDelaunayGraphGraphicsItem.h | 4 ++-- .../Qt/SegmentDelaunayGraphLinfGraphicsItem.h | 4 ++-- .../examples/HalfedgeDS/hds_prog_color.cpp | 6 ++--- .../Interpolation/interpolation_2_demo.cpp | 4 ++-- .../demo/Interpolation/surface_voronoi.cpp | 10 ++++----- .../applications/display_distribution.cpp | 6 ++--- Mesh_3/archive/applications/distribution.cpp | 4 ++-- .../applications/lanteri_process_results.cpp | 2 +- .../output_distribution_to_stdout.cpp | 6 ++--- Nef_3/include/CGAL/Nef_3/SM_visualizor.h | 6 ++--- Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h | 6 ++--- Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h | 6 ++--- .../include/CGAL/Nef_S2/Sphere_geometry_OGL.h | 22 +++++++++---------- .../p2t2_colored_vertices.cpp | 2 +- .../colored_vertices.cpp | 2 +- .../Polyhedron/polyhedron_prog_color.cpp | 2 +- .../polyhedron_prog_vertex_color.cpp | 2 +- .../demo/Polyhedron_IO/geomview_demo.cpp | 2 +- .../examples/Triangulation_2/colored_face.cpp | 4 ++-- .../Triangulation_3_color_demo.cpp | 2 +- .../Triangulation_3_demo.cpp | 4 ++-- .../Triangulation_3_voronoi_demo.cpp | 2 +- .../examples/Triangulation_3/color.cpp | 2 +- 28 files changed, 73 insertions(+), 73 deletions(-) diff --git a/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp b/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp index 5641b3e6296..453a43b5e6a 100644 --- a/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp +++ b/Arrangement_on_surface_2/archive/demo/Arr_algebraic_segment_traits_2/xalci/misc.cpp @@ -479,7 +479,7 @@ void xAlci_main_window::setup(int w, int h) tab_widget->addTab(cad_tab,"cad"); tab_widget->addTab(arr_tab,"arrangement"); - *widget << CGAL::LineWidth(2) << CGAL::BackgroundColor(CGAL::WHITE); + *widget << CGAL::LineWidth(2) << CGAL::BackgroundColor(CGAL::white()); resize(w,h); double ratio = 1.0;//(double)h/w; widget->set_window(-1, 1, -ratio, ratio, true); diff --git a/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp b/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp index 86e299c27ad..903fc5a1b90 100644 --- a/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp +++ b/Arrangement_on_surface_2/benchmark/Arrangement_on_surface_2/arr_bench.cpp @@ -277,11 +277,11 @@ inline std::ostream & operator<<(std::ostream & os, const Arr::Vertex & vertex) inline Window_stream & operator<<(Window_stream & ws, Arr & arr) { Arr::Edge_iterator ei; - ws << CGAL::BLUE; + ws << CGAL::blue(); for (ei = arr.edges_begin(); ei != arr.edges_end(); ++ei) ws << (*ei).curve(); Arr::Vertex_iterator vi; - ws << CGAL::RED; + ws << CGAL::red(); for (vi = arr.vertices_begin(); vi != arr.vertices_end(); ++vi) ws << (*vi).point(); return ws; @@ -474,7 +474,7 @@ public: m_window->flush(); #else m_window->lock(); - *m_window << CGAL::BackgroundColor(CGAL::WHITE) << CGAL::RED; + *m_window << CGAL::BackgroundColor(CGAL::white()) << CGAL::red(); (*m_window) << arr; m_window->unlock(); App->flush(); @@ -490,9 +490,9 @@ public: ps_stream.set_line_width(1); CGAL::Arr_drawer drawer(ps_stream); // drawer.draw_faces(arr.faces_begin(), arr.faces_end()); - ps_stream << CGAL::BLUE; + ps_stream << CGAL::blue(); drawer.draw_halfedges(arr.halfedges_begin(), arr.halfedges_end()); - ps_stream << CGAL::RED; + ps_stream << CGAL::red(); drawer.draw_vertices(arr.vertices_begin(), arr.vertices_end()); // draw_arr(arr, drawer, ps_stream); diff --git a/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp b/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp index d50f0faef09..786598fb80b 100644 --- a/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp +++ b/Convex_hull_3/demo/Convex_hull_3/quickhull_3_demo.cpp @@ -67,7 +67,7 @@ void draw_points_and_hull(const std::vector& points, std::vector::const_iterator p_it; CGAL::Geomview_stream geomview; - geomview << CGAL::RED; + geomview << CGAL::red(); for (p_it = points.begin(); p_it != points.end(); p_it++) { geomview << *p_it; @@ -78,7 +78,7 @@ void draw_points_and_hull(const std::vector& points, Point_3 point; Polyhedron_3 polyhedron; - geomview << CGAL::BLUE; + geomview << CGAL::blue(); if ( CGAL::assign(point, object) ) geomview << point; else if ( CGAL::assign(segment, object) ) diff --git a/Geomview/demo/Geomview/gv_terrain.cpp b/Geomview/demo/Geomview/gv_terrain.cpp index 27ce828d30c..bed8f15171a 100644 --- a/Geomview/demo/Geomview/gv_terrain.cpp +++ b/Geomview/demo/Geomview/gv_terrain.cpp @@ -57,13 +57,13 @@ int main() // use different colors, and put a few sleeps/clear. - gv << CGAL::BLUE; + gv << CGAL::blue(); std::cout << "Drawing 2D Delaunay triangulation in wired mode.\n"; gv.set_wired(true); gv << D; #if 1 // It's too slow ! Needs to use OFF for that. - gv << CGAL::RED; + gv << CGAL::red(); std::cout << "Drawing its Voronoi diagram.\n"; gv.set_wired(true); D.draw_dual(gv); diff --git a/Geomview/demo/Geomview/kernel.cpp b/Geomview/demo/Geomview/kernel.cpp index e496e59a311..0fe909a05fc 100644 --- a/Geomview/demo/Geomview/kernel.cpp +++ b/Geomview/demo/Geomview/kernel.cpp @@ -50,25 +50,25 @@ int main() gv.clear(); // remove the pickplane. gv << K::Point_2 (200, 100); - gv << CGAL::BLUE; + gv << CGAL::blue(); gv << K::Point_3 (200, 100, 100); - gv << CGAL::RED; + gv << CGAL::red(); gv << K::Segment_2 (K::Point_2(200, 100), K::Point_2(300, 100)); - gv << CGAL::GREEN; + gv << CGAL::green(); gv << K::Segment_3 (K::Point_3(200, 100, 100), K::Point_3(300, 100, 200)); - gv << CGAL::DEEPBLUE; + gv << CGAL::deep_blue(); gv << K::Sphere_3 (K::Point_3(100, 100, 100), 1000); - gv << CGAL::VIOLET; + gv << CGAL::violet(); gv << K::Triangle_2 (K::Point_2(200, 200), K::Point_2(220, 220), K::Point_2(180, 220)); - gv << CGAL::ORANGE; + gv << CGAL::orange(); gv << K::Triangle_3 (K::Point_3(200, 200, 50), K::Point_3(220, 220, 80), K::Point_3(180, 220, 100)); - gv << CGAL::PURPLE; + gv << CGAL::purple(); gv << K::Tetrahedron_3 (K::Point_3(100, 100, 180), K::Point_3(120, 70, 220), K::Point_3(100, 100, 220), @@ -76,7 +76,7 @@ int main() gv << CGAL::Bbox_2(10, 10, 30, 30); gv << CGAL::Bbox_3(10, 10, 10, 30, 30, 30); - gv << CGAL::RED; + gv << CGAL::red(); gv << K::Ray_2(K::Point_2(205,205), K::Point_2(500,500)); gv << K::Ray_3(K::Point_3(250,250,250), K::Point_3(500,500,500)); gv << K::Line_2(K::Point_2(195,195), K::Point_2(500,500)); diff --git a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h index d9fb9e6b5e0..71a52459805 100644 --- a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h +++ b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphGraphicsItem.h @@ -173,9 +173,9 @@ SegmentDelaunayGraphGraphicsItem::drawAll(QPainter *painter, const QStyleOpti vit != t->finite_vertices_end(); ++vit) { typename T::Site_2 s = vit->site(); if ( s.is_input() ) { - //*widget << CGAL::RED; + //*widget << CGAL::red(); } else { - //*widget << CGAL::YELLOW; + //*widget << CGAL::yellow(); } if ( s.is_point() ) { QPointF point = matrix.map(convert(s.point())); diff --git a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h index 43ba00ccbf6..1542ff69acf 100644 --- a/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h +++ b/GraphicsView/include/CGAL/Qt/SegmentDelaunayGraphLinfGraphicsItem.h @@ -208,9 +208,9 @@ SegmentDelaunayGraphLinfGraphicsItem::drawAll(QPainter *painter, const QStyle vit != t->finite_vertices_end(); ++vit) { typename T::Site_2 s = vit->site(); if ( s.is_input() ) { - //*widget << CGAL::RED; + //*widget << CGAL::red(); } else { - //*widget << CGAL::YELLOW; + //*widget << CGAL::yellow(); } if ( s.is_point() ) { QPointF point = matrix.map(convert(s.point())); diff --git a/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp b/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp index 35300c92bab..6b294fefe5c 100644 --- a/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp +++ b/HalfedgeDS/examples/HalfedgeDS/hds_prog_color.cpp @@ -28,8 +28,8 @@ typedef HDS::Face_handle Face_handle; int main() { HDS hds; - Face_handle f = hds.faces_push_back( Face( CGAL::RED)); - f->color = CGAL::BLUE; - CGAL_assertion( f->color == CGAL::BLUE); + Face_handle f = hds.faces_push_back( Face( CGAL::red())); + f->color = CGAL::blue(); + CGAL_assertion( f->color == CGAL::blue()); return 0; } diff --git a/Interpolation/demo/Interpolation/interpolation_2_demo.cpp b/Interpolation/demo/Interpolation/interpolation_2_demo.cpp index 2ed7aa06b07..d3d0a5136e6 100644 --- a/Interpolation/demo/Interpolation/interpolation_2_demo.cpp +++ b/Interpolation/demo/Interpolation/interpolation_2_demo.cpp @@ -287,14 +287,14 @@ int main(int , char** ) std::cout << "The data points are displayed in blue in the geomview" << " application." << std::endl; - gv << CGAL::BLUE; + gv << CGAL::blue(); visu_points(gv,sample_3); //show the gradients if(method>0){ std::cout << "The function gradients are displayed by red lines " <<" in the geomview application." << std::endl; - gv <> ch; diff --git a/Mesh_3/archive/applications/display_distribution.cpp b/Mesh_3/archive/applications/display_distribution.cpp index 838b3bb595a..547ff00693e 100644 --- a/Mesh_3/archive/applications/display_distribution.cpp +++ b/Mesh_3/archive/applications/display_distribution.cpp @@ -174,7 +174,7 @@ void output_distribution_to_png(std::vector& elements, const double scale = double_options["scale"]; - *widget << CGAL::FillColor(CGAL::BLACK); + *widget << CGAL::FillColor(CGAL::black()); // *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.)); for(int k=0;k0) @@ -184,12 +184,12 @@ void output_distribution_to_png(std::vector& elements, height = ( (distribution[k]+0.)/number_of_cells ) * scale; else height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale); - *widget << CGAL::BLACK + *widget << CGAL::black() << Rectangle_2(Point_2(k*width, 0), Point_2((k+1)*width, height)); } else - *widget << CGAL::RED << Segment_2(Point_2(k*width, 0), + *widget << CGAL::red() << Segment_2(Point_2(k*width, 0), Point_2((k+1)*width, 0)); widget->unlock(); diff --git a/Mesh_3/archive/applications/distribution.cpp b/Mesh_3/archive/applications/distribution.cpp index 42fb5678dde..4a7d44f780e 100644 --- a/Mesh_3/archive/applications/distribution.cpp +++ b/Mesh_3/archive/applications/distribution.cpp @@ -34,10 +34,10 @@ void display_distribution(Distribution_displayer* display, const double height = ( distribution[k]+0. ) * echelle; display->fill_rectangle(k * width, 0, (k+1)* width, height, - CGAL::BLACK); + CGAL::black()); } else display->segment(k * width, 0., (k+1) * width, 0., - CGAL::RED); + CGAL::red()); } diff --git a/Mesh_3/archive/applications/lanteri_process_results.cpp b/Mesh_3/archive/applications/lanteri_process_results.cpp index 982e18c5201..b7403c49f09 100644 --- a/Mesh_3/archive/applications/lanteri_process_results.cpp +++ b/Mesh_3/archive/applications/lanteri_process_results.cpp @@ -99,7 +99,7 @@ bool process_aux_2(const std::vector& qualities, displays[i]->segment(x_position_of_length_bound, 0.0, x_position_of_length_bound, -0.05, - CGAL::BLUE); + CGAL::blue()); } *out_stream << "saving " << filename.c_str() << "...\n"; diff --git a/Mesh_3/archive/applications/output_distribution_to_stdout.cpp b/Mesh_3/archive/applications/output_distribution_to_stdout.cpp index 4b7a586eba6..6ceef9c3ca0 100644 --- a/Mesh_3/archive/applications/output_distribution_to_stdout.cpp +++ b/Mesh_3/archive/applications/output_distribution_to_stdout.cpp @@ -180,7 +180,7 @@ void parse_argv(int argc, char** argv, int extra_args = 0) // // const double scale = double_options["scale"]; // -//// *widget << CGAL::FillColor(CGAL::BLACK); +//// *widget << CGAL::FillColor(CGAL::black()); // // *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.)); // for(int k=0;k0) @@ -190,12 +190,12 @@ void parse_argv(int argc, char** argv, int extra_args = 0) // height = ( (distribution[k]+0.)/number_of_cells ) * scale; // else // height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale); -//// *widget << CGAL::BLACK +//// *widget << CGAL::black() //// << Rectangle_2(Point_2(k*width, 0), //// Point_2((k+1)*width, height)); // } // else -//// *widget << CGAL::RED << Segment_2(Point_2(k*width, 0), +//// *widget << CGAL::red() << Segment_2(Point_2(k*width, 0), //// Point_2((k+1)*width, 0)); // // // widget->unlock(); diff --git a/Nef_3/include/CGAL/Nef_3/SM_visualizor.h b/Nef_3/include/CGAL/Nef_3/SM_visualizor.h index a8c6c67512b..0423db7b476 100644 --- a/Nef_3/include/CGAL/Nef_3/SM_visualizor.h +++ b/Nef_3/include/CGAL/Nef_3/SM_visualizor.h @@ -48,11 +48,11 @@ class SNC_SM_BooleColor typedef typename Refs_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF3_DGREY : CGAL_NEF3_LGREY ); } }; diff --git a/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h b/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h index 25330ad7501..b2d18c43130 100644 --- a/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h +++ b/Nef_3/include/CGAL/Nef_3/SNC_SM_visualizor.h @@ -48,11 +48,11 @@ class SNC_SM_BooleColor typedef typename Map_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); } }; diff --git a/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h b/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h index 51ee7fe9917..a007e6a9338 100644 --- a/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h +++ b/Nef_S2/include/CGAL/Nef_S2/SM_visualizor.h @@ -44,11 +44,11 @@ class SM_BooleColor typedef typename Map_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); } }; diff --git a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h index f0527bb932b..34fecb1aa9f 100644 --- a/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h +++ b/Nef_S2/include/CGAL/Nef_S2/Sphere_geometry_OGL.h @@ -254,7 +254,7 @@ class Sphere_point : public VPoint, public Gen_object { public: Sphere_point() {} Sphere_point(const CGAL::Sphere_point& p, - CGAL::Color c = CGAL::BLACK, unsigned w = 10) : + CGAL::Color c = CGAL::black(), unsigned w = 10) : VPoint(Approximator::approximate(p)), p_(p), c_(c), w_(w) {} Sphere_point(const Sphere_point& p) : VPoint(p), Gen_object() { p_ = p.p_; c_ = p.c_; w_ = p.w_; } @@ -297,7 +297,7 @@ class Sphere_segment : public VSegment, public Gen_object { public: Sphere_segment() {} Sphere_segment(const CGAL::Sphere_segment& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 2) + CGAL::Color c = CGAL::black(), unsigned w = 2) : VSegment(Approximator::approximate(s)), s_(s), c_(c), w_(w) {} Sphere_segment(const Sphere_segment& s) : VSegment(s), Gen_object() { s_ = s.s_; c_ = s.c_; w_ = s.w_; } @@ -350,7 +350,7 @@ class Sphere_circle : public VSegment, public Gen_object { public: Sphere_circle() {} Sphere_circle(const CGAL::Sphere_circle& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 2) + CGAL::Color c = CGAL::black(), unsigned w = 2) : VSegment(Approximator::approximate(s)), s_(s), c_(c), w_(w) {} Sphere_circle(const Sphere_circle& s) : VSegment(s), Gen_object() { s_ = s.s_; c_ = s.c_; w_ = s.w_; } @@ -539,27 +539,27 @@ Unit_sphere& operator=(const Unit_sphere& S) template void push_back(const CGAL::Sphere_point& p, - CGAL::Color c = CGAL::YELLOW, unsigned w = 5) + CGAL::Color c = CGAL::yellow(), unsigned w = 5) { objects_.push_back(new Sphere_point(p,c,w)); } template void push_back(const CGAL::Sphere_segment& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 1) + CGAL::Color c = CGAL::black(), unsigned w = 1) { objects_.push_back(new Sphere_segment(s,c,w)); } template void push_back(const CGAL::Sphere_circle& s, - CGAL::Color c = CGAL::BLACK, unsigned w = 1) + CGAL::Color c = CGAL::black(), unsigned w = 1) { objects_.push_back(new Sphere_circle(s,c,w)); } template void push_back(const CGAL::Sphere_triangle& t, - CGAL::Color c = CGAL::WHITE) + CGAL::Color c = CGAL::white()) { triangles_.push_back(new Sphere_triangle(t,c)); } template void push_back_triangle_edge(const CGAL::Sphere_segment& s, - CGAL::Color c = CGAL::BLUE, unsigned w = 1) + CGAL::Color c = CGAL::blue(), unsigned w = 1) { triangle_edges_.push_back(new Sphere_segment(s,c,w)); } void set_style(int style) { @@ -718,11 +718,11 @@ class SM_BooleColor typedef typename Map_::Mark Mark; public: Color color(SVertex_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfedge_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SHalfloop_const_handle, Mark m) const - { return ( m ? CGAL::BLACK : CGAL::WHITE ); } + { return ( m ? CGAL::black() : CGAL::white() ); } Color color(SFace_const_handle, Mark m) const { return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); } }; diff --git a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp index 63097b27e00..aeed55bfdd3 100644 --- a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp +++ b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_colored_vertices.cpp @@ -32,7 +32,7 @@ int main() PDT::Vertex_iterator vit; for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit) if (T.degree(vit) == 6) - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); return 0; } diff --git a/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp b/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp index aa9cd4e4225..989b702679a 100644 --- a/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp +++ b/Periodic_3_triangulation_3/examples/Periodic_3_triangulation_3/colored_vertices.cpp @@ -36,7 +36,7 @@ int main(int, char**) P3DT3::Vertex_iterator vit; for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit) { if (T.degree(vit) == 16) { - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); } } diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp index 57fba3f5d8e..13a5569c3d0 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_color.cpp @@ -23,6 +23,6 @@ typedef Polyhedron::Halfedge_handle Halfedge_handle; int main() { Polyhedron P; Halfedge_handle h = P.make_tetrahedron(); - h->facet()->color = CGAL::RED; + h->facet()->color = CGAL::red(); return 0; } diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp index 1a29a2674e9..63abfbc9b2a 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_vertex_color.cpp @@ -29,6 +29,6 @@ typedef Polyhedron::Halfedge_handle Halfedge_handle; int main() { Polyhedron P; Halfedge_handle h = P.make_tetrahedron(); - h->vertex()->color = CGAL::RED; + h->vertex()->color = CGAL::red(); return 0; } diff --git a/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp b/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp index 1b806c21fa4..7ab19eccca2 100644 --- a/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp +++ b/Polyhedron_IO/demo/Polyhedron_IO/geomview_demo.cpp @@ -47,7 +47,7 @@ int main() { Polyhedron P; P.make_tetrahedron( p,q,r,s); CGAL::Geomview_stream geo; - geo << CGAL::GREEN << P; + geo << CGAL::green() << P; // wait for a mouse click. Point click; diff --git a/Triangulation_2/examples/Triangulation_2/colored_face.cpp b/Triangulation_2/examples/Triangulation_2/colored_face.cpp index cbee32c63ed..84392cd820b 100644 --- a/Triangulation_2/examples/Triangulation_2/colored_face.cpp +++ b/Triangulation_2/examples/Triangulation_2/colored_face.cpp @@ -22,11 +22,11 @@ int main() { t.insert(Point(2,2)); Finite_faces_iterator fc = t.finite_faces_begin(); - for( ; fc != t.finite_faces_end(); ++fc) fc->info() = CGAL::BLUE; + for( ; fc != t.finite_faces_end(); ++fc) fc->info() = CGAL::blue(); Point p(0.5,0.5); Face_handle fh = t.locate(p); - fh->info() = CGAL::RED; + fh->info() = CGAL::red(); return 0; } diff --git a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp index c718b0bb087..8d3615ad60b 100644 --- a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp +++ b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp @@ -66,7 +66,7 @@ int main() Delaunay::Finite_vertices_iterator vit; for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) if (T.degree(vit) == 6) - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); std::cout << " Visualization of T" << std::endl; gv.set_wired(true); diff --git a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp index b7f14bf3808..206531e09c2 100644 --- a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp +++ b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp @@ -136,7 +136,7 @@ int main() std::cout <<" Locating point (1,1,1) :" << std::endl; Point p(1,1,1); - gv.set_vertex_color(CGAL::ORANGE); + gv.set_vertex_color(CGAL::orange()); gv << p; Locate_type lt; int li, lj; @@ -144,7 +144,7 @@ int main() sleep(3); - gv << CGAL::VIOLET; + gv << CGAL::violet(); if ( lt == Triangulation::CELL ) { std::cout <<" CELL" << std::endl; visu_cell(gv,T,c); diff --git a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp index e3fe523bcb2..383285ab01a 100644 --- a/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp +++ b/Triangulation_3/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp @@ -74,7 +74,7 @@ int main() gv << T; std::cout <<" Visualizing the Voronoi edges" << std::endl; - gv << CGAL::RED; + gv << CGAL::red(); T.draw_dual(gv); char ch; diff --git a/Triangulation_3/examples/Triangulation_3/color.cpp b/Triangulation_3/examples/Triangulation_3/color.cpp index c1e769c8875..1dbd7bdeb75 100644 --- a/Triangulation_3/examples/Triangulation_3/color.cpp +++ b/Triangulation_3/examples/Triangulation_3/color.cpp @@ -30,7 +30,7 @@ int main() Delaunay::Finite_vertices_iterator vit; for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) if (T.degree(vit) == 6) - vit->info() = CGAL::RED; + vit->info() = CGAL::red(); return 0; } From 4555385ac1919954a51d7e49c8f2f88dd872ad4d Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:46:22 +0100 Subject: [PATCH 69/81] Fix missing bracket and add undocumented functions r,g,b,a --- Stream_support/include/CGAL/IO/Color.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Stream_support/include/CGAL/IO/Color.h b/Stream_support/include/CGAL/IO/Color.h index 05119dc6220..cfaa585043d 100644 --- a/Stream_support/include/CGAL/IO/Color.h +++ b/Stream_support/include/CGAL/IO/Color.h @@ -123,7 +123,14 @@ public: */ unsigned char& alpha() { return m_data[3]; } - /// @} + /// \cond SKIP_IN_MANUAL + unsigned char r() const { return red(); } + unsigned char g() const { return green(); } + unsigned char b() const { return blue(); } + unsigned char a() const { return alpha(); } + /// \endcond + + /// @} /// \name Array Access /// @{ @@ -336,9 +343,6 @@ inline Color white() { return Color(255,255,255); } inline Color yellow() { return Color(255,255,0); } -}; - - } //namespace CGAL #endif // CGAL_COLOR_H From 19169d9caeb9b08fd31f60e4fc833a75d75b0593 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:46:39 +0100 Subject: [PATCH 70/81] Remove CGAL::Classification::RGB_Color and HSV_Color and just use CGAL::Color everywhere --- Classification/include/CGAL/Classification.h | 1 - .../include/CGAL/Classification/Color.h | 140 ------------------ .../Classification/Feature/Color_channel.h | 10 +- .../Classification/Mesh_feature_generator.h | 2 - .../Point_set_feature_generator.h | 8 +- .../test_classification_point_set.cpp | 10 +- .../Classification/Cluster_classification.cpp | 14 +- .../Classification/Cluster_classification.h | 6 +- .../Point_set_item_classification.cpp | 14 +- .../Point_set_item_classification.h | 6 +- 10 files changed, 33 insertions(+), 178 deletions(-) delete mode 100644 Classification/include/CGAL/Classification/Color.h diff --git a/Classification/include/CGAL/Classification.h b/Classification/include/CGAL/Classification.h index 6be192f22b8..fea4a0c044c 100644 --- a/Classification/include/CGAL/Classification.h +++ b/Classification/include/CGAL/Classification.h @@ -36,7 +36,6 @@ #endif #include -#include #include #include #include diff --git a/Classification/include/CGAL/Classification/Color.h b/Classification/include/CGAL/Classification/Color.h deleted file mode 100644 index 8b619b9c497..00000000000 --- a/Classification/include/CGAL/Classification/Color.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2017 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_CLASSIFICATION_COLOR_H -#define CGAL_CLASSIFICATION_COLOR_H - -#include -#include -#include -#include - -namespace CGAL { -namespace Classification { - - /*! - \ingroup PkgClassificationColor - - %Color described in red/green/blue space. Each component is stored - as an unsigned char ranging from 0 (no color) to 255 (full color). - */ -typedef CGAL::cpp11::array RGB_Color; - /*! - \ingroup PkgClassificationColor - - %Color described in hue/saturation/value space. Each component is stored - as a float: - - - `hue` ranges from 0° to 360° (corresponding to the color tint) - - `saturation` ranges from 0.0 (gray) to 100.0 (full saturation) - - `value` ranges from 0.0 (black) to 100.0 (white) - */ -typedef CGAL::cpp11::array HSV_Color; - - - /// \cond SKIP_IN_MANUAL -inline HSV_Color rgb_to_hsv (const RGB_Color& c) -{ - double r = (double)(c[0]) / 255.; - double g = (double)(c[1]) / 255.; - double b = (double)(c[2]) / 255.; - double Cmax = (std::max) (r, (std::max) (g, b)); - double Cmin = (std::min) (r, (std::min) (g, b)); - double delta = Cmax - Cmin; - double H = 0.; - - if (delta != 0.) - { - if (Cmax == r) - H = 60. * ((g - b) / delta); - else if (Cmax == g) - H = 60. * (((b - r) / delta) + 2.); - else - H = 60. * (((r - g) / delta) + 4.); - } - if (H < 0.) H += 360.; - double S = (Cmax == 0. ? 0. : 100. * (delta / Cmax)); - double V = 100. * Cmax; - HSV_Color out = {{ float(H), float(S), float(V) }}; - return out; -} - -inline RGB_Color hsv_to_rgb (const HSV_Color& c) -{ - double h = c[0]; - double s = c[1]; - double v = c[2]; - - s /= 100.; - v /= 100.; - double C = v*s; - int hh = (int)(h/60.); - double X = C * (1-CGAL::abs (hh % 2 - 1)); - double r = 0, g = 0, b = 0; - - if( hh>=0 && hh<1 ) - { - r = C; - g = X; - } - else if( hh>=1 && hh<2 ) - { - r = X; - g = C; - } - else if( hh>=2 && hh<3 ) - { - g = C; - b = X; - } - else if( hh>=3 && hh<4 ) - { - g = X; - b = C; - } - else if( hh>=4 && hh<5 ) - { - r = X; - b = C; - } - else - { - r = C; - b = X; - } - double m = v-C; - r += m; - g += m; - b += m; - r *= 255.0; - g *= 255.0; - b *= 255.0; - - RGB_Color out = {{ (unsigned char)r, (unsigned char)g, (unsigned char)b }}; - return out; -} - /// \endcond - -} // namespace Classification -} // namespace CGAL - - - -#endif // CGAL_CLASSIFICATION_COLOR_H diff --git a/Classification/include/CGAL/Classification/Feature/Color_channel.h b/Classification/include/CGAL/Classification/Feature/Color_channel.h index 73ff155f5b8..4d3ecea6459 100644 --- a/Classification/include/CGAL/Classification/Feature/Color_channel.h +++ b/Classification/include/CGAL/Classification/Feature/Color_channel.h @@ -25,7 +25,6 @@ #include -#include #include namespace CGAL { @@ -65,7 +64,7 @@ namespace Feature { `ColorMap`. \tparam ColorMap model of `ReadablePropertyMap` whose key type is the value type of the iterator of `PointRange` and value type - is `CGAL::Classification::RGB_Color`. + is `CGAL::Color`. */ template class Color_channel : public Feature_base @@ -82,9 +81,6 @@ public: private: - typedef typename Classification::RGB_Color RGB_Color; - typedef typename Classification::HSV_Color HSV_Color; - const PointRange& input; ColorMap color_map; Channel m_channel; @@ -111,8 +107,8 @@ public: /// \cond SKIP_IN_MANUAL virtual float value (std::size_t pt_index) { - HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index))); - return c[std::size_t(m_channel)]; + cpp11::array c = get(color_map, *(input.begin()+pt_index)).to_hsv(); + return float(c[std::size_t(m_channel)]); } /// \endcond }; diff --git a/Classification/include/CGAL/Classification/Mesh_feature_generator.h b/Classification/include/CGAL/Classification/Mesh_feature_generator.h index d15b139cb3e..8e4fc337535 100644 --- a/Classification/include/CGAL/Classification/Mesh_feature_generator.h +++ b/Classification/include/CGAL/Classification/Mesh_feature_generator.h @@ -153,8 +153,6 @@ public: typedef Classification::Feature::Verticality Verticality; typedef Classification::Feature::Eigenvalue Eigenvalue; - - typedef typename Classification::RGB_Color RGB_Color; /// \endcond private: diff --git a/Classification/include/CGAL/Classification/Point_set_feature_generator.h b/Classification/include/CGAL/Classification/Point_set_feature_generator.h index b017ebe427c..46a89172c45 100644 --- a/Classification/include/CGAL/Classification/Point_set_feature_generator.h +++ b/Classification/include/CGAL/Classification/Point_set_feature_generator.h @@ -154,8 +154,6 @@ public: typedef Classification::Feature::Gradient_of_feature Gradient_of_feature; #endif - - typedef typename Classification::RGB_Color RGB_Color; /// \endcond private: @@ -336,7 +334,7 @@ public: typedef typename Default::Get::type Vmap; - typedef typename Default::Get::type + typedef typename Default::Get::type Cmap; typedef typename Default::Get::type Emap; @@ -349,7 +347,7 @@ public: // Functions to remove when deprecated constructor is removed void generate_normal_based_features(const CGAL::Constant_property_map&) { } - void generate_color_based_features(const CGAL::Constant_property_map&) { } + void generate_color_based_features(const CGAL::Constant_property_map&) { } void generate_echo_based_features(const CGAL::Constant_property_map&) { } #endif @@ -435,7 +433,7 @@ public: \tparam ColorMap model of `ReadablePropertyMap` whose key type is the value type of the iterator of `PointRange` and value type is - `CGAL::Classification::RGB_Color`. + `CGAL::Color`. \param features the feature set where the features are instantiated. \param color_map property map to access the colors of the input points (if any). diff --git a/Classification/test/Classification/test_classification_point_set.cpp b/Classification/test/Classification/test_classification_point_set.cpp index 4636e07913b..3890533b608 100644 --- a/Classification/test/Classification/test_classification_point_set.cpp +++ b/Classification/test/Classification/test_classification_point_set.cpp @@ -37,7 +37,7 @@ typedef Classification::Point_set_feature_generator Size_t_map; -typedef Point_set::Property_map Color_map; +typedef Point_set::Property_map Color_map; @@ -55,7 +55,7 @@ int main (int, char**) normal_map = pts.normal_map(); boost::tie (echo_map, map_added) = pts.add_property_map ("echo"); assert (map_added); - boost::tie (color_map, map_added) = pts.add_property_map ("color"); + boost::tie (color_map, map_added) = pts.add_property_map ("color"); assert (map_added); for (std::size_t i = 0; i < 1000; ++ i) @@ -68,9 +68,9 @@ int main (int, char**) CGAL::get_default_random().get_double(), CGAL::get_default_random().get_double())); echo_map[*it] = std::size_t(CGAL::get_default_random().get_int(0, 4)); - color_map[*it] = CGAL::make_array ((unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255))); + color_map[*it] = CGAL::Color ((unsigned char)(CGAL::get_default_random().get_int(0, 255)), + (unsigned char)(CGAL::get_default_random().get_int(0, 255)), + (unsigned char)(CGAL::get_default_random().get_int(0, 255))); } Feature_set features; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp index a8ed8358285..516c56bbed4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.cpp @@ -396,12 +396,12 @@ void Cluster_classification::backup_existing_colors_and_add_new() { if (m_points->point_set()->has_colors()) { - m_color = m_points->point_set()->add_property_map("real_color").first; + m_color = m_points->point_set()->add_property_map("real_color").first; for (Point_set::const_iterator it = m_points->point_set()->begin(); it != m_points->point_set()->first_selected(); ++ it) - m_color[*it] = {{ (unsigned char)(255 * m_points->point_set()->red(*it)), - (unsigned char)(255 * m_points->point_set()->green(*it)), - (unsigned char)(255 * m_points->point_set()->blue(*it)) }}; + m_color[*it] = CGAL::Color ((unsigned char)(255 * m_points->point_set()->red(*it)), + (unsigned char)(255 * m_points->point_set()->green(*it)), + (unsigned char)(255 * m_points->point_set()->blue(*it))); m_points->point_set()->remove_colors(); } @@ -411,7 +411,7 @@ void Cluster_classification::backup_existing_colors_and_add_new() void Cluster_classification::reset_colors() { - if (m_color == Point_set::Property_map()) + if (m_color == Point_set::Property_map()) m_points->point_set()->remove_colors(); else { @@ -606,7 +606,7 @@ int Cluster_classification::real_index_color() const { int out = m_index_color; - if (out == 0 && m_color == Point_set::Property_map()) + if (out == 0 && m_color == Point_set::Property_map()) out = -1; return out; } @@ -642,7 +642,7 @@ void Cluster_classification::compute_features (std::size_t nb_scales, float voxe if (normals) normal_map = m_points->point_set()->normal_map(); - bool colors = (m_color != Point_set::Property_map()); + bool colors = (m_color != Point_set::Property_map()); Point_set::Property_map echo_map; bool echo; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h index 53753e7cbbb..fd88c9e7507 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h @@ -27,7 +27,6 @@ class Cluster_classification : public Item_classification_base public: typedef Kernel::Point_3 Point_3; typedef Kernel::Vector_3 Vector_3; - typedef CGAL::Classification::RGB_Color Color; typedef Point_set::Point_map Point_map; typedef Point_set::Vector_map Vector_map; @@ -382,7 +381,10 @@ class Cluster_classification : public Item_classification_base std::vector m_clusters; - Point_set::Property_map m_color; + Point_set::Property_map m_red; + Point_set::Property_map m_green; + Point_set::Property_map m_blue; + Point_set::Property_map m_color; Point_set::Property_map m_cluster_id; Point_set::Property_map m_training; Point_set::Property_map m_classif; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp index 2b64ea7349a..aee56b923e6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.cpp @@ -327,12 +327,12 @@ void Point_set_item_classification::backup_existing_colors_and_add_new() { if (m_points->point_set()->has_colors()) { - m_color = m_points->point_set()->add_property_map("real_color").first; + m_color = m_points->point_set()->add_property_map("real_color").first; for (Point_set::const_iterator it = m_points->point_set()->begin(); it != m_points->point_set()->first_selected(); ++ it) - m_color[*it] = {{ (unsigned char)(255 * m_points->point_set()->red(*it)), - (unsigned char)(255 * m_points->point_set()->green(*it)), - (unsigned char)(255 * m_points->point_set()->blue(*it)) }}; + m_color[*it] = CGAL::Color((unsigned char)(255 * m_points->point_set()->red(*it)), + (unsigned char)(255 * m_points->point_set()->green(*it)), + (unsigned char)(255 * m_points->point_set()->blue(*it))); m_points->point_set()->remove_colors(); } @@ -342,7 +342,7 @@ void Point_set_item_classification::backup_existing_colors_and_add_new() void Point_set_item_classification::reset_colors() { - if (m_color == Point_set::Property_map()) + if (m_color == Point_set::Property_map()) m_points->point_set()->remove_colors(); else { @@ -493,7 +493,7 @@ int Point_set_item_classification::real_index_color() const { int out = m_index_color; - if (out == 0 && m_color == Point_set::Property_map()) + if (out == 0 && m_color == Point_set::Property_map()) out = -1; return out; } @@ -532,7 +532,7 @@ void Point_set_item_classification::compute_features (std::size_t nb_scales, flo if (normals) normal_map = m_points->point_set()->normal_map(); - bool colors = (m_color != Point_set::Property_map()); + bool colors = (m_color != Point_set::Property_map()); Point_set::Property_map echo_map; bool echo; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h index 3dc0ba57af9..4de6fce22fc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Point_set_item_classification.h @@ -30,7 +30,6 @@ class Point_set_item_classification : public Item_classification_base public: typedef Kernel::Point_3 Point_3; typedef Kernel::Vector_3 Vector_3; - typedef CGAL::Classification::RGB_Color Color; typedef Point_set::Point_map Point_map; typedef Point_set::Vector_map Vector_map; @@ -398,9 +397,12 @@ class Point_set_item_classification : public Item_classification_base std::vector m_clusters; + Point_set::Property_map m_red; + Point_set::Property_map m_green; + Point_set::Property_map m_blue; + Point_set::Property_map m_color; std::vector > m_label_probabilities; - Point_set::Property_map m_color; Point_set::Property_map m_training; Point_set::Property_map m_classif; From 8dbb45959ef5f280a86ade0091ab857fce4cae1b Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 14:50:48 +0100 Subject: [PATCH 71/81] Remove deprecated parts of Classification --- .../CGAL/Classification/Feature/Eigen.h | 431 ------------------ .../include/CGAL/Classification/Feature/Hsv.h | 175 ------- .../Point_set_feature_generator.h | 58 --- .../test/Classification/CMakeLists.txt | 8 - ...precated_test_classification_point_set.cpp | 136 ------ 5 files changed, 808 deletions(-) delete mode 100644 Classification/include/CGAL/Classification/Feature/Eigen.h delete mode 100644 Classification/include/CGAL/Classification/Feature/Hsv.h delete mode 100644 Classification/test/Classification/deprecated_test_classification_point_set.cpp diff --git a/Classification/include/CGAL/Classification/Feature/Eigen.h b/Classification/include/CGAL/Classification/Feature/Eigen.h deleted file mode 100644 index 793e3433449..00000000000 --- a/Classification/include/CGAL/Classification/Feature/Eigen.h +++ /dev/null @@ -1,431 +0,0 @@ -// Copyright (c) 2017 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_CLASSIFICATION_FEATURES_EIGEN_H -#define CGAL_CLASSIFICATION_FEATURES_EIGEN_H - -#include - -#include -#include -#include - -/// \cond SKIP_IN_MANUAL -#ifndef CGAL_NO_DEPRECATED_CODE - -namespace CGAL { - -namespace Classification { - -namespace Feature { - -class Eigen_feature : public Feature_base -{ -protected: -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - std::vector attrib; -#else - const Classification::Local_eigen_analysis& eigen; -#endif - -public: - template - Eigen_feature (const InputRange&, - const Classification::Local_eigen_analysis& eigen) -#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - : eigen (eigen) -#endif - { - } - -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - virtual void init (std::size_t size, const Classification::Local_eigen_analysis& eigen) - { - attrib.reserve (size); - for (std::size_t i = 0; i < size; ++ i) - attrib.push_back (get_value (eigen, i)); - } -#else - virtual void init (std::size_t, const Classification::Local_eigen_analysis&) - { - } -#endif - - virtual float get_value (const Classification::Local_eigen_analysis& eigen, std::size_t i) = 0; - virtual float value (std::size_t pt_index) - { -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - return attrib[pt_index]; -#else - return get_value(eigen, pt_index); -#endif - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Linearity is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_1 - \lambda_2}{\lambda_1} - \f] - - Its default name is "linearity". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Linearity, please update your code with Eigenvalue instead") -class Linearity -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \tparam Input model of `ConstRange`. Its iterator type - is `RandomAccessIterator`. - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Linearity (const InputRange& input, - const Local_eigen_analysis& eigen) : Eigen_feature (input, eigen) - { - this->set_name("linearity"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return ((ev[2] - ev[1]) / ev[2]); - } -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Planarity is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_2 - \lambda_3}{\lambda_1} - \f] - - Its default name is "planarity". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Planarity, please update your code with Eigenvalue instead") -class Planarity -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Planarity (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("planarity"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return ((ev[1] - ev[0]) / ev[2]); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Sphericity is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_3}{\lambda_1} - \f] - - Its default name is "sphericity". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Sphericity, please update your code with Eigenvalue instead") -class Sphericity -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Sphericity (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("sphericity"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return (ev[0] / ev[2]); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Omnivariance is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - (\lambda_1 \times \lambda_2 \times \lambda_3)^{\frac{1}{3}} - \f] - - Its default name is "omnivariance". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Omnivariance, please update your code with Eigenvalue instead") -class Omnivariance -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Omnivariance (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("omnivariance"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - return (std::pow (CGAL::abs(ev[0] * ev[1] * ev[2]), 0.333333333f)); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Anisotropy is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - \frac{\lambda_1 - \lambda_3}{\lambda_1} - \f] - - Its default name is "anisotropy". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Anisotropy, please update your code with Eigenvalue instead") -class Anisotropy -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Anisotropy (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("anisotropy"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[2] < 1e-15) - return 0.; - else - return ((ev[2] - ev[0]) / ev[2]); - } - -}; - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance matrix of a - local neighborhood. Eigentropy is defined, for the 3 eigenvalues - \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as: - - \f[ - - \sum_{i=1}^3 \lambda_i \times \log{\lambda_i} - \f] - - Its default name is "eigentropy". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Eigentropy, please update your code with Eigenvalue instead") -class Eigentropy -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Eigentropy (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("eigentropy"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[0] < 1e-15 - || ev[1] < 1e-15 - || ev[2] < 1e-15) - return 0.; - else - return (- ev[0] * std::log(ev[0]) - - ev[1] * std::log(ev[1]) - - ev[2] * std::log(ev[2])); - } - -}; - - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on the eigenvalues of the covariance - matrix of a local neighborhood. Surface variation is defined, for - the 3 eigenvalues \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge - 0\f$, as: - - \f[ - \frac{\lambda_3}{\lambda_1 + \lambda_2 + \lambda_3} - \f] - - Its default name is "surface_variation". - */ -CGAL_DEPRECATED_MSG("you are using the deprecated feature Surface_variation, please update your code with Eigenvalue instead") -class Surface_variation -#ifdef DOXYGEN_RUNNING - : public Feature_base -#else - : public Eigen_feature -#endif -{ -public: - /*! - Constructs the feature. - - \param input point range. - \param eigen class with precomputed eigenvectors and eigenvalues. - */ - template - Surface_variation (const InputRange& input, - const Local_eigen_analysis& eigen) - : Eigen_feature(input, eigen) - { - this->set_name("surface_variation"); - this->init(input.size(), eigen); - } - - virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i) - { - const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i); - if (ev[0] + ev[1] + ev[2] < 1e-15) - return 0.; - else - return (ev[0] / (ev[0] + ev[1] + ev[2])); - } - -}; - -} // namespace Feature - -} // namespace Classification - -} // namespace CGAL - -#endif -/// \endcond - -#endif // CGAL_CLASSIFICATION_FEATURES_EIGEN_H diff --git a/Classification/include/CGAL/Classification/Feature/Hsv.h b/Classification/include/CGAL/Classification/Feature/Hsv.h deleted file mode 100644 index 536d6aaa5b0..00000000000 --- a/Classification/include/CGAL/Classification/Feature/Hsv.h +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2017 GeometryFactory Sarl (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// Author(s) : Simon Giraudot - -#ifndef CGAL_CLASSIFICATION_FEATURE_HSV_H -#define CGAL_CLASSIFICATION_FEATURE_HSV_H - -#include - -#include - -#include -#include - -/// \cond SKIP_IN_MANUAL -#ifndef CGAL_NO_DEPRECATED_CODE - -namespace CGAL { - -namespace Classification { - -namespace Feature { - - /*! - \ingroup PkgClassificationFeatures - - %Feature based on HSV colorimetric information. If the input - point cloud has colorimetric information, it can be used for - classification purposes. This feature is based on a Gaussian - probabilistic model on one of the three HSV channels (hue, - saturation or value). It computes the probability of the color of - the input point to match this specific color channel defined by a - mean and a standard deviation. - - The HSV channels are defined this way: - - - Hue ranges from 0 to 360 and measures the general "tint" of the - color (green, blue, pink, etc.) - - - Saturation ranges from 0 to 100 and measures the "strength" of the - color (0 is gray and 100 is the fully saturated color) - - - Value ranges from 0 to 100 and measures the "brightness" of the - color (0 is black and 100 is the fully bright color) - - For example, such an feature using the channel 0 (hue) with a - mean of 90 (which corresponds to a green hue) can help to identify - trees. - - \image html trees.png - -

Left: input point set with colors. Right: HSV feature on hue with - a mean of 90 (from low values in white to high values in dark - red).
- - Its default name is the channel followed by the mean value (for - example: "hue_180", "saturation_20" or "value_98"). - - \note The user only needs to provide a map to standard (and more common) - RGB colors, the conversion to HSV is done internally. - - \tparam GeomTraits model of \cgal Kernel. - \tparam PointRange model of `ConstRange`. Its iterator type - is `RandomAccessIterator` and its value type is the key type of - `ColorMap`. - \tparam ColorMap model of `ReadablePropertyMap` whose key - type is the value type of the iterator of `PointRange` and value type - is `CGAL::Classification::RGB_Color`. - */ -template -CGAL_DEPRECATED_MSG("you are using the deprecated feature Hsv, please update your code with Color_channel instead") -class Hsv : public Feature_base -{ -public: - - /// Selected channel. - enum Channel - { - HUE = 0, ///< 0 - SATURATION = 1, ///< 1 - VALUE = 2 ///< 2 - }; - -private: - - typedef typename Classification::RGB_Color RGB_Color; - typedef typename Classification::HSV_Color HSV_Color; - -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - std::vector color_feature; -#else - const PointRange& input; - ColorMap color_map; - Channel m_channel; - float m_mean; - float m_sd; -#endif - -public: - - /*! - - \brief Constructs a feature based on the given color channel, - mean and standard deviation. - - \param input point range. - \param color_map property map to access the colors of the input points. - \param channel chosen HSV channel. - \param mean mean value of the specified channel. - \param sd standard deviation of the specified channel. - */ - Hsv (const PointRange& input, - ColorMap color_map, - Channel channel, - float mean, float sd) -#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - : input(input), color_map(color_map), m_channel(channel), m_mean(mean), m_sd(sd) -#endif - { - -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - for(std::size_t i = 0; i < input.size();i++) - { - HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+i))); - color_feature.push_back (std::exp (-(c[std::size_t(channel)] - mean) - * (c[std::size_t(channel)] - mean) / (2. * sd * sd))); - } -#endif - std::ostringstream oss; - if (channel == HUE) oss << "hue"; - else if (channel == SATURATION) oss << "saturation"; - else if (channel == VALUE) oss << "value"; - oss << "_" << mean; - this->set_name (oss.str()); - } - - virtual float value (std::size_t pt_index) - { -#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES - return color_feature[pt_index]; -#else - HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index))); - return std::exp (-(c[std::size_t(m_channel)] - m_mean) - * (c[std::size_t(m_channel)] - m_mean) / (2.f * m_sd * m_sd)); -#endif - } - -}; - -} // namespace Feature - -} // namespace Classification - -} // namespace CGAL - -#endif -/// \endcond - -#endif // CGAL_CLASSIFICATION_FEATURE_HSV_H diff --git a/Classification/include/CGAL/Classification/Point_set_feature_generator.h b/Classification/include/CGAL/Classification/Point_set_feature_generator.h index 46a89172c45..ca50f0d3bde 100644 --- a/Classification/include/CGAL/Classification/Point_set_feature_generator.h +++ b/Classification/include/CGAL/Classification/Point_set_feature_generator.h @@ -293,64 +293,6 @@ public: /// @} /// \cond SKIP_IN_MANUAL - -#ifndef CGAL_NO_DEPRECATED_CODE - // deprecated - template - CGAL_DEPRECATED_MSG("you are using a deprecated constructor of CGAL::Classification::Point_set_feature_generator, please update your code") - Point_set_feature_generator(Feature_set& features, - const PointRange& input, - PointMap point_map, - std::size_t nb_scales, - VectorMap normal_map = VectorMap(), - ColorMap color_map = ColorMap(), - EchoMap echo_map = EchoMap(), - float voxel_size = -1.f) - : m_input (input), m_point_map (point_map) - { - m_bbox = CGAL::bounding_box - (boost::make_transform_iterator (m_input.begin(), CGAL::Property_map_to_unary_function(m_point_map)), - boost::make_transform_iterator (m_input.end(), CGAL::Property_map_to_unary_function(m_point_map))); - - CGAL::Real_timer t; t.start(); - - m_scales.reserve (nb_scales); - - m_scales.push_back (new Scale (m_input, m_point_map, m_bbox, voxel_size)); - - if (voxel_size == -1.f) - voxel_size = m_scales[0]->grid_resolution(); - - for (std::size_t i = 1; i < nb_scales; ++ i) - { - voxel_size *= 2; - m_scales.push_back (new Scale (m_input, m_point_map, m_bbox, voxel_size, m_scales[i-1]->grid)); - } - t.stop(); - CGAL_CLASSIFICATION_CERR << "Scales computed in " << t.time() << " second(s)" << std::endl; - t.reset(); - - typedef typename Default::Get::type - Vmap; - typedef typename Default::Get::type - Cmap; - typedef typename Default::Get::type - Emap; - - generate_point_based_features (features); - generate_normal_based_features (features, get_parameter(normal_map)); - generate_color_based_features (features, get_parameter(color_map)); - generate_echo_based_features (features, get_parameter(echo_map)); - } - - // Functions to remove when deprecated constructor is removed - void generate_normal_based_features(const CGAL::Constant_property_map&) { } - void generate_color_based_features(const CGAL::Constant_property_map&) { } - void generate_echo_based_features(const CGAL::Constant_property_map&) { } -#endif - virtual ~Point_set_feature_generator() { clear(); diff --git a/Classification/test/Classification/CMakeLists.txt b/Classification/test/Classification/CMakeLists.txt index fd5d89785b2..f6967a11db1 100644 --- a/Classification/test/Classification/CMakeLists.txt +++ b/Classification/test/Classification/CMakeLists.txt @@ -89,14 +89,6 @@ if(TARGET test_classification_point_set) endif() endif() -create_single_source_cgal_program( "deprecated_test_classification_point_set.cpp" CXX_FEATURES ${needed_cxx_features} ) -if(TARGET deprecated_test_classification_point_set) - target_link_libraries(deprecated_test_classification_point_set PUBLIC ${classification_linked_libraries}) - if (TBB_FOUND) - CGAL_target_use_TBB( deprecated_test_classification_point_set ) - endif() -endif() - create_single_source_cgal_program( "test_classification_io.cpp" CXX_FEATURES ${needed_cxx_features} ) if(TARGET test_classification_io) target_link_libraries(test_classification_io PUBLIC ${classification_linked_libraries}) diff --git a/Classification/test/Classification/deprecated_test_classification_point_set.cpp b/Classification/test/Classification/deprecated_test_classification_point_set.cpp deleted file mode 100644 index 46dc85b46a5..00000000000 --- a/Classification/test/Classification/deprecated_test_classification_point_set.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include - -#if defined (_MSC_VER) && !defined (_WIN64) -#pragma warning(disable:4244) // boost::number_distance::distance() - // converts 64 to 32 bits integers -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include - -typedef CGAL::Simple_cartesian Kernel; -typedef Kernel::Point_3 Point; -typedef Kernel::Vector_3 Vector; - -typedef CGAL::Point_set_3 Point_set; -typedef Point_set::Point_map Point_map; - -typedef Kernel::Iso_cuboid_3 Iso_cuboid_3; - -namespace Classification = CGAL::Classification; - -typedef Classification::Label_handle Label_handle; -typedef Classification::Feature_handle Feature_handle; -typedef Classification::Label_set Label_set; -typedef Classification::Feature_set Feature_set; - -typedef Classification::Sum_of_weighted_features_classifier Classifier; - -typedef Classification::Point_set_feature_generator Feature_generator; - -typedef Point_set::Property_map Size_t_map; -typedef Point_set::Property_map Color_map; - - - -int main (int, char**) -{ - Point_set pts; - - pts.add_normal_map(); - - bool map_added = false; - Size_t_map echo_map; - Color_map color_map; - - boost::tie (echo_map, map_added) = pts.add_property_map ("echo"); - assert (map_added); - boost::tie (color_map, map_added) = pts.add_property_map ("color"); - assert (map_added); - - for (std::size_t i = 0; i < 1000; ++ i) - { - Point_set::iterator it - = pts.insert (Point (CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double()), - Vector (CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double(), - CGAL::get_default_random().get_double())); - echo_map[*it] = std::size_t(CGAL::get_default_random().get_int(0, 4)); - color_map[*it] = CGAL::make_array ((unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255)), - (unsigned char)(CGAL::get_default_random().get_int(0, 255))); - } - - Feature_set features; - Feature_generator generator (features, pts, pts.point_map(), - 5, // using 5 scales - pts.normal_map(), - color_map, echo_map); - - assert (generator.number_of_scales() == 5); - assert (features.size() == 59); - - Label_set labels; - - std::vector training_set (pts.size(), -1); - for (std::size_t i = 0; i < 20; ++ i) - { - std::ostringstream oss; - oss << "label_" << i; - Label_handle lh = labels.add(oss.str().c_str()); - - for (std::size_t j = 0; j < 10; ++ j) - training_set[std::size_t(CGAL::get_default_random().get_int(0, int(training_set.size())))] = int(i); - } - assert (labels.size() == 20); - - Classifier classifier (labels, features); - - classifier.train (training_set, 800); -#ifdef CGAL_LINKED_WITH_TBB - classifier.train (training_set, 800); -#endif - - std::vector label_indices(pts.size(), -1); - - Classification::classify - (pts, labels, classifier, label_indices); - - Classification::classify_with_local_smoothing - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().sphere_neighbor_query(0.01f), - label_indices); - - Classification::classify_with_graphcut - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().k_neighbor_query(12), - 0.2f, 10, label_indices); - -#ifdef CGAL_LINKED_WITH_TBB - Classification::classify - (pts, labels, classifier, label_indices); - - Classification::classify_with_local_smoothing - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().sphere_neighbor_query(0.01f), - label_indices); - - Classification::classify_with_graphcut - (pts, pts.point_map(), labels, classifier, - generator.neighborhood().k_neighbor_query(12), - 0.2f, 10, label_indices); -#endif - - Classification::Evaluation evaluation (labels, training_set, label_indices); - - return EXIT_SUCCESS; -} From 4672c637bba12199f20697c156e5cc4bbf0b724b Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 15:21:09 +0100 Subject: [PATCH 72/81] Fix Color IO in binary + handle alpha --- Stream_support/include/CGAL/IO/io.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Stream_support/include/CGAL/IO/io.h b/Stream_support/include/CGAL/IO/io.h index 679565c8480..eb67fd391aa 100644 --- a/Stream_support/include/CGAL/IO/io.h +++ b/Stream_support/include/CGAL/IO/io.h @@ -393,39 +393,45 @@ std::ostream& operator<<( std::ostream& out, const Color& col) switch(get_mode(out)) { case IO::ASCII : return out << static_cast(col.red()) << ' ' - << static_cast(col.green()) << ' ' - << static_cast(col.blue()); + << static_cast(col.green()) << ' ' + << static_cast(col.blue()) << ' ' + << static_cast(col.alpha()); case IO::BINARY : - write(out, static_cast(col.red())); - write(out, static_cast(col.green())); - write(out, static_cast(col.blue())); + out.write(reinterpret_cast(col.to_rgba().data()), 4); return out; default: return out << "Color(" << static_cast(col.red()) << ", " - << static_cast(col.green()) << ", " - << static_cast(col.blue()) << ')'; + << static_cast(col.green()) << ", " + << static_cast(col.blue()) << ", " + << static_cast(col.alpha()) << ")"; } } inline std::istream &operator>>(std::istream &is, Color& col) { - int r = 0, g = 0, b = 0; + unsigned char r = 0, g = 0, b = 0, a = 0; + int ir = 0, ig = 0, ib = 0, ia = 0; switch(get_mode(is)) { case IO::ASCII : - is >> r >> g >> b; + is >> ir >> ig >> ib >> ia; + r = (unsigned char)ir; + g = (unsigned char)ig; + b = (unsigned char)ib; + a = (unsigned char)ia; break; case IO::BINARY : read(is, r); read(is, g); read(is, b); + read(is, a); break; default: std::cerr << "" << std::endl; std::cerr << "Stream must be in ascii or binary mode" << std::endl; break; } - col = Color((unsigned char)r,(unsigned char)g,(unsigned char)b); + col = Color(r,g,b,a); return is; } From fc16f50f2203095e9e4bbfae0bc4d642d1a4fe42 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Thu, 24 Jan 2019 15:51:53 +0100 Subject: [PATCH 73/81] Remove now useless Color_impl.h file --- Stream_support/include/CGAL/IO/Color_impl.h | 43 --------------------- 1 file changed, 43 deletions(-) delete mode 100644 Stream_support/include/CGAL/IO/Color_impl.h diff --git a/Stream_support/include/CGAL/IO/Color_impl.h b/Stream_support/include/CGAL/IO/Color_impl.h deleted file mode 100644 index 340facebed0..00000000000 --- a/Stream_support/include/CGAL/IO/Color_impl.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 1997 -// Utrecht University (The Netherlands), -// ETH Zurich (Switzerland), -// INRIA Sophia-Antipolis (France), -// Max-Planck-Institute Saarbruecken (Germany), -// and Tel-Aviv University (Israel). All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// 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. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// -// Author(s) : Andreas Fabri, Hervé Brönnimann - -namespace CGAL { - -const Color BLACK = Color(0, 0, 0); -const Color WHITE = Color(255, 255, 255); -const Color GRAY = Color(100,100,100); - -const Color GREEN = Color(0, 255, 0); - -const Color DEEPBLUE = Color(10, 0, 100); -const Color BLUE = Color(0, 0, 255); -const Color VIOLET = Color(255, 0, 255); -const Color PURPLE = Color(100, 0, 70); - -const Color RED = Color(255, 0, 0); -const Color ORANGE = Color(235, 150, 0); -const Color YELLOW = Color(255, 255, 0); - -} //namespace CGAL From 55adff47a427f67edf1f47d429dbede7d13728ce Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 31 Jan 2019 17:40:50 +0100 Subject: [PATCH 74/81] Fix Geomview_stream --- Geomview/include/CGAL/IO/Geomview_stream_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Geomview/include/CGAL/IO/Geomview_stream_impl.h b/Geomview/include/CGAL/IO/Geomview_stream_impl.h index b322c32652e..2f69d81cb44 100644 --- a/Geomview/include/CGAL/IO/Geomview_stream_impl.h +++ b/Geomview/include/CGAL/IO/Geomview_stream_impl.h @@ -49,7 +49,7 @@ CGAL_INLINE_FUNCTION Geomview_stream::Geomview_stream(const Bbox_3 &bbox, const char *machine, const char *login) - : bb(bbox), vertex_color(BLACK), edge_color(BLACK), face_color(BLACK), + : bb(bbox), vertex_color(black()), edge_color(black()), face_color(black()), wired_flag(false), echo_flag(true), raw_flag(false), trace_flag(false), binary_flag(false), line_width(1) From 80e4cb96d5a942385d6420490ae5a3fdf8831142 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 5 Feb 2019 13:25:21 +0100 Subject: [PATCH 75/81] fix Straight_skeleton --- .../include/CGAL/IO/Dxf_stream.h | 20 +++++++++---------- .../test/Straight_skeleton_2/test_sls.cpp | 10 +++++----- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Straight_skeleton_2/include/CGAL/IO/Dxf_stream.h b/Straight_skeleton_2/include/CGAL/IO/Dxf_stream.h index abc61e587a6..86fa9b55da1 100644 --- a/Straight_skeleton_2/include/CGAL/IO/Dxf_stream.h +++ b/Straight_skeleton_2/include/CGAL/IO/Dxf_stream.h @@ -112,7 +112,7 @@ public: mWriter (out) ,mDefaultDxfColor (255) ,mDxfColor (255) - ,mCgalColor (WHITE) + ,mCgalColor (white()) ,mLayer ("0") { setup_initial_color_table(); @@ -305,15 +305,15 @@ protected: void setup_initial_color_table() { - define_color(BLACK,0); - define_color(RED,1); - define_color(YELLOW,2); - define_color(GREEN,3); - define_color(PURPLE,4); - define_color(BLUE,5); - define_color(VIOLET,6); - define_color(WHITE,7); - define_color(GRAY,8); + define_color(black(),0); + define_color(red(),1); + define_color(yellow(),2); + define_color(green(),3); + define_color(purple(),4); + define_color(blue(),5); + define_color(violet(),6); + define_color(white(),7); + define_color(gray(),8); } }; diff --git a/Straight_skeleton_2/test/Straight_skeleton_2/test_sls.cpp b/Straight_skeleton_2/test/Straight_skeleton_2/test_sls.cpp index a8051bead6b..b4868d33acc 100644 --- a/Straight_skeleton_2/test/Straight_skeleton_2/test_sls.cpp +++ b/Straight_skeleton_2/test/Straight_skeleton_2/test_sls.cpp @@ -547,25 +547,25 @@ void dump_to_dxf ( TestCase const& aCase ) { if ( sVerbose ) cout << " Dumping input region. " << endl ; - dump_region_to_dxf(*aCase.Inner.Input,BLUE,"Input",lDxf); + dump_region_to_dxf(*aCase.Inner.Input,blue(),"Input",lDxf); } if ( aCase.Inner.PartialSkeleton ) { if ( sVerbose ) cout << " Dumping inner skeleton." << endl ; - dump_skeleton_to_dxf(*aCase.Inner.PartialSkeleton,YELLOW,GREEN,PURPLE,GRAY,"InnerSkeleton",lDxf); + dump_skeleton_to_dxf(*aCase.Inner.PartialSkeleton,yellow(),green(),purple(),gray(),"InnerSkeleton",lDxf); } if ( aCase.Outer.PartialSkeleton ) { if ( sVerbose ) cout << " Dumping outer skeleton." << endl ; - dump_skeleton_to_dxf(*aCase.Outer.PartialSkeleton,YELLOW,GREEN,PURPLE,GRAY,"OuterSkeleton",lDxf); + dump_skeleton_to_dxf(*aCase.Outer.PartialSkeleton,yellow(),green(),purple(),gray(),"OuterSkeleton",lDxf); } - dump_region_to_dxf(aCase.Inner.Contours,GRAY,"InnerOffset",lDxf); - dump_region_to_dxf(aCase.Outer.Contours,GRAY,"OuterOffset",lDxf); + dump_region_to_dxf(aCase.Inner.Contours,gray(),"InnerOffset",lDxf); + dump_region_to_dxf(aCase.Outer.Contours,gray(),"OuterOffset",lDxf); } From d6e36546f5a5add56af4547edd65c23534d5666f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 6 Feb 2019 17:10:36 +0100 Subject: [PATCH 76/81] Add #include --- .../include/CGAL/Classification/Feature/Color_channel.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Classification/include/CGAL/Classification/Feature/Color_channel.h b/Classification/include/CGAL/Classification/Feature/Color_channel.h index 4d3ecea6459..6c5778548c2 100644 --- a/Classification/include/CGAL/Classification/Feature/Color_channel.h +++ b/Classification/include/CGAL/Classification/Feature/Color_channel.h @@ -26,6 +26,7 @@ #include #include +#include namespace CGAL { From 259d911d75159075e82d1f70820060c80253ebf0 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Feb 2019 19:49:52 +0100 Subject: [PATCH 77/81] Remove #include --- Stream_support/src/CGAL/Color.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Stream_support/src/CGAL/Color.cpp b/Stream_support/src/CGAL/Color.cpp index 0dd475dfd09..a707f53375b 100644 --- a/Stream_support/src/CGAL/Color.cpp +++ b/Stream_support/src/CGAL/Color.cpp @@ -26,6 +26,5 @@ #ifndef CGAL_HEADER_ONLY #include -#include #endif // CGAL_HEADER_ONLY From a825e5b699ee0b438988401a771f3ece77f8633e Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 26 Feb 2019 10:00:18 +0100 Subject: [PATCH 78/81] Fix missing LaTeX delimitors --- Stream_support/include/CGAL/IO/Color.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Stream_support/include/CGAL/IO/Color.h b/Stream_support/include/CGAL/IO/Color.h index cfaa585043d..29732e0440c 100644 --- a/Stream_support/include/CGAL/IO/Color.h +++ b/Stream_support/include/CGAL/IO/Color.h @@ -136,14 +136,14 @@ public: /// @{ /*! - returns the i^{th} component of the rgb color (the 0^{th} is red, - the 1^{st} is blue, etc.). + returns the \f$i^{th}\f$ component of the rgb color (the + \f$0^{th}\f$ is red, the \f$1^{st}\f$ is blue, etc.). */ unsigned char operator[] (std::size_t i) const { return m_data[i]; } /*! - returns a reference on the i^{th} component of `c` (the 0^{th} is - red, the 1^{st} is blue, etc.). + returns a reference on the \f$i^{th}\f$ component of `c` (the + \f$0^{th}\f$ is red, the \f$1^{st}\f$ is blue, etc.). */ unsigned char& operator[] (std::size_t i) { return m_data[i]; } @@ -277,6 +277,7 @@ public: /*! + Constructs Color(0,0,0). \relates Color */ From 110c84bc5303127457dace095dbd502d650a1e37 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 26 Feb 2019 14:14:51 +0100 Subject: [PATCH 79/81] Fix missing class name --- Stream_support/include/CGAL/IO/PLY.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Stream_support/include/CGAL/IO/PLY.h b/Stream_support/include/CGAL/IO/PLY.h index 926ee1a314e..47d89ea9422 100644 --- a/Stream_support/include/CGAL/IO/PLY.h +++ b/Stream_support/include/CGAL/IO/PLY.h @@ -76,7 +76,7 @@ template <> struct Convert_FT { typedef float type; }; template struct Get_FT_from_map { - typedef typename + typedef typename Convert_FT ::value_type>::Kernel::FT>::type type; From e6fc07bf17517a366d5e783c534b200578ff3c1f Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 26 Feb 2019 15:34:32 +0100 Subject: [PATCH 80/81] Reset failbit after failing to load a surface mesh --- Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index 6d566d5da3a..d532a18db96 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -100,6 +100,7 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { return sm_item; } + in.clear(); in.seekg(0); // else try polygon soup From fe6f00203c8626f8beb88a774ad7fc5de0a14fb0 Mon Sep 17 00:00:00 2001 From: Simon Giraudot Date: Tue, 9 Apr 2019 15:04:25 +0200 Subject: [PATCH 81/81] Add comments of PLY mesh in demo --- Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 8 +++++--- Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp | 5 +++++ Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index d532a18db96..41e8e73acd4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -91,11 +91,13 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { { // First try mesh SMesh *surface_mesh = new SMesh(); - - if (CGAL::read_ply (in, *surface_mesh)) + std::string comments; + + if (CGAL::read_ply (in, *surface_mesh, comments)) { Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh); sm_item->setName(fileinfo.completeBaseName()); + sm_item->comments() = comments; QApplication::restoreOverrideCursor(); return sm_item; } @@ -185,7 +187,7 @@ bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFile Scene_surface_mesh_item* sm_item = const_cast(qobject_cast(item)); if (sm_item) - return CGAL::write_ply (out, *(sm_item->polyhedron())); + return CGAL::write_ply (out, *(sm_item->polyhedron()), sm_item->comments()); return false; } diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 3043d169ddd..4f2fee6645c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -209,6 +209,8 @@ struct Scene_surface_mesh_item_priv{ mutable QList text_ids; mutable std::vector targeted_id; + std::string comments; + mutable bool has_fpatch_id; mutable bool has_feature_edges; mutable bool floated; @@ -1048,6 +1050,9 @@ Scene_surface_mesh_item::~Scene_surface_mesh_item() SMesh* Scene_surface_mesh_item::polyhedron() { return d->smesh_; } const SMesh* Scene_surface_mesh_item::polyhedron() const { return d->smesh_; } +std::string& Scene_surface_mesh_item::comments() { return d->comments; } +const std::string& Scene_surface_mesh_item::comments() const { return d->comments; } + void Scene_surface_mesh_item::compute_bbox()const { SMesh::Property_map pprop = d->smesh_->points(); diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h index 6f2bc777a61..375b57b1380 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.h @@ -89,6 +89,10 @@ public: Face_graph* face_graph() { return polyhedron(); } const Face_graph* face_graph() const { return polyhedron(); } + // Gets PLY comments (empty if mesh not originated from PLY input) + std::string& comments(); + const std::string& comments() const; + void invalidate_aabb_tree(); void invalidateOpenGLBuffers()Q_DECL_OVERRIDE; void invalidate(Gl_data_names name);