From a36c7fe39b1c368c262ced59ca5f63b4888adace Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 7 May 2019 15:21:31 +0200 Subject: [PATCH 01/31] Write a 3mf wrapper --- Stream_support/include/CGAL/IO/read_3mf.h | 186 +++++++++++ Stream_support/include/CGAL/IO/write_3mf.h | 303 ++++++++++++++++++ .../test/Stream_support/CMakeLists.txt | 43 ++- .../test/Stream_support/test_3mf_to_sm.cpp | 147 +++++++++ 4 files changed, 676 insertions(+), 3 deletions(-) create mode 100644 Stream_support/include/CGAL/IO/read_3mf.h create mode 100644 Stream_support/include/CGAL/IO/write_3mf.h create mode 100644 Stream_support/test/Stream_support/test_3mf_to_sm.cpp diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h new file mode 100644 index 00000000000..5c6cf0798d2 --- /dev/null +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -0,0 +1,186 @@ +#ifndef READ_3MF_H +#define READ_3MF_H +#include +#include +#include +#include "Model/COM/NMR_DLLInterfaces.h" +namespace CGAL{ + +/*! + * \brief read_soups_from_3mf extracts ranges of points and triangles from the + * `MeshObject`s contained in `file_name` + * \tparam PointRanges a model of the concepts `RandomAccessContainer` and + * `BackInsertionSequence` whose `value type` is + * a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` + * whose `value type` is the point type. + * \tparam PolygonRanges a model of the concept `RandomAccessContainer` whose + * `value_type` is a model of the concept `RandomAccessContainer` + * whose `value_type` is a model of the concept `RandomAccessContainer` whose + * `value_type` is std::size_t. + * \param file_name the name of the 3mf file to read. + * \param all_points a `PointRanges` that will contain the points of the meshes + * in `file_name`. + * Each of these meshes will add a range of its points. + * \param all_polygons a `PolygonRanges` that will contain the triangles of the + * meshes in `file_name`. + * 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]. + * \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. + * \return the number of meshes processed in `file_name`. + */ +template +int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, + PolygonRanges& all_polygons, std::vector& names) +{ + typedef typename PointRanges::value_type PointRange; + typedef typename PointRange::value_type Point_3; + typedef typename PolygonRanges::value_type PolygonRange; + typedef typename PolygonRange::value_type Polygon; + DWORD nInterfaceVersionMajor, nInterfaceVersionMinor, nInterfaceVersionMicro, nbVertices, nbPolygons; + HRESULT hResult; + NMR::PLib3MFModel * pModel; + NMR::PLib3MFModelReader * pReader; + // Extract Extension of filename + std::string sReaderName("3mf"); + + hResult = NMR::lib3mf_getinterfaceversion(&nInterfaceVersionMajor, &nInterfaceVersionMinor, &nInterfaceVersionMicro); + if (hResult != LIB3MF_OK) { + std::cout << "could not get 3MF Library version: " << std::hex << hResult << std::endl; + return -1; + } + + // Create Model Instance + hResult = NMR::lib3mf_createmodel(&pModel); + if (hResult != LIB3MF_OK) { + std::cout << "could not create model: " << std::hex << hResult << std::endl; + return -1; + } + + // Create Model Reader + hResult = NMR::lib3mf_model_queryreader(pModel, sReaderName.c_str(), &pReader); + if (hResult != LIB3MF_OK) { + std::cout << "could not create model reader: " << std::hex << hResult << std::endl; + NMR::lib3mf_release(pModel); + return -1; + } + + // Import Model from File + hResult = NMR::lib3mf_reader_readfromfileutf8(pReader, file_name.c_str()); + if (hResult != LIB3MF_OK) { + std::cout << "could not parse file: " << std::hex << hResult << std::endl; + NMR::lib3mf_release(pReader); + NMR::lib3mf_release(pModel); + return -1; + } + + // Release Model Reader + NMR::lib3mf_release(pReader); + + //Iterate Model + + BOOL pbHasNext; + NMR::PLib3MFModelResourceIterator * pResourceIterator; + + hResult = NMR::lib3mf_model_getobjects(pModel, &pResourceIterator); + if (hResult != LIB3MF_OK) { + std::cout << "could not get object: " << std::hex << hResult << std::endl; + NMR::lib3mf_release(pModel); + return -1; + } + hResult = NMR::lib3mf_resourceiterator_movenext(pResourceIterator, &pbHasNext); + if (hResult != LIB3MF_OK) { + std::cout << "could not get next object: " << std::hex << hResult << std::endl; + NMR::lib3mf_release(pResourceIterator); + NMR::lib3mf_release(pModel); + return -1; + } + while (pbHasNext) { + NMR::PLib3MFModelResource * pResource; + NMR::PLib3MFModelMeshObject * pMeshObject; + NMR::PLib3MFModelComponentsObject * pComponentsObject; + NMR::ModelResourceID ResourceID; + + // get current resource + hResult = NMR::lib3mf_resourceiterator_getcurrent(pResourceIterator, &pResource); + if (hResult != LIB3MF_OK) { + std::cout << "could not get resource: " << std::hex << hResult << std::endl; + NMR::lib3mf_release(pResourceIterator); + NMR::lib3mf_release(pModel); + return -1; + } + + // get resource ID + hResult = NMR::lib3mf_resource_getresourceid(pResource, &ResourceID); + if (hResult != LIB3MF_OK) { + std::cout << "could not get resource id: " << std::hex << hResult << std::endl; + NMR::lib3mf_release(pResource); + NMR::lib3mf_release(pResourceIterator); + NMR::lib3mf_release(pModel); + return -1; + } + + // Query mesh interface + BOOL bIsMeshObject; + hResult = NMR::lib3mf_object_ismeshobject(pResource, &bIsMeshObject); + if ((hResult == LIB3MF_OK) && (bIsMeshObject)) { + std::cout << "------------------------------------------------------" << std::endl; + std::cout << "mesh object #" << ResourceID << ": " << std::endl; + + pMeshObject = pResource; + NMR::lib3mf_meshobject_getvertexcount(pMeshObject, &nbVertices); + NMR::lib3mf_meshobject_gettrianglecount(pMeshObject, &nbPolygons); + PointRange points (nbVertices); + PolygonRange triangles(nbPolygons); + DWORD nNeededChars; + std::vector pBuffer; + // Retrieve Mesh Name Length + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars); + if (hResult != LIB3MF_OK) + return hResult; + + // Retrieve Mesh Name + if (nNeededChars > 0) { + pBuffer.resize(nNeededChars + 1); + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL); + pBuffer[nNeededChars] = 0; + names.push_back(std::string(&pBuffer[0])); + } + else + names.push_back(std::string("Unknown Mesh")); + for(DWORD vid = 0; vid < nbVertices; ++vid) + { + NMR::MODELMESHVERTEX pVertex; + NMR::lib3mf_meshobject_getvertex(pMeshObject, vid, &pVertex); + points[vid] = + Point_3(pVertex.m_fPosition[0], + pVertex.m_fPosition[1], + pVertex.m_fPosition[2]); + } + for(DWORD pid = 0; pid < nbPolygons; ++pid) + { + NMR::MODELMESHTRIANGLE pTriangle; + NMR::lib3mf_meshobject_gettriangle(pMeshObject, pid, &pTriangle); + Polygon triangle(3); + for(DWORD i = 0; i< 3; ++i) + triangle[i] = pTriangle.m_nIndices[i]; + triangles[pid] = triangle; + } + all_points.push_back(points); + all_polygons.push_back(triangles); + } + // free instances + NMR::lib3mf_release(pResource); + hResult = NMR::lib3mf_resourceiterator_movenext(pResourceIterator, &pbHasNext); + if (hResult != LIB3MF_OK) { + std::cout << "could not get next object: " << std::hex << hResult << std::endl; + return -1; + } + } + return all_points.size(); +} + +}//end CGAL + +#endif // READ_3MF_H + diff --git a/Stream_support/include/CGAL/IO/write_3mf.h b/Stream_support/include/CGAL/IO/write_3mf.h new file mode 100644 index 00000000000..322d54495c3 --- /dev/null +++ b/Stream_support/include/CGAL/IO/write_3mf.h @@ -0,0 +1,303 @@ +// 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 WRITE_3MF_H +#define WRITE_3MF_H +#include +#include +#include +#include "Model/COM/NMR_DLLInterfaces.h" +namespace CGAL{ +namespace tmf_internal{ +// Utility functions to create vertices and triangles +NMR::MODELMESHVERTEX fnCreateVertex(float x, float y, float z) +{ + NMR::MODELMESHVERTEX result; + result.m_fPosition[0] = x; + result.m_fPosition[1] = y; + result.m_fPosition[2] = z; + return result; +} +NMR::MODELMESHTRIANGLE fnCreateTriangle(int v0, int v1, int v2) +{ + NMR::MODELMESHTRIANGLE result; + result.m_nIndices[0] = v0; + result.m_nIndices[1] = v1; + result.m_nIndices[2] = v2; + return result; +} + +} //end internal + +bool add_build_item(NMR::PLib3MFModel * pModel, + NMR::PLib3MFModelMeshObject* pMeshObject) +{ + HRESULT hResult; + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + // Add Build Item for Mesh + NMR::PLib3MFModelBuildItem * pBuildItem; + hResult = NMR::lib3mf_model_addbuilditem(pModel, pMeshObject, NULL, &pBuildItem); + if (hResult != LIB3MF_OK) { + std::cout << "could not create build item: " + << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage + << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(pMeshObject); + NMR::lib3mf_release(pModel); + return false; + } + // Release BuildItem and Mesh + NMR::lib3mf_release(pMeshObject); + NMR::lib3mf_release(pBuildItem); + return true; +} + +bool export_model_to_file(const std::string& file_name, + NMR::PLib3MFModel * pModel) +{ + HRESULT hResult; + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + // Output mesh as 3MF + // Create Model Writer for 3MF + NMR::PLib3MFModelWriter * p3MFWriter; + hResult = NMR::lib3mf_model_querywriter(pModel, "3mf", &p3MFWriter); + if (hResult != LIB3MF_OK) { + std::cout << "could not create model reader: " + << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage + << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(pModel); + return false; + } + // Export Model into File + hResult = NMR::lib3mf_writer_writetofileutf8(p3MFWriter, file_name.c_str()); + if (hResult != LIB3MF_OK) { + std::cout << "could not write file: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(p3MFWriter, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage << ": " + << pszErrorMessage << std::endl; + NMR::lib3mf_release(pModel); + NMR::lib3mf_release(p3MFWriter); + return false; + } + + // Release Model Writer + NMR::lib3mf_release(p3MFWriter); + return true; +} + +template +bool write_mesh_to_model( const PointRange& points, + const PolygonRange& polygons, + const std::string& name, + NMR::PLib3MFModelMeshObject** pMeshObject, + NMR::PLib3MFModel * pModel + ) +{ + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + HRESULT hResult; + // Create mesh structure + std::vector pVertices; + std::vector pTriangles; + // Create Mesh Object + hResult = NMR::lib3mf_model_addmeshobject(pModel, pMeshObject); + if (hResult != LIB3MF_OK) { + std::cout << "could not add mesh object: " << std::hex + << hResult << std::endl; + NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage << ": " + << pszErrorMessage << std::endl; + NMR::lib3mf_release(pModel); + return false; + } + for( auto point : points) + { + pVertices.push_back(tmf_internal::fnCreateVertex(point.x(), point.y(), point.z())); + } + + for( auto triangle : polygons) + { + pTriangles.push_back(tmf_internal::fnCreateTriangle(triangle[0], triangle[1], triangle[2])); + } + + hResult = NMR::lib3mf_meshobject_setgeometry(*pMeshObject, pVertices.data(), + pVertices.size(), pTriangles.data(), + pTriangles.size()); + if (hResult != LIB3MF_OK) { + std::cout << "could not set mesh geometry: " + << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage + << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(*pMeshObject); + NMR::lib3mf_release(pModel); + return false; + } + // Set name + hResult = NMR::lib3mf_object_setnameutf8(*pMeshObject, name.c_str()); + if (hResult != LIB3MF_OK) { + std::cout << "could not set object name: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(*pMeshObject); + NMR::lib3mf_release(pModel); + return -1; + } +} + +//remember that it adds 3 demmy vertices in the beginning, and a dummy triangle to be ignored. +template +bool write_points(const PointRange& points, + const std::string& name, + NMR::PLib3MFModelMeshObject** pMeshObject, + NMR::PLib3MFModel * pModel + ) +{ + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + HRESULT hResult; + // Create mesh structure + std::vector pVertices; + // Create Mesh Object + hResult = NMR::lib3mf_model_addmeshobject(pModel, pMeshObject); + if (hResult != LIB3MF_OK) { + std::cout << "could not add mesh object: " << std::hex + << hResult << std::endl; + NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage << ": " + << pszErrorMessage << std::endl; + NMR::lib3mf_release(pModel); + return false; + } + //add 3 demmy vertices to be sure to have a valid triangle and accept point sets with less than 3 vertices. + for(int i = 0; i< 3; ++i) + pVertices.push_back(tmf_internal::fnCreateVertex(0,0,0)); + for( auto point : points) + { + pVertices.push_back(tmf_internal::fnCreateVertex(point.x(), point.y(), point.z())); + } + NMR::MODELMESHTRIANGLE dummy_triangle = tmf_internal::fnCreateTriangle(0,1,2); //add a triangle to avoid lib error. + hResult = NMR::lib3mf_meshobject_setgeometry(*pMeshObject, pVertices.data(), + pVertices.size(), &dummy_triangle, 1); + if (hResult != LIB3MF_OK) { + std::cout << "could not set mesh geometry: " + << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage + << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(*pMeshObject); + NMR::lib3mf_release(pModel); + return false; + } + // Set name + hResult = NMR::lib3mf_object_setnameutf8(*pMeshObject, name.c_str()); + if (hResult != LIB3MF_OK) { + std::cout << "could not set object name: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cout << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(*pMeshObject); + NMR::lib3mf_release(pModel); + return -1; + } +} + +template +bool write_point_cloud_to_model(const PointRange& points, + const std::string& name, + NMR::PLib3MFModelMeshObject** pMeshObject, + NMR::PLib3MFModel * pModel + ) +{ + std::string pc_name = name; + pc_name.append("_cgal_pc"); + write_points(points, pc_name, pMeshObject, pModel); +} + +template +bool write_polyline_to_model(const PointRange& points, + const std::string& name, + NMR::PLib3MFModelMeshObject** pMeshObject, + NMR::PLib3MFModel * pModel + ) +{ + std::string pc_name = name; + pc_name.append("_cgal_pl"); + write_points(points, pc_name, pMeshObject, pModel); +} + +/*! + * \brief write_soups_to_3mf will write the polygon soups in all_points and + * all_polygons in `file_name`, in the 3mf format. + * \tparam PointRanges a model of the concepts `RandomAccessContainer` and + * `BackInsertionSequence` whose `value type` is + * a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` + * whose `value type` is the point type. + * \tparam PolygonRanges a model of the concept `RandomAccessContainer` whose + * `value_type` is a model of the concept `RandomAccessContainer` + * whose `value_type` is a model of the concept `RandomAccessContainer` whose + * `value_type` is std::size_t. + * \param file_name the name of the 3mf file to write. + * \param all_points a `PointRanges` that contains the points of the soups + * to write. + * \param all_polygons a `PolygonRanges` that contains the triangles of the + * soups in `file_name`. + * \param names will contains the name of each mesh in `file_name`. + * \return `true` if the writing is successful, `false` otherwise. + */ +template +bool write_soups_to_3mf(const std::string& file_name, + const PointRanges& all_points, + const PolygonRanges& all_polygons, + const std::vector& names) +{ + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + HRESULT hResult; + + // Create Model Instance + NMR::PLib3MFModel * pModel; + hResult = NMR::lib3mf_createmodel(&pModel); + if (hResult != LIB3MF_OK) { + std::cout << "could not create model: " << std::hex << hResult << std::endl; + return false; + } + for(std::size_t id = 0; id < all_points.size(); ++id) + { + NMR::PLib3MFModelMeshObject* pMeshObject; + std::string name; + if(names.size() > id + && ! names[id].empty()) + { + name=names[id]; + } + else + name = std::string(""); + write_mesh_to_model(all_points[id], all_polygons[id], name, &pMeshObject, pModel); + //write_mesh_object_to_model(pModel, pMeshObject); + } + return export_model_to_file(file_name, pModel); +} +}//end CGAL +#endif // WRITE_3MF_H diff --git a/Stream_support/test/Stream_support/CMakeLists.txt b/Stream_support/test/Stream_support/CMakeLists.txt index 5eb7092e2b7..ca3d81698c4 100644 --- a/Stream_support/test/Stream_support/CMakeLists.txt +++ b/Stream_support/test/Stream_support/CMakeLists.txt @@ -7,13 +7,49 @@ project( Stream_support_Tests ) cmake_minimum_required(VERSION 3.1) find_package(CGAL QUIET) - if ( CGAL_FOUND ) - + set(3MF_INCLUDE_DIR "" CACHE PATH "Path to lib3MF headers") + set(3MF_LIBRARY_DIR "" CACHE PATH "Path to lib3MF library files") + if(IS_DIRECTORY "${3MF_INCLUDE_DIR}/Common") + set(3MF_FOUND true) + endif() + # create a target per cppfile file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) foreach(cppfile ${cppfiles}) - create_single_source_cgal_program( "${cppfile}" ) + if ( "${cppfile}" STREQUAL "test_3mf_to_sm.cpp" ) + + if(3MF_FOUND) + if (WIN32) + set(LSUFFIX "dll") + set(LSUFFIXOUT ".dll") + elseif(UNIX AND NOT APPLE) + set(LSUFFIX "so") + set(LSUFFIXOUT ".so.1") + else() + set(LSUFFIX "dylib") + set(LSUFFIXOUT ".1.dylib") + endif() + include_directories(${3MF_INCLUDE_DIR}) + link_directories(${3MF_LIBRARY_DIR}) + create_single_source_cgal_program( "${cppfile}" ) + + if (WIN32) + target_link_libraries(test_3mf_to_sm PRIVATE lib3MF) + else() + # Unix prefixes the name of the library with "lib" anyway + target_link_libraries(test_3mf_to_sm PRIVATE 3MF) + if(APPLE) + target_link_directories(test_3mf_to_sm PRIVATE ${3MF_LIBRARY_DIR}/..) + endif() + endif() + + else() + message(STATUS "NOTICE: This program requires the lib3MF library, and will not be compiled.") + endif() + else() + create_single_source_cgal_program( "${cppfile}" ) + endif() endforeach() else() @@ -22,3 +58,4 @@ else() endif() + diff --git a/Stream_support/test/Stream_support/test_3mf_to_sm.cpp b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp new file mode 100644 index 00000000000..ee86814d079 --- /dev/null +++ b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp @@ -0,0 +1,147 @@ +//needed by functions +#include +#include +#include +#include "Model/COM/NMR_DLLInterfaces.h" +//needed by example +#include +#include +#include +#include +#include +#include +#include +#include +#include +// Use NMR namespace for the interfaces +using namespace NMR; +namespace PMP = CGAL::Polygon_mesh_processing; +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef Kernel::Point_3 Point_3; +typedef CGAL::Surface_mesh Mesh; +typedef std::vector PointRange; +typedef std::vector Polygon; +typedef std::vector PolygonRange; + +int main(int argc, char** argv) +{ +/* if( argc != 2) + { + std::cerr<<"please give an input 3mf file."; + return 1; + } + std::vector all_points; + std::vector all_polygons; + std::vector names; + std::size_t nb_meshes = + CGAL::read_soups_from_3mf(argv[1], all_points, all_polygons, names); + if(nb_meshes <0) + return 1; + for(std::size_t i = 0; i< nb_meshes; ++i) + { + PolygonRange triangles = all_polygons[i]; + PointRange points = all_points[i]; + bool ok = true; + if(!PMP::is_polygon_soup_a_polygon_mesh(triangles)) + ok = PMP::orient_polygon_soup(points, triangles); + if(!ok) + { + std::cerr<<"Object is not orientable. Skipped."<(sphere); + CGAL::make_regular_prism(10, tube, Point_3(0,-10,0), 10); + /* + all_points.clear(); + all_polygons.clear(); + names.clear(); + */ + PointRange points; + //PolygonRange triangles; + typedef boost::property_map::type VPMap; + VPMap vpm = get(boost::vertex_point, sphere); + std::unordered_map::vertex_descriptor, + std::size_t> vertex_id_map; + std::size_t i = 0; + for(auto v : sphere.vertices()) + { + points.push_back(get(vpm, v)); + vertex_id_map[v] = i++; + } + //all_points.push_back(points); + /*for(auto f : sphere.faces()) + { + Polygon triangle; + for(auto vert : CGAL::vertices_around_face(halfedge(f, sphere), sphere)) + { + triangle.push_back(vertex_id_map[vert]); + } + triangles.push_back(triangle); + } + all_polygons.push_back(triangles); + points.clear(); + triangles.clear(); + vertex_id_map.clear(); + i = 0; + + vpm = get(boost::vertex_point, tube); + for(auto v : tube.vertices()) + { + points.push_back(get(vpm, v)); + vertex_id_map[v] = i++; + } + all_points.push_back(points); + for(auto f : tube.faces()) + { + Polygon triangle; + for(auto vert : CGAL::vertices_around_face(halfedge(f, tube), tube)) + { + triangle.push_back(vertex_id_map[vert]); + } + triangles.push_back(triangle); + } + all_polygons.push_back(triangles); + names.push_back(std::string("sphere")); + names.push_back(std::string("tube")); + if(!CGAL::write_soups_to_3mf("micro.3mf", all_points, all_polygons, names)){ + std::cerr<<"an error has occured in final writing."< Date: Fri, 10 May 2019 14:58:27 +0200 Subject: [PATCH 02/31] Add reading functions for polylines and point clouds --- Stream_support/include/CGAL/IO/read_3mf.h | 323 ++++++++++++++---- .../test/Stream_support/CMakeLists.txt | 33 +- .../test/Stream_support/data/test.3mf | Bin 0 -> 2322 bytes .../test/Stream_support/test_3mf_to_sm.cpp | 74 ++-- 4 files changed, 316 insertions(+), 114 deletions(-) create mode 100644 Stream_support/test/Stream_support/data/test.3mf diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h index 5c6cf0798d2..d9e477f2820 100644 --- a/Stream_support/include/CGAL/IO/read_3mf.h +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -1,41 +1,203 @@ +// 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 READ_3MF_H #define READ_3MF_H #include #include #include -#include "Model/COM/NMR_DLLInterfaces.h" +#include +#include +#include namespace CGAL{ -/*! - * \brief read_soups_from_3mf extracts ranges of points and triangles from the - * `MeshObject`s contained in `file_name` - * \tparam PointRanges a model of the concepts `RandomAccessContainer` and - * `BackInsertionSequence` whose `value type` is - * a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` - * whose `value type` is the point type. - * \tparam PolygonRanges a model of the concept `RandomAccessContainer` whose - * `value_type` is a model of the concept `RandomAccessContainer` - * whose `value_type` is a model of the concept `RandomAccessContainer` whose - * `value_type` is std::size_t. - * \param file_name the name of the 3mf file to read. - * \param all_points a `PointRanges` that will contain the points of the meshes - * in `file_name`. - * Each of these meshes will add a range of its points. - * \param all_polygons a `PolygonRanges` that will contain the triangles of the - * meshes in `file_name`. - * 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]. - * \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. - * \return the number of meshes processed in `file_name`. - */ -template -int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, - PolygonRanges& all_polygons, std::vector& names) -{ - typedef typename PointRanges::value_type PointRange; +template +bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, + PointRange& points, + PolygonRange& triangles, + std::string& name) { + typedef typename PointRange::value_type Point_3; + typedef typename PolygonRange::value_type Polygon; + + HRESULT hResult; + DWORD nNeededChars; + std::vector pBuffer; + // Retrieve Mesh Name Length + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars); + if (hResult != LIB3MF_OK) + { + std::cerr<<"Error during name extraction."; + return false; + } + + // Retrieve Mesh Name + if (nNeededChars > 0) { + pBuffer.resize(nNeededChars + 1); + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL); + pBuffer[nNeededChars] = 0; + std::string temp(&pBuffer[0]); + if(temp.find("_cgal_pc") != std::string::npos + || temp.find("_cgal_pl")!= std::string::npos) //ignore point clouds and polylines + { + return false; + } + name = std::string(&pBuffer[0]); + } + else + name = std::string("Unknown Mesh"); + for(DWORD vid = 0; vid < points.size(); ++vid) + { + NMR::MODELMESHVERTEX pVertex; + NMR::lib3mf_meshobject_getvertex(pMeshObject, vid, &pVertex); + points[vid] = + Point_3(pVertex.m_fPosition[0], + pVertex.m_fPosition[1], + pVertex.m_fPosition[2]); + } + for(DWORD pid = 0; pid < triangles.size(); ++pid) + { + NMR::MODELMESHTRIANGLE pTriangle; + NMR::lib3mf_meshobject_gettriangle(pMeshObject, pid, &pTriangle); + Polygon triangle(3); + for(DWORD i = 0; i< 3; ++i) + triangle[i] = pTriangle.m_nIndices[i]; + triangles[pid] = triangle; + } + return true; +} + +template +bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, + PointRange& points, + PolygonRange&, + std::string& name) { + typedef typename PointRange::value_type Point_3; + typedef typename PolygonRange::value_type Polygon; + + HRESULT hResult; + DWORD nNeededChars; + std::vector pBuffer; + // Retrieve Mesh Name Length + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars); + if (hResult != LIB3MF_OK) + { + points.resize(0); + std::cerr<<"Error during name extraction."; + return false; + } + + // Retrieve Mesh Name + if (nNeededChars > 0) { + pBuffer.resize(nNeededChars + 1); + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL); + pBuffer[nNeededChars] = 0; + std::string temp(&pBuffer[0]); + if(temp.find("_cgal_pl")== std::string::npos) //ignore not polylines + { + points.resize(0); + return false; + } + name = std::string(&pBuffer[0]); + } + else + { + points.resize(0); + return false; + } + points.resize(points.size()-3); + for(DWORD vid = 0; vid < points.size()-3; ++vid) //ignore dummy_vertices + { + NMR::MODELMESHVERTEX pVertex; + NMR::lib3mf_meshobject_getvertex(pMeshObject, vid+3, &pVertex); + points[vid] = + Point_3(pVertex.m_fPosition[0], + pVertex.m_fPosition[1], + pVertex.m_fPosition[2]); + } + return true; +} + +template +bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject, + PointRange& points, + PolygonRange&, + std::string& name) { + typedef typename PointRange::value_type Point_3; + typedef typename PolygonRange::value_type Polygon; + + HRESULT hResult; + DWORD nNeededChars; + std::vector pBuffer; + // Retrieve Mesh Name Length + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars); + if (hResult != LIB3MF_OK) + { + std::cerr<<"Error during name extraction."; + points.resize(0); + return false; + } + + // Retrieve Mesh Name + if (nNeededChars > 0) { + pBuffer.resize(nNeededChars + 1); + hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL); + pBuffer[nNeededChars] = 0; + std::string temp(&pBuffer[0]); + if(temp.find("_cgal_pc")== std::string::npos) //ignore not point_cloud + { + points.resize(0); + return false; + } + name = std::string(&pBuffer[0]); + } + else{ + points.resize(0); + return false; + } + points.resize(points.size()-3); + for(DWORD vid = 0; vid < points.size()-3; ++vid) //ignore dummy_vertices + { + NMR::MODELMESHVERTEX pVertex; + NMR::lib3mf_meshobject_getvertex(pMeshObject, vid+3, &pVertex); + points[vid] = + Point_3(pVertex.m_fPosition[0], + pVertex.m_fPosition[1], + pVertex.m_fPosition[2]); + } + //ignore dummy_triangle. + return true; +} + +template +int read_from_3mf(const std::string& file_name, PointRanges& all_points, + PolygonRanges& all_polygons, std::vector& names, + std::function func + ) +{ typedef typename PointRange::value_type Point_3; - typedef typename PolygonRanges::value_type PolygonRange; typedef typename PolygonRange::value_type Polygon; DWORD nInterfaceVersionMajor, nInterfaceVersionMinor, nInterfaceVersionMicro, nbVertices, nbPolygons; HRESULT hResult; @@ -119,7 +281,6 @@ int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, NMR::lib3mf_release(pModel); return -1; } - // Query mesh interface BOOL bIsMeshObject; hResult = NMR::lib3mf_object_ismeshobject(pResource, &bIsMeshObject); @@ -132,42 +293,13 @@ int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, NMR::lib3mf_meshobject_gettrianglecount(pMeshObject, &nbPolygons); PointRange points (nbVertices); PolygonRange triangles(nbPolygons); - DWORD nNeededChars; - std::vector pBuffer; - // Retrieve Mesh Name Length - hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars); - if (hResult != LIB3MF_OK) - return hResult; + std::string name; - // Retrieve Mesh Name - if (nNeededChars > 0) { - pBuffer.resize(nNeededChars + 1); - hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, &pBuffer[0], nNeededChars + 1, NULL); - pBuffer[nNeededChars] = 0; - names.push_back(std::string(&pBuffer[0])); + if(func(pMeshObject, points, triangles, name)){ + all_points.push_back(points); + all_polygons.push_back(triangles); + names.push_back(name); } - else - names.push_back(std::string("Unknown Mesh")); - for(DWORD vid = 0; vid < nbVertices; ++vid) - { - NMR::MODELMESHVERTEX pVertex; - NMR::lib3mf_meshobject_getvertex(pMeshObject, vid, &pVertex); - points[vid] = - Point_3(pVertex.m_fPosition[0], - pVertex.m_fPosition[1], - pVertex.m_fPosition[2]); - } - for(DWORD pid = 0; pid < nbPolygons; ++pid) - { - NMR::MODELMESHTRIANGLE pTriangle; - NMR::lib3mf_meshobject_gettriangle(pMeshObject, pid, &pTriangle); - Polygon triangle(3); - for(DWORD i = 0; i< 3; ++i) - triangle[i] = pTriangle.m_nIndices[i]; - triangles[pid] = triangle; - } - all_points.push_back(points); - all_polygons.push_back(triangles); } // free instances NMR::lib3mf_release(pResource); @@ -180,6 +312,67 @@ int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, return all_points.size(); } +/*! + * \brief read_soups_from_3mf extracts ranges of points and triangles from the + * `MeshObject`s contained in `file_name` + * \tparam PointRanges a model of the concepts `RandomAccessContainer` and + * `BackInsertionSequence` whose `value type` is + * a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` + * whose `value type` is the point type. + * \tparam PolygonRanges a model of the concept `RandomAccessContainer` whose + * `value_type` is a model of the concept `RandomAccessContainer` + * whose `value_type` is a model of the concept `RandomAccessContainer` whose + * `value_type` is std::size_t. + * \param file_name the name of the 3mf file to read. + * \param all_points a `PointRanges` that will contain the points of the meshes + * in `file_name`. + * Each of these meshes will add a range of its points. + * \param all_polygons a `PolygonRanges` that will contain the triangles of the + * meshes in `file_name`. + * 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]. + * \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. + * \return the number of meshes processed in `file_name`. + */ +template +int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, + PolygonRanges& all_polygons, std::vector& names + ) +{ + typedef typename PointRanges::value_type PointRange; + typedef typename PolygonRanges::value_type PolygonRange; + return read_from_3mf + (file_name, all_points, all_polygons, names, extract_soups); +} + + +template +int read_polylines_from_3mf(const std::string& file_name, PointRanges& all_points, + std::vector& names + ) +{ + typedef typename PointRanges::value_type PointRange; + typedef std::vector Polygon; + typedef std::vector PolygonRange; + std::vector all_polygons; + return read_from_3mf, PointRange, PolygonRange> + (file_name, all_points, all_polygons, names, extract_polylines); +} + + +template +int read_point_clouds_from_3mf(const std::string& file_name, PointRanges& all_points, + std::vector& names + ) +{ + typedef typename PointRanges::value_type PointRange; + typedef std::vector Polygon; + typedef std::vector PolygonRange; + std::vector all_polygons; + return read_from_3mf, PointRange, PolygonRange> + (file_name, all_points, all_polygons, names, extract_point_clouds); +} }//end CGAL #endif // READ_3MF_H diff --git a/Stream_support/test/Stream_support/CMakeLists.txt b/Stream_support/test/Stream_support/CMakeLists.txt index ca3d81698c4..f9905b79012 100644 --- a/Stream_support/test/Stream_support/CMakeLists.txt +++ b/Stream_support/test/Stream_support/CMakeLists.txt @@ -8,42 +8,23 @@ cmake_minimum_required(VERSION 3.1) find_package(CGAL QUIET) if ( CGAL_FOUND ) - set(3MF_INCLUDE_DIR "" CACHE PATH "Path to lib3MF headers") - set(3MF_LIBRARY_DIR "" CACHE PATH "Path to lib3MF library files") + find_path(3MF_INCLUDE_DIR + NAMES Common Model + DOC "Path to lib3MF headers" + ) if(IS_DIRECTORY "${3MF_INCLUDE_DIR}/Common") set(3MF_FOUND true) endif() - + find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library") + # create a target per cppfile file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) foreach(cppfile ${cppfiles}) if ( "${cppfile}" STREQUAL "test_3mf_to_sm.cpp" ) - if(3MF_FOUND) - if (WIN32) - set(LSUFFIX "dll") - set(LSUFFIXOUT ".dll") - elseif(UNIX AND NOT APPLE) - set(LSUFFIX "so") - set(LSUFFIXOUT ".so.1") - else() - set(LSUFFIX "dylib") - set(LSUFFIXOUT ".1.dylib") - endif() include_directories(${3MF_INCLUDE_DIR}) - link_directories(${3MF_LIBRARY_DIR}) create_single_source_cgal_program( "${cppfile}" ) - - if (WIN32) - target_link_libraries(test_3mf_to_sm PRIVATE lib3MF) - else() - # Unix prefixes the name of the library with "lib" anyway - target_link_libraries(test_3mf_to_sm PRIVATE 3MF) - if(APPLE) - target_link_directories(test_3mf_to_sm PRIVATE ${3MF_LIBRARY_DIR}/..) - endif() - endif() - + target_link_libraries(test_3mf_to_sm PRIVATE ${3MF_LIBRARIES}) else() message(STATUS "NOTICE: This program requires the lib3MF library, and will not be compiled.") endif() diff --git a/Stream_support/test/Stream_support/data/test.3mf b/Stream_support/test/Stream_support/data/test.3mf new file mode 100644 index 0000000000000000000000000000000000000000..223e1185b3ef069cda761b2bff1415d1f16b3fd6 GIT binary patch literal 2322 zcmZ`*2{@E%8~$djSqEcKno^SxW5QulNXFJ!rYtA>lCcy#F|$yRP?rp6^}m>wWL%x$fu1Vfpwq000nPZvY@j z3RC>D^+5nAppDVg_6Z{R-~*9gdk_Et-Yb4x3YZ9N+65=h`4Tk5ZNGvwM+BR-M3!Qn`!)Sc>QO|AHy9U&QVGKwfk>XfSy0L3A93TDGCG;^RMR&ZK z)zba35S?R`%&XO~4E%C2%6bmlctG^w>?{8m*24QKwDns1JacrAwi*$D#Mf{%tDeh- zU#iOrn3y0?+3lKoi>NHYWKQ5b(Xh(A#?WDq@k*n9l)i*3^iRrbU-1|>;&$av_!rq2 zkExa_+vQXy%$peuj}`tttAR1`7ZFOSNV=_+JLK?`Mf>CVuJF|;8tchJ21#1j+o!&^ z4xu;Uy7-8q_vTHyYejwJgfk6n)5GEhbfrXuetw}B?6UCSz>)A-KbPU=m6g00#Rbni za_4oCCapPXqq`aRjMLK6wP1_bn|*zzhp9EMy8M=hvEYFCK>a%(qzsn`^DF)`7L>(S z7SRhv)`>8fWUU=~nu@d0)D#VD=@xJ3*A-O;PpN!BDu8GA9~P0QZD6y-jP!ON^7Zv{ z^L!^qkBym1_p$XdRzgXgoZ7c^1!gZTsVwc6>tZQdb$N|ma3MV9%+NCT*8N^D%}cIC@5D9FiXOrpTX zSQ@U4|JE5*vHjQW0ou#h{8r(;at#5NiEI-j(4P+ZNOA>q(<~@TV=Ff)Xp>4C3K5}B zL0-*J$^1t%~{dz5WOm%@L8o=njAU8x^`SD66$8jjfAUXtfjqGD;&3#K=Tx< z?WH7@f4%!SBE7^(>{%YvEajBGHg7SB)8xJVZ0ktRvqpWE)8`ND#gtITDdu<%GS-=c z&N-^o)QdV&OoI~l@KxQMmC2r)9RSm-j^w4-2e&p0&%v};`3*3&7N%zv_V1m7B%`a{ zx@9-EdS~oWlx-?dz9LE;syKy$B#Y1(D_TgJ!Ak+$S*QDZgw4sH_MHX|I6uLV<*!v8 z&3n+Ss|8fuBp*u~5rYpN^hpFb-Fns_Xm$|w932!?x*M=Mz3(VgTt@@}E4ZDcqLx-6 zxIN*;kfSKL=!I?%IwOwdigCL7*Sb3p$8v`NhS&aC_o4ADPYAHxl(@rRQO(%ppfHfM zhaj#ap-`rwz#nVYJF^aW&%SglE4WSOV`gXf>fTbKd+2yc_U;QNb5Ho)TS8{!A~8Ij zSyGdPd&Y^*KW+s%)yKv4{w_cvo{cI#UAJIGkY%d*l@x%8!9Xst9=QE!G^{y$MhpHJ zT3rq*6R|QcXuziFF{$YnQRU}o%@rhlxboo0(?@dqna^IEsUNTG%TN{{N2RRBXB-hv ztnXe%NEjUNptmh)SvfiReyQ)HcpJdwNw(*hl}U93p&eyD1q~fJUPSAI8L3Fm0@B;s zlC0QCk-Dj_-xde&T*vm*r-T020}ScLqE22oPjr-F6_qTjr>w%-x1G8E5g?_9>O280gvLI3w3k;!p>uYV)hFw-X(K7t|ovWCFBqNUz| znS(qv|E01h+#`JCga4R=?@?e9qdvb5YKL8_K)Cz52X+uZmsE3E{idZi3tUuK{N`8SD)H7r zb#;%T-?p_4Ms0tRx)x!E3WcD14sm0qr*$%&V=Qh&gTLp?u&dDK8(*U9e0iM52Zm}Q zH~I~pgh87GRc!HuPw5hALP1E~Jk_R&1r`j$X3A;07ivQK79@3z5R5;^YU1Nto^v~i zos`=N*)2K8D3naxD*@q(r{OntBGeg^a4Ms+Khrl8E#2B~-e{zIT;A@TIh$^-rS^(@ z15dlqNN4-W_Z*0}I~MFsF9^7pCtBl7=DMERc*k-YUV_!0d3IQ PolygonRange; int main(int argc, char** argv) { -/* if( argc != 2) + if( argc != 2) { std::cerr<<"please give an input 3mf file."; return 1; @@ -34,7 +34,8 @@ int main(int argc, char** argv) std::vector all_points; std::vector all_polygons; std::vector names; - std::size_t nb_meshes = + //testing reading functions. + int nb_meshes = CGAL::read_soups_from_3mf(argv[1], all_points, all_polygons, names); if(nb_meshes <0) return 1; @@ -61,17 +62,44 @@ int main(int argc, char** argv) ofs << mesh; ofs.close(); } - }*/ + } + all_points.clear(); + int nb_polylines = + CGAL::read_polylines_from_3mf(argv[1], all_points, names); + + if(nb_polylines == 0) + std::cout<<"No polyline found."<(sphere); CGAL::make_regular_prism(10, tube, Point_3(0,-10,0), 10); - /* all_points.clear(); all_polygons.clear(); names.clear(); - */ PointRange points; - //PolygonRange triangles; + PolygonRange triangles; typedef boost::property_map::type VPMap; VPMap vpm = get(boost::vertex_point, sphere); std::unordered_map::vertex_descriptor, @@ -82,8 +110,8 @@ int main(int argc, char** argv) points.push_back(get(vpm, v)); vertex_id_map[v] = i++; } - //all_points.push_back(points); - /*for(auto f : sphere.faces()) + all_points.push_back(points); + for(auto f : sphere.faces()) { Polygon triangle; for(auto vert : CGAL::vertices_around_face(halfedge(f, sphere), sphere)) @@ -117,30 +145,30 @@ int main(int argc, char** argv) all_polygons.push_back(triangles); names.push_back(std::string("sphere")); names.push_back(std::string("tube")); - if(!CGAL::write_soups_to_3mf("micro.3mf", all_points, all_polygons, names)){ - std::cerr<<"an error has occured in final writing."< Date: Mon, 13 May 2019 16:11:15 +0200 Subject: [PATCH 03/31] Replace IO API to be able to load/save several items at a time --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 173 ++++++++++-------- Polyhedron/demo/Polyhedron/MainWindow.h | 9 +- .../Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp | 33 ++-- .../Polyhedron/Plugins/IO/LAS_io_plugin.cpp | 29 +-- .../Polyhedron/Plugins/IO/Nef_io_plugin.cpp | 38 ++-- .../Polyhedron/Plugins/IO/OFF_io_plugin.cpp | 76 ++++++-- .../Plugins/IO/OFF_to_nef_io_plugin.cpp | 28 ++- .../Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 79 ++++++-- .../Plugins/IO/Polylines_io_plugin.cpp | 53 ++++-- .../Polyhedron/Plugins/IO/STL_io_plugin.cpp | 40 ++-- .../Polyhedron/Plugins/IO/Surf_io_plugin.cpp | 25 ++- .../Polyhedron/Plugins/IO/XYZ_io_plugin.cpp | 38 ++-- .../Polyhedron/Plugins/IO/lcc_io_plugin.cpp | 17 +- .../Plugins/Mesh_3/C3t3_io_plugin.cpp | 131 +++++++------ .../Plugins/Mesh_3/Io_image_plugin.cpp | 30 ++- .../Plugins/PMP/Selection_plugin.cpp | 26 ++- .../Polyhedron_demo_io_plugin_interface.h | 16 +- .../CGAL/Three/Scene_3mf_item_interface.h | 4 + 18 files changed, 565 insertions(+), 280 deletions(-) create mode 100644 Three/include/CGAL/Three/Scene_3mf_item_interface.h diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 7f7978a5e8f..d9b85c33c55 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -41,7 +41,7 @@ #include #include #include - +#include #ifdef QT_SCRIPT_LIB # include # ifdef QT_SCRIPTTOOLS_LIB @@ -998,20 +998,33 @@ void MainWindow::reloadItem() { CGAL::Three::Polyhedron_demo_io_plugin_interface* fileloader = findLoader(loader_name); QFileInfo fileinfo(filename); - - CGAL::Three::Scene_item* new_item = loadItem(fileinfo, fileloader); - if(!new_item) + bool ok; + QList new_items = loadItem(fileinfo, fileloader, ok, false); + if(!ok) return; - new_item->setName(item->name()); - new_item->setColor(item->color()); - new_item->setRenderingMode(item->renderingMode()); - new_item->setVisible(item->visible()); - Scene_item_with_properties *property_item = dynamic_cast(new_item); - scene->replaceItem(scene->item_id(item), new_item, true); - if(property_item) - property_item->copyProperties(item); - new_item->invalidateOpenGLBuffers(); - item->deleteLater(); + QVariant varian = item->property("load_mates"); + if (!varian.canConvert()) + qDebug()<<"Well, that's gonna be a problem !"; + QSequentialIterable iterable = varian.value(); + // Can use foreach: + int mate_id = 0; + Q_FOREACH(const QVariant &v, iterable) + { + Scene_item* mate = v.value(); + Scene_item* new_item = new_items[mate_id]; + if(!new_item) + qDebug()<<"That too, is gonna be a problem..."; + new_item->setName(mate->name()); + new_item->setColor(mate->color()); + new_item->setRenderingMode(mate->renderingMode()); + new_item->setVisible(mate->visible()); + Scene_item_with_properties *property_item = dynamic_cast(new_item); + scene->replaceItem(scene->item_id(mate), new_item, true); + if(property_item) + property_item->copyProperties(mate); + new_item->invalidateOpenGLBuffers(); + mate->deleteLater(); + } } } @@ -1105,7 +1118,7 @@ void MainWindow::open(QString filename) // collect all io_plugins and offer them to load if the file extension match one name filter // also collect all available plugin in case of a no extension match Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* io_plugin, io_plugins) { - if ( !io_plugin->canLoad() ) continue; + if ( !io_plugin->canLoad(fileinfo) ) continue; all_items << io_plugin->name(); if ( file_matches_filter(io_plugin->loadNameFilters(), filename.toLower()) ) { @@ -1148,71 +1161,70 @@ void MainWindow::open(QString filename) settings.setValue("OFF open directory", fileinfo.absoluteDir().absolutePath()); - CGAL::Three::Scene_item* scene_item = loadItem(fileinfo, findLoader(load_pair.first)); + loadItem(fileinfo, findLoader(load_pair.first), ok); - if(!scene_item) + if(!ok) return; this->addToRecentFiles(fileinfo.absoluteFilePath()); - selectSceneItem(scene->addItem(scene_item)); - - CGAL::Three::Scene_group_item* group = - qobject_cast(scene_item); - if(group) - scene->redraw_model(); updateViewersBboxes(true); } bool MainWindow::open(QString filename, QString loader_name) { QFileInfo fileinfo(filename); - boost::optional item_opt; + boost::optional item_opt; CGAL::Three::Scene_item* item = 0; try { item_opt = wrap_a_call_to_cpp ([this, fileinfo, loader_name]() { - return loadItem(fileinfo, findLoader(loader_name)); + bool ok; + loadItem(fileinfo, findLoader(loader_name), ok); + return ok; }, this, __FILE__, __LINE__ ); if(!item_opt) return false; - else item = *item_opt; + //else item = *item_opt; } catch(std::logic_error& e) { std::cerr << e.what() << std::endl; return false; } - selectSceneItem(scene->addItem(item)); - - CGAL::Three::Scene_group_item* group = - qobject_cast(item); - if(group) - scene->redraw_model(); - return true; } -CGAL::Three::Scene_item* MainWindow::loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface* loader) { - CGAL::Three::Scene_item* item = NULL; +QList MainWindow::loadItem(QFileInfo fileinfo, + CGAL::Three::Polyhedron_demo_io_plugin_interface* loader, + bool &ok, + bool add_to_scene) { if(!fileinfo.isFile() || !fileinfo.isReadable()) { QMessageBox::warning(this, tr("Error"), QString("File %1 is not a readable file.") .arg(fileinfo.absoluteFilePath())); } - QApplication::setOverrideCursor(Qt::WaitCursor); - - item = loader->load(fileinfo); - QApplication::restoreOverrideCursor(); - if(!item) { + CGAL::Three::Three::CursorScopeGuard guard(QCursor(Qt::WaitCursor)); + QList result = loader->load(fileinfo, ok, add_to_scene); + selectSceneItem(scene->item_id(result.back())); + if(!ok) + { + QApplication::restoreOverrideCursor(); QMessageBox::warning(this, tr("Error"), QString("Could not load item from file %1 using plugin %2") .arg(fileinfo.absoluteFilePath()).arg(loader->name())); - return 0; + return QList(); } - - item->setProperty("source filename", fileinfo.absoluteFilePath()); - item->setProperty("loader_name", loader->name()); - return item; + for(Scene_item* item : result) + { + CGAL::Three::Scene_group_item* group = + qobject_cast(item); + if(group) + scene->redraw_model(); + item->setProperty("source filename", fileinfo.absoluteFilePath()); + item->setProperty("loader_name", loader->name()); + item->setProperty("load_mates",QVariant::fromValue(result)); + } + return result; } @@ -1831,7 +1843,7 @@ void MainWindow::on_actionLoad_triggered() typedef QMap FilterPluginMap; FilterPluginMap filterPluginMap; - Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin, io_plugins) { + for(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin : io_plugins) { QStringList split_filters = plugin->loadNameFilters().split(";;"); Q_FOREACH(const QString& filter, split_filters) { FilterPluginMap::iterator it = filterPluginMap.find(filter); @@ -1877,18 +1889,25 @@ void MainWindow::on_actionLoad_triggered() std::size_t nb_item = -1; Q_FOREACH(const QString& filename, dialog.selectedFiles()) { - + CGAL::Three::Scene_item* item = NULL; if(selectedPlugin) { QFileInfo info(filename); - item = loadItem(info, selectedPlugin); - item->setColor(colors_[++nb_item]); - Scene::Item_id index = scene->addItem(item); - selectSceneItem(index); - CGAL::Three::Scene_group_item* group = - qobject_cast(item); - if(group) - scene->redraw_model(); + bool ok; + QList result = loadItem(info, selectedPlugin, ok); + if(!ok) + continue; + for(Scene_item* item : result) + { + ++nb_item; + item->setColor(colors_[nb_item]); + Scene::Item_id index = scene->addItem(item); + selectSceneItem(index); + CGAL::Three::Scene_group_item* group = + qobject_cast(item); + if(group) + scene->redraw_model(); + } this->addToRecentFiles(filename); } else { int scene_size = scene->numberOfEntries(); @@ -1901,15 +1920,19 @@ void MainWindow::on_actionLoad_triggered() void MainWindow::on_actionSaveAs_triggered() { - Scene_item* item = NULL; - - Q_FOREACH(Scene::Item_id id, scene->selectionIndices()) + QList to_save; + for(Scene::Item_id id : scene->selectionIndices()) { - item = scene->item(id); + Scene_item* item = scene->item(id); + to_save.append(item); + } + while(!to_save.empty()) + { + Scene_item* item = to_save.front(); QVector canSavePlugins; QStringList filters; QString sf; - Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin, io_plugins) { + for(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin : io_plugins) { if(plugin->canSave(item)) { canSavePlugins << plugin; filters += plugin->saveNameFilters(); @@ -1925,7 +1948,7 @@ void MainWindow::on_actionSaveAs_triggered() tr("Cannot save"), tr("The selected object %1 cannot be saved.") .arg(item->name())); - return; + return; } Q_FOREACH(QString string, filters) { @@ -1961,14 +1984,14 @@ void MainWindow::on_actionSaveAs_triggered() dir, filters.join(";;"), &sf); - + if(filename.isEmpty()) return; last_saved_dir = QFileInfo(filename).absoluteDir().path(); extensions.indexIn(sf.split(";;").first()); QString filter_ext, filename_ext; filter_ext = extensions.cap().split(" ").first();// in case of syntax like (*.a *.b) - + filter_ext.remove(")"); filter_ext.remove("("); //remove * @@ -2016,18 +2039,18 @@ void MainWindow::on_actionSaveAs_triggered() } for(auto v : CGAL::QGLViewer::QGLViewerPool()) v->update(); - save(filename, item); + save(filename, to_save); } } -void MainWindow::save(QString filename, CGAL::Three::Scene_item* item) { +void MainWindow::save(QString filename, QList& to_save) { QFileInfo fileinfo(filename); bool saved = false; - Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin, io_plugins) { - if( plugin->canSave(item) && + for(CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin : io_plugins) { + if( plugin->canSave(to_save.front()) && file_matches_filter(plugin->saveNameFilters(),filename.toLower()) ) { - if(plugin->save(item, fileinfo)) + if(plugin->save(fileinfo, to_save)) { saved = true; break; @@ -2038,7 +2061,7 @@ void MainWindow::save(QString filename, CGAL::Three::Scene_item* item) { QMessageBox::warning(this, tr("Cannot save"), tr("The selected object %1 was not saved. (Maybe a wrong extension ?)") - .arg(item->name())); + .arg(to_save.front()->name())); } void MainWindow::on_actionSaveSnapshot_triggered() @@ -2470,7 +2493,7 @@ QString MainWindow::get_item_stats() for(int i=0; iitem(id); - QString classname = item->property("classname").toString(); + QString classname = item->property("classname").toString(); if(classname.isEmpty()) classname = item->metaObject()->className(); if(classnames.at(i).contains(classname)) @@ -3131,14 +3154,16 @@ void MainWindow::on_action_Save_triggered() if(QMessageBox::question(this, "Save", "Are you sure you want to override these files ?") == QMessageBox::No) return; - Scene_item* item = nullptr; - Q_FOREACH(Scene::Item_id id, scene->selectionIndices()) + QList to_save; + + for(Scene::Item_id id : scene->selectionIndices()) { - item = scene->item(id); + Scene_item* item = scene->item(id); if(!item->property("source filename").toString().isEmpty()) { QString filename = item->property("source filename").toString(); - save(filename, item); + to_save.append(item); + save(filename, to_save); } } } diff --git a/Polyhedron/demo/Polyhedron/MainWindow.h b/Polyhedron/demo/Polyhedron/MainWindow.h index bae08376816..28a09278abd 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.h +++ b/Polyhedron/demo/Polyhedron/MainWindow.h @@ -87,11 +87,14 @@ public: @returns the IO plugin associated with `loader_name`*/ CGAL::Three::Polyhedron_demo_io_plugin_interface* findLoader(const QString& loader_name) const; - /*! \brief Loads an item with a given loader. + /*! \brief Loads on or more item with a given loader. * * throws `std::logic_error` if loading does not succeed or * `std::invalid_argument` if `fileinfo` specifies an invalid file*/ - CGAL::Three::Scene_item* loadItem(QFileInfo fileinfo, CGAL::Three::Polyhedron_demo_io_plugin_interface*); + QList loadItem(QFileInfo fileinfo, + CGAL::Three::Polyhedron_demo_io_plugin_interface*, + bool& ok, + bool add_to_scene=true); void computeViewerBBox(CGAL::qglviewer::Vec &min, CGAL::qglviewer::Vec &max); void updateViewerBbox(Viewer* vi, bool recenter, CGAL::qglviewer::Vec min, CGAL::qglviewer::Vec max); @@ -346,7 +349,7 @@ protected Q_SLOTS: //!Opens a dialog to save selected item if able. void on_actionSaveAs_triggered(); //!Calls the function save of the current plugin if able. - void save(QString filename, CGAL::Three::Scene_item* item); + void save(QString filename, QList& to_save); //!Calls the function saveSnapShot of the viewer. void on_actionSaveSnapshot_triggered(); //!Opens a Dialog to choose a color and make it the background color. diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp index caae0705b5c..1709c1dfa60 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp @@ -40,30 +40,31 @@ public: bool applicable(QAction*) const { return false;} QString nameFilters() const; QString name() const { return "gocad_plugin"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo, QList& ); }; QString Polyhedron_demo_gocad_plugin::nameFilters() const { return "GOCAD files (*.ts)"; } -bool Polyhedron_demo_gocad_plugin::canLoad() const { +bool Polyhedron_demo_gocad_plugin::canLoad(QFileInfo) const { return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) { +QList +Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { // Open file std::ifstream in(fileinfo.filePath().toUtf8()); if(!in) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; - return NULL; + ok = false; + return QList(); } @@ -74,7 +75,10 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) { if(fileinfo.size() == 0) { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(item->polyhedron()); @@ -82,7 +86,8 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) { if(! read_gocad(P, in, name, color)){ std::cerr << "Error: Invalid polyhedron" << std::endl; delete item; - return 0; + ok = false; + return QList(); } t.stop(); @@ -98,7 +103,10 @@ Polyhedron_demo_gocad_plugin::load(QFileInfo fileinfo) { item->setColor(qcolor); } item->invalidateOpenGLBuffers(); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(item); } -bool Polyhedron_demo_gocad_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +bool Polyhedron_demo_gocad_plugin:: +save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); // This plugin supports polyhedrons const Scene_surface_mesh_item* sm_item = qobject_cast(item); @@ -120,6 +130,7 @@ bool Polyhedron_demo_gocad_plugin::save(const CGAL::Three::Scene_item* item, QFi out.precision (std::numeric_limits::digits10 + 2); SMesh* poly = const_cast(sm_item->polyhedron()); write_gocad(*poly, out, qPrintable(fileinfo.baseName())); + items.pop_front(); return true; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp index 37878451544..176824c2e16 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp @@ -1,8 +1,9 @@ #include "Scene_points_with_normal_item.h" #include - +#include +#include #include - +using namespace CGAL::Three; class Polyhedron_demo_las_plugin : public QObject, public CGAL::Three::Polyhedron_demo_io_plugin_interface @@ -14,19 +15,19 @@ class Polyhedron_demo_las_plugin : public: QString name() const { return "las_plugin"; } QString nameFilters() const { return "LAS files (*.las);;Compressed LAS files (*.laz)"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo fileinfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList& ); }; -bool Polyhedron_demo_las_plugin::canLoad() const { +bool Polyhedron_demo_las_plugin::canLoad(QFileInfo fileinfo) const { return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_las_plugin::load(QFileInfo fileinfo) { +QList Polyhedron_demo_las_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary); if(!in) @@ -37,11 +38,15 @@ Polyhedron_demo_las_plugin::load(QFileInfo fileinfo) { if(!item->read_las_point_set(in)) { delete item; - return 0; + ok = false; + return QList(); } item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(item); } -bool Polyhedron_demo_las_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +bool Polyhedron_demo_las_plugin::save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); // Check extension (quietly) std::string extension = fileinfo.suffix().toUtf8().data(); if (extension != "las" && extension != "LAS") @@ -63,6 +69,7 @@ bool Polyhedron_demo_las_plugin::save(const CGAL::Three::Scene_item* item, QFile return false; std::ofstream out(fileinfo.filePath().toUtf8().data()); + items.pop_front(); return point_set_item->write_las_point_set(out); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp index 11265427374..4aab33b4e0a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Nef_io_plugin.cpp @@ -17,32 +17,37 @@ class Polyhedron_demo_io_nef_plugin : public: QString nameFilters() const; QString name() const { return "io_nef_plugin"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList& items); }; QString Polyhedron_demo_io_nef_plugin::nameFilters() const { return "nef files (*.nef3)"; } -bool Polyhedron_demo_io_nef_plugin::canLoad() const { +bool Polyhedron_demo_io_nef_plugin::canLoad(QFileInfo) const { return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_io_nef_plugin::load(QFileInfo fileinfo) { +QList Polyhedron_demo_io_nef_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { //do not try file with extension different from nef3 - if (fileinfo.suffix() != "nef3") return 0; + if (fileinfo.suffix() != "nef3") + { + ok = false; + return QList(); + } // Open file std::ifstream in(fileinfo.filePath().toUtf8()); if(!in) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; - return NULL; + ok = false; + return QList(); } // Try to read .nef3 in a polyhedron @@ -51,15 +56,22 @@ Polyhedron_demo_io_nef_plugin::load(QFileInfo fileinfo) { if(fileinfo.size() == 0) { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<load(in)) { delete item; - return 0; + ok = false; + return QList(); } - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(item); } -bool Polyhedron_demo_io_nef_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +bool Polyhedron_demo_io_nef_plugin::save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); // This plugin supports polyhedrons and polygon soups const Scene_nef_polyhedron_item* nef_item = qobject_cast(item); @@ -79,6 +92,7 @@ bool Polyhedron_demo_io_nef_plugin::save(const CGAL::Three::Scene_item* item, QF std::ofstream out(fileinfo.filePath().toUtf8()); out.precision (std::numeric_limits::digits10 + 2); + items.pop_front(); return (nef_item && nef_item->save(out)); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp index ba869f77b9d..58edff9b8e3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp @@ -40,22 +40,21 @@ public: } QString name() const { return "off_plugin"; } QString nameFilters() const { return "OFF files (*.off);;Wavefront OBJ (*.obj)"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); - CGAL::Three::Scene_item* load_off(QFileInfo fileinfo); - CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo); + bool canLoad(QFileInfo fileinfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); + CGAL::Three::Scene_item* load_off(QFileInfo fileinfo); + CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList& ); }; -bool Polyhedron_demo_off_plugin::canLoad() const { +bool Polyhedron_demo_off_plugin::canLoad(QFileInfo) const { return true; } - -CGAL::Three::Scene_item* -Polyhedron_demo_off_plugin::load(QFileInfo fileinfo) { +QList Polyhedron_demo_off_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { if(fileinfo.size() == 0) { @@ -63,14 +62,41 @@ Polyhedron_demo_off_plugin::load(QFileInfo fileinfo) { Scene_surface_mesh_item* item = new Scene_surface_mesh_item(SMesh()); item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<addItem(item); + return QList()<(); + } } else if(fileinfo.suffix().toLower() == "obj"){ - return load_obj(fileinfo); + + Scene_item* item = load_obj(fileinfo); + if(item) + { + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(); + } } - return 0; + return QList(); } @@ -183,8 +209,12 @@ bool Polyhedron_demo_off_plugin::canSave(const CGAL::Three::Scene_item* item) qobject_cast(item); } -bool Polyhedron_demo_off_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) + +bool +Polyhedron_demo_off_plugin:: +save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); // This plugin supports point sets, surface_meshes and polygon soups const Scene_points_with_normal_item* points_item = qobject_cast(item); @@ -200,12 +230,26 @@ bool Polyhedron_demo_off_plugin::save(const CGAL::Three::Scene_item* item, QFile out.precision (std::numeric_limits::digits10 + 2); if(fileinfo.suffix().toLower() == "off"){ - return (sm_item && sm_item->save(out)) || + bool res = (sm_item && sm_item->save(out)) || (soup_item && soup_item->save(out)) || (points_item && points_item->write_off_point_set(out)); + if(res){ + items.pop_front(); + return true; + } + else{ + return false; + } } if(fileinfo.suffix().toLower() == "obj"){ - return (sm_item && sm_item->save_obj(out)); + bool res = (sm_item && sm_item->save_obj(out)); + if(res) + { + items.pop_front(); + return true; + } + else + return false; } return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp index 5d142129b4c..dd765722381 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp @@ -16,19 +16,19 @@ class Polyhedron_demo_off_to_nef_plugin : public: QString name() const { return "off_to_nef_plugin"; } QString nameFilters() const { return "OFF files, into nef (*.off)"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList& ); }; -bool Polyhedron_demo_off_to_nef_plugin::canLoad() const { +bool Polyhedron_demo_off_to_nef_plugin::canLoad(QFileInfo) const { return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_off_to_nef_plugin::load(QFileInfo fileinfo) { +QList Polyhedron_demo_off_to_nef_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene){ std::ifstream in(fileinfo.filePath().toUtf8()); if(!in) @@ -38,16 +38,23 @@ Polyhedron_demo_off_to_nef_plugin::load(QFileInfo fileinfo) { { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<load_from_off(in)) { delete item; - return 0; + ok = false; + return QList()<setName(fileinfo.baseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<& items) { return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index cc2c1bcd865..d72084a7e0b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -13,7 +13,7 @@ #include #include #include - +using namespace CGAL::Three; class Polyhedron_demo_ply_plugin : public QObject, public CGAL::Three::Polyhedron_demo_io_plugin_interface @@ -31,20 +31,22 @@ public: } QString name() const { return "ply_plugin"; } QString nameFilters() const { return "PLY files (*.ply)"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo fileinfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList&); }; -bool Polyhedron_demo_ply_plugin::canLoad() const { +bool Polyhedron_demo_ply_plugin:: +canLoad(QFileInfo) const { return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { +QList +Polyhedron_demo_ply_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::binary); if(!in) @@ -55,7 +57,8 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { if(fileinfo.size() == 0) { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); - return 0; + ok = false; + return QList(); } // Test if input is mesh or point set @@ -99,7 +102,10 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) { sm_item->setName(fileinfo.completeBaseName()); sm_item->comments() = comments; QApplication::restoreOverrideCursor(); - return sm_item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(sm_item); + return QList()<(); } 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; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(soup_item); + return QList()<(); } if(item->has_normals()) item->setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode()); item->setName(fileinfo.completeBaseName()); QApplication::restoreOverrideCursor(); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(); } bool Polyhedron_demo_ply_plugin::canSave(const CGAL::Three::Scene_item* item) @@ -152,8 +167,10 @@ bool Polyhedron_demo_ply_plugin::canSave(const CGAL::Three::Scene_item* item) || qobject_cast(item)); } -bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +bool Polyhedron_demo_ply_plugin:: +save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); // Check extension (quietly) std::string extension = fileinfo.suffix().toUtf8().data(); if (extension != "ply" && extension != "PLY") @@ -179,25 +196,49 @@ bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFile const Scene_points_with_normal_item* point_set_item = qobject_cast(item); if (point_set_item) - return point_set_item->write_ply_point_set(out, (choice == tr("Binary"))); + { + bool res = + point_set_item->write_ply_point_set(out, (choice == tr("Binary"))); + if(res) + items.pop_front(); + return res; + } // This plugin supports polygon soups const Scene_polygon_soup_item* soup_item = qobject_cast(item); if (soup_item) - return CGAL::write_PLY (out, soup_item->points(), soup_item->polygons()); + { + bool res = + CGAL::write_PLY (out, soup_item->points(), soup_item->polygons()); + if(res) + items.pop_front(); + return res; + } // This plugin supports surface meshes const Scene_surface_mesh_item* sm_item = qobject_cast(item); if (sm_item) - return CGAL::write_ply (out, *(sm_item->polyhedron()), sm_item->comments()); + { + bool res = + CGAL::write_ply (out, *(sm_item->polyhedron()), sm_item->comments()); + if(res) + items.pop_front(); + return res; + } // This plugin supports textured surface meshes const Scene_textured_surface_mesh_item* stm_item = qobject_cast(item); if (stm_item) - return CGAL::write_ply (out, *(stm_item->textured_face_graph())); + { + bool res = + CGAL::write_ply (out, *(stm_item->textured_face_graph())); + if(res) + items.pop_front(); + return res; + } return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index 769c0a0587e..222f7362d2f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -45,11 +45,11 @@ public: } QString name() const { return "polylines_io_plugin"; } QString nameFilters() const { return "Polylines files (*.polylines.txt *.cgal)"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo fileinfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList&); bool applicable(QAction* a) const { bool all_polylines_selected = true; Q_FOREACH(int index, scene->selectionIndices()) @@ -85,19 +85,21 @@ private: QAction* actionJoin_polylines; }; -bool Polyhedron_demo_polylines_io_plugin::canLoad() const { +bool Polyhedron_demo_polylines_io_plugin::canLoad(QFileInfo fileinfo) const{ return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) { +QList +Polyhedron_demo_polylines_io_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene){ // Open file std::ifstream ifs(fileinfo.filePath().toUtf8()); if(!ifs) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; - return NULL; + ok = false; + return QList(); } if(fileinfo.size() == 0) @@ -105,7 +107,10 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); Scene_polylines_item* item = new Scene_polylines_item; item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()< > polylines; @@ -123,7 +128,11 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) { Scene_polylines_item::Point_3 p; ifs >> p; polyline.push_back(p); - if(!ifs.good()) return 0; + if(!ifs.good()) + { + ok = false; + return QList(); + } } std::string line_remainder; std::getline(ifs, line_remainder); @@ -136,9 +145,17 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) { std::cerr << " (metadata: \"" << qPrintable(metadata) << "\")\n"; } else { } - if(ifs.bad() || ifs.fail()) return 0; + if(ifs.bad() || ifs.fail()) + { + ok = false; + return QList(); + } + } + if(counter == 0) + { + ok = false; + return QList(); } - if(counter == 0) return 0; Scene_polylines_item* item = new Scene_polylines_item; item->polylines = polylines; item->setName(fileinfo.baseName()); @@ -146,7 +163,10 @@ Polyhedron_demo_polylines_io_plugin::load(QFileInfo fileinfo) { item->setProperty("polylines metadata", polylines_metadata); std::cerr << "Number of polylines in item: " << item->polylines.size() << std::endl; item->invalidateOpenGLBuffers(); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(item) != 0; } -bool Polyhedron_demo_polylines_io_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +bool Polyhedron_demo_polylines_io_plugin:: +save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); const Scene_polylines_item* poly_item = qobject_cast(item); @@ -188,7 +210,10 @@ bool Polyhedron_demo_polylines_io_plugin::save(const CGAL::Three::Scene_item* it } out << std::endl; } - return (bool) out; + bool res = (bool) out; + if(res) + items.pop_front(); + return res; } void Polyhedron_demo_polylines_io_plugin::split() diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp index 523698a72f7..475fc302197 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp @@ -47,44 +47,51 @@ public: bool applicable(QAction*) const { return false;} QString nameFilters() const; QString name() const { return "stl_plugin"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo fileinfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList&); }; QString Polyhedron_demo_stl_plugin::nameFilters() const { return "STL files (*.stl)"; } -bool Polyhedron_demo_stl_plugin::canLoad() const { +bool Polyhedron_demo_stl_plugin::canLoad(QFileInfo) const { return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) { + +QList +Polyhedron_demo_stl_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene){ // Open file std::ifstream in(fileinfo.filePath().toUtf8(), std::ios::in | std::ios::binary); if(!in) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; - return NULL; + ok = false; + return QList(); } if(fileinfo.size() == 0) { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); Scene_surface_mesh_item* item = new Scene_surface_mesh_item(); item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()< > points; std::vector > triangles; if (!CGAL::read_STL(in, points, triangles)) { std::cerr << "Error: invalid STL file" << std::endl; - return NULL; + ok = false; + return QList(); } try{ @@ -98,7 +105,10 @@ Polyhedron_demo_stl_plugin::load(QFileInfo fileinfo) { else{ Scene_surface_mesh_item* item = new Scene_surface_mesh_item(SM); item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<setName(fileinfo.completeBaseName()); item->load(points, triangles); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(item); } -bool Polyhedron_demo_stl_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +bool Polyhedron_demo_stl_plugin:: +save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); const Scene_surface_mesh_item* sm_item = qobject_cast(item); @@ -144,6 +159,7 @@ bool Polyhedron_demo_stl_plugin::save(const CGAL::Three::Scene_item* item, QFile if (sm_item) { CGAL::write_STL(*sm_item->face_graph(), out); + items.pop_front(); return true; } return false; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp index dfac3829add..f97fed4afad 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp @@ -42,19 +42,34 @@ public: bool applicable(QAction*) const { return false;} QString name() const { return "surf_io_plugin"; } QString nameFilters() const { return "Amira files (*.surf)"; } - bool canLoad() const{ return true; } + bool canLoad(QFileInfo) const{ return true; } template CGAL::Three::Scene_item* actual_load(QFileInfo fileinfo); - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*) { return false; } - bool save(const CGAL::Three::Scene_item*, QFileInfo) { return false; } + bool save(QFileInfo fileinfo,QList& ) { return false; } }; -CGAL::Three::Scene_item* Surf_io_plugin::load(QFileInfo fileinfo) +QList +Surf_io_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { - return actual_load(fileinfo); + Scene_item* item = + actual_load(fileinfo); + if(item) + { + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(); + } } template< class FaceGraphItem> CGAL::Three::Scene_item* Surf_io_plugin::actual_load(QFileInfo fileinfo) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp index 7bed8af9e55..8ab464ed7c6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp @@ -21,26 +21,28 @@ public: QString name() const { return "xyz_plugin"; } QString nameFilters() const { return "XYZ as Point Set (*.xyz);;Point Set with Normal (*.pwn)"; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList&); }; -bool Polyhedron_demo_xyz_plugin::canLoad() const { +bool Polyhedron_demo_xyz_plugin::canLoad(QFileInfo) const { return true; } -CGAL::Three::Scene_item* -Polyhedron_demo_xyz_plugin::load(QFileInfo fileinfo) +QList +Polyhedron_demo_xyz_plugin:: +load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { // Open file std::ifstream in(fileinfo.filePath().toUtf8().data()); if(!in) { std::cerr << "Error! Cannot open file " << fileinfo.filePath().toStdString() << std::endl; - return NULL; + ok = false; + return QList(); } @@ -50,19 +52,26 @@ Polyhedron_demo_xyz_plugin::load(QFileInfo fileinfo) Scene_points_with_normal_item* item = new Scene_points_with_normal_item(); item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<setName(fileinfo.completeBaseName()); if(!point_set_item->read_xyz_point_set(in)) { delete point_set_item; - return NULL; + ok = false; + return QList(); } if(point_set_item->has_normals()) point_set_item->setRenderingMode(CGAL::Three::Three::defaultPointSetRenderingMode()); - return point_set_item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(point_set_item); + return QList()<(item); } -bool Polyhedron_demo_xyz_plugin::save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +bool Polyhedron_demo_xyz_plugin:: +save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); // Check extension (quietly) std::string extension = fileinfo.suffix().toUtf8().data(); if (extension != "xyz" && extension != "XYZ" && @@ -88,7 +99,10 @@ bool Polyhedron_demo_xyz_plugin::save(const CGAL::Three::Scene_item* item, QFile // Save point set as .xyz std::ofstream out(fileinfo.filePath().toUtf8().data()); out.precision (std::numeric_limits::digits10 + 2); - return point_set_item->write_xyz_point_set(out); + bool res = point_set_item->write_xyz_point_set(out); + if(res) + items.pop_front(); + return res; } #include "XYZ_io_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp index 9bf6a73226c..2b4d0649093 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp @@ -33,13 +33,14 @@ public: "3-map files (*.3map)"; } - bool canLoad() const { return true; } - CGAL::Three::Scene_item* load(QFileInfo fileinfo){ + bool canLoad(QFileInfo) const { return true; } + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true){ // Open file std::ifstream ifs(fileinfo.filePath().toUtf8()); if(!ifs) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; - return nullptr; + ok = false; + return QList(); } Scene_lcc_item::LCC lcc; @@ -53,17 +54,21 @@ public: } if(!res) { - return nullptr; + ok = false; + return QList(); } Scene_lcc_item* new_item = new Scene_lcc_item(lcc); new_item->setName(fileinfo.fileName()); new_item->invalidateOpenGLBuffers(); - return new_item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(new_item); + ok = true; + return QList()<& ){ return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp index 68ccf77ea8e..93af632e9e8 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp @@ -37,11 +37,11 @@ public: { return false; } - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo); + bool save(QFileInfo fileinfo,QList& ); private: bool try_load_other_binary_format(std::istream& in, C3t3& c3t3); @@ -50,21 +50,23 @@ private: }; -bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad() const { +bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad(QFileInfo) const { return true; } - -CGAL::Three::Scene_item* -Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) { +QList +Polyhedron_demo_c3t3_binary_io_plugin::load( + QFileInfo fileinfo, bool& ok, bool add_to_scene) { // Open file + ok = true; std::ifstream in(fileinfo.filePath().toUtf8(), std::ios_base::in|std::ios_base::binary); if(!in) { std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; - return NULL; + ok = false; + return QList(); } Scene_c3t3_item* item = new Scene_c3t3_item(); @@ -72,7 +74,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) { { CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); item->setName(fileinfo.completeBaseName()); - return item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<< item; } if(fileinfo.suffix().toLower() == "cgal") { @@ -80,7 +84,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) { if(item->load_binary(in)) { - return item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList() << item; } item->c3t3().clear(); @@ -89,7 +95,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) { item->c3t3_changed(); item->changed(); item->resetCutPlane(); - return item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<< item; } item->c3t3().clear(); @@ -98,7 +106,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) { item->c3t3_changed(); item->changed(); item->resetCutPlane(); - return item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<c3t3_changed(); item->resetCutPlane(); - return item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<c3t3().triangulation().number_of_finite_cells() == 0) { @@ -168,7 +180,8 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) { // if all loading failed... delete item; - return NULL; + ok = false; + return QList(); } bool Polyhedron_demo_c3t3_binary_io_plugin::canSave(const CGAL::Three::Scene_item* item) @@ -179,51 +192,63 @@ bool Polyhedron_demo_c3t3_binary_io_plugin::canSave(const CGAL::Three::Scene_ite bool Polyhedron_demo_c3t3_binary_io_plugin:: -save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) +save(QFileInfo fileinfo, QList &items) { - const Scene_c3t3_item* c3t3_item = qobject_cast(item); - if ( NULL == c3t3_item ) - { - return false; - } + Scene_item* item = items.front(); + const Scene_c3t3_item* c3t3_item = qobject_cast(item); + if ( NULL == c3t3_item ) + { + return false; + } - QString path = fileinfo.absoluteFilePath(); + QString path = fileinfo.absoluteFilePath(); - if(path.endsWith(".cgal")) - { + if(path.endsWith(".cgal")) + { std::ofstream out(fileinfo.filePath().toUtf8(), - std::ios_base::out|std::ios_base::binary); + std::ios_base::out|std::ios_base::binary); - return out && c3t3_item->save_binary(out); - } - - else if (fileinfo.suffix() == "mesh") - { - std::ofstream medit_file (qPrintable(path)); - c3t3_item->c3t3().output_to_medit(medit_file,true,true); - return true; - } - else if (fileinfo.suffix() == "ma") - { - std::ofstream maya_file (qPrintable(path)); - c3t3_item->c3t3().output_to_maya( - maya_file,true); - return true; - } - else if (fileinfo.suffix() == "am") - { - std::ofstream avizo_file (qPrintable(path)); - CGAL::output_to_avizo(avizo_file, c3t3_item->c3t3()); - return true; - } - else if (fileinfo.suffix() == "off") - { - std::ofstream off_file(qPrintable(path)); - c3t3_item->c3t3().output_facets_in_complex_to_off(off_file); - return true; - } + bool ok = out && c3t3_item->save_binary(out); + if(!ok) + return false; else - return false; + { + items.pop_front(); + return true; + } + } + + else if (fileinfo.suffix() == "mesh") + { + std::ofstream medit_file (qPrintable(path)); + c3t3_item->c3t3().output_to_medit(medit_file,true,true); + items.pop_front(); + return true; + } + else if (fileinfo.suffix() == "ma") + { + std::ofstream maya_file (qPrintable(path)); + c3t3_item->c3t3().output_to_maya( + maya_file,true); + items.pop_front(); + return true; + } + else if (fileinfo.suffix() == "am") + { + std::ofstream avizo_file (qPrintable(path)); + CGAL::output_to_avizo(avizo_file, c3t3_item->c3t3()); + items.pop_front(); + return true; + } + else if (fileinfo.suffix() == "off") + { + std::ofstream off_file(qPrintable(path)); + c3t3_item->c3t3().output_facets_in_complex_to_off(off_file); + items.pop_front(); + return true; + } + else + return false; } struct Fake_mesh_domain { diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp index 7e646bf1029..69e31f785fa 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -282,15 +282,18 @@ public: Io_image_plugin() : planeSwitch(NULL) {} QString nameFilters() const; - bool canLoad() const; - CGAL::Three::Scene_item* load(QFileInfo fileinfo); + bool canLoad(QFileInfo) const; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*); - bool save(const CGAL::Three::Scene_item* item, QFileInfo fi) { + bool save(QFileInfo fileinfo, QList& items ) { + Scene_item* item = items.front(); const Scene_image_item* im_item = qobject_cast(item); point_image p_im = *im_item->image()->image(); - return _writeImage(&p_im, fi.filePath().toUtf8()) == 0; + bool ok = _writeImage(&p_im, fileinfo.filePath().toUtf8()) == 0; + items.pop_front(); + return ok; } QString name() const { return "segmented images"; } @@ -965,7 +968,7 @@ QString Io_image_plugin::nameFilters() const { } -bool Io_image_plugin::canLoad() const { +bool Io_image_plugin::canLoad(QFileInfo) const { return true; } @@ -987,8 +990,11 @@ void convert(Image* image) image->image()->wdim = 4; image->image()->wordKind = WK_FLOAT; } -CGAL::Three::Scene_item* -Io_image_plugin::load(QFileInfo fileinfo) { + +QList +Io_image_plugin::load(QFileInfo fileinfo, bool& ok, bool add_to_scene) +{ + ok = true; QApplication::restoreOverrideCursor(); Image* image = new Image; if(fileinfo.suffix() != "H" && fileinfo.suffix() != "HH" && @@ -1075,8 +1081,9 @@ Io_image_plugin::load(QFileInfo fileinfo) { success = false; } if(!success){ + ok = false; delete image; - return NULL; + return QList(); } } //read a sep file @@ -1117,7 +1124,8 @@ Io_image_plugin::load(QFileInfo fileinfo) { if(return_code != QDialog::Accepted) { delete image; - return NULL; + ok = false; + return QList(); } // Get selected precision @@ -1145,7 +1153,9 @@ Io_image_plugin::load(QFileInfo fileinfo) { else image_item = new Scene_image_item(image,voxel_scale, false); image_item->setName(fileinfo.baseName()); - return image_item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(image_item); + return QList() << image_item; } bool Io_image_plugin::canSave(const CGAL::Three::Scene_item* item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index 7534498a7af..cd8512993f0 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -78,7 +78,7 @@ public: QString nameFilters() const { return "Selection files(*.selection.txt)"; } QString name() const { return "selection_sm_plugin"; } - bool canLoad() const { + bool canLoad(QFileInfo) const { Scene_item * item = CGAL::Three::Three::scene()->item( CGAL::Three::Three::scene()->mainSelectionIndex()); Scene_facegraph_item* fg_item = qobject_cast(item); @@ -91,26 +91,38 @@ public: return false; } - CGAL::Three::Scene_item* load(QFileInfo fileinfo) { - if(fileinfo.suffix().toLower() != "txt") return 0; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) { + if(fileinfo.suffix().toLower() != "txt") + { + ok = false; + return QList(); + } // There will be no actual loading at this step. Scene_polyhedron_selection_item* item = new Scene_polyhedron_selection_item(); if(!item->load(fileinfo.filePath().toStdString())) { delete item; - return NULL; + ok = false; + return QList(); } item->setName(fileinfo.baseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()<(scene_item); } - bool save(const CGAL::Three::Scene_item* scene_item, QFileInfo fileinfo) { + bool save(QFileInfo fileinfo,QList& items) { + Scene_item* scene_item = items.front(); const Scene_polyhedron_selection_item* item = qobject_cast(scene_item); if(item == NULL) { return false; } - return item->save(fileinfo.filePath().toStdString()); + bool res = item->save(fileinfo.filePath().toStdString()); + if(res) + items.pop_front(); + return res; } bool applicable(QAction*) const { diff --git a/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h b/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h index 40210f4c6d9..8361b1e5384 100644 --- a/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h +++ b/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h @@ -58,17 +58,23 @@ public: //! Specifies if the io_plugin is able to load an item or not. //! This must be overriden. - virtual bool canLoad() const = 0; - //! Loads an item from a file. + virtual bool canLoad(QFileInfo fileinfo) const = 0; + //! Loads one or more item(s) from a file. `ok` is `true` if the loading + //! was successful, `false` otherwise. + //! New items will be added to the scene if `add_to_scene` is `true`. + //! You don't want that when you reload an item, for example, + //! as it will be added at some other point of the process. //! This must be overriden. - virtual Scene_item* load(QFileInfo fileinfo) = 0; + virtual QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) = 0; //!Specifies if the io_plugin can save the item or not. //!This must be overriden. virtual bool canSave(const Scene_item*) = 0; - //!Saves the item in the file corresponding to the path + //!Saves one or more items in the file corresponding to the path //!contained in fileinfo. Returns false if error. //! This must be overriden. - virtual bool save(const Scene_item*, QFileInfo fileinfo) = 0; + //! @attention When a file is successfully saved, it must be removed from the + //! list. + virtual bool save(QFileInfo fileinfo,QList& ) = 0; //! If this returns `true`, then the loader will be chosen as default in the //! list of available loaders when saving a file, which means it will be the diff --git a/Three/include/CGAL/Three/Scene_3mf_item_interface.h b/Three/include/CGAL/Three/Scene_3mf_item_interface.h new file mode 100644 index 00000000000..15b25cbfdbf --- /dev/null +++ b/Three/include/CGAL/Three/Scene_3mf_item_interface.h @@ -0,0 +1,4 @@ +#ifndef SCENE_3MF_ITEM_INTERFACE_H +#define SCENE_3MF_ITEM_INTERFACE_H + +#endif // SCENE_3MF_ITEM_INTERFACE_H From 1fba61107dc80d279c38651866522a93203ce9f9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 14 May 2019 16:39:31 +0200 Subject: [PATCH 04/31] Add an IO plugin for the 3mf --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 51 +++- .../Polyhedron/Plugins/IO/3mf_io_plugin.cpp | 288 ++++++++++++++++++ .../demo/Polyhedron/Plugins/IO/CMakeLists.txt | 17 ++ Stream_support/include/CGAL/IO/read_3mf.h | 159 +++++++--- Stream_support/include/CGAL/IO/write_3mf.h | 187 +++++++++--- .../test/Stream_support/test_3mf_to_sm.cpp | 30 +- 6 files changed, 635 insertions(+), 97 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index d9b85c33c55..693b00f40e3 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -342,6 +342,41 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren this, &MainWindow::filterOperations); loadPlugins(); + //If 3mf plugin is present, add action to save scene + Polyhedron_demo_io_plugin_interface* io_3mf_plugin = nullptr; + for(Polyhedron_demo_io_plugin_interface* plugin : io_plugins) + { + if(plugin->name() == "3mf_io_plugin") + { + io_3mf_plugin = plugin; + break; + } + } + if(io_3mf_plugin ) + { + QAction* actionSaveSceneTo3mf = new QAction("Save the Scene as a 3mf File..."); + QString dir = QString("%1/scene").arg(def_save_dir); + connect(actionSaveSceneTo3mf, &QAction::triggered, this, + [this, dir, io_3mf_plugin](){ + + QString filename = + QFileDialog::getSaveFileName(this, + tr("Save Scene to File..."), + dir, + "*.3mf"); + + if(filename.isEmpty()) + return; + if(!filename.endsWith(".3mf")) + filename.append(".3mf"); + QList all_items; + for(int i = 0; i< scene->numberOfEntries(); ++i) + all_items.push_back(scene->item(i)); + io_3mf_plugin->save(filename, all_items); + }); + ui->menuFile->insertAction(ui->actionSa_ve_Scene_as_Script, actionSaveSceneTo3mf); + } + // Setup the submenu of the View menu that can toggle the dockwidgets Q_FOREACH(QDockWidget* widget, findChildren()) { ui->menuDockWindows->addAction(widget->toggleViewAction()); @@ -1899,10 +1934,12 @@ void MainWindow::on_actionLoad_triggered() continue; for(Scene_item* item : result) { - ++nb_item; - item->setColor(colors_[nb_item]); - Scene::Item_id index = scene->addItem(item); - selectSceneItem(index); + if(!item->property("already_colored").toBool()) + { + ++nb_item; + item->setColor(colors_[nb_item]); + } + selectSceneItem(scene->item_id(item)); CGAL::Three::Scene_group_item* group = qobject_cast(item); if(group) @@ -1912,8 +1949,10 @@ void MainWindow::on_actionLoad_triggered() } else { int scene_size = scene->numberOfEntries(); open(filename); - if(scene->numberOfEntries() != scene_size) - scene->item(scene->numberOfEntries()-1)->setColor(colors_[++nb_item]); + item = scene->item(scene->numberOfEntries()-1); + if(scene->numberOfEntries() != scene_size + && !item->property("already_colored").toBool()) + item->setColor(colors_[++nb_item]); } } } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp new file mode 100644 index 00000000000..879328347ce --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp @@ -0,0 +1,288 @@ +#include +#include + +#include + +#include +#include + +#include +#include + +#include "Scene_surface_mesh_item.h" +#include "Scene_points_with_normal_item.h" +#include "Scene_polylines_item.h" + +#include +#include +#include + +using namespace NMR; + +class Io_3mf_plugin: + public QObject, + public CGAL::Three::Polyhedron_demo_io_plugin_interface +{ + Q_OBJECT + Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "3mf_io_plugin.json") + + typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + typedef std::vector PointRange; + typedef std::vector Polygon; + typedef std::vector PolygonRange; + typedef std::list PolylineRange; + typedef std::vector ColorRange; + QString name() const { return "3mf_io_plugin"; } + + + QString nameFilters() const { return + "3mf files (*.3mf)"; } + + + bool canLoad(QFileInfo) const { return true; } + + + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true){ + namespace PMP = CGAL::Polygon_mesh_processing; + // Open file + ok = true; + std::vector all_points; + std::vector all_polygons; + std::vector names; + QList result; + std::vector > all_colors; + int nb_polylines = + CGAL::read_polylines_from_3mf(fileinfo.filePath().toUtf8().toStdString(), + all_points, all_colors, names); + if(nb_polylines > 0 ) + { + for(int i=0; i< nb_polylines; ++i) + { + Scene_polylines_item* pol_item = new Scene_polylines_item(); + PolylineRange& polylines = pol_item->polylines; + polylines.push_back(all_points[i]); + pol_item->setName(names[i].data()); + pol_item->invalidateOpenGLBuffers(); + CGAL::Color c = all_colors[i].front(); + pol_item->setColor(QColor(c.red(), c.green(), c.blue())); + pol_item->setProperty("already_colord", true); + result << pol_item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(pol_item); + } + } + all_points.clear(); + all_colors.clear(); + names.clear(); + int nb_point_sets = + CGAL::read_point_clouds_from_3mf(fileinfo.filePath().toUtf8().toStdString(), + all_points, all_colors, names); + for(int i=0; i< nb_point_sets; ++i) + { + Scene_points_with_normal_item* pts_item = new Scene_points_with_normal_item(); + for(std::size_t j = 0; j < all_points[i].size(); ++j) + { + pts_item->point_set()->insert(all_points[i][j]); + } + pts_item->setName(names[i].data()); + pts_item->invalidateOpenGLBuffers(); + CGAL::Color c = all_colors[i].front(); + pts_item->setColor(QColor(c.red(), c.green(), c.blue())); + pts_item->setProperty("already_colord", true); + result << pts_item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(pts_item); + } + all_points.clear(); + names.clear(); + all_colors.clear(); + int nb_meshes = + CGAL::read_soups_from_3mf(fileinfo.filePath().toUtf8().toStdString(), + all_points, all_polygons, all_colors, names); + for(std::size_t i = 0; i< nb_meshes; ++i) + { + PolygonRange triangles = all_polygons[i]; + PointRange points = all_points[i]; + ColorRange colors = all_colors[i]; + bool ok = true; + if(!PMP::is_polygon_soup_a_polygon_mesh(triangles)) + ok = PMP::orient_polygon_soup(points, triangles); + if(!ok) + { + std::cerr<<"Object is not orientable. Skipped."< fcolor = + mesh.add_property_map("f:color",first).first; + for(std::size_t pid = 0; pid < colors.size(); ++pid) + { + put(fcolor, face_descriptor(pid), colors[pid]);//should work bc mesh is just created and shouldn't have any destroyed face. Not so sure bc of orientation though. + } + } + Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(mesh); + sm_item->setColor(QColor(first.red(), first.green(), first.blue())); + sm_item->setProperty("already_colored", true); + sm_item->setName(names[i].data()); + sm_item->invalidateOpenGLBuffers(); + result << sm_item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(sm_item); + } + } + ok = true; + return result; + } + + + bool canSave(const CGAL::Three::Scene_item*){return false;} + + + bool save(QFileInfo fi, QList& items){ + + QList to_return; + std::vector sm_items; + std::vector pts_items; + std::vector pol_items; + for(Scene_item* item : items) + { + Scene_surface_mesh_item* sm_item = + qobject_cast(item); + if(sm_item) + { + sm_items.push_back(sm_item); + continue; + } + + Scene_points_with_normal_item* pts_item = + qobject_cast(item); + if(pts_item) + { + pts_items.push_back(pts_item); + continue; + } + + Scene_polylines_item* pol_item = + qobject_cast(item); + if(pol_item) + { + pol_items.push_back(pol_item); + continue; + } + qDebug()<name()<<" will not be saved."; + to_return.push_back(item); + } + + HRESULT hResult; + NMR::PLib3MFModel * pModel; + hResult = NMR::lib3mf_createmodel(&pModel); + NMR::PLib3MFModelMeshObject* pMeshObject; + if (hResult != LIB3MF_OK) { + std::cerr << "could not create model: " << std::hex << hResult << std::endl; + return false; + } + for(Scene_surface_mesh_item* sm_item : sm_items) + { + SMesh &mesh = *sm_item->polyhedron(); + PointRange points; + PolygonRange triangles; + typedef boost::property_map::type VPMap; + VPMap vpm = get(boost::vertex_point, mesh); + std::unordered_map::vertex_descriptor, + std::size_t> vertex_id_map; + std::size_t i = 0; + for(auto v : mesh.vertices()) + { + points.push_back(get(vpm, v)); + vertex_id_map[v] = i++; + } + for(auto f : mesh.faces()) + { + Polygon triangle; + for(auto vert : CGAL::vertices_around_face(halfedge(f, mesh), mesh)) + { + triangle.push_back(vertex_id_map[vert]); + } + triangles.push_back(triangle); + } + + std::vector colors; + //if item is multicolor, fill colors with f:color + if(sm_item->isItemMulticolor()) + { + colors.reserve(triangles.size()); + SMesh::Property_map fcolors = + mesh.property_map("f:color").first; + for(auto fd : mesh.faces()) + { + colors.push_back(get(fcolors, fd)); + } + } + else if(sm_item->hasPatchIds()) + { + colors.reserve(triangles.size()); + SMesh::Property_map fpid = + mesh.property_map("f:patch_id").first; + for(auto fd : mesh.faces()) + { + int pid = get(fpid, fd); + QColor q_color = sm_item->color_vector()[pid]; + colors.push_back(CGAL::Color(q_color.red(), q_color.green(), + q_color.blue(), q_color.alpha())); + } + } + //else fill it with item->color() + else + { + colors.resize(triangles.size()); + const QColor& c = sm_item->color(); + for(auto& color : colors) + color.set_rgb(c.red(), c.green(), c.blue()); + } + + CGAL::write_mesh_to_model(points, triangles, colors, + sm_item->name().toStdString(), &pMeshObject, pModel); + } + for(Scene_points_with_normal_item* pts_item : pts_items) + { + QColor qc = pts_item->color(); + CGAL::Color color(qc.red(), qc.green(), qc.blue()); + CGAL::write_point_cloud_to_model(pts_item->point_set()->points(), color, + pts_item->name().toStdString(), + &pMeshObject, pModel); + } + for(Scene_polylines_item* pol_item : pol_items) + { + for(auto pol_it = pol_item->polylines.begin(); + pol_it != pol_item->polylines.end(); ++pol_it) + { + QColor qc = pol_item->color(); + CGAL::Color color(qc.red(), qc.green(), qc.blue()); + CGAL::write_polyline_to_model(*pol_it,color, + pol_item->name().toStdString(), + &pMeshObject, pModel); + } + } + CGAL::export_model_to_file(fi.filePath().toUtf8().toStdString(), pModel); + items = to_return; + return true; + } +}; +#include "3mf_io_plugin.moc" + diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index 5a0289798e6..5c8bf384e39 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -72,4 +72,21 @@ else() else() message(STATUS "NOTICE : the LAS IO plugin needs LAS libraries and will not be compiled.") endif() + + find_path(3MF_INCLUDE_DIR + NAMES Common Model + DOC "Path to lib3MF headers" + ) + if(IS_DIRECTORY "${3MF_INCLUDE_DIR}/Common") + set(3MF_FOUND true) + endif() + find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library") + + if(3MF_FOUND) + include_directories(${3MF_INCLUDE_DIR}) + polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO) + target_link_libraries(3mf_io_plugin PRIVATE scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item ${3MF_LIBRARIES}) + else() + message(STATUS "NOTICE: The 3mf_io_plugin requires the lib3MF library, and will not be compiled.") + endif() endif() diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h index d9e477f2820..062ea68d6a0 100644 --- a/Stream_support/include/CGAL/IO/read_3mf.h +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -25,17 +25,21 @@ #include #include #include +#include #include namespace CGAL{ template + typename PolygonRange, + typename ColorRange> bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, PointRange& points, PolygonRange& triangles, + ColorRange& colors, std::string& name) { typedef typename PointRange::value_type Point_3; typedef typename PolygonRange::value_type Polygon; + typedef typename ColorRange::value_type _Color; HRESULT hResult; DWORD nNeededChars; @@ -63,6 +67,19 @@ bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, } else name = std::string("Unknown Mesh"); + + NMR::PLib3MFPropertyHandler * pPropertyHandler; + hResult = NMR::lib3mf_meshobject_createpropertyhandler(pMeshObject, &pPropertyHandler); + if (hResult != LIB3MF_OK) { + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + std::cerr << "could not create property handler: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(pMeshObject); + return -1; + } + for(DWORD vid = 0; vid < points.size(); ++vid) { NMR::MODELMESHVERTEX pVertex; @@ -80,15 +97,22 @@ bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, for(DWORD i = 0; i< 3; ++i) triangle[i] = pTriangle.m_nIndices[i]; triangles[pid] = triangle; + NMR::MODELMESH_TRIANGLECOLOR_SRGB pColor; + NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, pid, &pColor); + NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0]; + colors[pid]=CGAL::Color(mColor.m_Red, mColor.m_Green, + mColor.m_Blue, mColor.m_Alpha); } return true; } template + typename PolygonRange, + typename ColorRange> bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, PointRange& points, PolygonRange&, + ColorRange& colors, std::string& name) { typedef typename PointRange::value_type Point_3; typedef typename PolygonRange::value_type Polygon; @@ -123,8 +147,21 @@ bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, points.resize(0); return false; } - points.resize(points.size()-3); - for(DWORD vid = 0; vid < points.size()-3; ++vid) //ignore dummy_vertices + + NMR::PLib3MFPropertyHandler * pPropertyHandler; + hResult = NMR::lib3mf_meshobject_createpropertyhandler(pMeshObject, &pPropertyHandler); + if (hResult != LIB3MF_OK) { + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + std::cerr << "could not create property handler: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(pMeshObject); + return -1; + } + + points.resize(points.size()-3);//ignore dummy_vertices + for(DWORD vid = 0; vid < points.size(); ++vid) { NMR::MODELMESHVERTEX pVertex; NMR::lib3mf_meshobject_getvertex(pMeshObject, vid+3, &pVertex); @@ -133,17 +170,24 @@ bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, pVertex.m_fPosition[1], pVertex.m_fPosition[2]); } + + NMR::MODELMESH_TRIANGLECOLOR_SRGB pColor; + NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, 0, &pColor);//get color of the dummy triangle + NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0]; + colors[0]=CGAL::Color(mColor.m_Red, mColor.m_Green, + mColor.m_Blue, mColor.m_Alpha); return true; } template + typename PolygonRange, + typename ColorRange> bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject, PointRange& points, PolygonRange&, + ColorRange& colors, std::string& name) { typedef typename PointRange::value_type Point_3; - typedef typename PolygonRange::value_type Polygon; HRESULT hResult; DWORD nNeededChars; @@ -174,8 +218,21 @@ bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject, points.resize(0); return false; } - points.resize(points.size()-3); - for(DWORD vid = 0; vid < points.size()-3; ++vid) //ignore dummy_vertices + + NMR::PLib3MFPropertyHandler * pPropertyHandler; + hResult = NMR::lib3mf_meshobject_createpropertyhandler(pMeshObject, &pPropertyHandler); + if (hResult != LIB3MF_OK) { + DWORD nErrorMessage; + LPCSTR pszErrorMessage; + std::cerr << "could not create property handler: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(pMeshObject); + return -1; + } + + points.resize(points.size()-3);//ignore dummy_vertices + for(DWORD vid = 0; vid < points.size(); ++vid) { NMR::MODELMESHVERTEX pVertex; NMR::lib3mf_meshobject_getvertex(pMeshObject, vid+3, &pVertex); @@ -184,16 +241,24 @@ bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject, pVertex.m_fPosition[1], pVertex.m_fPosition[2]); } - //ignore dummy_triangle. + + NMR::MODELMESH_TRIANGLECOLOR_SRGB pColor; + NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, 0, &pColor);//get color of the dummy triangle + NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0]; + colors[0]=CGAL::Color(mColor.m_Red, mColor.m_Green, + mColor.m_Blue, mColor.m_Alpha); return true; } -template +template int read_from_3mf(const std::string& file_name, PointRanges& all_points, - PolygonRanges& all_polygons, std::vector& names, + PolygonRanges& all_polygons, ColorRanges& all_colors, + std::vector& names, std::function func ) { @@ -208,21 +273,21 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, hResult = NMR::lib3mf_getinterfaceversion(&nInterfaceVersionMajor, &nInterfaceVersionMinor, &nInterfaceVersionMicro); if (hResult != LIB3MF_OK) { - std::cout << "could not get 3MF Library version: " << std::hex << hResult << std::endl; + std::cerr << "could not get 3MF Library version: " << std::hex << hResult << std::endl; return -1; } // Create Model Instance hResult = NMR::lib3mf_createmodel(&pModel); if (hResult != LIB3MF_OK) { - std::cout << "could not create model: " << std::hex << hResult << std::endl; + std::cerr << "could not create model: " << std::hex << hResult << std::endl; return -1; } // Create Model Reader hResult = NMR::lib3mf_model_queryreader(pModel, sReaderName.c_str(), &pReader); if (hResult != LIB3MF_OK) { - std::cout << "could not create model reader: " << std::hex << hResult << std::endl; + std::cerr << "could not create model reader: " << std::hex << hResult << std::endl; NMR::lib3mf_release(pModel); return -1; } @@ -230,7 +295,7 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, // Import Model from File hResult = NMR::lib3mf_reader_readfromfileutf8(pReader, file_name.c_str()); if (hResult != LIB3MF_OK) { - std::cout << "could not parse file: " << std::hex << hResult << std::endl; + std::cerr << "could not parse file: " << std::hex << hResult << std::endl; NMR::lib3mf_release(pReader); NMR::lib3mf_release(pModel); return -1; @@ -246,13 +311,13 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, hResult = NMR::lib3mf_model_getobjects(pModel, &pResourceIterator); if (hResult != LIB3MF_OK) { - std::cout << "could not get object: " << std::hex << hResult << std::endl; + std::cerr << "could not get object: " << std::hex << hResult << std::endl; NMR::lib3mf_release(pModel); return -1; } hResult = NMR::lib3mf_resourceiterator_movenext(pResourceIterator, &pbHasNext); if (hResult != LIB3MF_OK) { - std::cout << "could not get next object: " << std::hex << hResult << std::endl; + std::cerr << "could not get next object: " << std::hex << hResult << std::endl; NMR::lib3mf_release(pResourceIterator); NMR::lib3mf_release(pModel); return -1; @@ -266,7 +331,7 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, // get current resource hResult = NMR::lib3mf_resourceiterator_getcurrent(pResourceIterator, &pResource); if (hResult != LIB3MF_OK) { - std::cout << "could not get resource: " << std::hex << hResult << std::endl; + std::cerr << "could not get resource: " << std::hex << hResult << std::endl; NMR::lib3mf_release(pResourceIterator); NMR::lib3mf_release(pModel); return -1; @@ -275,7 +340,7 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, // get resource ID hResult = NMR::lib3mf_resource_getresourceid(pResource, &ResourceID); if (hResult != LIB3MF_OK) { - std::cout << "could not get resource id: " << std::hex << hResult << std::endl; + std::cerr << "could not get resource id: " << std::hex << hResult << std::endl; NMR::lib3mf_release(pResource); NMR::lib3mf_release(pResourceIterator); NMR::lib3mf_release(pModel); @@ -285,19 +350,18 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, BOOL bIsMeshObject; hResult = NMR::lib3mf_object_ismeshobject(pResource, &bIsMeshObject); if ((hResult == LIB3MF_OK) && (bIsMeshObject)) { - std::cout << "------------------------------------------------------" << std::endl; - std::cout << "mesh object #" << ResourceID << ": " << std::endl; - pMeshObject = pResource; NMR::lib3mf_meshobject_getvertexcount(pMeshObject, &nbVertices); NMR::lib3mf_meshobject_gettrianglecount(pMeshObject, &nbPolygons); PointRange points (nbVertices); PolygonRange triangles(nbPolygons); + ColorRange colors(nbPolygons); std::string name; - if(func(pMeshObject, points, triangles, name)){ + if(func(pMeshObject, points, triangles, colors, name)){ all_points.push_back(points); all_polygons.push_back(triangles); + all_colors.push_back(colors); names.push_back(name); } } @@ -305,7 +369,7 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, NMR::lib3mf_release(pResource); hResult = NMR::lib3mf_resourceiterator_movenext(pResourceIterator, &pbHasNext); if (hResult != LIB3MF_OK) { - std::cout << "could not get next object: " << std::hex << hResult << std::endl; + std::cerr << "could not get next object: " << std::hex << hResult << std::endl; return -1; } } @@ -323,6 +387,10 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, * `value_type` is a model of the concept `RandomAccessContainer` * whose `value_type` is a model of the concept `RandomAccessContainer` whose * `value_type` is std::size_t. + * \tparam ColorRanges a model of the concepts `RandomAccessContainer` and + * `BackInsertionSequence` whose `value type` is + * a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` + * whose `value type` is `CGAL::Color`. * \param file_name the name of the 3mf file to read. * \param all_points a `PointRanges` that will contain the points of the meshes * in `file_name`. @@ -331,47 +399,62 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, * meshes in `file_name`. * 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]. + * \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. * 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`. */ -template +template int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, - PolygonRanges& all_polygons, std::vector& names + PolygonRanges& all_polygons, ColorRanges& all_colors, + std::vector& names ) { typedef typename PointRanges::value_type PointRange; typedef typename PolygonRanges::value_type PolygonRange; - return read_from_3mf - (file_name, all_points, all_polygons, names, extract_soups); + typedef typename ColorRanges::value_type ColorRange; + return read_from_3mf + (file_name, all_points, all_polygons, + all_colors, names, extract_soups); } -template -int read_polylines_from_3mf(const std::string& file_name, PointRanges& all_points, - std::vector& names +template +int read_polylines_from_3mf(const std::string& file_name, + PointRanges& all_points, + ColorRanges& all_colors, + std::vector& names ) { typedef typename PointRanges::value_type PointRange; typedef std::vector Polygon; typedef std::vector PolygonRange; + typedef std::vector ColorRange; std::vector all_polygons; - return read_from_3mf, PointRange, PolygonRange> - (file_name, all_points, all_polygons, names, extract_polylines); + return read_from_3mf, + std::vector, PointRange, PolygonRange, ColorRange> + (file_name, all_points, all_polygons, all_colors, names, + extract_polylines); } -template -int read_point_clouds_from_3mf(const std::string& file_name, PointRanges& all_points, - std::vector& names +template +int read_point_clouds_from_3mf(const std::string& file_name, + PointRanges& all_points, + ColorRanges& all_colors, + std::vector& names ) { typedef typename PointRanges::value_type PointRange; typedef std::vector Polygon; typedef std::vector PolygonRange; + typedef std::vector ColorRange; std::vector all_polygons; - return read_from_3mf, PointRange, PolygonRange> - (file_name, all_points, all_polygons, names, extract_point_clouds); + return read_from_3mf, + std::vector, PointRange, PolygonRange, ColorRange> + (file_name, all_points, all_polygons, all_colors, names, + extract_point_clouds); } }//end CGAL diff --git a/Stream_support/include/CGAL/IO/write_3mf.h b/Stream_support/include/CGAL/IO/write_3mf.h index 322d54495c3..ac4500a17b2 100644 --- a/Stream_support/include/CGAL/IO/write_3mf.h +++ b/Stream_support/include/CGAL/IO/write_3mf.h @@ -43,7 +43,18 @@ NMR::MODELMESHTRIANGLE fnCreateTriangle(int v0, int v1, int v2) result.m_nIndices[2] = v2; return result; } +NMR::MODELMESHCOLOR_SRGB fnCreateColor(unsigned char red, unsigned char green, + unsigned char blue, unsigned char alpha=255) +{ + NMR::MODELMESHCOLOR_SRGB result; + result.m_Red = red; + result.m_Green = green; + result.m_Blue = blue; + result.m_Alpha = alpha; + return result; + +} } //end internal bool add_build_item(NMR::PLib3MFModel * pModel, @@ -56,10 +67,10 @@ bool add_build_item(NMR::PLib3MFModel * pModel, NMR::PLib3MFModelBuildItem * pBuildItem; hResult = NMR::lib3mf_model_addbuilditem(pModel, pMeshObject, NULL, &pBuildItem); if (hResult != LIB3MF_OK) { - std::cout << "could not create build item: " + std::cerr << "could not create build item: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(pMeshObject); NMR::lib3mf_release(pModel); @@ -82,10 +93,10 @@ bool export_model_to_file(const std::string& file_name, NMR::PLib3MFModelWriter * p3MFWriter; hResult = NMR::lib3mf_model_querywriter(pModel, "3mf", &p3MFWriter); if (hResult != LIB3MF_OK) { - std::cout << "could not create model reader: " + std::cerr << "could not create model reader: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(pModel); return false; @@ -93,9 +104,9 @@ bool export_model_to_file(const std::string& file_name, // Export Model into File hResult = NMR::lib3mf_writer_writetofileutf8(p3MFWriter, file_name.c_str()); if (hResult != LIB3MF_OK) { - std::cout << "could not write file: " << std::hex << hResult << std::endl; + std::cerr << "could not write file: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(p3MFWriter, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage << ": " + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(pModel); NMR::lib3mf_release(p3MFWriter); @@ -107,13 +118,14 @@ bool export_model_to_file(const std::string& file_name, return true; } -template +template bool write_mesh_to_model( const PointRange& points, - const PolygonRange& polygons, + const PolygonRange& polygons, + const ColorRange& colors, const std::string& name, - NMR::PLib3MFModelMeshObject** pMeshObject, - NMR::PLib3MFModel * pModel - ) + NMR::PLib3MFModelMeshObject** pMeshObject, + NMR::PLib3MFModel * pModel + ) { DWORD nErrorMessage; LPCSTR pszErrorMessage; @@ -124,10 +136,10 @@ bool write_mesh_to_model( const PointRange& points, // Create Mesh Object hResult = NMR::lib3mf_model_addmeshobject(pModel, pMeshObject); if (hResult != LIB3MF_OK) { - std::cout << "could not add mesh object: " << std::hex + std::cerr << "could not add mesh object: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage << ": " + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(pModel); return false; @@ -135,41 +147,83 @@ bool write_mesh_to_model( const PointRange& points, for( auto point : points) { pVertices.push_back(tmf_internal::fnCreateVertex(point.x(), point.y(), point.z())); - } + } for( auto triangle : polygons) { pTriangles.push_back(tmf_internal::fnCreateTriangle(triangle[0], triangle[1], triangle[2])); - } + } hResult = NMR::lib3mf_meshobject_setgeometry(*pMeshObject, pVertices.data(), pVertices.size(), pTriangles.data(), pTriangles.size()); if (hResult != LIB3MF_OK) { - std::cout << "could not set mesh geometry: " + std::cerr << "could not set mesh geometry: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); return false; } + // Create color entries + NMR::PLib3MFPropertyHandler * pPropertyHandler; + hResult = NMR::lib3mf_meshobject_createpropertyhandler(*pMeshObject, &pPropertyHandler); + if (hResult != LIB3MF_OK) { + std::cerr << "could not create property handler: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(*pMeshObject); + NMR::lib3mf_release(pModel); + return -1; + } + + // define colors + for(std::size_t pid = 0; pid +template bool write_points(const PointRange& points, + const Color& color, const std::string& name, NMR::PLib3MFModelMeshObject** pMeshObject, NMR::PLib3MFModel * pModel @@ -183,10 +237,10 @@ bool write_points(const PointRange& points, // Create Mesh Object hResult = NMR::lib3mf_model_addmeshobject(pModel, pMeshObject); if (hResult != LIB3MF_OK) { - std::cout << "could not add mesh object: " << std::hex + std::cerr << "could not add mesh object: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(pModel, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage << ": " + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(pModel); return false; @@ -197,34 +251,74 @@ bool write_points(const PointRange& points, for( auto point : points) { pVertices.push_back(tmf_internal::fnCreateVertex(point.x(), point.y(), point.z())); - } + } NMR::MODELMESHTRIANGLE dummy_triangle = tmf_internal::fnCreateTriangle(0,1,2); //add a triangle to avoid lib error. hResult = NMR::lib3mf_meshobject_setgeometry(*pMeshObject, pVertices.data(), pVertices.size(), &dummy_triangle, 1); if (hResult != LIB3MF_OK) { - std::cout << "could not set mesh geometry: " + std::cerr << "could not set mesh geometry: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); return false; } + + // Create color entries + NMR::PLib3MFPropertyHandler * pPropertyHandler; + hResult = NMR::lib3mf_meshobject_createpropertyhandler(*pMeshObject, &pPropertyHandler); + if (hResult != LIB3MF_OK) { + std::cerr << "could not create property handler: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(*pMeshObject); + NMR::lib3mf_release(pModel); + return -1; + } + + // define colors + NMR::MODELMESHCOLOR_SRGB sColor = tmf_internal::fnCreateColor (color.red(), + color.green(), + color.blue(), + color.alpha()); + // One-colored Triangles + NMR::lib3mf_propertyhandler_setsinglecolor(pPropertyHandler, 0, &sColor); + + // make sure to define a default property + NMR::PLib3MFDefaultPropertyHandler * pDefaultPropertyHandler; + hResult = NMR::lib3mf_object_createdefaultpropertyhandler(*pMeshObject, &pDefaultPropertyHandler); + if (hResult != LIB3MF_OK) { + std::cerr<< "could not create default property handler: " << std::hex << hResult << std::endl; + NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); + std::cerr<< "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + NMR::lib3mf_release(*pMeshObject); + NMR::lib3mf_release(pModel); + return -1; + } + NMR::MODELMESHCOLOR_SRGB default_color = tmf_internal::fnCreateColor(0,0,0,0); + NMR::lib3mf_defaultpropertyhandler_setcolor(pDefaultPropertyHandler, + &default_color); + + // release default property handler + NMR::lib3mf_release(pDefaultPropertyHandler); + // Set name hResult = NMR::lib3mf_object_setnameutf8(*pMeshObject, name.c_str()); if (hResult != LIB3MF_OK) { - std::cout << "could not set object name: " << std::hex << hResult << std::endl; + std::cerr << "could not set object name: " << std::hex << hResult << std::endl; NMR::lib3mf_getlasterror(*pMeshObject, &nErrorMessage, &pszErrorMessage); - std::cout << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; + std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); return -1; } } -template +template bool write_point_cloud_to_model(const PointRange& points, + const Color& color, const std::string& name, NMR::PLib3MFModelMeshObject** pMeshObject, NMR::PLib3MFModel * pModel @@ -232,24 +326,25 @@ bool write_point_cloud_to_model(const PointRange& points, { std::string pc_name = name; pc_name.append("_cgal_pc"); - write_points(points, pc_name, pMeshObject, pModel); + write_points(points, color, pc_name, pMeshObject, pModel); } -template +template bool write_polyline_to_model(const PointRange& points, - const std::string& name, - NMR::PLib3MFModelMeshObject** pMeshObject, - NMR::PLib3MFModel * pModel - ) + const Color& color, + const std::string& name, + NMR::PLib3MFModelMeshObject** pMeshObject, + NMR::PLib3MFModel * pModel + ) { std::string pc_name = name; pc_name.append("_cgal_pl"); - write_points(points, pc_name, pMeshObject, pModel); + write_points(points, color, pc_name, pMeshObject, pModel); } /*! - * \brief write_soups_to_3mf will write the polygon soups in all_points and - * all_polygons in `file_name`, in the 3mf format. + * \brief write_soups_to_3mf will write the polygon soups contained in all_points and + * all_polygons into the file named `file_name`, in the 3mf format. * \tparam PointRanges a model of the concepts `RandomAccessContainer` and * `BackInsertionSequence` whose `value type` is * a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` @@ -269,7 +364,7 @@ bool write_polyline_to_model(const PointRange& points, template bool write_soups_to_3mf(const std::string& file_name, const PointRanges& all_points, - const PolygonRanges& all_polygons, + const PolygonRanges& all_polygons, const std::vector& names) { DWORD nErrorMessage; @@ -280,7 +375,7 @@ bool write_soups_to_3mf(const std::string& file_name, NMR::PLib3MFModel * pModel; hResult = NMR::lib3mf_createmodel(&pModel); if (hResult != LIB3MF_OK) { - std::cout << "could not create model: " << std::hex << hResult << std::endl; + std::cerr << "could not create model: " << std::hex << hResult << std::endl; return false; } for(std::size_t id = 0; id < all_points.size(); ++id) diff --git a/Stream_support/test/Stream_support/test_3mf_to_sm.cpp b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp index f776128fa9c..a2c1fe8dbab 100644 --- a/Stream_support/test/Stream_support/test_3mf_to_sm.cpp +++ b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp @@ -23,6 +23,7 @@ typedef CGAL::Surface_mesh Mesh; typedef std::vector PointRange; typedef std::vector Polygon; typedef std::vector PolygonRange; +typedef std::vector ColorRange; int main(int argc, char** argv) { @@ -33,10 +34,12 @@ int main(int argc, char** argv) } std::vector all_points; std::vector all_polygons; + std::vector all_colors; std::vector names; //testing reading functions. int nb_meshes = - CGAL::read_soups_from_3mf(argv[1], all_points, all_polygons, names); + CGAL::read_soups_from_3mf(argv[1], all_points, all_polygons, + all_colors, names); if(nb_meshes <0) return 1; for(std::size_t i = 0; i< nb_meshes; ++i) @@ -64,8 +67,9 @@ int main(int argc, char** argv) } } all_points.clear(); + all_colors.clear(); int nb_polylines = - CGAL::read_polylines_from_3mf(argv[1], all_points, names); + CGAL::read_polylines_from_3mf(argv[1], all_points, all_colors, names); if(nb_polylines == 0) std::cout<<"No polyline found."<::type VPMap; VPMap vpm = get(boost::vertex_point, sphere); std::unordered_map::vertex_descriptor, @@ -119,10 +126,13 @@ int main(int argc, char** argv) triangle.push_back(vertex_id_map[vert]); } triangles.push_back(triangle); + colors.push_back(CGAL::Color(255,0,0,255)); } all_polygons.push_back(triangles); + all_colors.push_back(colors); points.clear(); triangles.clear(); + colors.clear(); vertex_id_map.clear(); i = 0; @@ -141,8 +151,11 @@ int main(int argc, char** argv) triangle.push_back(vertex_id_map[vert]); } triangles.push_back(triangle); + colors.push_back(CGAL::Color(0,0,255,255)); + } all_polygons.push_back(triangles); + all_colors.push_back(colors); names.push_back(std::string("sphere")); names.push_back(std::string("tube")); @@ -160,13 +173,16 @@ int main(int argc, char** argv) } for(int i=0; i< names.size(); ++i) { - CGAL::write_mesh_to_model(all_points[i], all_polygons[i], names[i], &pMeshObject, pModel); + CGAL::write_mesh_to_model(all_points[i], all_polygons[i], + all_colors[i], names[i], &pMeshObject, pModel); } - - CGAL::write_point_cloud_to_model(all_points.front(), names.front(), &pMeshObject, pModel); + CGAL::Color color(255,0,0); + CGAL::write_point_cloud_to_model(all_points.front(), + color, names.front(), &pMeshObject, pModel); CGAL::export_model_to_file("micro.3mf", pModel); //testing of polylines - CGAL::write_polyline_to_model(all_points.back(), names.back(), &pMeshObject, pModel); + CGAL::write_polyline_to_model(all_points.back(), + color, names.back(), &pMeshObject, pModel); CGAL::export_model_to_file("micro.3mf", pModel); std::cout<<"OK."< Date: Thu, 16 May 2019 13:20:05 +0200 Subject: [PATCH 05/31] Update interface version --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 36 +------------------ .../Camera_positions_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/3mf_io_plugin.cpp | 35 +++++++++++++++--- .../Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/LAS_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/OFF_io_plugin.cpp | 2 +- .../Plugins/IO/OFF_to_nef_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 2 +- .../Plugins/IO/Polylines_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/STL_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/Surf_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/VTK_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/XYZ_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/lcc_io_plugin.cpp | 2 +- .../Plugins/Mesh_3/Io_image_plugin.cpp | 2 +- .../Plugins/PMP/Selection_plugin.cpp | 2 +- .../Point_set/Features_detection_plugin.cpp | 2 +- .../Polyhedron_demo_io_plugin_interface.h | 11 ++++-- 18 files changed, 55 insertions(+), 57 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 693b00f40e3..bd87e92fbcf 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -342,41 +342,6 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren this, &MainWindow::filterOperations); loadPlugins(); - //If 3mf plugin is present, add action to save scene - Polyhedron_demo_io_plugin_interface* io_3mf_plugin = nullptr; - for(Polyhedron_demo_io_plugin_interface* plugin : io_plugins) - { - if(plugin->name() == "3mf_io_plugin") - { - io_3mf_plugin = plugin; - break; - } - } - if(io_3mf_plugin ) - { - QAction* actionSaveSceneTo3mf = new QAction("Save the Scene as a 3mf File..."); - QString dir = QString("%1/scene").arg(def_save_dir); - connect(actionSaveSceneTo3mf, &QAction::triggered, this, - [this, dir, io_3mf_plugin](){ - - QString filename = - QFileDialog::getSaveFileName(this, - tr("Save Scene to File..."), - dir, - "*.3mf"); - - if(filename.isEmpty()) - return; - if(!filename.endsWith(".3mf")) - filename.append(".3mf"); - QList all_items; - for(int i = 0; i< scene->numberOfEntries(); ++i) - all_items.push_back(scene->item(i)); - io_3mf_plugin->save(filename, all_items); - }); - ui->menuFile->insertAction(ui->actionSa_ve_Scene_as_Script, actionSaveSceneTo3mf); - } - // Setup the submenu of the View menu that can toggle the dockwidgets Q_FOREACH(QDockWidget* widget, findChildren()) { ui->menuDockWindows->addAction(widget->toggleViewAction()); @@ -824,6 +789,7 @@ bool MainWindow::initIOPlugin(QObject* obj) CGAL::Three::Polyhedron_demo_io_plugin_interface* plugin = qobject_cast(obj); if(plugin) { + plugin->init(); io_plugins << plugin; return true; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp index 25fd3cdc230..6cb07bd250e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp @@ -16,7 +16,7 @@ class Polyhedron_demo_camera_positions_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* ); diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp index 879328347ce..6acf62d8768 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp @@ -25,7 +25,7 @@ class Io_3mf_plugin: { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "3mf_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "3mf_io_plugin.json") typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef std::vector PointRange; @@ -33,6 +33,31 @@ class Io_3mf_plugin: typedef std::vector PolygonRange; typedef std::list PolylineRange; typedef std::vector ColorRange; + void init() Q_DECL_OVERRIDE + { + QMenu* menuFile = CGAL::Three::Three::mainWindow()->findChild("menuFile"); + + QAction* actionSaveSceneTo3mf = new QAction("Save the Scene as a 3mf File..."); + connect(actionSaveSceneTo3mf, &QAction::triggered, this, + [this](){ + + QString filename = + QFileDialog::getSaveFileName(CGAL::Three::Three::mainWindow(), + tr("Save Scene to File..."), + QString(), + "*.3mf"); + + if(filename.isEmpty()) + return; + if(!filename.endsWith(".3mf")) + filename.append(".3mf"); + QList all_items; + for(int i = 0; i< CGAL::Three::Three::scene()->numberOfEntries(); ++i) + all_items.push_back(CGAL::Three::Three::scene()->item(i)); + save(filename, all_items); + }); + menuFile->insertAction(CGAL::Three::Three::mainWindow()->findChild("actionSa_ve_Scene_as_Script"), actionSaveSceneTo3mf); + } QString name() const { return "3mf_io_plugin"; } @@ -40,10 +65,10 @@ class Io_3mf_plugin: "3mf files (*.3mf)"; } - bool canLoad(QFileInfo) const { return true; } + bool canLoad(QFileInfo) const Q_DECL_OVERRIDE { return true; } - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true){ + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) Q_DECL_OVERRIDE { namespace PMP = CGAL::Polygon_mesh_processing; // Open file ok = true; @@ -151,10 +176,10 @@ class Io_3mf_plugin: } - bool canSave(const CGAL::Three::Scene_item*){return false;} + bool canSave(const CGAL::Three::Scene_item*) Q_DECL_OVERRIDE {return false;} - bool save(QFileInfo fi, QList& items){ + bool save(QFileInfo fi, QList& items) Q_DECL_OVERRIDE { QList to_return; std::vector sm_items; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp index 1709c1dfa60..0f00e7eea6f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp @@ -24,7 +24,7 @@ class Polyhedron_demo_gocad_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "gocad_io_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" ) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" ) public: void init(QMainWindow* mainWindow, diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp index 176824c2e16..813b29186e0 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp @@ -10,7 +10,7 @@ class Polyhedron_demo_las_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "las_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "las_io_plugin.json") public: QString name() const { return "las_plugin"; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp index 58edff9b8e3..76d53b4014b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_io_plugin.cpp @@ -22,7 +22,7 @@ class Polyhedron_demo_off_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "off_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "off_io_plugin.json") public: bool isDefaultLoader(const Scene_item *item) const diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp index dd765722381..3366e1dbb68 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp @@ -11,7 +11,7 @@ class Polyhedron_demo_off_to_nef_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "off_to_nef_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "off_to_nef_io_plugin.json") public: QString name() const { return "off_to_nef_plugin"; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index d72084a7e0b..6ce2fdeb793 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -20,7 +20,7 @@ class Polyhedron_demo_ply_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "ply_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "ply_io_plugin.json") public: bool isDefaultLoader(const CGAL::Three::Scene_item *item) const diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index 222f7362d2f..f5898b953bc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -17,7 +17,7 @@ class Polyhedron_demo_polylines_io_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "polylines_io_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp index 475fc302197..ff0ccea88ed 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp @@ -31,7 +31,7 @@ class Polyhedron_demo_stl_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "stl_io_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: void init(QMainWindow* mainWindow, diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp index f97fed4afad..9e728d6efe0 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp @@ -26,7 +26,7 @@ class Surf_io_plugin: Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "surf_io_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: void init(QMainWindow* mainWindow, diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp index 485c5a0c6f8..cc235ee91a2 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp @@ -291,7 +291,7 @@ class Polyhedron_demo_vtk_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "vtk_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "vtk_io_plugin.json") public: typedef boost::graph_traits::vertex_descriptor vertex_descriptor; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp index 8ab464ed7c6..f049fed6007 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/XYZ_io_plugin.cpp @@ -15,7 +15,7 @@ class Polyhedron_demo_xyz_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "xyz_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "xyz_io_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp index 2b4d0649093..71c47452676 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/lcc_io_plugin.cpp @@ -14,7 +14,7 @@ class LCC_io_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "lcc_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "lcc_io_plugin.json") public: bool isDefaultLoader(const CGAL::Three::Scene_item *item) const diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp index 69e31f785fa..d1103dac9ff 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -207,7 +207,7 @@ class Io_image_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0" FILE "io_image_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "io_image_plugin.json") public: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index cd8512993f0..22a29ef9991 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -73,7 +73,7 @@ class Polyhedron_demo_selection_plugin : Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "selection_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: QString nameFilters() const { return "Selection files(*.selection.txt)"; } QString name() const { return "selection_sm_plugin"; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp index c8e045980b2..3741d73da1b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp @@ -19,7 +19,7 @@ class Polyhedron_demo_features_detection_plugin : { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") QAction* actionDetectFeatures; public: QList actions() const { return QList() << actionDetectFeatures; } diff --git a/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h b/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h index 8361b1e5384..039c8e9ad73 100644 --- a/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h +++ b/Three/include/CGAL/Three/Polyhedron_demo_io_plugin_interface.h @@ -28,16 +28,23 @@ #include #include #include - +class QMainWindow; +class Messages_interface; namespace CGAL{ namespace Three { class Scene_item; +class Scene_interface; /*! * This class provides a base for creating a new IO plugin. */ class Polyhedron_demo_io_plugin_interface { public: + //! \brief Initializes the plugin + //! This function is called in the constructor of the MainWindow. + //! Whatever initialization the plugin needs can be done here. Default + //! behavior is to do nothing. + virtual void init(){} //!Returns the name of the plugin //!It is used by the loading system. virtual QString name() const = 0; @@ -89,6 +96,6 @@ public: } } Q_DECLARE_INTERFACE(CGAL::Three::Polyhedron_demo_io_plugin_interface, - "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0") + "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") #endif // POLYHEDRON_DEMO_IO_PLUGIN_INTERFACE_H From dbf2a6854f7705a50e6a40d7d0bab5dc274934ac Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 16 May 2019 14:00:04 +0200 Subject: [PATCH 06/31] Clean-up io-plugins --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 6 +-- .../Camera_positions_plugin.cpp | 29 +++++--------- .../Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp | 20 ++-------- .../Polyhedron/Plugins/IO/STL_io_plugin.cpp | 21 ++-------- .../Polyhedron/Plugins/IO/Surf_io_plugin.cpp | 26 +++---------- .../Plugins/Mesh_3/C3t3_io_plugin.cpp | 38 +++++++++---------- .../CGAL/Three/Scene_3mf_item_interface.h | 4 -- 7 files changed, 45 insertions(+), 99 deletions(-) delete mode 100644 Three/include/CGAL/Three/Scene_3mf_item_interface.h diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index bd87e92fbcf..a949b58ded9 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1118,11 +1118,11 @@ void MainWindow::open(QString filename) { // collect all io_plugins and offer them to load if the file extension match one name filter // also collect all available plugin in case of a no extension match - Q_FOREACH(CGAL::Three::Polyhedron_demo_io_plugin_interface* io_plugin, io_plugins) { - if ( !io_plugin->canLoad(fileinfo) ) continue; - all_items << io_plugin->name(); + for(CGAL::Three::Polyhedron_demo_io_plugin_interface* io_plugin : io_plugins) { if ( file_matches_filter(io_plugin->loadNameFilters(), filename.toLower()) ) { + if ( !io_plugin->canLoad(fileinfo) ) continue; + all_items << io_plugin->name(); if(io_plugin->isDefaultLoader(fileinfo.completeSuffix())) selected_items.prepend(io_plugin->name()); else diff --git a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp index 6cb07bd250e..c4823cd01aa 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp @@ -1,50 +1,41 @@ #include #include "Messages_interface.h" -#include #include #include "Camera_positions_list.h" + +#include #include #include using namespace CGAL::Three; class Polyhedron_demo_camera_positions_plugin : public QObject, - public Polyhedron_demo_plugin_interface, public CGAL::Three::Polyhedron_demo_io_plugin_interface { Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: - void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface* ); - QList actions() const; + void init(); QString name() const { return "camera_positions_plugin"; } QString nameFilters() const { return "Camera positions (*.camera.txt)"; } - bool canLoad() const { return true; } - Scene_item* load(QFileInfo fileinfo) { cpl->load(fileinfo.filePath()); return 0; } + bool canLoad(QFileInfo) const { return true; } + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) { ok = true; cpl->load(fileinfo.filePath()); return QList(); } bool canSave(const Scene_item*) { return false; } - bool save(const Scene_item*, QFileInfo ) {return false; } - bool applicable(QAction*) const {return false;} + bool save(QFileInfo,QList& ) {return false; } private: Camera_positions_list* cpl; }; -void Polyhedron_demo_camera_positions_plugin::init(QMainWindow* mainWindow, Scene_interface*, Messages_interface *) +void Polyhedron_demo_camera_positions_plugin::init() { - cpl = new Camera_positions_list(mainWindow); - mainWindow->addDockWidget(Qt::LeftDockWidgetArea, cpl); -} - -QList -Polyhedron_demo_camera_positions_plugin::actions() const -{ - return QList(); + cpl = new Camera_positions_list(CGAL::Three::Three::mainWindow()); + CGAL::Three::Three::mainWindow()->addDockWidget(Qt::LeftDockWidgetArea, cpl); } #include "Camera_positions_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp index 0f00e7eea6f..9aca2423ca0 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/GOCAD_io_plugin.cpp @@ -17,27 +17,15 @@ using namespace CGAL::Three; class Polyhedron_demo_gocad_plugin : public QObject, - public Polyhedron_demo_io_plugin_interface, - public Polyhedron_demo_plugin_helper + public Polyhedron_demo_io_plugin_interface { Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "gocad_io_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" ) + Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "gocad_io_plugin.json") public: - void init(QMainWindow* mainWindow, - CGAL::Three::Scene_interface* scene_interface, - Messages_interface*) { - //get the references - this->scene = scene_interface; - this->mw = mainWindow; - } - QList actions() const { - return QList(); - } - bool applicable(QAction*) const { return false;} + QString nameFilters() const; QString name() const { return "gocad_plugin"; } bool canLoad(QFileInfo) const; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp index ff0ccea88ed..66d08020a49 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/STL_io_plugin.cpp @@ -5,8 +5,6 @@ #include "SMesh_type.h" #include -#include -#include #include #include @@ -25,26 +23,13 @@ using namespace CGAL::Three; class Polyhedron_demo_stl_plugin : public QObject, - public Polyhedron_demo_io_plugin_interface, - public Polyhedron_demo_plugin_helper + public Polyhedron_demo_io_plugin_interface { Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "stl_io_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") + Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "stl_io_plugin.json") public: - void init(QMainWindow* mainWindow, - CGAL::Three::Scene_interface* scene_interface, - Messages_interface*) { - //get the references - this->scene = scene_interface; - this->mw = mainWindow; - } - QList actions() const { - return QList(); - } - bool applicable(QAction*) const { return false;} QString nameFilters() const; QString name() const { return "stl_plugin"; } bool canLoad(QFileInfo fileinfo) const; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp index 9e728d6efe0..6b0e4b8708e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp @@ -3,8 +3,6 @@ #include #include #include -#include -#include #include #include @@ -20,26 +18,14 @@ using namespace CGAL::Three; class Surf_io_plugin: public QObject, - public Polyhedron_demo_io_plugin_interface, - public Polyhedron_demo_plugin_helper + public Polyhedron_demo_io_plugin_interface { Q_OBJECT - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "surf_io_plugin.json") - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") + Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "surf_io_plugin.json") public: - void init(QMainWindow* mainWindow, - CGAL::Three::Scene_interface* scene_interface, - Messages_interface*) { - //get the references - this->scene = scene_interface; - this->mw = mainWindow; - } - QList actions() const { - return QList(); - } - bool applicable(QAction*) const { return false;} + QString name() const { return "surf_io_plugin"; } QString nameFilters() const { return "Amira files (*.surf)"; } bool canLoad(QFileInfo) const{ return true; } @@ -118,8 +104,8 @@ CGAL::Three::Scene_item* Surf_io_plugin::actual_load(QFileInfo fileinfo) FaceGraphItem *patch = new FaceGraphItem(patches[i]); patch->setName(QString("Patch #%1").arg(i)); patch->setColor(colors_[i]); - scene->addItem(patch); - scene->changeGroup(patch, group); + CGAL::Three::Three::scene()->addItem(patch); + CGAL::Three::Three::scene()->changeGroup(patch, group); } return group; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp index 93af632e9e8..15a93660153 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp @@ -2,7 +2,6 @@ #include "Scene_c3t3_item.h" #include #include -#include #include #include #include @@ -12,31 +11,17 @@ class Polyhedron_demo_c3t3_binary_io_plugin : public QObject, - public CGAL::Three::Polyhedron_demo_io_plugin_interface, - public CGAL::Three::Polyhedron_demo_plugin_interface + public CGAL::Three::Polyhedron_demo_io_plugin_interface { Q_OBJECT Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) - Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) - Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "c3t3_io_plugin.json") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "c3t3_io_plugin.json") public: - void init(QMainWindow*, CGAL::Three::Scene_interface* sc, Messages_interface*) - { - this->scene = sc; - } QString name() const { return "C3t3_io_plugin"; } QString nameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma)"; } QString saveNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh);;maya (*.ma);;avizo (*.am);;OFF files (*.off)"; } QString loadNameFilters() const { return "binary files (*.cgal);;ascii (*.mesh)"; } - QList actions() const - { - return QList(); - } - bool applicable(QAction*) const - { - return false; - } bool canLoad(QFileInfo) const; QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); @@ -50,8 +35,23 @@ private: }; -bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad(QFileInfo) const { - return true; +bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad(QFileInfo fi) const { + std::ifstream in(fi.filePath().toUtf8(), + std::ios_base::in|std::ios_base::binary); + if(!in) { + std::cerr << "Error! Cannot open file " + << (const char*)fi.filePath().toUtf8() << std::endl; + return false; + } + std::string line; + std::istringstream iss; + std::getline (in,line); + iss.str(line); + std::string keyword; + if (iss >> keyword) + if (keyword == "binary") + return true; + return false; } QList diff --git a/Three/include/CGAL/Three/Scene_3mf_item_interface.h b/Three/include/CGAL/Three/Scene_3mf_item_interface.h deleted file mode 100644 index 15b25cbfdbf..00000000000 --- a/Three/include/CGAL/Three/Scene_3mf_item_interface.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef SCENE_3MF_ITEM_INTERFACE_H -#define SCENE_3MF_ITEM_INTERFACE_H - -#endif // SCENE_3MF_ITEM_INTERFACE_H From c342a88440d7733317895fb200c82e2df109af20 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 16 May 2019 14:31:48 +0200 Subject: [PATCH 07/31] Fix c3t3 loading --- .../Plugins/AABB_tree/Cut_plugin.cpp | 28 +++++++++++-------- .../demo/Polyhedron/Scene_c3t3_item.cpp | 15 ++++++++-- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 4ac25e6eee9..7cdc88c9a74 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -791,12 +791,13 @@ class Polyhedron_demo_cut_plugin : Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface) Q_INTERFACES(CGAL::Three::Polyhedron_demo_io_plugin_interface) Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: Polyhedron_demo_cut_plugin() : QObject(), edges_item(0) { } - virtual ~Polyhedron_demo_cut_plugin(); + ~Polyhedron_demo_cut_plugin(); bool applicable(QAction*) const { // returns true if one surface_mesh is in the entries @@ -808,29 +809,30 @@ public: return false; } - virtual QString name() const + QString name() const { return "cut-plugin"; } - virtual QString nameFilters() const + QString nameFilters() const { return "Segment soup file (*.polylines.txt *.cgal)"; } - bool canLoad() const + bool canLoad(QFileInfo) const { return false; } - virtual CGAL::Three::Scene_item* load(QFileInfo /* fileinfo */) + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) { - return 0; + ok = false; + return QList(); } - virtual bool canSave(const CGAL::Three::Scene_item* item) + bool canSave(const CGAL::Three::Scene_item* item) { // This plugin supports edges items bool b = qobject_cast(item) != 0; @@ -838,8 +840,10 @@ public: } - virtual bool save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) - { // This plugin supports edges items + bool save(QFileInfo fileinfo,QList& items) + { + Scene_item* item = items.front(); + // This plugin supports edges items const Scene_edges_item* edges_item = qobject_cast(item); @@ -848,8 +852,10 @@ public: } std::ofstream out(fileinfo.filePath().toUtf8()); - - return (out && edges_item->save(out)); + bool ok = (out && edges_item->save(out)); + if(ok) + items.pop_front(); + return ok; } void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index 8a79e3fe427..7834bca3dd6 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -1633,14 +1633,23 @@ void Scene_c3t3_item::show_intersection(bool b) d->intersection->setName("Intersection tetrahedra"); d->intersection->setRenderingMode(renderingMode()); connect(d->intersection, SIGNAL(destroyed()), this, SLOT(reset_intersection_item())); - scene->addItem(d->intersection); - scene->changeGroup(d->intersection, this); - lockChild(d->intersection); + BOOST_FOREACH(auto v, CGAL::QGLViewer::QGLViewerPool()) { CGAL::Three::Viewer_interface* viewer = static_cast(v); d->are_intersection_buffers_filled[viewer] = false; + if(!d->areInterBufFilled(viewer)) + { + //initGL + Scene_c3t3_item* ncthis = const_cast(this); + ncthis->d->computeIntersections(viewer); + d->are_intersection_buffers_filled[viewer] = true; + ncthis->show_intersection(true); + } } + scene->addItem(d->intersection); + scene->changeGroup(d->intersection, this); + lockChild(d->intersection); } else if (!b && d->intersection!=NULL) { From 0c7ba063a6f8d525b5d893411188de0cf30de670 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 16 May 2019 15:24:02 +0200 Subject: [PATCH 08/31] Add override in cut_plugin --- .../Plugins/AABB_tree/Cut_plugin.cpp | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 7cdc88c9a74..d1472428108 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -799,7 +799,7 @@ public: ~Polyhedron_demo_cut_plugin(); - bool applicable(QAction*) const { + bool applicable(QAction*) const Q_DECL_OVERRIDE{ // returns true if one surface_mesh is in the entries for (int i=0; i< scene->numberOfEntries(); ++i) { @@ -809,30 +809,31 @@ public: return false; } - QString name() const + QString name() const Q_DECL_OVERRIDE { return "cut-plugin"; } - QString nameFilters() const + QString nameFilters() const Q_DECL_OVERRIDE { return "Segment soup file (*.polylines.txt *.cgal)"; } - bool canLoad(QFileInfo) const + bool canLoad(QFileInfo) const Q_DECL_OVERRIDE { return false; } - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) Q_DECL_OVERRIDE + { ok = false; return QList(); } - bool canSave(const CGAL::Three::Scene_item* item) + bool canSave(const CGAL::Three::Scene_item* item) Q_DECL_OVERRIDE { // This plugin supports edges items bool b = qobject_cast(item) != 0; @@ -840,7 +841,7 @@ public: } - bool save(QFileInfo fileinfo,QList& items) + bool save(QFileInfo fileinfo,QList& items) Q_DECL_OVERRIDE { Scene_item* item = items.front(); // This plugin supports edges items @@ -859,10 +860,10 @@ public: } void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, - Messages_interface* m); - QList actions() const; + Messages_interface* m) Q_DECL_OVERRIDE; + QList actions() const Q_DECL_OVERRIDE; - bool eventFilter(QObject *, QEvent *event) + bool eventFilter(QObject *, QEvent *event) Q_DECL_OVERRIDE { if(!plane_item) return false; From 4012cabb11698e17630940b52b48794aacd33361 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 16 May 2019 16:20:40 +0200 Subject: [PATCH 09/31] Fix Plane_items manipulation --- Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h index eb720862a40..53796d48b86 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h @@ -560,7 +560,7 @@ void Volume_plane::draw(Viewer_interface *viewer) const { template bool Volume_plane::eventFilter(QObject *sender, QEvent *event) { - CGAL::QGLViewer* viewer = qobject_cast(sender); + CGAL::Three::Viewer_interface* viewer = qobject_cast(sender); if(!viewer) return false; if(event->type() == QEvent::MouseButtonPress) From 1a08685a2ff038db9bf6259e94743c59c5b3eb12 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 17 May 2019 15:39:03 +0200 Subject: [PATCH 10/31] Add build_items and components to work with real case data --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 4 +- .../Polyhedron/Plugins/IO/3mf_io_plugin.cpp | 48 +++- Stream_support/include/CGAL/IO/read_3mf.h | 268 +++++++++++++++--- Stream_support/include/CGAL/IO/write_3mf.h | 5 + 4 files changed, 274 insertions(+), 51 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index a949b58ded9..c9061238a3f 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1206,8 +1206,7 @@ QList MainWindow::loadItem(QFileInfo fileinfo, } CGAL::Three::Three::CursorScopeGuard guard(QCursor(Qt::WaitCursor)); QList result = loader->load(fileinfo, ok, add_to_scene); - selectSceneItem(scene->item_id(result.back())); - if(!ok) + if(result.empty() || !ok) { QApplication::restoreOverrideCursor(); QMessageBox::warning(this, tr("Error"), @@ -1215,6 +1214,7 @@ QList MainWindow::loadItem(QFileInfo fileinfo, .arg(fileinfo.absoluteFilePath()).arg(loader->name())); return QList(); } + selectSceneItem(scene->item_id(result.back())); for(Scene_item* item : result) { CGAL::Three::Scene_group_item* group = diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp index 6acf62d8768..484724d2a40 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp @@ -80,22 +80,26 @@ class Io_3mf_plugin: int nb_polylines = CGAL::read_polylines_from_3mf(fileinfo.filePath().toUtf8().toStdString(), all_points, all_colors, names); - if(nb_polylines > 0 ) + if(nb_polylines < 0 ) { - for(int i=0; i< nb_polylines; ++i) - { - Scene_polylines_item* pol_item = new Scene_polylines_item(); - PolylineRange& polylines = pol_item->polylines; - polylines.push_back(all_points[i]); - pol_item->setName(names[i].data()); - pol_item->invalidateOpenGLBuffers(); - CGAL::Color c = all_colors[i].front(); - pol_item->setColor(QColor(c.red(), c.green(), c.blue())); - pol_item->setProperty("already_colord", true); - result << pol_item; - if(add_to_scene) - CGAL::Three::Three::scene()->addItem(pol_item); - } + ok = false; + std::cerr << "Error in reading of meshes."<polylines; + polylines.push_back(all_points[i]); + pol_item->setName(names[i].data()); + pol_item->invalidateOpenGLBuffers(); + CGAL::Color c = all_colors[i].front(); + pol_item->setColor(QColor(c.red(), c.green(), c.blue())); + pol_item->setProperty("already_colord", true); + result << pol_item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(pol_item); } all_points.clear(); all_colors.clear(); @@ -103,6 +107,12 @@ class Io_3mf_plugin: int nb_point_sets = CGAL::read_point_clouds_from_3mf(fileinfo.filePath().toUtf8().toStdString(), all_points, all_colors, names); + if(nb_point_sets < 0 ) + { + ok = false; + std::cerr << "Error in reading of meshes."<setColor(QColor(first.red(), first.green(), first.blue())); sm_item->setProperty("already_colored", true); sm_item->setName(names[i].data()); diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h index 062ea68d6a0..3448ca8b7a0 100644 --- a/Stream_support/include/CGAL/IO/read_3mf.h +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -26,24 +26,42 @@ #include #include #include +#include #include namespace CGAL{ +namespace transform_nmr_internal{ +NMR::MODELTRANSFORM initMatrix() +{ + NMR::MODELTRANSFORM mMatrix; + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 3; j++) { + mMatrix.m_fFields[j][i] = (i == j) ? 1.0f : 0.0f; + } + } + + return mMatrix; +} +}//end internal + template bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, - PointRange& points, - PolygonRange& triangles, - ColorRange& colors, - std::string& name) { + const NMR::MODELTRANSFORM& transform, + PointRange& points, + PolygonRange& triangles, + ColorRange& colors, + std::string& name) { typedef typename PointRange::value_type Point_3; typedef typename PolygonRange::value_type Polygon; typedef typename ColorRange::value_type _Color; - + typedef typename Kernel_traits::Kernel Kernel; HRESULT hResult; DWORD nNeededChars; std::vector pBuffer; + // Retrieve Mesh Name Length hResult = NMR::lib3mf_object_getnameutf8(pMeshObject, NULL, 0, &nNeededChars); if (hResult != LIB3MF_OK) @@ -68,6 +86,12 @@ bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, else name = std::string("Unknown Mesh"); + typename Kernel::Aff_transformation_3 t( + transform.m_fFields[0][0], transform.m_fFields[0][1], transform.m_fFields[0][2], transform.m_fFields[0][3], + transform.m_fFields[1][0], transform.m_fFields[1][1], transform.m_fFields[1][2], transform.m_fFields[1][3], + transform.m_fFields[2][0], transform.m_fFields[2][1], transform.m_fFields[2][2], transform.m_fFields[2][3] + ); + NMR::PLib3MFPropertyHandler * pPropertyHandler; hResult = NMR::lib3mf_meshobject_createpropertyhandler(pMeshObject, &pPropertyHandler); if (hResult != LIB3MF_OK) { @@ -84,10 +108,10 @@ bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, { NMR::MODELMESHVERTEX pVertex; NMR::lib3mf_meshobject_getvertex(pMeshObject, vid, &pVertex); - points[vid] = - Point_3(pVertex.m_fPosition[0], + Point_3 p(pVertex.m_fPosition[0], pVertex.m_fPosition[1], pVertex.m_fPosition[2]); + points[vid] = t.transform(p); } for(DWORD pid = 0; pid < triangles.size(); ++pid) { @@ -110,10 +134,11 @@ template bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, - PointRange& points, - PolygonRange&, - ColorRange& colors, - std::string& name) { + const NMR::MODELTRANSFORM& transform, + PointRange& points, + PolygonRange&, + ColorRange& colors, + std::string& name) { typedef typename PointRange::value_type Point_3; typedef typename PolygonRange::value_type Polygon; @@ -175,7 +200,7 @@ bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, 0, &pColor);//get color of the dummy triangle NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0]; colors[0]=CGAL::Color(mColor.m_Red, mColor.m_Green, - mColor.m_Blue, mColor.m_Alpha); + mColor.m_Blue, mColor.m_Alpha); return true; } @@ -183,10 +208,11 @@ template bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject, - PointRange& points, - PolygonRange&, - ColorRange& colors, - std::string& name) { + const NMR::MODELTRANSFORM& transform, + PointRange& points, + PolygonRange&, + ColorRange& colors, + std::string& name) { typedef typename PointRange::value_type Point_3; HRESULT hResult; @@ -246,16 +272,18 @@ bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject, NMR::lib3mf_propertyhandler_getcolor(pPropertyHandler, 0, &pColor);//get color of the dummy triangle NMR::MODELMESHCOLOR_SRGB mColor = pColor.m_Colors[0]; colors[0]=CGAL::Color(mColor.m_Red, mColor.m_Green, - mColor.m_Blue, mColor.m_Alpha); + mColor.m_Blue, mColor.m_Alpha); return true; } + template int read_from_3mf(const std::string& file_name, PointRanges& all_points, - PolygonRanges& all_polygons, ColorRanges& all_colors, + PolygonRanges& all_polygons, ColorRanges& all_colors, std::vector& names, std::function int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, PolygonRanges& all_polygons, ColorRanges& all_colors, std::vector& names - ) + ) { typedef typename PointRanges::value_type PointRange; typedef typename PolygonRanges::value_type PolygonRange; @@ -425,7 +625,7 @@ int read_polylines_from_3mf(const std::string& file_name, PointRanges& all_points, ColorRanges& all_colors, std::vector& names - ) + ) { typedef typename PointRanges::value_type PointRange; typedef std::vector Polygon; @@ -444,7 +644,7 @@ int read_point_clouds_from_3mf(const std::string& file_name, PointRanges& all_points, ColorRanges& all_colors, std::vector& names - ) + ) { typedef typename PointRanges::value_type PointRange; typedef std::vector Polygon; diff --git a/Stream_support/include/CGAL/IO/write_3mf.h b/Stream_support/include/CGAL/IO/write_3mf.h index ac4500a17b2..32a6d23a3f2 100644 --- a/Stream_support/include/CGAL/IO/write_3mf.h +++ b/Stream_support/include/CGAL/IO/write_3mf.h @@ -218,6 +218,9 @@ bool write_mesh_to_model( const PointRange& points, NMR::lib3mf_release(pModel); return -1; } + + //add a builditem to finish + add_build_item(pModel, *pMeshObject); } //remember that it adds 3 demmy vertices in the beginning, and a dummy triangle to be ignored. @@ -314,6 +317,7 @@ bool write_points(const PointRange& points, NMR::lib3mf_release(pModel); return -1; } + add_build_item(pModel, *pMeshObject); } template @@ -390,6 +394,7 @@ bool write_soups_to_3mf(const std::string& file_name, else name = std::string(""); write_mesh_to_model(all_points[id], all_polygons[id], name, &pMeshObject, pModel); + add_build_item(pModel, pMeshObject); //write_mesh_object_to_model(pModel, pMeshObject); } return export_model_to_file(file_name, pModel); From 4b66010b75d92402a2128648437a4dc7300ce013 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 21 May 2019 13:33:05 +0200 Subject: [PATCH 11/31] Fix znear management in orthographic mode --- GraphicsView/include/CGAL/Qt/camera.h | 11 ++++ GraphicsView/include/CGAL/Qt/camera_impl.h | 3 +- Polyhedron/demo/Polyhedron/Viewer.cpp | 60 +++++++++++++++++----- 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h index 5d621bd5d0e..6ff78265792 100644 --- a/GraphicsView/include/CGAL/Qt/camera.h +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -299,6 +299,16 @@ public Q_SLOTS: zClippingCoef_ = coef; projectionMatrixIsUpToDate_ = false; } + /*! Sets the zNear value in orthographic mode. */ + void setOrthoZNear(qreal z) + { + m_zMin = z; + } + /*! Returns the zNear value in orthographic mode*/ + qreal orthoZNear() + { + return m_zMin; + } //@} /*! @name Scene radius and center */ @@ -463,6 +473,7 @@ private: mutable bool modelViewMatrixIsUpToDate_; mutable GLdouble projectionMatrix_[16]; // Buffered projection matrix. mutable bool projectionMatrixIsUpToDate_; + qreal m_zMin; //USed for near plane in orthographic projection. // S t e r e o p a r a m e t e r s qreal IODistance_; // inter-ocular distance, in meters diff --git a/GraphicsView/include/CGAL/Qt/camera_impl.h b/GraphicsView/include/CGAL/Qt/camera_impl.h index 2241ca9a40e..0680c4d8a29 100644 --- a/GraphicsView/include/CGAL/Qt/camera_impl.h +++ b/GraphicsView/include/CGAL/Qt/camera_impl.h @@ -46,6 +46,7 @@ CGAL_INLINE_FUNCTION Camera::Camera(QObject *parent) : frame_(NULL), fieldOfView_(CGAL_PI / 4.0), modelViewMatrixIsUpToDate_(false), projectionMatrixIsUpToDate_(false) { + m_zMin = 0; setParent(parent); // #CONNECTION# Camera copy constructor interpolationKfi_ = new KeyFrameInterpolator; @@ -228,7 +229,7 @@ qreal Camera::zNear() const { z = zMin; break; case Camera::ORTHOGRAPHIC: - z = 0.0; + z = m_zMin; break; } return z; diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index ae26fd47029..a1daacb0a76 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -621,11 +621,23 @@ void Viewer::keyPressEvent(QKeyEvent* e) } else if(e->key() == Qt::Key_M) { d->macro_mode = ! d->macro_mode; - - if(d->macro_mode) { + switch(camera()->type()){ + case CGAL::qglviewer::Camera::PERSPECTIVE: + if(d->macro_mode) { camera()->setZNearCoefficient(0.0005f); - } else { - camera()->setZNearCoefficient(0.005f); + } else { + camera()->setZNearCoefficient(0.005f); + } + break; + case CGAL::qglviewer::Camera::ORTHOGRAPHIC: + if(d->macro_mode) { + camera()->setOrthoZNear(-0.5f); + } else { + camera()->setOrthoZNear(0.0f); + } + break; + deafult: + break; } this->displayMessage(tr("Macro mode: %1"). arg(d->macro_mode ? tr("on") : tr("off"))); @@ -1351,19 +1363,39 @@ QOpenGLShaderProgram* Viewer::getShaderProgram(int name) const void Viewer::wheelEvent(QWheelEvent* e) { - if(e->modifiers().testFlag(Qt::ShiftModifier)) + if(e->modifiers().testFlag(Qt::ShiftModifier)) + { + double delta = e->delta(); + if(delta>0) { - double delta = e->delta(); - if(delta>0) - { - camera()->setZNearCoefficient(camera()->zNearCoefficient() * 1.01); - } - else - camera()->setZNearCoefficient(camera()->zNearCoefficient() / 1.01); - update(); + switch(camera()->type()) + { + case CGAL::qglviewer::Camera::ORTHOGRAPHIC: + camera()->setOrthoZNear(camera()->orthoZNear() + 0.01); + break; + case CGAL::qglviewer::Camera::PERSPECTIVE: + camera()->setZNearCoefficient(camera()->zNearCoefficient() * 1.01); + break; + default: + break; + } } else - CGAL::QGLViewer::wheelEvent(e); + switch(camera()->type()) + { + case CGAL::qglviewer::Camera::ORTHOGRAPHIC: + camera()->setOrthoZNear(camera()->orthoZNear() - 0.01); + break; + case CGAL::qglviewer::Camera::PERSPECTIVE: + camera()->setZNearCoefficient(camera()->zNearCoefficient() / 1.01); + break; + default: + break; + } + update(); + } + else + CGAL::QGLViewer::wheelEvent(e); } bool Viewer::testDisplayId(double x, double y, double z) From f08f69e745318d06815e33c1d4c60b95ae2ba294 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 21 May 2019 13:44:23 +0200 Subject: [PATCH 12/31] fix text items not displayed entirely --- Three/include/CGAL/Three/TextRenderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Three/include/CGAL/Three/TextRenderer.h b/Three/include/CGAL/Three/TextRenderer.h index d9c3417fd21..75a7be68623 100644 --- a/Three/include/CGAL/Three/TextRenderer.h +++ b/Three/include/CGAL/Three/TextRenderer.h @@ -60,7 +60,7 @@ public : :x(p_x), y(p_y), z(p_z),_3D(p_3D), _is_always_visible(always_visible), m_text(p_text), m_font(font), m_color(p_color) { QFontMetrics fm(m_font); - _width = float(fm.width(m_text)); + _width = float(fm.horizontalAdvance(m_text)+2); _height = float(fm.height()); } //!\brief Accessor for the string From 4f8b67e115f889eed779ed733ce2320e04b403a7 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 22 May 2019 13:20:12 +0200 Subject: [PATCH 13/31] Fix nef_3 item normals --- Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index 57b5a2fc816..362c34ee29b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -286,6 +286,14 @@ void Scene_nef_polyhedron_item_priv::compute_normals_and_vertices(void) const Nef_polyhedron::Vector_3 v = f->plane().orthogonal_vector(); + if(f->plane().a() != 0) + v /= f->plane().a(); + else if(f->plane().b() != 0) + v /= f->plane().b(); + else if(f->plane().c() != 0) + v /= f->plane().c(); + else if(f->plane().d() != 0) + v /= f->plane().d(); GLfloat normal[3]; normal[0] = CGAL::to_double(v.x()); normal[1] = CGAL::to_double(v.y()); From c4d774efb87706e48f36c530886452ed71536d1d Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 22 May 2019 15:20:54 +0200 Subject: [PATCH 14/31] Fix return values of bool functions --- Stream_support/include/CGAL/IO/read_3mf.h | 4 ++-- Stream_support/include/CGAL/IO/write_3mf.h | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h index 3448ca8b7a0..1e6d691512d 100644 --- a/Stream_support/include/CGAL/IO/read_3mf.h +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -101,7 +101,7 @@ bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage); std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(pMeshObject); - return -1; + return false; } for(DWORD vid = 0; vid < points.size(); ++vid) @@ -182,7 +182,7 @@ bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, NMR::lib3mf_getlasterror(pMeshObject, &nErrorMessage, &pszErrorMessage); std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(pMeshObject); - return -1; + return false; } points.resize(points.size()-3);//ignore dummy_vertices diff --git a/Stream_support/include/CGAL/IO/write_3mf.h b/Stream_support/include/CGAL/IO/write_3mf.h index 32a6d23a3f2..199764f91bf 100644 --- a/Stream_support/include/CGAL/IO/write_3mf.h +++ b/Stream_support/include/CGAL/IO/write_3mf.h @@ -176,7 +176,7 @@ bool write_mesh_to_model( const PointRange& points, std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); - return -1; + return false; } // define colors @@ -199,7 +199,7 @@ bool write_mesh_to_model( const PointRange& points, std::cerr<< "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); - return -1; + return false; } NMR::MODELMESHCOLOR_SRGB default_color = tmf_internal::fnCreateColor(0,0,0,0); NMR::lib3mf_defaultpropertyhandler_setcolor(pDefaultPropertyHandler, @@ -216,11 +216,11 @@ bool write_mesh_to_model( const PointRange& points, std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); - return -1; + return false; } //add a builditem to finish - add_build_item(pModel, *pMeshObject); + return add_build_item(pModel, *pMeshObject); } //remember that it adds 3 demmy vertices in the beginning, and a dummy triangle to be ignored. @@ -278,7 +278,7 @@ bool write_points(const PointRange& points, std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); - return -1; + return false; } // define colors @@ -298,7 +298,7 @@ bool write_points(const PointRange& points, std::cerr<< "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); - return -1; + return false; } NMR::MODELMESHCOLOR_SRGB default_color = tmf_internal::fnCreateColor(0,0,0,0); NMR::lib3mf_defaultpropertyhandler_setcolor(pDefaultPropertyHandler, @@ -315,9 +315,9 @@ bool write_points(const PointRange& points, std::cerr << "error #" << std::hex << nErrorMessage << ": " << pszErrorMessage << std::endl; NMR::lib3mf_release(*pMeshObject); NMR::lib3mf_release(pModel); - return -1; + return false; } - add_build_item(pModel, *pMeshObject); + return add_build_item(pModel, *pMeshObject); } template @@ -330,7 +330,7 @@ bool write_point_cloud_to_model(const PointRange& points, { std::string pc_name = name; pc_name.append("_cgal_pc"); - write_points(points, color, pc_name, pMeshObject, pModel); + return write_points(points, color, pc_name, pMeshObject, pModel); } template @@ -343,7 +343,7 @@ bool write_polyline_to_model(const PointRange& points, { std::string pc_name = name; pc_name.append("_cgal_pl"); - write_points(points, color, pc_name, pMeshObject, pModel); + return write_points(points, color, pc_name, pMeshObject, pModel); } /*! From dcf8e6bac3b3ce43eda5a15852061fdae9408362 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 24 May 2019 09:54:47 +0200 Subject: [PATCH 15/31] Fix wheel k_ring events --- .../Polyhedron/Scene_polyhedron_selection_item.cpp | 1 + .../demo/Polyhedron/Scene_polyhedron_selection_item.h | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 7f5eded2882..8d244d0a38d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -1779,6 +1779,7 @@ void Scene_polyhedron_selection_item::common_constructor() d->are_temp_buffers_filled = false; d->poly = NULL; d->ready_to_move = false; + do_process = true; setProperty("no_picking", true); setPointContainer(3, diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h index 72ccd68ffea..a2b7be5ea91 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h @@ -879,8 +879,13 @@ protected: if(gen_event->type() == QEvent::Wheel) { QWheelEvent *event = static_cast(gen_event); - int steps = event->delta() / 120; - expand_or_reduce(steps); + int steps = event->angleDelta().y()/120; + if(do_process) + { + expand_or_reduce(steps); + do_process = false; + QTimer::singleShot(0,this, [this](){do_process = true;}); + } return true; } return false; @@ -997,6 +1002,7 @@ protected: Scene_facegraph_item_k_ring_selection k_ring_selector; // action state bool is_insert; + bool do_process; public: // selection From e3229053494182f5912b9065fd964d149dee6dc3 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 27 May 2019 16:27:24 +0200 Subject: [PATCH 16/31] Don't use horizontalAdvance as it was introduced in qt5.11 --- Three/include/CGAL/Three/TextRenderer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Three/include/CGAL/Three/TextRenderer.h b/Three/include/CGAL/Three/TextRenderer.h index 75a7be68623..962b2499964 100644 --- a/Three/include/CGAL/Three/TextRenderer.h +++ b/Three/include/CGAL/Three/TextRenderer.h @@ -60,7 +60,7 @@ public : :x(p_x), y(p_y), z(p_z),_3D(p_3D), _is_always_visible(always_visible), m_text(p_text), m_font(font), m_color(p_color) { QFontMetrics fm(m_font); - _width = float(fm.horizontalAdvance(m_text)+2); + _width = float(fm.width(m_text)+2); _height = float(fm.height()); } //!\brief Accessor for the string From 1160e396f6db9aab85355fb49c6bc6043df77b58 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 27 May 2019 16:33:33 +0200 Subject: [PATCH 17/31] Fix stuffs --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 3 ++- Polyhedron/demo/Polyhedron/Viewer.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index c9061238a3f..6e6a2248a32 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1204,7 +1204,8 @@ QList MainWindow::loadItem(QFileInfo fileinfo, QString("File %1 is not a readable file.") .arg(fileinfo.absoluteFilePath())); } - CGAL::Three::Three::CursorScopeGuard guard(QCursor(Qt::WaitCursor)); + QCursor tmp_cursor(Qt::WaitCursor); + CGAL::Three::Three::CursorScopeGuard guard(tmp_cursor); QList result = loader->load(fileinfo, ok, add_to_scene); if(result.empty() || !ok) { diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index a1daacb0a76..b8210cc0de2 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -636,7 +636,7 @@ void Viewer::keyPressEvent(QKeyEvent* e) camera()->setOrthoZNear(0.0f); } break; - deafult: + default: break; } this->displayMessage(tr("Macro mode: %1"). From 30bb614ed076dc231dbd00e09f35d11ba64c06b9 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 28 May 2019 11:44:13 +0200 Subject: [PATCH 18/31] Fix plugins --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 2 - .../Plugins/AABB_tree/Cut_plugin.cpp | 2 +- .../Plugins/IO/Polylines_io_plugin.cpp | 2 +- .../Polyhedron/Plugins/IO/VTK_io_plugin.cpp | 52 ++++++++++++++----- .../Plugins/Mesh_3/Io_image_plugin.cpp | 2 +- .../Plugins/PMP/Selection_plugin.cpp | 2 +- 6 files changed, 43 insertions(+), 19 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 6e6a2248a32..9ebbe521004 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1173,7 +1173,6 @@ void MainWindow::open(QString filename) bool MainWindow::open(QString filename, QString loader_name) { QFileInfo fileinfo(filename); boost::optional item_opt; - CGAL::Three::Scene_item* item = 0; try { item_opt = wrap_a_call_to_cpp ([this, fileinfo, loader_name]() @@ -1185,7 +1184,6 @@ bool MainWindow::open(QString filename, QString loader_name) { this, __FILE__, __LINE__ ); if(!item_opt) return false; - //else item = *item_opt; } catch(std::logic_error& e) { std::cerr << e.what() << std::endl; diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index d1472428108..8df17c89083 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -860,7 +860,7 @@ public: } void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, - Messages_interface* m) Q_DECL_OVERRIDE; + Messages_interface* m) override; QList actions() const Q_DECL_OVERRIDE; bool eventFilter(QObject *, QEvent *event) Q_DECL_OVERRIDE diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index f5898b953bc..7c3b0c7e264 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -27,7 +27,7 @@ public: //! Configures the widget void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, - Messages_interface*) { + Messages_interface*) override{ //get the references this->scene = scene_interface; this->mw = mainWindow; diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp index cc235ee91a2..b21c1a21d5d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/VTK_io_plugin.cpp @@ -308,8 +308,9 @@ public: } - bool save(const CGAL::Three::Scene_item* item, QFileInfo fileinfo) + bool save(QFileInfo fileinfo,QList& items) { + Scene_item* item = items.front(); std::string extension = fileinfo.suffix().toLower().toStdString(); if ( extension != "vtk" && extension != "vtp" && extension != "vtu") return false; @@ -356,10 +357,11 @@ public: CGAL::output_to_vtu(os, c3t3); } + items.pop_front(); return true; } - bool canLoad() const { return true; } + bool canLoad(QFileInfo) const { return true; } template vtkSmartPointer @@ -374,11 +376,14 @@ public: return reader; } - CGAL::Three::Scene_item* load(QFileInfo fileinfo) + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { std::string extension=fileinfo.suffix().toLower().toStdString(); if (extension != "vtk" && extension != "vtp" && extension != "vtu") - return 0; + { + ok = false; + return QList(); + } std::string fname = fileinfo.absoluteFilePath().toStdString(); @@ -389,7 +394,10 @@ public: Scene_facegraph_item* item = new Scene_facegraph_item(); item->setName(fileinfo.completeBaseName()); - return item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(item); + return QList()< data; @@ -421,7 +429,8 @@ public: msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Critical); msgBox.exec(); - return NULL; + ok = false; + return QList(); } if (obs->GetWarning()) { @@ -442,7 +451,8 @@ public: msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Critical); msgBox.exec(); - return NULL; + ok = false; + return QList(); } if (obs->GetWarning()) { @@ -491,7 +501,10 @@ public: } else{ poly_item->setName(fileinfo.baseName()); - return poly_item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(poly_item); + return QList()<setName(fileinfo.baseName()); - return c3t3_item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(c3t3_item); + return QList()<setName(fileinfo.baseName()); - return polyline_item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(polyline_item); + return QList()<addItem(group); + return QList()<point_set()->insert(Point_3(p[0], p[1], p[2])); } point_item->setName(fileinfo.baseName()); - return point_item; + ok = true; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(point_item); + return QList()<message_interface = mi; this->scene = scene_interface; this->mw = mainWindow; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index 22a29ef9991..f9f946cb59e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -132,7 +132,7 @@ public: void print_message(QString message) { CGAL::Three::Three::information(message); } QList actions() const { return QList() << actionSelection; } - void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) { + void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override{ mw = mainWindow; scene = scene_interface; messages = m; From 736461b8f25a28331f096fc2faa8d08425032174 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 28 May 2019 13:31:46 +0200 Subject: [PATCH 19/31] Fix polylines/c3t3 reading --- .../demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp | 10 ++++++++++ .../demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp | 2 ++ 2 files changed, 12 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index 7c3b0c7e264..16d06fb67fb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -86,6 +86,16 @@ private: }; bool Polyhedron_demo_polylines_io_plugin::canLoad(QFileInfo fileinfo) const{ + if(!fileinfo.suffix().contains("cgal")) + return true; + std::ifstream in(fileinfo.filePath().toUtf8()); + if(!in) { + return false; + } + int first; + if(!(in >> first) + || first <= 0) + return false; return true; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp index 15a93660153..7e7de0d7e2c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp @@ -36,6 +36,8 @@ private: bool Polyhedron_demo_c3t3_binary_io_plugin::canLoad(QFileInfo fi) const { + if(!fi.suffix().contains("cgal")) + return true; std::ifstream in(fi.filePath().toUtf8(), std::ios_base::in|std::ios_base::binary); if(!in) { From 79008f16187f8014b9e9e6910d430f21aacc58ff Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 28 May 2019 14:03:27 +0200 Subject: [PATCH 20/31] Fix warnings --- .../demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp | 3 ++- .../Plugins/Camera_position/Camera_positions_plugin.cpp | 8 +++++++- Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp | 2 +- Polyhedron/demo/Polyhedron/Plugins/IO/LAS_io_plugin.cpp | 2 +- .../demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp | 2 +- Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp | 2 +- Stream_support/include/CGAL/IO/read_3mf.h | 8 ++------ 7 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 8df17c89083..d32bb11e8b5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -826,9 +826,10 @@ public: return false; } - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) Q_DECL_OVERRIDE + QList load(QFileInfo , bool& ok, bool add_to_scene=true) Q_DECL_OVERRIDE { + CGAL_UNUSED(add_to_scene); ok = false; return QList(); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp index c4823cd01aa..0c149a40cff 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp @@ -23,7 +23,13 @@ public: QString name() const { return "camera_positions_plugin"; } QString nameFilters() const { return "Camera positions (*.camera.txt)"; } bool canLoad(QFileInfo) const { return true; } - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) { ok = true; cpl->load(fileinfo.filePath()); return QList(); } + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) + { + Q_UNUSED(add_to_scene); + ok = true; + cpl->load(fileinfo.filePath()); + return QList(); + } bool canSave(const Scene_item*) { return false; } bool save(QFileInfo,QList& ) {return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp index 484724d2a40..553d560656c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp @@ -141,7 +141,7 @@ class Io_3mf_plugin: std::cerr << "Error in reading of meshes."<& ); }; -bool Polyhedron_demo_las_plugin::canLoad(QFileInfo fileinfo) const { +bool Polyhedron_demo_las_plugin::canLoad(QFileInfo ) const { return true; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp index 3366e1dbb68..0f04fcd2dbf 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/OFF_to_nef_io_plugin.cpp @@ -63,7 +63,7 @@ bool Polyhedron_demo_off_to_nef_plugin::canSave(const CGAL::Three::Scene_item*) } bool Polyhedron_demo_off_to_nef_plugin:: -save(QFileInfo fileinfo,QList& items) +save(QFileInfo ,QList&) { return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp index 6b0e4b8708e..c9ac059823d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Surf_io_plugin.cpp @@ -34,7 +34,7 @@ public: QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); bool canSave(const CGAL::Three::Scene_item*) { return false; } - bool save(QFileInfo fileinfo,QList& ) { return false; } + bool save(QFileInfo ,QList& ) { return false; } }; diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h index 1e6d691512d..f528c79de2f 100644 --- a/Stream_support/include/CGAL/IO/read_3mf.h +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -56,7 +56,6 @@ bool extract_soups (NMR::PLib3MFModelMeshObject *pMeshObject, std::string& name) { typedef typename PointRange::value_type Point_3; typedef typename PolygonRange::value_type Polygon; - typedef typename ColorRange::value_type _Color; typedef typename Kernel_traits::Kernel Kernel; HRESULT hResult; DWORD nNeededChars; @@ -134,13 +133,12 @@ template bool extract_polylines (NMR::PLib3MFModelMeshObject *pMeshObject, - const NMR::MODELTRANSFORM& transform, + const NMR::MODELTRANSFORM& , PointRange& points, PolygonRange&, ColorRange& colors, std::string& name) { typedef typename PointRange::value_type Point_3; - typedef typename PolygonRange::value_type Polygon; HRESULT hResult; DWORD nNeededChars; @@ -208,7 +206,7 @@ template bool extract_point_clouds (NMR::PLib3MFModelMeshObject *pMeshObject, - const NMR::MODELTRANSFORM& transform, + const NMR::MODELTRANSFORM&, PointRange& points, PolygonRange&, ColorRange& colors, @@ -290,8 +288,6 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, std::string&)> func ) { - typedef typename PointRange::value_type Point_3; - typedef typename PolygonRange::value_type Polygon; DWORD nInterfaceVersionMajor, nInterfaceVersionMinor, nInterfaceVersionMicro, nbVertices, nbPolygons; HRESULT hResult; NMR::PLib3MFModel * pModel; From 6c581bac7fb06599aee626a8814302b5cf6efacf Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 29 May 2019 09:39:53 +0200 Subject: [PATCH 21/31] Don't use CGAL_UNUSED --- Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index d32bb11e8b5..5ff4e16e3a5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -829,7 +829,7 @@ public: QList load(QFileInfo , bool& ok, bool add_to_scene=true) Q_DECL_OVERRIDE { - CGAL_UNUSED(add_to_scene); + Q_UNUSED(add_to_scene); ok = false; return QList(); } From ef26c37b75d61081c30c033951ae52c1ef62a585 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Wed, 29 May 2019 09:45:48 +0200 Subject: [PATCH 22/31] Try to fix cmake bug on Blake --- Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index 5c8bf384e39..d0f070f1c1c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -79,6 +79,8 @@ else() ) if(IS_DIRECTORY "${3MF_INCLUDE_DIR}/Common") set(3MF_FOUND true) + else() + set(3MF_FOUND false) endif() find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library") From d34ac7b14bf7b51e98cf0072077b0b7415cbede5 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 31 May 2019 10:22:21 +0200 Subject: [PATCH 23/31] Fix override and shadow warnings for clang --- .../Plugins/AABB_tree/Cut_plugin.cpp | 1 + .../Camera_positions_plugin.cpp | 2 +- .../IO/Implicit_function_io_plugin.cpp | 1 - .../Plugins/IO/Polylines_io_plugin.cpp | 17 +++++++------- .../Plugins/Mesh_3/C3t3_io_plugin.cpp | 1 - .../Plugins/Mesh_3/Io_image_plugin.cpp | 20 ++++++++--------- .../Plugins/PMP/Selection_plugin.cpp | 22 +++++++++---------- 7 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 5ff4e16e3a5..4160a9b84d1 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -860,6 +860,7 @@ public: return ok; } + using Polyhedron_demo_plugin_interface::init; void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override; QList actions() const Q_DECL_OVERRIDE; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp index 0c149a40cff..29179170419 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp @@ -18,7 +18,7 @@ class Polyhedron_demo_camera_positions_plugin : Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: - void init(); + void init() override; QString name() const { return "camera_positions_plugin"; } QString nameFilters() const { return "Camera positions (*.camera.txt)"; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp index 928e974cf8b..24ddcc7a818 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Implicit_function_io_plugin.cpp @@ -42,7 +42,6 @@ using namespace CGAL::Three; class Io_implicit_function_plugin : public QObject, - // public Polyhedron_demo_plugin_interface, protected Polyhedron_demo_plugin_helper { Q_OBJECT diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp index 16d06fb67fb..d86309749f8 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/Polylines_io_plugin.cpp @@ -24,6 +24,7 @@ public: // To silent a warning -Woverloaded-virtual // See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings + using Polyhedron_demo_io_plugin_interface::init; //! Configures the widget void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, @@ -43,14 +44,14 @@ public: connect(actionJoin_polylines, &QAction::triggered, this, &Polyhedron_demo_polylines_io_plugin::join); } - QString name() const { return "polylines_io_plugin"; } - QString nameFilters() const { return "Polylines files (*.polylines.txt *.cgal)"; } - bool canLoad(QFileInfo fileinfo) const; - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); + QString name() const override{ return "polylines_io_plugin"; } + QString nameFilters() const override{ return "Polylines files (*.polylines.txt *.cgal)"; } + bool canLoad(QFileInfo fileinfo) const override; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override; - bool canSave(const CGAL::Three::Scene_item*); - bool save(QFileInfo fileinfo,QList&); - bool applicable(QAction* a) const { + bool canSave(const CGAL::Three::Scene_item*) override; + bool save(QFileInfo fileinfo,QList&) override; + bool applicable(QAction* a) const override{ bool all_polylines_selected = true; Q_FOREACH(int index, scene->selectionIndices()) { @@ -69,7 +70,7 @@ public: else return false; } - QList actions() const { + QList actions() const override{ return QList()<(scene->item(scene->mainSelectionIndex())); } - + using Polyhedron_demo_plugin_interface::init; void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface *mi) override { this->message_interface = mi; this->scene = scene_interface; @@ -270,10 +270,10 @@ public: } } } - QList actions() const { + QList actions() const override{ return QList() << planeSwitch; } - virtual void closure() + virtual void closure() override { QDockWidget* controlDockWidget = mw->findChild("volumePlanesControl"); if(controlDockWidget) @@ -281,12 +281,12 @@ public: } Io_image_plugin() : planeSwitch(NULL) {} - QString nameFilters() const; - bool canLoad(QFileInfo) const; - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); + QString nameFilters() const override; + bool canLoad(QFileInfo) const override; + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override; - bool canSave(const CGAL::Three::Scene_item*); - bool save(QFileInfo fileinfo, QList& items ) { + bool canSave(const CGAL::Three::Scene_item*) override; + bool save(QFileInfo fileinfo, QList& items ) override{ Scene_item* item = items.front(); const Scene_image_item* im_item = qobject_cast(item); @@ -295,7 +295,7 @@ public: items.pop_front(); return ok; } - QString name() const { return "segmented images"; } + QString name() const override{ return "segmented images"; } public Q_SLOTS: diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index f9f946cb59e..7169c7efd4f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -75,10 +75,10 @@ class Polyhedron_demo_selection_plugin : Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "selection_plugin.json") Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90") public: - QString nameFilters() const { return "Selection files(*.selection.txt)"; } - QString name() const { return "selection_sm_plugin"; } + QString nameFilters() const override { return "Selection files(*.selection.txt)"; } + QString name() const override { return "selection_sm_plugin"; } - bool canLoad(QFileInfo) const { + bool canLoad(QFileInfo) const override { Scene_item * item = CGAL::Three::Three::scene()->item( CGAL::Three::Three::scene()->mainSelectionIndex()); Scene_facegraph_item* fg_item = qobject_cast(item); @@ -91,7 +91,7 @@ public: return false; } - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) { + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override { if(fileinfo.suffix().toLower() != "txt") { ok = false; @@ -111,10 +111,10 @@ public: return QList()<(scene_item); } - bool save(QFileInfo fileinfo,QList& items) { + bool save(QFileInfo fileinfo,QList& items) override { Scene_item* scene_item = items.front(); const Scene_polyhedron_selection_item* item = qobject_cast(scene_item); if(item == NULL) { return false; } @@ -125,14 +125,14 @@ public: return res; } - bool applicable(QAction*) const { + bool applicable(QAction*) const override { return qobject_cast(scene->item(scene->mainSelectionIndex())) || qobject_cast(scene->item(scene->mainSelectionIndex())); } void print_message(QString message) { CGAL::Three::Three::information(message); } - QList actions() const { return QList() << actionSelection; } - - void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override{ + QList actions() const override { return QList() << actionSelection; } + using Polyhedron_demo_io_plugin_interface::init; + virtual void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override{ mw = mainWindow; scene = scene_interface; messages = m; @@ -216,7 +216,7 @@ public: operations_map[operations_strings[8]] = 8; operations_map[operations_strings[9]] = 9; } - virtual void closure() + virtual void closure() override { dock_widget->hide(); } From 0dc66db1958df1b7042aacaa0a0a654f4f021206 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 31 May 2019 10:44:05 +0200 Subject: [PATCH 24/31] Don't use default path in 3MF find_path to avoid VTK interfering (at least on Blake, that's the reason the testsuite is red over there.) --- Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index d0f070f1c1c..370166a697f 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -73,7 +73,7 @@ else() message(STATUS "NOTICE : the LAS IO plugin needs LAS libraries and will not be compiled.") endif() - find_path(3MF_INCLUDE_DIR + find_path(3MF_INCLUDE_DIR NO_DEFAULT_PATH NAMES Common Model DOC "Path to lib3MF headers" ) From 87f7a68ed0cf6f7b4a3ff90a496f0d8d2600916a Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 3 Jun 2019 10:10:39 +0200 Subject: [PATCH 25/31] Fix find_path and don't make blue results if 3mf not found --- .../demo/Polyhedron/Plugins/IO/CMakeLists.txt | 35 ++++++++----------- .../test/Stream_support/CMakeLists.txt | 13 +++---- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index 370166a697f..809ff9f9ada 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -57,7 +57,7 @@ list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_rvalue_references has_cxx_rvalues) list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_variadic_templates has_cxx_variadic) if(has_cxx_rvalues LESS 0 OR has_cxx_variadic LESS 0) - message(STATUS "NOTICE: LAS/PLY IO examples require a C++11 compiler and will not be compiled.") + message(STATUS "NOTICE : LAS/PLY IO examples require a C++11 compiler and will not be compiled.") else() set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates) @@ -72,23 +72,18 @@ else() else() message(STATUS "NOTICE : the LAS IO plugin needs LAS libraries and will not be compiled.") endif() - - find_path(3MF_INCLUDE_DIR NO_DEFAULT_PATH - NAMES Common Model - DOC "Path to lib3MF headers" - ) - if(IS_DIRECTORY "${3MF_INCLUDE_DIR}/Common") - set(3MF_FOUND true) - else() - set(3MF_FOUND false) - endif() - find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library") - - if(3MF_FOUND) - include_directories(${3MF_INCLUDE_DIR}) - polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO) - target_link_libraries(3mf_io_plugin PRIVATE scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item ${3MF_LIBRARIES}) - else() - message(STATUS "NOTICE: The 3mf_io_plugin requires the lib3MF library, and will not be compiled.") - endif() +endif() + +find_path(3MF_INCLUDE_DIR + NAMES Model/COM/NMR_DLLInterfaces.h + DOC "Path to lib3MF headers" + ) +find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library") + +if(3MF_LIBRARIES AND 3MF_INCLUDE_DIR) + include_directories(${3MF_INCLUDE_DIR}) + polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO) + target_link_libraries(3mf_io_plugin PRIVATE scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item ${3MF_LIBRARIES}) +else() + message(STATUS "NOTICE : The 3mf_io_plugin requires the lib3MF library, and will not be compiled.") endif() diff --git a/Stream_support/test/Stream_support/CMakeLists.txt b/Stream_support/test/Stream_support/CMakeLists.txt index f9905b79012..147767cad3f 100644 --- a/Stream_support/test/Stream_support/CMakeLists.txt +++ b/Stream_support/test/Stream_support/CMakeLists.txt @@ -9,24 +9,21 @@ cmake_minimum_required(VERSION 3.1) find_package(CGAL QUIET) if ( CGAL_FOUND ) find_path(3MF_INCLUDE_DIR - NAMES Common Model - DOC "Path to lib3MF headers" - ) - if(IS_DIRECTORY "${3MF_INCLUDE_DIR}/Common") - set(3MF_FOUND true) - endif() + NAMES Model/COM/NMR_DLLInterfaces.h + DOC "Path to lib3MF headers" + ) find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library") # create a target per cppfile file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) foreach(cppfile ${cppfiles}) if ( "${cppfile}" STREQUAL "test_3mf_to_sm.cpp" ) - if(3MF_FOUND) + if(3MF_LIBRARIES AND 3MF_INCLUDE_DIR) include_directories(${3MF_INCLUDE_DIR}) create_single_source_cgal_program( "${cppfile}" ) target_link_libraries(test_3mf_to_sm PRIVATE ${3MF_LIBRARIES}) else() - message(STATUS "NOTICE: This program requires the lib3MF library, and will not be compiled.") + message(STATUS "NOTICE : This program requires the lib3MF library, and will not be compiled.") endif() else() create_single_source_cgal_program( "${cppfile}" ) From ef17e71efaf54ae0cee9d46a4d928bfebc9363e2 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 3 Jun 2019 10:14:43 +0200 Subject: [PATCH 26/31] Fix remaining warnings --- .../demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp | 2 +- .../Camera_position/Camera_positions_plugin.cpp | 12 ++++++------ .../Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 4160a9b84d1..2619db2aca5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -860,7 +860,7 @@ public: return ok; } - using Polyhedron_demo_plugin_interface::init; + using Polyhedron_demo_io_plugin_interface::init; void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override; QList actions() const Q_DECL_OVERRIDE; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp index 29179170419..0af8d9491ca 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_plugin.cpp @@ -20,10 +20,10 @@ class Polyhedron_demo_camera_positions_plugin : public: void init() override; - QString name() const { return "camera_positions_plugin"; } - QString nameFilters() const { return "Camera positions (*.camera.txt)"; } - bool canLoad(QFileInfo) const { return true; } - QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) + QString name() const override { return "camera_positions_plugin"; } + QString nameFilters() const override { return "Camera positions (*.camera.txt)"; } + bool canLoad(QFileInfo) const override { return true; } + QList load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true) override { Q_UNUSED(add_to_scene); ok = true; @@ -31,8 +31,8 @@ public: return QList(); } - bool canSave(const Scene_item*) { return false; } - bool save(QFileInfo,QList& ) {return false; } + bool canSave(const Scene_item*) override { return false; } + bool save(QFileInfo,QList& ) override {return false; } private: Camera_positions_list* cpl; }; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp index 1d4ab9a733b..fb15ee12af6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -215,7 +215,7 @@ public: return qobject_cast(scene->item(scene->mainSelectionIndex())); } - using Polyhedron_demo_plugin_interface::init; + using Polyhedron_demo_io_plugin_interface::init; void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface *mi) override { this->message_interface = mi; this->scene = scene_interface; From 5c6f20e1ec7c5d0c1454c04133d61171b957f902 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 6 Jun 2019 13:04:47 +0200 Subject: [PATCH 27/31] add a writing function for meshes --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 4 - .../Polyhedron/Plugins/IO/3mf_io_plugin.cpp | 1 - Stream_support/include/CGAL/IO/write_3mf.h | 77 +++++++++++++++++-- .../test/Stream_support/test_3mf_to_sm.cpp | 5 ++ 4 files changed, 76 insertions(+), 11 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 9ebbe521004..879294d57db 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1004,8 +1004,6 @@ void MainWindow::reloadItem() { if(!ok) return; QVariant varian = item->property("load_mates"); - if (!varian.canConvert()) - qDebug()<<"Well, that's gonna be a problem !"; QSequentialIterable iterable = varian.value(); // Can use foreach: int mate_id = 0; @@ -1013,8 +1011,6 @@ void MainWindow::reloadItem() { { Scene_item* mate = v.value(); Scene_item* new_item = new_items[mate_id]; - if(!new_item) - qDebug()<<"That too, is gonna be a problem..."; new_item->setName(mate->name()); new_item->setColor(mate->color()); new_item->setRenderingMode(mate->renderingMode()); diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp index 553d560656c..b72e3cb1971 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp @@ -169,7 +169,6 @@ class Io_3mf_plugin: } if(need_pmap) { - //todo: check if possibility to store pid as property or not SMesh::Property_map fcolor = mesh.add_property_map("f:color",first).first; for(std::size_t pid = 0; pid < colors.size(); ++pid) diff --git a/Stream_support/include/CGAL/IO/write_3mf.h b/Stream_support/include/CGAL/IO/write_3mf.h index 199764f91bf..de335110f3c 100644 --- a/Stream_support/include/CGAL/IO/write_3mf.h +++ b/Stream_support/include/CGAL/IO/write_3mf.h @@ -23,7 +23,11 @@ #include #include #include + +#include + #include "Model/COM/NMR_DLLInterfaces.h" + namespace CGAL{ namespace tmf_internal{ // Utility functions to create vertices and triangles @@ -347,8 +351,8 @@ bool write_polyline_to_model(const PointRange& points, } /*! - * \brief write_soups_to_3mf will write the polygon soups contained in all_points and - * all_polygons into the file named `file_name`, in the 3mf format. + * \brief writes the triangle soups contained in `all_points` and + * `all_polygons` into the 3mf file `file_name`. * \tparam PointRanges a model of the concepts `RandomAccessContainer` and * `BackInsertionSequence` whose `value type` is * a model of the concepts `RandomAccessContainer` and `BackInsertionSequence` @@ -366,7 +370,7 @@ bool write_polyline_to_model(const PointRange& points, * \return `true` if the writing is successful, `false` otherwise. */ template -bool write_soups_to_3mf(const std::string& file_name, +bool write_triangle_soups_to_3mf(const std::string& file_name, const PointRanges& all_points, const PolygonRanges& all_polygons, const std::vector& names) @@ -393,11 +397,72 @@ bool write_soups_to_3mf(const std::string& file_name, } else name = std::string(""); - write_mesh_to_model(all_points[id], all_polygons[id], name, &pMeshObject, pModel); - add_build_item(pModel, pMeshObject); - //write_mesh_object_to_model(pModel, pMeshObject); + std::vector colors(all_polygons[id].size()); + write_mesh_to_model(all_points[id], all_polygons[id], colors, name, &pMeshObject, pModel); } return export_model_to_file(file_name, pModel); } + + +/*! + * \brief writes the triangle meshes contained in `tms` + * into the 3mf file `file_name`. + * \tparam TriangleMeshRange a model of the concepts `RandomAccessContainer` + * and `BackInsertionSequence` whose `value type` is + * a model of the concepts `FaceListGraph` and `HalfedgeListGraph` + * that has only triangle faces. + * \param file_name the name of the 3mf file to write. + * \param tms a `TriangleMeshRange` that contains the meshes + * to write. An internal property map for `CGAL::vertex_point_t` + * must be available for each mesh. + * \param names will contains the name of each mesh in `file_name`. + * \return `true` if the writing is successful, `false` otherwise. + */ +template +bool write_triangle_meshes_to_3mf(const std::string& file_name, + const TriangleMeshRange& tms, + const std::vector& names) +{ + typedef typename TriangleMeshRange::value_type Mesh; + typedef typename boost::property_map::type VPMap; + typedef typename boost::property_traits::value_type Point_3; + + typedef std::vector Polygon; + typedef std::vector PolygonRange; + + typedef std::vector PointRange; + + std::vector all_points; + std::vector all_polygons; + + + for(auto tm : tms) + { + PointRange points; + PolygonRange triangles; + VPMap vpm = get(boost::vertex_point, tm); + std::unordered_map::vertex_descriptor, + std::size_t> vertex_id_map; + std::size_t i = 0; + for(auto v : vertices(tm)) + { + points.push_back(get(vpm, v)); + vertex_id_map[v] = i++; + } + all_points.push_back(points); + for(auto f : faces(tm)) + { + Polygon triangle; + for(auto vert : CGAL::vertices_around_face(halfedge(f, tm), tm)) + { + triangle.push_back(vertex_id_map[vert]); + } + triangles.push_back(triangle); + } + all_polygons.push_back(triangles); + } + + return write_triangle_soups_to_3mf(file_name, all_points, all_polygons, names); +} }//end CGAL #endif // WRITE_3MF_H diff --git a/Stream_support/test/Stream_support/test_3mf_to_sm.cpp b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp index a2c1fe8dbab..31578a5bca5 100644 --- a/Stream_support/test/Stream_support/test_3mf_to_sm.cpp +++ b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp @@ -159,6 +159,11 @@ int main(int argc, char** argv) names.push_back(std::string("sphere")); names.push_back(std::string("tube")); + std::vector meshes(2); + meshes[0] = sphere; + meshes[1] = tube; + CGAL::write_triangle_meshes_to_3mf("meshes.3mf", meshes, names); + //testing of point clouds DWORD nErrorMessage; From 1970d94c5329397be8babadf5f5f4e63571bb813 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 17 Jun 2019 14:03:55 +0200 Subject: [PATCH 28/31] Add a function to Surface_mesh that reads a range of surface_meshes from a 3mf file. --- Stream_support/include/CGAL/IO/read_3mf.h | 15 +-- .../test/Stream_support/test_3mf_to_sm.cpp | 49 +++---- .../include/CGAL/Surface_mesh/IO/3mf.h | 125 ++++++++++++++++++ 3 files changed, 148 insertions(+), 41 deletions(-) create mode 100644 Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h index f528c79de2f..1d6ee3cd3d4 100644 --- a/Stream_support/include/CGAL/IO/read_3mf.h +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -18,8 +18,8 @@ // // Author(s) : Maxime Gimeno -#ifndef READ_3MF_H -#define READ_3MF_H +#ifndef CGAL_IO_READ_3MF_H +#define CGAL_IO_READ_3MF_H #include #include #include @@ -43,7 +43,7 @@ NMR::MODELTRANSFORM initMatrix() return mMatrix; } -}//end internal +}//end transform_nmr_internal template 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 -#endif // READ_3MF_H +#endif // CGAL_IO_READ_3MF_H diff --git a/Stream_support/test/Stream_support/test_3mf_to_sm.cpp b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp index 31578a5bca5..5c96e769ed9 100644 --- a/Stream_support/test/Stream_support/test_3mf_to_sm.cpp +++ b/Stream_support/test/Stream_support/test_3mf_to_sm.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -27,49 +28,31 @@ typedef std::vector ColorRange; int main(int argc, char** argv) { - if( argc != 2) - { - std::cerr<<"please give an input 3mf file."; - return 1; - } + const char* file_name=(argc == 2) ? argv[1] : "data/test.3mf"; + std::vector all_points; std::vector all_polygons; std::vector all_colors; std::vector names; + std::vector meshes; //testing reading functions. int nb_meshes = - CGAL::read_soups_from_3mf(argv[1], all_points, all_polygons, - all_colors, names); + CGAL::read_3mf(file_name, meshes); if(nb_meshes <0) return 1; for(std::size_t i = 0; i< nb_meshes; ++i) { - PolygonRange triangles = all_polygons[i]; - PointRange points = all_points[i]; - bool ok = true; - if(!PMP::is_polygon_soup_a_polygon_mesh(triangles)) - ok = PMP::orient_polygon_soup(points, triangles); - if(!ok) - { - std::cerr<<"Object is not orientable. Skipped."< meshes(2); + meshes.resize(2); meshes[0] = sphere; meshes[1] = tube; CGAL::write_triangle_meshes_to_3mf("meshes.3mf", meshes, names); diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h new file mode 100644 index 00000000000..36acfa11e37 --- /dev/null +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h @@ -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 +#include +#include + +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 +int read_3mf(const std::string& file_name, + std::vector >& output) +{ + typedef std::vector PointRange; + typedef std::vector Polygon; + typedef std::vector PolygonRange; + typedef CGAL::Surface_mesh SMesh; + typedef typename SMesh::Vertex_index Vertex_index; + typedef typename SMesh::Face_index Face_index; + + std::vector all_points; + std::vector all_polygons; + std::vector names; + std::vector > 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."< 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 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 fcolor = + sm.template add_property_map("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 From 7de29bdd9373f68ca288aea1ca4f436ade1356c4 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 17 Jun 2019 14:06:12 +0200 Subject: [PATCH 29/31] update doc --- Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h index 36acfa11e37..1fd956c8e76 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h @@ -29,11 +29,10 @@ 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`. + *\tparam Point the Point type of the output meshes. * \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. + * \param output a `std::vector` containing the `CGAL::Surface_mesh`s that will be filled by this function. + * \return the number of extracted meshes. */ template From c5174f693c89bcdd0b00835968c5e50d1b4be66f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 17 Jun 2019 14:07:27 +0200 Subject: [PATCH 30/31] Rename soup function --- Stream_support/include/CGAL/IO/read_3mf.h | 2 +- Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Stream_support/include/CGAL/IO/read_3mf.h b/Stream_support/include/CGAL/IO/read_3mf.h index 1d6ee3cd3d4..cbd1dbd6c40 100644 --- a/Stream_support/include/CGAL/IO/read_3mf.h +++ b/Stream_support/include/CGAL/IO/read_3mf.h @@ -600,7 +600,7 @@ int read_from_3mf(const std::string& file_name, PointRanges& all_points, * \return the number of soups read. */ template -int read_soups_from_3mf(const std::string& file_name, PointRanges& all_points, +int read_triangle_soups_from_3mf(const std::string& file_name, PointRanges& all_points, PolygonRanges& all_polygons, ColorRanges& all_colors, std::vector& names ) diff --git a/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h b/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h index 1fd956c8e76..4ca44a0e890 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/IO/3mf.h @@ -52,7 +52,7 @@ int read_3mf(const std::string& file_name, std::vector > all_colors; int result = 0; int nb_meshes = - CGAL::read_soups_from_3mf(file_name, + CGAL::read_triangle_soups_from_3mf(file_name, all_points, all_polygons, all_colors, names); if(nb_meshes < 0 ) { From 86ca13a388767e036f63b88e0cb6f85aae8d974f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 17 Jun 2019 14:11:32 +0200 Subject: [PATCH 31/31] change behavior when soup is not orientable in the demo. --- .../Polyhedron/Plugins/IO/3mf_io_plugin.cpp | 61 +++++++++---------- Stream_support/include/CGAL/IO/write_3mf.h | 8 +-- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp index b72e3cb1971..4b3c921dce5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/3mf_io_plugin.cpp @@ -133,7 +133,7 @@ class Io_3mf_plugin: names.clear(); all_colors.clear(); int nb_meshes = - CGAL::read_soups_from_3mf(fileinfo.filePath().toUtf8().toStdString(), + CGAL::read_triangle_soups_from_3mf(fileinfo.filePath().toUtf8().toStdString(), all_points, all_polygons, all_colors, names); if(nb_meshes <0 ) { @@ -151,42 +151,39 @@ class Io_3mf_plugin: ok = PMP::orient_polygon_soup(points, triangles); if(!ok) { - std::cerr<<"Object is not orientable. Skipped."< fcolor = - mesh.add_property_map("f:color",first).first; - for(std::size_t pid = 0; pid < colors.size(); ++pid) - { - put(fcolor, face_descriptor(pid), colors[pid]);//should work bc mesh is just created and shouldn't have any destroyed face. Not so sure bc of orientation though. - } - } - Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(mesh); - if(first == CGAL::Color(0,0,0,0)) - first = CGAL::Color(50,80,120,255); - sm_item->setColor(QColor(first.red(), first.green(), first.blue())); - sm_item->setProperty("already_colored", true); - sm_item->setName(names[i].data()); - sm_item->invalidateOpenGLBuffers(); - result << sm_item; - if(add_to_scene) - CGAL::Three::Three::scene()->addItem(sm_item); } + if(need_pmap) + { + SMesh::Property_map fcolor = + mesh.add_property_map("f:color",first).first; + for(std::size_t pid = 0; pid < colors.size(); ++pid) + { + put(fcolor, face_descriptor(pid), colors[pid]);//should work bc mesh is just created and shouldn't have any destroyed face. Not so sure bc of orientation though. + } + } + Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(mesh); + if(first == CGAL::Color(0,0,0,0)) + first = CGAL::Color(50,80,120,255); + sm_item->setColor(QColor(first.red(), first.green(), first.blue())); + sm_item->setProperty("already_colored", true); + sm_item->setName(names[i].data()); + sm_item->invalidateOpenGLBuffers(); + result << sm_item; + if(add_to_scene) + CGAL::Three::Three::scene()->addItem(sm_item); } ok = true; return result; diff --git a/Stream_support/include/CGAL/IO/write_3mf.h b/Stream_support/include/CGAL/IO/write_3mf.h index de335110f3c..8f66e342767 100644 --- a/Stream_support/include/CGAL/IO/write_3mf.h +++ b/Stream_support/include/CGAL/IO/write_3mf.h @@ -18,15 +18,15 @@ // // Author(s) : Maxime Gimeno -#ifndef WRITE_3MF_H -#define WRITE_3MF_H +#ifndef CGAL_IO_WRITE_3MF_H +#define CGAL_IO_WRITE_3MF_H #include #include #include #include -#include "Model/COM/NMR_DLLInterfaces.h" +#include namespace CGAL{ namespace tmf_internal{ @@ -465,4 +465,4 @@ bool write_triangle_meshes_to_3mf(const std::string& file_name, return write_triangle_soups_to_3mf(file_name, all_points, all_polygons, names); } }//end CGAL -#endif // WRITE_3MF_H +#endif // CGAL_IO_WRITE_3MF_H