diff --git a/Mesh_3/doc/Mesh_3/CGAL/Mesh_complex_3_in_triangulation_3.h b/Mesh_3/doc/Mesh_3/CGAL/Mesh_complex_3_in_triangulation_3.h index efa376cc52a..0ec666384e5 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Mesh_complex_3_in_triangulation_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -90,6 +90,11 @@ std::ostream& output_boundary_to_off(std::ostream& out) const; */ std::ostream& output_boundary_to_off(std::ostream& out, Subdomain_index subdomain) const; +/** + * Outputs the surface facets with a consistent orientation at the interface of two subdomains. + */ +std::ostream& output_facets_in_complex_to_off(std::ostream& out) const; + /// @} }; /* end Mesh_complex_3_in_triangulation_3 */ diff --git a/Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h b/Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h index 8f591cf537e..b64d4517c5b 100644 --- a/Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h +++ b/Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h @@ -339,7 +339,7 @@ public: */ std::ostream& output_boundary_to_off(std::ostream& out) const { - output_boundary_of_c3t3_to_off(*this, out); + internal::output_boundary_of_c3t3_to_off(*this, 0, out, false); return out; } @@ -352,6 +352,15 @@ public: return out; } + /** + * Outputs the surface facets with a consistent orientation at the interface of two subdomains. + */ + std::ostream& output_facets_in_complex_to_off(std::ostream& out) const + { + internal::output_facets_in_complex_to_off(*this, out); + return out; + } + /** * Fills \c out with incident edges (1-dimensional features of \c v. * OutputIterator value type is std::pair diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h b/Mesh_3/include/CGAL/internal/Mesh_3/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h index 760d0600a7f..8fc67a56520 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h @@ -29,6 +29,8 @@ namespace CGAL { namespace internal{ + +namespace mesh_3_export{ template std::size_t get_vertex_index(Vertex_handle v,std::map& V,std::size_t& inum,std::stringstream& vertex_buffer){ std::pair::iterator,bool> res= @@ -39,13 +41,14 @@ std::size_t get_vertex_index(Vertex_handle v,std::mapsecond; } -}//namespace internal +} // end of namespace mesh_3_export template std::ostream& output_boundary_of_c3t3_to_off(const C3T3& c3t3, typename C3T3::Subdomain_index sd_index, - std::ostream& output) + std::ostream& output, + bool normals_point_outside_of_the_subdomain=true) { typedef typename C3T3::Triangulation Triangulation; typedef typename Triangulation::Vertex_handle Vertex_handle; @@ -72,8 +75,9 @@ output_boundary_of_c3t3_to_off(const C3T3& c3t3, for (int i = 0; i < 4; ++i) if (i != fit->second) - indices[++j]=internal::get_vertex_index((*fit).first->vertex(i), V, inum,vertex_buffer); - if ( (cell_sd==sd_index) == (fit->second%2 == 1) ) std::swap(indices[0],indices[1]); + indices[++j]=mesh_3_export::get_vertex_index((*fit).first->vertex(i), V, inum,vertex_buffer); + if ( ( (cell_sd==sd_index) == (fit->second%2 == 1) ) == normals_point_outside_of_the_subdomain ) + std::swap(indices[0],indices[1]); facet_buffer << "3" << " " << indices[0] <<" " << indices[1] <<" " << indices[2] << "\n"; } @@ -87,8 +91,8 @@ output_boundary_of_c3t3_to_off(const C3T3& c3t3, template std::ostream& -output_boundary_of_c3t3_to_off(const C3T3& c3t3, - std::ostream& output) +output_facets_in_complex_to_off(const C3T3& c3t3, + std::ostream& output) { typedef typename C3T3::Triangulation Triangulation; typedef typename Triangulation::Vertex_handle Vertex_handle; @@ -113,7 +117,7 @@ output_boundary_of_c3t3_to_off(const C3T3& c3t3, for (int i = 0; i < 4; ++i) if (i != fit->second) - indices[++j]=internal::get_vertex_index((*fit).first->vertex(i), V, inum,vertex_buffer); + indices[++j]=mesh_3_export::get_vertex_index((*fit).first->vertex(i), V, inum,vertex_buffer); if ( (cell_sd > opp_sd) == (fit->second%2 == 1) ) std::swap(indices[0],indices[1]); facet_buffer << "3" << " " << indices[0] <<" " << indices[1] <<" " << indices[2] << "\n"; } @@ -126,6 +130,7 @@ output_boundary_of_c3t3_to_off(const C3T3& c3t3, return output; } -} // end namespace CGAL +} } // end of namespace CGAL::internal + #endif // CGAL_INTERNAL_MESH_3_BOUNDARY_OF_SUDDOMAIN_OF_COMPLEX_3_IN_TRIANGULATION_3_TO_OFF_H diff --git a/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp b/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp index feeb4694e47..6986dd9bf11 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp +++ b/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp @@ -83,6 +83,10 @@ int main() c3t3.output_boundary_to_off(off_file); assert( off_file.str().size() > 20 ); + off_file.str(""); + c3t3.output_facets_in_complex_to_off(off_file); + assert( off_file.str().size() > 20 ); + for (int i=0;i<4; ++i){ off_file.str(""); c3t3.output_boundary_to_off(off_file,i); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp index 506c923942b..0812962bf6d 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin_cgal_code.cpp @@ -278,10 +278,10 @@ private: } public slots: - void export_domain_boundary_as_polyhedron() + void export_facets_in_complex() { std::stringstream off_sstream; - c3t3().output_boundary_to_off(off_sstream); + c3t3().output_facets_in_complex_to_off(off_sstream); std::string backup = off_sstream.str(); // Try to read .off in a polyhedron Scene_polyhedron_item* item = new Scene_polyhedron_item(); @@ -298,11 +298,11 @@ public slots: return; } - soup_item->setName(QString("%1_%2").arg(this->name()).arg("boundary")); + soup_item->setName(QString("%1_%2").arg(this->name()).arg("facets")); last_known_scene->addItem(soup_item); } else{ - item->setName(QString("%1_%2").arg(this->name()).arg("boundary")); + item->setName(QString("%1_%2").arg(this->name()).arg("facets")); last_known_scene->addItem(item); } } @@ -320,12 +320,12 @@ public: bool menuChanged = menu->property(prop_name).toBool(); if(!menuChanged) { - QAction* actionDomainBoundaryAsPolyhedron = - menu->addAction(tr("Export domain boundary as polyhedron")); - actionDomainBoundaryAsPolyhedron->setObjectName("actionSelectNextVolume"); - connect(actionDomainBoundaryAsPolyhedron, + QAction* actionExportFacetsInComplex = + menu->addAction(tr("Export facets in complex")); + actionExportFacetsInComplex->setObjectName("actionExportFacetsInComplex"); + connect(actionExportFacetsInComplex, SIGNAL(triggered()),this, - SLOT(export_domain_boundary_as_polyhedron())); + SLOT(export_facets_in_complex())); } return menu; }