From 871b3caa851ff9d6a2a26ac7407de8f7a46696f8 Mon Sep 17 00:00:00 2001 From: lvk88 <15655519+lvk88@users.noreply.github.com> Date: Sat, 17 Aug 2024 10:33:06 +0200 Subject: [PATCH] Handle error when lib3mf throws exception --- src/meshlabplugins/io_3mf/io_3mf.cpp | 202 +++++++++++++++------------ 1 file changed, 110 insertions(+), 92 deletions(-) diff --git a/src/meshlabplugins/io_3mf/io_3mf.cpp b/src/meshlabplugins/io_3mf/io_3mf.cpp index ebcae04dc..128d420de 100644 --- a/src/meshlabplugins/io_3mf/io_3mf.cpp +++ b/src/meshlabplugins/io_3mf/io_3mf.cpp @@ -27,10 +27,8 @@ #include "common/ml_document/mesh_model.h" #include "common/parameters/rich_parameter/rich_bool.h" #include "common/parameters/rich_parameter_list.h" -#include "external/downloads/lib3mf-2.2.0/Autogenerated/Source/lib3mf_abi.hpp" #include "lib3mf_implicit.hpp" #include "lib3mf_types.hpp" -#include "vcg/complex/algorithms/update/color.h" #include "vcg/complex/allocate.h" #include "vcg/space/color4.h" #include "wrap/io_trimesh/io_mask.h" @@ -264,19 +262,29 @@ unsigned int Lib3MFPlugin::numberMeshesContainedInFile( const QString errorMsgFormat = "Error encountered while loading file:\n\"%1\"\n\nError details: %2"; - const auto& model = get_model_from_file(fileName); - const auto& build_item_iterator = get_build_item_iterator(model); + try { + const auto& model = get_model_from_file(fileName); + const auto& build_item_iterator = get_build_item_iterator(model); - if (build_item_iterator == nullptr) { - throw MLException( - errorMsgFormat.arg(fileName, "Failed to iterate over build items in file")); - } + if (build_item_iterator == nullptr) { + throw MLException( + errorMsgFormat.arg(fileName, "Failed to iterate over build items in file")); + } - if (build_item_iterator->Count() == 0) { - throw MLException(errorMsgFormat.arg(fileName, "The file does not contain any models!")); - } + if (build_item_iterator->Count() == 0) { + throw MLException( + errorMsgFormat.arg(fileName, "The file does not contain any models!")); + } - return build_item_iterator->Count(); + return build_item_iterator->Count(); + } + catch (const Lib3MF::ELib3MFException& e) { + std::stringstream message_stream; + message_stream << "An exception occurred while opening the 3MF file.\n" << e.what(); + log(message_stream.str()); + throw MLException( + errorMsgFormat.arg(fileName, QString::fromStdString((message_stream.str())))); + } } void Lib3MFPlugin::open( @@ -287,103 +295,113 @@ void Lib3MFPlugin::open( const RichParameterList& par, vcg::CallBackPos* cb) { - using namespace vcg::tri::io; - - if (cb != nullptr) { - (*cb)(0, std::string("Loading " + fileName.toStdString()).c_str()); - } - const QString errorMsgFormat = "Error encountered while loading file:\n\"%1\"\n\nError details: %2"; - auto lib3mf_model = get_model_from_file(fileName); - auto build_item_iterator = get_build_item_iterator(lib3mf_model); - auto mesh_model_iterator = meshModelList.begin(); - if (meshModelList.size() != build_item_iterator->Count()) { - throw MLException(errorMsgFormat.arg( - fileName, - "Internal error while loading mesh objects: inconsistent number of meshes encontered")); - } - - auto delta_percent = 100 / meshModelList.size(); + try { + using namespace vcg::tri::io; - for (size_t i_mesh = 0; i_mesh < meshModelList.size(); ++i_mesh) { - build_item_iterator->MoveNext(); - const auto& current_build_item = build_item_iterator->GetCurrent(); - if (current_build_item == nullptr) { - throw MLException(errorMsgFormat.arg(fileName, "Failed to access build item")); + if (cb != nullptr) { + (*cb)(0, std::string("Loading " + fileName.toStdString()).c_str()); } - const auto& object = current_build_item->GetObjectResource(); - if (!object->IsMeshObject()) { + auto lib3mf_model = get_model_from_file(fileName); + auto build_item_iterator = get_build_item_iterator(lib3mf_model); + auto mesh_model_iterator = meshModelList.begin(); + if (meshModelList.size() != build_item_iterator->Count()) { throw MLException(errorMsgFormat.arg( - fileName, "Error while loading mesh object: build item is not a mesh")); + fileName, + "Internal error while loading mesh objects: inconsistent number of meshes " + "encontered")); } - const auto& current_mesh_object = lib3mf_model->GetMeshObjectByID(object->GetResourceID()); + auto delta_percent = 100 / meshModelList.size(); - if (current_mesh_object == nullptr) { - throw MLException(errorMsgFormat.arg( - fileName, "Internal error while loading mesh objects: invalid mesh object")); - } + for (size_t i_mesh = 0; i_mesh < meshModelList.size(); ++i_mesh) { + build_item_iterator->MoveNext(); + const auto& current_build_item = build_item_iterator->GetCurrent(); + if (current_build_item == nullptr) { + throw MLException(errorMsgFormat.arg(fileName, "Failed to access build item")); + } - auto current_mesh_model = (*mesh_model_iterator); - if (current_mesh_model == nullptr) { - throw MLException(errorMsgFormat.arg( - fileName, "Internal error while loading mesh objects: invalid mesh model")); - } + const auto& object = current_build_item->GetObjectResource(); + if (!object->IsMeshObject()) { + throw MLException(errorMsgFormat.arg( + fileName, "Error while loading mesh object: build item is not a mesh")); + } + + const auto& current_mesh_object = + lib3mf_model->GetMeshObjectByID(object->GetResourceID()); - // TODO (lvk88): even if enable WEDGCOLOR, meshlab will crash when trying to add a per - // vertex wedge color later on - // maskList.push_back(Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX | Mask::IOM_WEDGCOLOR); - // current_mesh_model->enable( Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX | - // Mask::Mask::IOM_WEDGCOLOR); - - maskList.push_back(Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX); - current_mesh_model->enable(Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX); - - load_mesh_to_meshmodel( - lib3mf_model, - current_mesh_object, - *current_mesh_model, - "_" + std::to_string(i_mesh), - par.getBool("usecolors")); - - if (current_build_item->HasObjectTransform()) { - auto transform = current_build_item->GetObjectTransform(); - Matrix44m tr; - tr.SetZero(); - tr.V()[0] = transform.m_Fields[0][0]; - tr.V()[1] = transform.m_Fields[0][1]; - tr.V()[2] = transform.m_Fields[0][2]; - tr.V()[4] = transform.m_Fields[1][0]; - tr.V()[5] = transform.m_Fields[1][1]; - tr.V()[6] = transform.m_Fields[1][2]; - tr.V()[8] = transform.m_Fields[2][0]; - tr.V()[9] = transform.m_Fields[2][1]; - tr.V()[10] = transform.m_Fields[2][2]; - tr.V()[12] = transform.m_Fields[3][0]; - tr.V()[13] = transform.m_Fields[3][1]; - tr.V()[14] = transform.m_Fields[3][2]; - tr.V()[15] = 1.0; - if (par.getBool("forcetransform")) { - vcg::tri::UpdatePositioncm)>::Matrix( - current_mesh_model->cm, tr.transpose(), true); + if (current_mesh_object == nullptr) { + throw MLException(errorMsgFormat.arg( + fileName, "Internal error while loading mesh objects: invalid mesh object")); } - else { - current_mesh_model->cm.Tr = tr.transpose(); + + auto current_mesh_model = (*mesh_model_iterator); + if (current_mesh_model == nullptr) { + throw MLException(errorMsgFormat.arg( + fileName, "Internal error while loading mesh objects: invalid mesh model")); } - } - mesh_model_iterator++; - if (cb != nullptr) { - cb(i_mesh * delta_percent, - std::string( - "Finished reading mesh " + std::to_string(i_mesh + 1) + " of " + - std::to_string(meshModelList.size())) - .c_str()); + // TODO (lvk88): even if enable WEDGCOLOR, meshlab will crash when trying to add a + // per vertex wedge color later on maskList.push_back(Mask::IOM_VERTCOORD | + // Mask::IOM_FACEINDEX | Mask::IOM_WEDGCOLOR); current_mesh_model->enable( + // Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX | Mask::Mask::IOM_WEDGCOLOR); + + maskList.push_back(Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX); + current_mesh_model->enable(Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX); + + load_mesh_to_meshmodel( + lib3mf_model, + current_mesh_object, + *current_mesh_model, + "_" + std::to_string(i_mesh), + par.getBool("usecolors")); + + if (current_build_item->HasObjectTransform()) { + auto transform = current_build_item->GetObjectTransform(); + Matrix44m tr; + tr.SetZero(); + tr.V()[0] = transform.m_Fields[0][0]; + tr.V()[1] = transform.m_Fields[0][1]; + tr.V()[2] = transform.m_Fields[0][2]; + tr.V()[4] = transform.m_Fields[1][0]; + tr.V()[5] = transform.m_Fields[1][1]; + tr.V()[6] = transform.m_Fields[1][2]; + tr.V()[8] = transform.m_Fields[2][0]; + tr.V()[9] = transform.m_Fields[2][1]; + tr.V()[10] = transform.m_Fields[2][2]; + tr.V()[12] = transform.m_Fields[3][0]; + tr.V()[13] = transform.m_Fields[3][1]; + tr.V()[14] = transform.m_Fields[3][2]; + tr.V()[15] = 1.0; + if (par.getBool("forcetransform")) { + vcg::tri::UpdatePositioncm)>::Matrix( + current_mesh_model->cm, tr.transpose(), true); + } + else { + current_mesh_model->cm.Tr = tr.transpose(); + } + } + + mesh_model_iterator++; + if (cb != nullptr) { + cb(i_mesh * delta_percent, + std::string( + "Finished reading mesh " + std::to_string(i_mesh + 1) + " of " + + std::to_string(meshModelList.size())) + .c_str()); + } } } + catch (const Lib3MF::ELib3MFException& e) { + std::stringstream message_stream; + message_stream << "An exception occurred while opening the 3MF file.\n" << e.what(); + log(message_stream.str()); + throw MLException( + errorMsgFormat.arg(fileName, QString::fromStdString((message_stream.str())))); + } } void Lib3MFPlugin::open(