Follow-up to 963f96b - fixed crash when one of the partial meshes was degenerate (SPE-2661)

This commit is contained in:
Lukas Matena 2025-01-28 00:20:44 +01:00
parent 9b8790e4d8
commit 7e4ac102f4

View File

@ -40,26 +40,38 @@ void model_to_csgmesh(const ModelObject &mo,
((do_positives && vol->is_model_part()) ||
(do_negatives && vol->is_negative_volume()))) {
if (do_splits && its_is_splittable(vol->mesh().its)) {
bool attempt_split = do_splits && its_is_splittable(vol->mesh().its);
bool split_failed = false;
if (attempt_split) {
// Collect partial meshes and keep outward and inward facing meshes separately.
std::vector<indexed_triangle_set> meshes_union;
std::vector<indexed_triangle_set> meshes_difference;
its_split(vol->mesh().its, SplitOutputFn{[&meshes_union, &meshes_difference, &split_failed](indexed_triangle_set &&its) {
if (its.empty())
return;
double volume = its_volume(its);
if (std::abs(volume) > 1.) {
if (volume > 0.)
meshes_union.emplace_back(std::move(its));
else if (volume < 0.) {
its_flip_triangles(its);
meshes_difference.emplace_back(std::move(its));
}
} else {
// Little mesh like that may be some degenerate artifact.
// Things like that might throw further processing off track (SPE-2661).
// Better do not split the mesh and work with it as we got it.
split_failed = true;
}
}});
if (! split_failed) {
CSGPart part_begin{{}, vol->is_model_part() ? CSGType::Union : CSGType::Difference};
part_begin.stack_operation = CSGStackOp::Push;
*out = std::move(part_begin);
++out;
// Collect partial meshes and keep outward and inward facing meshes separately.
std::vector<indexed_triangle_set> meshes_union;
std::vector<indexed_triangle_set> meshes_difference;
its_split(vol->mesh().its, SplitOutputFn{[&meshes_union, &meshes_difference](indexed_triangle_set &&its) {
if (its.empty())
return;
if (its_volume(its) >= 0.f)
meshes_union.emplace_back(std::move(its));
else {
its_flip_triangles(its);
meshes_difference.emplace_back(std::move(its));
}
}});
// Add the operation for each of the partial mesh (outward-facing normals go first).
for (auto* meshes : { &meshes_union, &meshes_difference}) {
for (indexed_triangle_set& its : *meshes) {
@ -75,7 +87,10 @@ void model_to_csgmesh(const ModelObject &mo,
part_end.stack_operation = CSGStackOp::Pop;
*out = std::move(part_end);
++out;
} else {
}
}
if (! attempt_split || split_failed) {
CSGPart part{&(vol->mesh().its),
vol->is_model_part() ? CSGType::Union : CSGType::Difference,
(trafo * vol->get_matrix()).cast<float>()};