ENH: output the part name that causes mesh boolean failure
jira: none Change-Id: Ie90809575291d66d54462f81c157d3e89fc34d55 (cherry picked from commit fdb6457798757a35b9623ece3b3071b3ad7ad38d)
This commit is contained in:
parent
356e4d825e
commit
d75e79c2ec
|
@ -70,6 +70,7 @@ struct CSGPart {
|
|||
Transform3f trafo;
|
||||
CSGType operation;
|
||||
CSGStackOp stack_operation;
|
||||
std::string name;
|
||||
|
||||
CSGPart(AnyPtr<const indexed_triangle_set> ptr = {},
|
||||
CSGType op = CSGType::Union,
|
||||
|
|
|
@ -64,7 +64,7 @@ bool model_to_csgmesh(const ModelObject &mo,
|
|||
CSGPart part{&(vol->mesh().its),
|
||||
vol->is_model_part() ? CSGType::Union : CSGType::Difference,
|
||||
(trafo * vol->get_matrix()).cast<float>()};
|
||||
|
||||
part.name = vol->name;
|
||||
*out = std::move(part);
|
||||
++out;
|
||||
}
|
||||
|
|
|
@ -257,12 +257,13 @@ void perform_csgmesh_booleans_mcut(MeshBoolean::mcut::McutMeshPtr& mcutm,
|
|||
|
||||
|
||||
template<class It, class Visitor>
|
||||
BooleanFailReason check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vfn)
|
||||
std::tuple<BooleanFailReason,std::string> check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vfn)
|
||||
{
|
||||
using namespace detail_cgal;
|
||||
BooleanFailReason fail_reason = BooleanFailReason::OK;
|
||||
std::string fail_part_name;
|
||||
std::vector<CGALMeshPtr> cgalmeshes(csgrange.size());
|
||||
auto check_part = [&csgrange, &cgalmeshes,&fail_reason](size_t i)
|
||||
auto check_part = [&csgrange, &cgalmeshes,&fail_reason,&fail_part_name](size_t i)
|
||||
{
|
||||
auto it = csgrange.begin();
|
||||
std::advance(it, i);
|
||||
|
@ -279,18 +280,21 @@ BooleanFailReason check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vf
|
|||
if (!m || MeshBoolean::cgal::empty(*m)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh " << i << "/" << csgrange.size() << " is empty, cannot do boolean!";
|
||||
fail_reason= BooleanFailReason::MeshEmpty;
|
||||
fail_part_name = csgpart.name;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!MeshBoolean::cgal::does_bound_a_volume(*m)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh "<<i<<"/"<<csgrange.size()<<" does_bound_a_volume is false, cannot do boolean!";
|
||||
fail_reason= BooleanFailReason::NotBoundAVolume;
|
||||
fail_part_name = csgpart.name;
|
||||
return;
|
||||
}
|
||||
|
||||
if (MeshBoolean::cgal::does_self_intersect(*m)) {
|
||||
BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh " << i << "/" << csgrange.size() << " does_self_intersect is true, cannot do boolean!";
|
||||
fail_reason= BooleanFailReason::SelfIntersect;
|
||||
fail_part_name = csgpart.name;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -312,20 +316,21 @@ BooleanFailReason check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vf
|
|||
// }
|
||||
//}
|
||||
|
||||
return fail_reason;
|
||||
return { fail_reason,fail_part_name };
|
||||
}
|
||||
|
||||
template<class It>
|
||||
BooleanFailReason check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcut=false)
|
||||
std::tuple<BooleanFailReason, std::string> check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcut=false)
|
||||
{
|
||||
if(!use_mcut)
|
||||
return check_csgmesh_booleans(csgrange, [](auto &) {});
|
||||
else {
|
||||
using namespace detail_mcut;
|
||||
BooleanFailReason fail_reason = BooleanFailReason::OK;
|
||||
std::string fail_part_name;
|
||||
|
||||
std::vector<McutMeshPtr> McutMeshes(csgrange.size());
|
||||
auto check_part = [&csgrange, &McutMeshes,&fail_reason](size_t i) {
|
||||
auto check_part = [&csgrange, &McutMeshes,&fail_reason,&fail_part_name](size_t i) {
|
||||
auto it = csgrange.begin();
|
||||
std::advance(it, i);
|
||||
auto& csgpart = *it;
|
||||
|
@ -340,6 +345,7 @@ BooleanFailReason check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcu
|
|||
try {
|
||||
if (!m || MeshBoolean::mcut::empty(*m)) {
|
||||
fail_reason=BooleanFailReason::MeshEmpty;
|
||||
fail_part_name = csgpart.name;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -348,7 +354,7 @@ BooleanFailReason check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcu
|
|||
McutMeshes[i] = std::move(m);
|
||||
};
|
||||
execution::for_each(ex_tbb, size_t(0), csgrange.size(), check_part);
|
||||
return fail_reason;
|
||||
return { fail_reason,fail_part_name };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10987,14 +10987,15 @@ TriangleMesh Plater::combine_mesh_fff(const ModelObject& mo, int instance_id, st
|
|||
|
||||
std::string fail_msg = _u8L("Unable to perform boolean operation on model meshes. "
|
||||
"Only positive parts will be kept. You may fix the meshes and try agian.");
|
||||
if (auto fail_reason = csg::check_csgmesh_booleans(Range{ std::begin(csgmesh), std::end(csgmesh) }); fail_reason != csg::BooleanFailReason::OK) {
|
||||
if (auto fail_reason_name = csg::check_csgmesh_booleans(Range{ std::begin(csgmesh), std::end(csgmesh) }); std::get<0>(fail_reason_name) != csg::BooleanFailReason::OK) {
|
||||
std::string name = std::get<1>(fail_reason_name);
|
||||
std::map<csg::BooleanFailReason, std::string> fail_reasons = {
|
||||
{csg::BooleanFailReason::OK, "OK"},
|
||||
{csg::BooleanFailReason::MeshEmpty, _u8L("Reason: mesh is empty.")},
|
||||
{csg::BooleanFailReason::NotBoundAVolume, _u8L("Reason: mesh does not bound a volume.")},
|
||||
{csg::BooleanFailReason::SelfIntersect, _u8L("Reason: mesh has self intersection.")},
|
||||
{csg::BooleanFailReason::NoIntersection, _u8L("Reason: meshes have no intersection.")} };
|
||||
fail_msg += " " + fail_reasons[fail_reason];
|
||||
{csg::BooleanFailReason::MeshEmpty, Slic3r::format( _u8L("Reason: part \"%1%\" is empty."), name)},
|
||||
{csg::BooleanFailReason::NotBoundAVolume, Slic3r::format(_u8L("Reason: part \"%1%\" does not bound a volume."), name)},
|
||||
{csg::BooleanFailReason::SelfIntersect, Slic3r::format(_u8L("Reason: part \"%1%\" has self intersection."), name)},
|
||||
{csg::BooleanFailReason::NoIntersection, Slic3r::format(_u8L("Reason: \"%1%\" and another part have no intersection."), name)} };
|
||||
fail_msg += " " + fail_reasons[std::get<0>(fail_reason_name)];
|
||||
}
|
||||
else {
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue