From 6dbf2d3d7876bdab685ff0d4a45bc8cddf91e7db Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 9 Aug 2019 12:09:20 +0200 Subject: [PATCH] Move STL bgl writer into BGL, and replace it by a soup writer in Stream_support. Write a SS test for read and write soups in STL --- BGL/include/CGAL/boost/graph/io.h | 66 +++++++++++++++++++ BGL/test/BGL/test_bgl_read_write.cpp | 1 + .../demo/Polyhedron/Plugins/IO/CMakeLists.txt | 2 +- .../Polyhedron/Plugins/IO/STL_io_plugin.cpp | 4 +- Polyhedron_IO/include/CGAL/IO/STL_writer.h | 4 +- .../include/CGAL/IO/STL/STL_writer.h | 38 +++++------ .../include/CGAL/IO/reader_helpers.h | 1 + .../test/Stream_support/test_STL.cpp | 58 ++++++++++++++++ 8 files changed, 147 insertions(+), 27 deletions(-) create mode 100644 Stream_support/test/Stream_support/test_STL.cpp diff --git a/BGL/include/CGAL/boost/graph/io.h b/BGL/include/CGAL/boost/graph/io.h index ddbeb1676a4..a6f28a93809 100644 --- a/BGL/include/CGAL/boost/graph/io.h +++ b/BGL/include/CGAL/boost/graph/io.h @@ -33,6 +33,8 @@ #include #include #include +#include +#include #ifdef CGAL_USE_VTK #include #endif @@ -846,6 +848,70 @@ bool read_vtp(const char* filename, FaceGraph& face_graph) return VTK_internal::vtkPointSet_to_polygon_mesh(data, face_graph); } #endif //CGAL_USE_VTK + +template +std::ostream& +write_STL(const TriangleMesh& tm, std::ostream& out) +{ + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::property_map::const_type Vpm; + typedef typename boost::property_traits::reference Point_3_ref; + typedef typename boost::property_traits::value_type Point_3; + typedef typename Kernel_traits::Kernel::Vector_3 Vector_3; + + Vpm vpm = get(boost::vertex_point, tm); + + if (get_mode(out) == IO::BINARY) + { + out << "FileType: Binary "; + const boost::uint32_t N32 = static_cast(faces(tm).size()); + out.write(reinterpret_cast(&N32), sizeof(N32)); + + for(face_descriptor f : faces(tm)) + { + halfedge_descriptor h = halfedge(f, tm); + Point_3_ref p = get(vpm, target(h, tm)); + Point_3_ref q = get(vpm, target(next(h, tm), tm)); + Point_3_ref r = get(vpm, source(h, tm)); + + Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0): + unit_normal(p,q,r); + + const float coords[12]={ + static_cast(n.x()), static_cast(n.y()), static_cast(n.z()), + static_cast(p.x()), static_cast(p.y()), static_cast(p.z()), + static_cast(q.x()), static_cast(q.y()), static_cast(q.z()), + static_cast(r.x()), static_cast(r.y()), static_cast(r.z()) }; + + for (int i=0; i<12; ++i) + out.write(reinterpret_cast(&coords[i]), sizeof(coords[i])); + out << " "; + } + } + else + { + out << "solid\n"; + for(face_descriptor f : faces(tm)) + { + halfedge_descriptor h = halfedge(f, tm); + Point_3_ref p = get(vpm, target(h, tm)); + Point_3_ref q = get(vpm, target(next(h, tm), tm)); + Point_3_ref r = get(vpm, source(h, tm)); + + Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0): + unit_normal(p,q,r); + out << "facet normal " << n << "\nouter loop\n"; + out << "vertex " << p << "\n"; + out << "vertex " << q << "\n"; + out << "vertex " << r << "\n"; + out << "endloop\nendfacet\n"; + } + out << "endsolid\n"; + } + return out; +} + } // namespace CGAL diff --git a/BGL/test/BGL/test_bgl_read_write.cpp b/BGL/test/BGL/test_bgl_read_write.cpp index c1c1b3f2953..bb3811c3393 100644 --- a/BGL/test/BGL/test_bgl_read_write.cpp +++ b/BGL/test/BGL/test_bgl_read_write.cpp @@ -18,6 +18,7 @@ #endif #include +#include #include #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index 8ca46a36441..48220216e21 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -44,7 +44,7 @@ if (VTK_FOUND) polyhedron_demo_plugin(vtk_plugin VTK_io_plugin KEYWORDS IO Mesh_3) target_link_libraries(vtk_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_c3t3_item scene_points_with_normal_item ${VTK_LIBRARIES}) - add_definitions(-DCGAL_USE_VTK) + target_compile_definitions(vtk_plugin PRIVATE -DCGAL_USE_VTK) else() message(STATUS "NOTICE : the vtk IO plugin needs VTK libraries and will not be compiled.") endif() diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp index 66d08020a49..d1d879bd5b4 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp @@ -8,8 +8,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/Polyhedron_IO/include/CGAL/IO/STL_writer.h b/Polyhedron_IO/include/CGAL/IO/STL_writer.h index a568c9995e9..b873edde233 100644 --- a/Polyhedron_IO/include/CGAL/IO/STL_writer.h +++ b/Polyhedron_IO/include/CGAL/IO/STL_writer.h @@ -21,9 +21,9 @@ #define CGAL_IO_STL_WRITER_H #define CGAL_DEPRECATED_HEADER "" -#define CGAL_REPLACEMENT_HEADER "" +#define CGAL_REPLACEMENT_HEADER "" #include -#include +#include #include #endif // CGAL_IO_STL_WRITER_H diff --git a/Stream_support/include/CGAL/IO/STL/STL_writer.h b/Stream_support/include/CGAL/IO/STL/STL_writer.h index 6bf46b593d1..3189628414b 100644 --- a/Stream_support/include/CGAL/IO/STL/STL_writer.h +++ b/Stream_support/include/CGAL/IO/STL/STL_writer.h @@ -21,40 +21,35 @@ #define CGAL_IO_STL_STL_WRITER_H #include -#include +#include #include -#include namespace CGAL{ -template +template std::ostream& -write_STL(const TriangleMesh& tm, std::ostream& out) +write_STL(const std::vector& points, + const std::vector& facets, + std::ostream& out) { - typedef typename boost::graph_traits::face_descriptor face_descriptor; - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::property_map::const_type Vpm; - typedef typename boost::property_traits::reference Point_3_ref; - typedef typename boost::property_traits::value_type Point_3; - typedef typename Kernel_traits::Kernel::Vector_3 Vector_3; + typedef typename CGAL::Kernel_traits::Kernel K; + typedef typename K::Vector_3 Vector_3; - Vpm vpm = get(boost::vertex_point, tm); if (get_mode(out) == IO::BINARY) { out << "FileType: Binary "; - const boost::uint32_t N32 = static_cast(faces(tm).size()); + const boost::uint32_t N32 = static_cast(facets.size()); out.write(reinterpret_cast(&N32), sizeof(N32)); - for(face_descriptor f : faces(tm)) + for(auto face : facets) { - halfedge_descriptor h = halfedge(f, tm); - Point_3_ref p = get(vpm, target(h, tm)); - Point_3_ref q = get(vpm, target(next(h, tm), tm)); - Point_3_ref r = get(vpm, source(h, tm)); + const Point& p = points[face[0]]; + const Point& q = points[face[1]]; + const Point& r = points[face[2]]; Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0): unit_normal(p,q,r); @@ -73,12 +68,11 @@ write_STL(const TriangleMesh& tm, std::ostream& out) else { out << "solid\n"; - for(face_descriptor f : faces(tm)) + for(auto face : facets) { - halfedge_descriptor h = halfedge(f, tm); - Point_3_ref p = get(vpm, target(h, tm)); - Point_3_ref q = get(vpm, target(next(h, tm), tm)); - Point_3_ref r = get(vpm, source(h, tm)); + const Point& p = points[face[0]]; + const Point& q = points[face[1]]; + const Point& r = points[face[2]]; Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0): unit_normal(p,q,r); diff --git a/Stream_support/include/CGAL/IO/reader_helpers.h b/Stream_support/include/CGAL/IO/reader_helpers.h index 62e465a7e07..92e46137965 100644 --- a/Stream_support/include/CGAL/IO/reader_helpers.h +++ b/Stream_support/include/CGAL/IO/reader_helpers.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/Stream_support/test/Stream_support/test_STL.cpp b/Stream_support/test/Stream_support/test_STL.cpp new file mode 100644 index 00000000000..6243d12d65f --- /dev/null +++ b/Stream_support/test/Stream_support/test_STL.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +#include +#include +#include + +int main () +{ + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + typedef K::Point_3 Point; + typedef std::vector Polygon; + //make a tetrahedorn soup. + std::vector ps(4); + ps[0] = Point(0,0,0); ps[1] = Point(1,0,0); + ps[2] = Point(0,1,0); ps[3] = Point(0,0,1); + std::vector faces(4); + + faces[0].push_back(0); + faces[0].push_back(2); + faces[0].push_back(1); + + faces[1].push_back(0); + faces[1].push_back(3); + faces[1].push_back(2); + + faces[2].push_back(1); + faces[2].push_back(2); + faces[2].push_back(3); + + faces[3].push_back(0); + faces[3].push_back(1); + faces[3].push_back(3); + + std::ofstream os("tetra.stl"); + CGAL::write_STL(ps, faces, os); + if(!os) + { + std::cerr<<"error during STL writing."<