From e4e65dcedac0156f37b98f67d5c18827c5cc1198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 24 Jul 2014 19:30:41 +0200 Subject: [PATCH 1/6] import file to write the surface of a subdomain into a file use it in the demo, with writting in a .off for now --- ...n_of_complex_3_in_triangulation_3_to_off.h | 90 +++++++++++++++++++ ...olyhedron_demo_mesh_3_plugin_cgal_code.cpp | 6 ++ 2 files changed, 96 insertions(+) create mode 100644 Mesh_3/include/CGAL/internal/Mesh_3/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h 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 new file mode 100644 index 00000000000..402c0311e47 --- /dev/null +++ b/Mesh_3/include/CGAL/internal/Mesh_3/Boundary_of_subdomain_of_complex_3_in_triangulation_3_to_off.h @@ -0,0 +1,90 @@ +// Copyright (c) 2008-2014 GeometryFactory (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: svn+ssh://sloriot@scm.gforge.inria.fr/svn/cgal/branches/next/Mesh_3/include/CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h $ +// $Id: Complex_3_in_triangulation_3_to_vtk.h 67117 2012-01-13 18:14:48Z lrineau $ +// +// +// Author(s) : Laurent Rineau and Sebastien Loriot + +#ifndef CGAL_INTERNAL_MESH_3_BOUNDARY_OF_SUDDOMAIN_OF_COMPLEX_3_IN_TRIANGULATION_3_TO_OFF_H +#define CGAL_INTERNAL_MESH_3_BOUNDARY_OF_SUDDOMAIN_OF_COMPLEX_3_IN_TRIANGULATION_3_TO_OFF_H + +#include +#include + +#include + +namespace CGAL { + +namespace internal{ +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= + V.insert(std::make_pair(v,inum)); + if (res.second){ + ++inum; + vertex_buffer << res.first->first->point().point() <<"\n"; //point is weighted! + } + return res.first->second; +} +}//namespace internal + +template +std::ostream& +output_boundary_of_c3t3_to_off(const C3T3& c3t3, + typename C3T3::Subdomain_index sd_index, + std::ostream& output) +{ + typedef typename C3T3::Triangulation Triangulation; + typedef typename Triangulation::Vertex_handle Vertex_handle; + + std::map V; + + std::size_t inum = 0; + std::size_t nfacets = 0; + cpp0x::array indices={{0,0,0}}; + std::stringstream facet_buffer,vertex_buffer; + for(typename C3T3::Facets_in_complex_iterator + fit = c3t3.facets_in_complex_begin(), + end = c3t3.facets_in_complex_end(); + fit != end; ++fit) + { + typename C3T3::Subdomain_index cell_sd=c3t3.subdomain_index(fit->first); + typename C3T3::Subdomain_index opp_sd=c3t3.subdomain_index(fit->first->neighbor(fit->second)); + + if (cell_sd!=sd_index && opp_sd!=sd_index) continue; + + ++nfacets; + int j=-1; + + + 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]); + facet_buffer << "3" << " " << indices[0] <<" " << indices[1] <<" " << indices[2] << "\n"; + } + + output << "OFF " << inum << " " << nfacets << " 0\n"; + output << vertex_buffer.str(); + output << facet_buffer.str(); + + + return output; +} + +} // end namespace CGAL + +#endif // CGAL_INTERNAL_MESH_3_BOUNDARY_OF_SUDDOMAIN_OF_COMPLEX_3_IN_TRIANGULATION_3_TO_OFF_H 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 f31c12c8ae6..27356d874f0 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 @@ -10,6 +10,8 @@ #include #include +#include + #include #include @@ -329,6 +331,10 @@ Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, { std::ofstream medit_out("out.mesh"); new_item->c3t3().output_to_medit(medit_out); + + std::ofstream surface_out("surface_mesh.off"); + CGAL::output_boundary_of_c3t3_to_off(new_item->c3t3(), 1, surface_out); + const Scene_item::Bbox& bbox = new_item->bbox(); new_item->setPosition((float)(bbox.xmin + bbox.xmax)/2.f, (float)(bbox.ymin + bbox.ymax)/2.f, From 543761cd31885f73834f2058957374d19a557536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 23 Sep 2014 16:40:39 +0200 Subject: [PATCH 2/6] add context menu in c3t3 to extract the boundary of the 3D mesh --- Polyhedron/demo/Polyhedron/CMakeLists.txt | 2 +- .../Polyhedron_demo_mesh_3_plugin.cpp | 6 +- ...olyhedron_demo_mesh_3_plugin_cgal_code.cpp | 74 ++++++++++++++++--- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 5e8214357d1..bd931d49176 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -301,7 +301,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) polyhedron_demo_plugin(mesh_3_plugin Polyhedron_demo_mesh_3_plugin Polyhedron_demo_mesh_3_plugin_cgal_code.cpp Scene_c3t3_item.moc ${meshingUI_FILES}) - target_link_libraries(mesh_3_plugin scene_polyhedron_item ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) + target_link_libraries(mesh_3_plugin scene_polyhedron_item scene_polygon_soup_item ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) else( Boost_VERSION GREATER 103400 ) message(STATUS "warning: the plugin mesh_3_plugin requires Boost>=1.34.1 and will not be compiled.") endif( Boost_VERSION GREATER 103400 ) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp index 7b2a167ec10..c37865a9bc1 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_mesh_3_plugin.cpp @@ -22,7 +22,8 @@ Scene_item* cgal_code_mesh_3(const Polyhedron*, const double approx, const double tets_sizing, const double tet_shape, - const bool protect_features); + const bool protect_features, + Scene_interface* scene); class Polyhedron_demo_mesh_3_plugin : public QObject, @@ -163,7 +164,8 @@ void Polyhedron_demo_mesh_3_plugin::mesh_3() approx, tet_sizing, radius_edge, - protect_features); + protect_features, + scene); if(result_item) { result_item->setName(tr("%1 3d mesh (%2 %3 %4 %5)") .arg(item->name()) 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 27356d874f0..c76ac447e2b 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 @@ -11,11 +11,14 @@ #include #include - +#include +#include #include +#include #include +#include typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; @@ -54,8 +57,7 @@ public: typedef qglviewer::ManipulatedFrame ManipulatedFrame; Scene_c3t3_item(const C3t3& c3t3) - : c3t3_(c3t3), frame(new ManipulatedFrame()) - + : c3t3_(c3t3), frame(new ManipulatedFrame()), last_known_scene(NULL) {} ~Scene_c3t3_item() @@ -276,9 +278,65 @@ private: return diag * 0.7; } - C3t3 c3t3_; +public slots: + void export_domain_boundary_as_polyhedron() + { + std::stringstream off_sstream; + CGAL::output_boundary_of_c3t3_to_off(c3t3(), 1, off_sstream); + std::string backup = off_sstream.str(); + // Try to read .off in a polyhedron + Scene_polyhedron_item* item = new Scene_polyhedron_item(); + if(!item->load(off_sstream)) + { + delete item; + off_sstream.str(backup); + // Try to read .off in a polygon soup + Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item; + + if(!soup_item->load(off_sstream)) { + delete soup_item; + return; + } + + soup_item->setName(QString("%1_%2").arg(this->name()).arg("boundary")); + last_known_scene->addItem(soup_item); + } + else{ + item->setName(QString("%1_%2").arg(this->name()).arg("boundary")); + last_known_scene->addItem(item); + } + } + +public: + + QMenu* contextMenu() + { + const char* prop_name = "Menu modified by Scene_c3t3_item."; + + QMenu* menu = Scene_item::contextMenu(); + + // Use dynamic properties: + // http://doc.trolltech.com/lastest/qobject.html#property + bool menuChanged = menu->property(prop_name).toBool(); + + if(!menuChanged) { + QAction* actionDomainBoundaryAsPolyhedron = + menu->addAction(tr("Export domain boundary as polyhedron")); + actionDomainBoundaryAsPolyhedron->setObjectName("actionSelectNextVolume"); + connect(actionDomainBoundaryAsPolyhedron, + SIGNAL(triggered()),this, + SLOT(export_domain_boundary_as_polyhedron())); + } + return menu; + } + + void set_scene(Scene_interface* scene){ last_known_scene=scene; } + +private: + C3t3 c3t3_; qglviewer::ManipulatedFrame* frame; + Scene_interface* last_known_scene; }; Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, @@ -288,7 +346,8 @@ Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, const double approx, const double tet_sizing, const double tet_shape, - const bool protect_features) + const bool protect_features, + Scene_interface* scene) { if(!pMesh) return 0; @@ -324,7 +383,7 @@ Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, Scene_c3t3_item* new_item = new Scene_c3t3_item(CGAL::make_mesh_3(domain, criteria, features)); - + new_item->set_scene(scene); std::cerr << "done (" << timer.time() << " ms, " << new_item->c3t3().triangulation().number_of_vertices() << " vertices)" << std::endl; if(new_item->c3t3().triangulation().number_of_vertices() > 0) @@ -332,9 +391,6 @@ Scene_item* cgal_code_mesh_3(const Polyhedron* pMesh, std::ofstream medit_out("out.mesh"); new_item->c3t3().output_to_medit(medit_out); - std::ofstream surface_out("surface_mesh.off"); - CGAL::output_boundary_of_c3t3_to_off(new_item->c3t3(), 1, surface_out); - const Scene_item::Bbox& bbox = new_item->bbox(); new_item->setPosition((float)(bbox.xmin + bbox.xmax)/2.f, (float)(bbox.ymin + bbox.ymax)/2.f, From 684104c032d001956d7824fb3969adc7d5b9477d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 23 Sep 2014 17:20:07 +0200 Subject: [PATCH 3/6] add 2 overloads of output_boundary_of_c3t3_to_off in the C3T3 class also update the demo plugin to use one of them --- .../CGAL/Mesh_complex_3_in_triangulation_3.h | 10 +++++ .../CGAL/Mesh_complex_3_in_triangulation_3.h | 20 +++++++++ ...n_of_complex_3_in_triangulation_3_to_off.h | 41 +++++++++++++++++++ ...olyhedron_demo_mesh_3_plugin_cgal_code.cpp | 3 +- 4 files changed, 72 insertions(+), 2 deletions(-) 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 6104673fe32..efa376cc52a 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 @@ -80,6 +80,16 @@ in medit format. */ void output_to_medit(std::ofstream& os); +/** + * Outputs the outer boundary of the entire domain with facets oriented outward. + */ +std::ostream& output_boundary_to_off(std::ostream& out) const; + +/** + * Outputs the outer boundary of the selected subdomain with facets oriented outward. + */ +std::ostream& output_boundary_to_off(std::ostream& out, Subdomain_index subdomain) 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 0205a07fe66..8f591cf537e 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 @@ -38,6 +38,7 @@ #include #include #include +#include namespace CGAL { @@ -72,6 +73,7 @@ public: typedef typename Base::Triangulation Triangulation; using Base::surface_patch_index; + using typename Base::Subdomain_index; private: // Type to store the edges: @@ -332,6 +334,24 @@ public: return Corner_index(); } + /** + * Outputs the outer boundary of the entire domain with facets oriented outward. + */ + std::ostream& output_boundary_to_off(std::ostream& out) const + { + output_boundary_of_c3t3_to_off(*this, out); + return out; + } + + /** + * Outputs the outer boundary of the selected subdomain with facets oriented outward. + */ + std::ostream& output_boundary_to_off(std::ostream& out, Subdomain_index subdomain) const + { + output_boundary_of_c3t3_to_off(*this, subdomain, 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 402c0311e47..760d0600a7f 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 @@ -85,6 +85,47 @@ output_boundary_of_c3t3_to_off(const C3T3& c3t3, return output; } +template +std::ostream& +output_boundary_of_c3t3_to_off(const C3T3& c3t3, + std::ostream& output) +{ + typedef typename C3T3::Triangulation Triangulation; + typedef typename Triangulation::Vertex_handle Vertex_handle; + + std::map V; + + std::size_t inum = 0; + std::size_t nfacets = 0; + cpp0x::array indices={{0,0,0}}; + std::stringstream facet_buffer,vertex_buffer; + for(typename C3T3::Facets_in_complex_iterator + fit = c3t3.facets_in_complex_begin(), + end = c3t3.facets_in_complex_end(); + fit != end; ++fit) + { + typename C3T3::Subdomain_index cell_sd=c3t3.subdomain_index(fit->first); + typename C3T3::Subdomain_index opp_sd=c3t3.subdomain_index(fit->first->neighbor(fit->second)); + + ++nfacets; + int j=-1; + + + 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 > opp_sd) == (fit->second%2 == 1) ) std::swap(indices[0],indices[1]); + facet_buffer << "3" << " " << indices[0] <<" " << indices[1] <<" " << indices[2] << "\n"; + } + + output << "OFF " << inum << " " << nfacets << " 0\n"; + output << vertex_buffer.str(); + output << facet_buffer.str(); + + + return output; +} + } // end namespace CGAL #endif // CGAL_INTERNAL_MESH_3_BOUNDARY_OF_SUDDOMAIN_OF_COMPLEX_3_IN_TRIANGULATION_3_TO_OFF_H 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 c76ac447e2b..506c923942b 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 @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -282,7 +281,7 @@ public slots: void export_domain_boundary_as_polyhedron() { std::stringstream off_sstream; - CGAL::output_boundary_of_c3t3_to_off(c3t3(), 1, off_sstream); + c3t3().output_boundary_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(); From 9f3151c9f1f63bfd63d225299a0feb40eebf02f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 Sep 2014 09:12:21 +0200 Subject: [PATCH 4/6] add test for C3T3::output_boundary_to_off --- Mesh_3/test/Mesh_3/CMakeLists.txt | 1 + ...est_c3t3_extract_subdomains_boundaries.cpp | 93 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 6fcde2058ef..ef893683917 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -53,6 +53,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" ) create_single_source_cgal_program( "test_robust_weighted_circumcenter.cpp" ) create_single_source_cgal_program( "test_meshing_determinism.cpp" ) + create_single_source_cgal_program( "test_c3t3_extract_subdomains_boundaries.cpp" ) else() 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 new file mode 100644 index 00000000000..feeb4694e47 --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp @@ -0,0 +1,93 @@ +#include + +#include +#include +#include + +#include +#include +#include + +#include + +using namespace CGAL::parameters; + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::FT FT; + +template +double sphere_function (double x, double y, double z) // (c=(0,0,0), r=Sq_radius) +{ + double x2=x*x, y2=y*y, z2=z*z; + return (x2+y2+z2)/Sq_radius - 1; +} + +template +class FT_to_point_function_wrapper : public std::unary_function +{ + typedef FT (*Implicit_function)(FT, FT, FT); + Implicit_function function; +public: + typedef P Point; + FT_to_point_function_wrapper(Implicit_function f) : function(f) {} + FT operator()(Point p) const { return function(p.x(), p.y(), p.z()); } +}; + +double torus_function (double x, double y, double z) { + double x2=x*x, y2=y*y, z2=z*z; + double x4=x2*x2, y4=y2*y2, z4=z2*z2; + + return x4 + y4 + z4 + 2 *x2* y2 + 2* + x2*z2 + 2*y2* z2 - 5 *x2 + 4* y2 - 5*z2+4; +} + +typedef FT_to_point_function_wrapper Function; +typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper + Function_wrapper; +typedef Function_wrapper::Function_vector Function_vector; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Mesh Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; +typedef Mesh_criteria::Facet_criteria Facet_criteria; +typedef Mesh_criteria::Cell_criteria Cell_criteria; + + +int main() +{ + // Define functions + Function f1(&torus_function); + Function f2(&sphere_function<3>); + + Function_vector v; + v.push_back(f1); + v.push_back(f2); + // Domain (Warning: Sphere_3 constructor uses square radius !) + Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); + + // Set mesh criteria + Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation + Cell_criteria cell_criteria(2., 0.4); // radius-edge ratio, size + Mesh_criteria criteria(facet_criteria, cell_criteria); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); + + // Output + std::stringstream off_file; + c3t3.output_boundary_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); + assert( off_file.str().size() > 20 ); + } + + return 0; +} From 024bd2724f70cec6a08664be9e2dae633cde93c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 24 Sep 2014 12:05:02 +0200 Subject: [PATCH 5/6] add output_facets_in_complex_to_off and update test and demo --- .../CGAL/Mesh_complex_3_in_triangulation_3.h | 5 +++++ .../CGAL/Mesh_complex_3_in_triangulation_3.h | 11 +++++++++- ...n_of_complex_3_in_triangulation_3_to_off.h | 21 ++++++++++++------- ...est_c3t3_extract_subdomains_boundaries.cpp | 4 ++++ ...olyhedron_demo_mesh_3_plugin_cgal_code.cpp | 18 ++++++++-------- 5 files changed, 41 insertions(+), 18 deletions(-) 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; } From 3616d28c86b6e4b0096c4b66bb62a6aad3160ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 25 Sep 2014 14:10:38 +0200 Subject: [PATCH 6/6] typedef instead of using --- Mesh_3/include/CGAL/Mesh_complex_3_in_triangulation_3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 b64d4517c5b..3f00cc48f06 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 @@ -71,9 +71,9 @@ public: typedef CurveSegmentIndex Curve_segment_index; typedef typename Base::Triangulation Triangulation; + typedef typename Base::Subdomain_index Subdomain_index; using Base::surface_patch_index; - using typename Base::Subdomain_index; private: // Type to store the edges: