mirror of https://github.com/CGAL/cgal
Add a function to Surface_mesh that reads a range of surface_meshes from a 3mf file.
This commit is contained in:
parent
5c6f20e1ec
commit
1970d94c53
|
|
@ -18,8 +18,8 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Maxime Gimeno
|
// Author(s) : Maxime Gimeno
|
||||||
|
|
||||||
#ifndef READ_3MF_H
|
#ifndef CGAL_IO_READ_3MF_H
|
||||||
#define READ_3MF_H
|
#define CGAL_IO_READ_3MF_H
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -43,7 +43,7 @@ NMR::MODELTRANSFORM initMatrix()
|
||||||
|
|
||||||
return mMatrix;
|
return mMatrix;
|
||||||
}
|
}
|
||||||
}//end internal
|
}//end transform_nmr_internal
|
||||||
|
|
||||||
template<typename PointRange,
|
template<typename PointRange,
|
||||||
typename PolygonRange,
|
typename PolygonRange,
|
||||||
|
|
@ -573,8 +573,7 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief read_soups_from_3mf extracts ranges of points and triangles from the
|
* \brief extracts ranges of points and triangles from a 3mf file.
|
||||||
* `MeshObject`s contained in `file_name`
|
|
||||||
* \tparam PointRanges a model of the concepts `RandomAccessContainer` and
|
* \tparam PointRanges a model of the concepts `RandomAccessContainer` and
|
||||||
* `BackInsertionSequence` whose `value type` is
|
* `BackInsertionSequence` whose `value type` is
|
||||||
* a model of the concepts `RandomAccessContainer` and `BackInsertionSequence`
|
* a model of the concepts `RandomAccessContainer` and `BackInsertionSequence`
|
||||||
|
|
@ -594,11 +593,11 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points,
|
||||||
* \param all_polygons a `PolygonRanges` that will contain the triangles of the
|
* \param all_polygons a `PolygonRanges` that will contain the triangles of the
|
||||||
* meshes in `file_name`.
|
* meshes in `file_name`.
|
||||||
* Each of these meshes will add a range of its triangles. A `triangle` of
|
* Each of these meshes will add a range of its triangles. A `triangle` of
|
||||||
* all_polygons[i] contains the indices of its points in all_points[i].
|
* `all_polygons[i]` contains the indices of its points in `all_points[i]`.
|
||||||
* \param all_colors will contain the color of each triangle for each soup.
|
* \param all_colors will contain the color of each triangle for each soup.
|
||||||
* \param names will contain the name of each mesh in `file_name` if any.
|
* \param names will contain the name of each mesh in `file_name` if any.
|
||||||
* If the i'th mesh has no name, it will be called "Unknown Mesh" in names.
|
* If the i'th mesh has no name, it will be called "Unknown Mesh" in names.
|
||||||
* \return the number of meshes processed in `file_name`.
|
* \return the number of soups read.
|
||||||
*/
|
*/
|
||||||
template<typename PointRanges, typename PolygonRanges, typename ColorRanges>
|
template<typename PointRanges, typename PolygonRanges, typename ColorRanges>
|
||||||
int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points,
|
int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points,
|
||||||
|
|
@ -654,5 +653,5 @@ int read_point_clouds_from_3mf(const std::string& file_name,
|
||||||
}
|
}
|
||||||
}//end CGAL
|
}//end CGAL
|
||||||
|
|
||||||
#endif // READ_3MF_H
|
#endif // CGAL_IO_READ_3MF_H
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <CGAL/boost/graph/helpers.h>
|
#include <CGAL/boost/graph/helpers.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <CGAL/Surface_mesh.h>
|
#include <CGAL/Surface_mesh.h>
|
||||||
|
#include <CGAL/Surface_mesh/IO/3mf.h>
|
||||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
|
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
|
||||||
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
|
||||||
|
|
@ -27,49 +28,31 @@ typedef std::vector<CGAL::Color> ColorRange;
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if( argc != 2)
|
const char* file_name=(argc == 2) ? argv[1] : "data/test.3mf";
|
||||||
{
|
|
||||||
std::cerr<<"please give an input 3mf file.";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
std::vector<PointRange> all_points;
|
std::vector<PointRange> all_points;
|
||||||
std::vector<PolygonRange> all_polygons;
|
std::vector<PolygonRange> all_polygons;
|
||||||
std::vector<ColorRange> all_colors;
|
std::vector<ColorRange> all_colors;
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
|
std::vector<Mesh> meshes;
|
||||||
//testing reading functions.
|
//testing reading functions.
|
||||||
int nb_meshes =
|
int nb_meshes =
|
||||||
CGAL::read_soups_from_3mf(argv[1], all_points, all_polygons,
|
CGAL::read_3mf(file_name, meshes);
|
||||||
all_colors, names);
|
|
||||||
if(nb_meshes <0)
|
if(nb_meshes <0)
|
||||||
return 1;
|
return 1;
|
||||||
for(std::size_t i = 0; i< nb_meshes; ++i)
|
for(std::size_t i = 0; i< nb_meshes; ++i)
|
||||||
{
|
{
|
||||||
PolygonRange triangles = all_polygons[i];
|
Mesh mesh = meshes[i];
|
||||||
PointRange points = all_points[i];
|
std::cout<<names[i]<<" is valid: "<<mesh.is_valid()<<std::endl;
|
||||||
bool ok = true;
|
std::string outputName("output");
|
||||||
if(!PMP::is_polygon_soup_a_polygon_mesh(triangles))
|
outputName.append(std::to_string(i));
|
||||||
ok = PMP::orient_polygon_soup(points, triangles);
|
outputName.append(".off");
|
||||||
if(!ok)
|
std::ofstream ofs(outputName);
|
||||||
{
|
ofs << mesh;
|
||||||
std::cerr<<"Object is not orientable. Skipped."<<std::endl;
|
ofs.close();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Mesh mesh;
|
|
||||||
PMP::polygon_soup_to_polygon_mesh(points, triangles, mesh);
|
|
||||||
std::cout<<names[i]<<" is valid: "<<mesh.is_valid()<<std::endl;
|
|
||||||
std::string outputName("output");
|
|
||||||
outputName.append(std::to_string(i));
|
|
||||||
outputName.append(".off");
|
|
||||||
std::ofstream ofs(outputName);
|
|
||||||
ofs << mesh;
|
|
||||||
ofs.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
all_points.clear();
|
|
||||||
all_colors.clear();
|
|
||||||
int nb_polylines =
|
int nb_polylines =
|
||||||
CGAL::read_polylines_from_3mf(argv[1], all_points, all_colors, names);
|
CGAL::read_polylines_from_3mf(file_name, all_points, all_colors, names);
|
||||||
|
|
||||||
if(nb_polylines == 0)
|
if(nb_polylines == 0)
|
||||||
std::cout<<"No polyline found."<<std::endl;
|
std::cout<<"No polyline found."<<std::endl;
|
||||||
|
|
@ -84,7 +67,7 @@ int main(int argc, char** argv)
|
||||||
all_points.clear();
|
all_points.clear();
|
||||||
all_colors.clear();
|
all_colors.clear();
|
||||||
int nb_point_sets =
|
int nb_point_sets =
|
||||||
CGAL::read_point_clouds_from_3mf(argv[1], all_points, all_colors, names);
|
CGAL::read_point_clouds_from_3mf(file_name, all_points, all_colors, names);
|
||||||
if(nb_point_sets == 0)
|
if(nb_point_sets == 0)
|
||||||
std::cout<<"No point cloud found."<<std::endl;
|
std::cout<<"No point cloud found."<<std::endl;
|
||||||
else
|
else
|
||||||
|
|
@ -159,7 +142,7 @@ int main(int argc, char** argv)
|
||||||
names.push_back(std::string("sphere"));
|
names.push_back(std::string("sphere"));
|
||||||
names.push_back(std::string("tube"));
|
names.push_back(std::string("tube"));
|
||||||
|
|
||||||
std::vector<Mesh> meshes(2);
|
meshes.resize(2);
|
||||||
meshes[0] = sphere;
|
meshes[0] = sphere;
|
||||||
meshes[1] = tube;
|
meshes[1] = tube;
|
||||||
CGAL::write_triangle_meshes_to_3mf("meshes.3mf", meshes, names);
|
CGAL::write_triangle_meshes_to_3mf("meshes.3mf", meshes, names);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
// Copyright (c) 2019 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 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) : Maxime Gimeno
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CGAL_SURFACE_MESH_IO_3MF_H
|
||||||
|
#define CGAL_SURFACE_MESH_IO_3MF_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <CGAL/IO/read_3mf.h>
|
||||||
|
#include <CGAL/Surface_mesh.h>
|
||||||
|
|
||||||
|
namespace CGAL{
|
||||||
|
/*!
|
||||||
|
* Extracts the surface meshes from an input 3mf file and appends it to `output`.
|
||||||
|
*\tparam SurfaceMeshRange a model of the concepts `RandomAccessContainer` and
|
||||||
|
* `BackInsertionSequence` whose `value type` is `CGAL::Surface_mesh`.
|
||||||
|
* \param file_name the path to the 3mf file.
|
||||||
|
* \param output the `SurfaceMeshRange` that will be filled by this function.
|
||||||
|
* \return the number of extracted surface meshes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename Point>
|
||||||
|
int read_3mf(const std::string& file_name,
|
||||||
|
std::vector<CGAL::Surface_mesh<Point> >& output)
|
||||||
|
{
|
||||||
|
typedef std::vector<Point> PointRange;
|
||||||
|
typedef std::vector<std::size_t> Polygon;
|
||||||
|
typedef std::vector<Polygon> PolygonRange;
|
||||||
|
typedef CGAL::Surface_mesh<Point> SMesh;
|
||||||
|
typedef typename SMesh::Vertex_index Vertex_index;
|
||||||
|
typedef typename SMesh::Face_index Face_index;
|
||||||
|
|
||||||
|
std::vector<PointRange> all_points;
|
||||||
|
std::vector<PolygonRange> all_polygons;
|
||||||
|
std::vector<std::string> names;
|
||||||
|
std::vector<std::vector<CGAL::Color> > all_colors;
|
||||||
|
int result = 0;
|
||||||
|
int nb_meshes =
|
||||||
|
CGAL::read_soups_from_3mf(file_name,
|
||||||
|
all_points, all_polygons, all_colors, names);
|
||||||
|
if(nb_meshes < 0 )
|
||||||
|
{
|
||||||
|
std::cerr << "Error in reading meshes."<<std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
output.reserve(nb_meshes);
|
||||||
|
for(int i = 0; i< nb_meshes; ++i)
|
||||||
|
{
|
||||||
|
bool skip = false;
|
||||||
|
SMesh sm;
|
||||||
|
PolygonRange triangles = all_polygons[i];
|
||||||
|
PointRange points = all_points[i];
|
||||||
|
std::vector<CGAL::Color> colors = all_colors[i];
|
||||||
|
//Create the surface mesh from scratch
|
||||||
|
std::size_t n(points.size());
|
||||||
|
sm.reserve(n,0, triangles.size());
|
||||||
|
for(const Point& p : points)
|
||||||
|
{
|
||||||
|
sm.add_vertex(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Polygon& triangle : triangles)
|
||||||
|
{
|
||||||
|
std::vector<Vertex_index> face;
|
||||||
|
face.reserve(triangle.size());
|
||||||
|
for(auto index : triangle)
|
||||||
|
{
|
||||||
|
face.push_back(Vertex_index(index));
|
||||||
|
}
|
||||||
|
Face_index fi = sm.add_face(face);
|
||||||
|
if(fi == sm.null_face())
|
||||||
|
{
|
||||||
|
skip = true;
|
||||||
|
sm.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(skip)
|
||||||
|
continue;
|
||||||
|
//end constructin the surface mesh from scratch
|
||||||
|
|
||||||
|
CGAL::Color first = colors.front();
|
||||||
|
bool need_pmap = false;
|
||||||
|
for(auto color : colors)
|
||||||
|
{
|
||||||
|
if (color != first)
|
||||||
|
{
|
||||||
|
need_pmap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(need_pmap)
|
||||||
|
{
|
||||||
|
typename SMesh::template Property_map<Face_index, CGAL::Color> fcolor =
|
||||||
|
sm.template add_property_map<Face_index,CGAL::Color>("f:color",first).first;
|
||||||
|
for(std::size_t pid = 0; pid < colors.size(); ++pid)
|
||||||
|
{
|
||||||
|
put(fcolor, Face_index(pid), colors[pid]);//should work bc mesh is just created and shouldn't have any destroyed face.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.push_back(sm);
|
||||||
|
++result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end CGAL
|
||||||
|
#endif // CGAL_SURFACE_MESH_3MF_H
|
||||||
Loading…
Reference in New Issue