diff --git a/VirtualRobot/Import/MeshImport/AssimpReader.cpp b/VirtualRobot/Import/MeshImport/AssimpReader.cpp index 9f7ece6190ae4889b4f2414afe8905e452548f95..b7742c6edb81ae7fb8d9bc4228f0f1ae5b0d6654 100644 --- a/VirtualRobot/Import/MeshImport/AssimpReader.cpp +++ b/VirtualRobot/Import/MeshImport/AssimpReader.cpp @@ -9,8 +9,17 @@ namespace { - bool readScene(const aiScene* scene, const VirtualRobot::TriMeshModelPtr& t, const std::string& filename, float scaling, float eps, bool mergeMultipleMeshes, bool ignoreMissingNormals) + bool readScene( + const aiScene* scene, + const VirtualRobot::TriMeshModelPtr& t, + const std::string& filename, + const VirtualRobot::AssimpReader::Parameters& param, + VirtualRobot::AssimpReader::ResultMetaData& meta + ) { + meta.loadingSuccessful = false; + meta.regeneratedNormals = false; + meta.skippedFaces = 0; if (!t) { VR_ERROR << "Tri mesh is null\n"; @@ -31,7 +40,7 @@ namespace VR_ERROR << "mesh from '" << filename << "' has no mesh\n"; return false; } - if (scene->mNumMeshes > 1 && !mergeMultipleMeshes) + if (scene->mNumMeshes > 1 && !param.mergeMultipleMeshes) { VR_ERROR << "mesh from '" << filename << "' has not exactly one mesh" << " It has " << scene->mNumMeshes << " meshes\n"; @@ -63,12 +72,13 @@ namespace } if (!m.mNormals) { - if (!ignoreMissingNormals) + if (!param.ignoreMissingNormals) { error_log << " has no normals (and none were generated when loading it)\n"; return false; } error_log << " has no normals (and none were generated when loading it) (ignoring this)\n"; + meta.regeneratedNormals = true; } for (unsigned i = 0; i < m.mNumVertices; ++i) @@ -89,6 +99,12 @@ namespace error_log << " has face (# " << i << ") with the wrong number of vertices (" << f.mNumIndices << ")\n"; + if (param.skipInvalidFaces) + { + ++meta.skippedFaces; + continue; + } + return false; } if ( @@ -113,18 +129,21 @@ namespace #undef error_log } - t->scale(scaling); - t->mergeVertices(eps); + t->scale(param.scaling); + t->mergeVertices(param.eps); t->addMissingNormals(); + meta.loadingSuccessful = true; return true; } } namespace VirtualRobot { - AssimpReader::AssimpReader(float eps, float scaling) : - scaling{scaling}, eps{eps} - {} + AssimpReader::AssimpReader(float eps, float scaling) + { + parameters.scaling = scaling; + parameters.eps = eps; + } std::string AssimpReader::get_extensions() { @@ -148,7 +167,7 @@ namespace VirtualRobot return extensions; } - bool AssimpReader::readFileAsTriMesh(const std::string& filename, const TriMeshModelPtr& t, bool mergeMultipleMeshes, bool ignoreMissingNormals) + bool AssimpReader::readFileAsTriMesh(const std::string& filename, const TriMeshModelPtr& t) { //code adapted from http://assimp.sourceforge.net/lib_html/usage.html Assimp::Importer importer; @@ -162,9 +181,9 @@ namespace VirtualRobot aiProcess_GenSmoothNormals | aiProcess_SortByPType ); - return readScene(scene, t, filename, scaling, eps, mergeMultipleMeshes, ignoreMissingNormals); + return readScene(scene, t, filename, parameters, resultMetaData); } - bool AssimpReader::readBufferAsTriMesh(const std::string_view& v, const TriMeshModelPtr& t, bool mergeMultipleMeshes, bool ignoreMissingNormals) + bool AssimpReader::readBufferAsTriMesh(const std::string_view& v, const TriMeshModelPtr& t) { //code adapted from http://assimp.sourceforge.net/lib_html/usage.html Assimp::Importer importer; @@ -178,59 +197,44 @@ namespace VirtualRobot aiProcess_GenSmoothNormals | aiProcess_SortByPType ); - return readScene(scene, t, "<MEMORY_BUFFER>", scaling, eps, mergeMultipleMeshes, ignoreMissingNormals); + return readScene(scene, t, "<MEMORY_BUFFER>", parameters, resultMetaData); } - TriMeshModelPtr AssimpReader::readFileAsTriMesh(const std::string& filename, bool mergeMultipleMeshes, bool ignoreMissingNormals) + TriMeshModelPtr AssimpReader::readFileAsTriMesh(const std::string& filename) { auto tri = boost::make_shared<TriMeshModel>(); - if (!readFileAsTriMesh(filename, tri, mergeMultipleMeshes, ignoreMissingNormals)) + if (!readFileAsTriMesh(filename, tri)) { return nullptr; } return tri; } - TriMeshModelPtr AssimpReader::readBufferAsTriMesh(const std::string_view& v, bool mergeMultipleMeshes, bool ignoreMissingNormals) + TriMeshModelPtr AssimpReader::readBufferAsTriMesh(const std::string_view& v) { auto tri = boost::make_shared<TriMeshModel>(); - if (!readBufferAsTriMesh(v, tri, mergeMultipleMeshes, ignoreMissingNormals)) + if (!readBufferAsTriMesh(v, tri)) { return nullptr; } return tri; } - ManipulationObjectPtr AssimpReader::readFileAsManipulationObject(const std::string& filename, const std::string& name, bool mergeMultipleMeshes, bool ignoreMissingNormals) + ManipulationObjectPtr AssimpReader::readFileAsManipulationObject(const std::string& filename, const std::string& name) { - if (auto tri = readFileAsTriMesh(filename, mergeMultipleMeshes, ignoreMissingNormals)) + if (auto tri = readFileAsTriMesh(filename)) { return boost::make_shared<ManipulationObject>(name, tri, filename); } return nullptr; } - ManipulationObjectPtr AssimpReader::readBufferAsManipulationObject(const std::string_view& v, const std::string& name, bool mergeMultipleMeshes, bool ignoreMissingNormals) + ManipulationObjectPtr AssimpReader::readBufferAsManipulationObject(const std::string_view& v, const std::string& name) { - if (auto tri = readBufferAsTriMesh(v, mergeMultipleMeshes, ignoreMissingNormals)) + if (auto tri = readBufferAsTriMesh(v)) { return boost::make_shared<ManipulationObject>(name, tri); } return nullptr; } - - void AssimpReader::set_epsilon(float _eps) - { - eps = _eps; - } - - float AssimpReader::epsilon() const - { - return eps; - } - - void AssimpReader::setScaling(float s) - { - scaling = s; - } } diff --git a/VirtualRobot/Import/MeshImport/AssimpReader.h b/VirtualRobot/Import/MeshImport/AssimpReader.h index f6c48efd5f2f01a4383ea917b0803015d888945e..77f18d436b93567e4733e522921d71c6cf6f7566 100644 --- a/VirtualRobot/Import/MeshImport/AssimpReader.h +++ b/VirtualRobot/Import/MeshImport/AssimpReader.h @@ -22,26 +22,34 @@ namespace VirtualRobot static std::string get_extensions(); // read data and store it to trimesh - bool readFileAsTriMesh(const std::string& _filename, const TriMeshModelPtr& t, bool mergeMultipleMeshes = false, bool ignoreMissingNormals = false); - bool readBufferAsTriMesh(const std::string_view& v, const TriMeshModelPtr& t, bool mergeMultipleMeshes = false, bool ignoreMissingNormals = false); + bool readFileAsTriMesh(const std::string& _filename, const TriMeshModelPtr& t); + bool readBufferAsTriMesh(const std::string_view& v, const TriMeshModelPtr& t); - TriMeshModelPtr readFileAsTriMesh(const std::string& filename, bool mergeMultipleMeshes = false, bool ignoreMissingNormals = false); - TriMeshModelPtr readBufferAsTriMesh(const std::string_view& v, bool mergeMultipleMeshes = false, bool ignoreMissingNormals = false); + TriMeshModelPtr readFileAsTriMesh(const std::string& filename); + TriMeshModelPtr readBufferAsTriMesh(const std::string_view& v); - ManipulationObjectPtr readFileAsManipulationObject(const std::string& filename, const std::string& name = "", bool mergeMultipleMeshes = false, bool ignoreMissingNormals = false); - ManipulationObjectPtr readBufferAsManipulationObject(const std::string_view& v, const std::string& name = "", bool mergeMultipleMeshes = false, bool ignoreMissingNormals = false); - - /** Set the threshold to be used for considering two point to be equal. - Can be used to merge small gaps */ - void set_epsilon(float _eps); - - /// Returns the threshold to be used for considering two point to be equal. - float epsilon() const; + ManipulationObjectPtr readFileAsManipulationObject(const std::string& filename, const std::string& name = ""); + ManipulationObjectPtr readBufferAsManipulationObject(const std::string_view& v, const std::string& name = ""); + + struct Parameters + { + float scaling = 1; + /// Returns the threshold to be used for considering two point to be equal. + float eps = FLT_MIN; + bool mergeMultipleMeshes = false; + bool ignoreMissingNormals = false; + bool skipInvalidFaces = false; + }; + Parameters parameters; + + struct ResultMetaData + { + std::size_t skippedFaces = 0; + bool loadingSuccessful = false; + bool regeneratedNormals = false; + }; - void setScaling(float s); - private: - float scaling; - float eps; + ResultMetaData resultMetaData; }; typedef boost::shared_ptr<AssimpReader> AssimpReaderPtr; diff --git a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp index 04da6baa1b1ca9ca1c790274d64070a7e14550a6..7f8c7ba80f52a5147a4b5de5a7729dea87e3785c 100644 --- a/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp +++ b/VirtualRobot/Visualization/CoinVisualization/CoinVisualizationFactory.cpp @@ -278,8 +278,9 @@ namespace VirtualRobot // try to read from file TriMeshModelPtr t(new TriMeshModel()); AssimpReader r; - r.setScaling(1000.0f); // mm - bool readOK = r.readFileAsTriMesh(filename, t, true); + r.parameters.scaling = 1000.0f; // mm + r.parameters.mergeMultipleMeshes = true; + bool readOK = r.readFileAsTriMesh(filename, t); if (!readOK) { @@ -393,19 +394,17 @@ namespace VirtualRobot VisualizationPtr CoinVisualizationFactory::getVisualization(const std::vector<VisualizationNodePtr>& visus) { - boost::shared_ptr<CoinVisualization> v(new CoinVisualization(visus)); - return v; + return boost::make_shared<CoinVisualization>(visus); } VisualizationPtr CoinVisualizationFactory::getVisualization(VisualizationNodePtr visu) { - boost::shared_ptr<CoinVisualization> v(new CoinVisualization(visu)); - return v; + return boost::make_shared<CoinVisualization>(visu); } SoSeparator* CoinVisualizationFactory::CreateBoundingBox(SoNode* ivModel, bool wireFrame) { - THROW_VR_EXCEPTION_IF(!ivModel, "NULL ivModel!"); + THROW_VR_EXCEPTION_IF(!ivModel, "NULL ivModel!") float minX; float minY; @@ -869,8 +868,8 @@ namespace VirtualRobot float theta = 0.0f; float phi = 0.0f; - float verticalAngularStride = (float)(M_PI * 2.0f) / (float)rings; - float horizontalAngularStride = ((float)M_PI * 2.0f) / (float)sides; + float verticalAngularStride = static_cast<float>((M_PI * 2.0f) / rings); + float horizontalAngularStride = static_cast<float>((M_PI * 2.0f) / sides); for (int verticalIt = 0; verticalIt < numVerticesPerColumn; verticalIt++) {