mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-13 20:36:02 +08:00
Follow-up to 963f96b - fixed crash when one of the partial meshes was degenerate (SPE-2661)
This commit is contained in:
parent
9b8790e4d8
commit
7e4ac102f4
@ -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>()};
|
||||
|
Loading…
x
Reference in New Issue
Block a user