Skip to content

Commit

Permalink
Handle error when lib3mf throws exception
Browse files Browse the repository at this point in the history
  • Loading branch information
lvk88 committed Aug 17, 2024
1 parent cd2937b commit 871b3ca
Showing 1 changed file with 110 additions and 92 deletions.
202 changes: 110 additions & 92 deletions src/meshlabplugins/io_3mf/io_3mf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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(
Expand All @@ -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::UpdatePosition<decltype(current_mesh_model->cm)>::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::UpdatePosition<decltype(current_mesh_model->cm)>::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(
Expand Down

0 comments on commit 871b3ca

Please sign in to comment.