mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 02:55:55 +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,42 +40,57 @@ void model_to_csgmesh(const ModelObject &mo,
|
|||||||
((do_positives && vol->is_model_part()) ||
|
((do_positives && vol->is_model_part()) ||
|
||||||
(do_negatives && vol->is_negative_volume()))) {
|
(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);
|
||||||
CSGPart part_begin{{}, vol->is_model_part() ? CSGType::Union : CSGType::Difference};
|
bool split_failed = false;
|
||||||
part_begin.stack_operation = CSGStackOp::Push;
|
|
||||||
*out = std::move(part_begin);
|
if (attempt_split) {
|
||||||
++out;
|
|
||||||
|
|
||||||
// Collect partial meshes and keep outward and inward facing meshes separately.
|
// Collect partial meshes and keep outward and inward facing meshes separately.
|
||||||
std::vector<indexed_triangle_set> meshes_union;
|
std::vector<indexed_triangle_set> meshes_union;
|
||||||
std::vector<indexed_triangle_set> meshes_difference;
|
std::vector<indexed_triangle_set> meshes_difference;
|
||||||
its_split(vol->mesh().its, SplitOutputFn{[&meshes_union, &meshes_difference](indexed_triangle_set &&its) {
|
its_split(vol->mesh().its, SplitOutputFn{[&meshes_union, &meshes_difference, &split_failed](indexed_triangle_set &&its) {
|
||||||
if (its.empty())
|
if (its.empty())
|
||||||
return;
|
return;
|
||||||
if (its_volume(its) >= 0.f)
|
double volume = its_volume(its);
|
||||||
meshes_union.emplace_back(std::move(its));
|
if (std::abs(volume) > 1.) {
|
||||||
else {
|
if (volume > 0.)
|
||||||
its_flip_triangles(its);
|
meshes_union.emplace_back(std::move(its));
|
||||||
meshes_difference.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;
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
|
|
||||||
// Add the operation for each of the partial mesh (outward-facing normals go first).
|
if (! split_failed) {
|
||||||
for (auto* meshes : { &meshes_union, &meshes_difference}) {
|
CSGPart part_begin{{}, vol->is_model_part() ? CSGType::Union : CSGType::Difference};
|
||||||
for (indexed_triangle_set& its : *meshes) {
|
part_begin.stack_operation = CSGStackOp::Push;
|
||||||
CSGPart part{ std::make_unique<indexed_triangle_set>(std::move(its)),
|
*out = std::move(part_begin);
|
||||||
meshes == &meshes_union ? CSGType::Union : CSGType::Difference,
|
++out;
|
||||||
(trafo * vol->get_matrix()).cast<float>() };
|
|
||||||
*out = std::move(part);
|
|
||||||
++out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CSGPart part_end{{}};
|
// Add the operation for each of the partial mesh (outward-facing normals go first).
|
||||||
part_end.stack_operation = CSGStackOp::Pop;
|
for (auto* meshes : { &meshes_union, &meshes_difference}) {
|
||||||
*out = std::move(part_end);
|
for (indexed_triangle_set& its : *meshes) {
|
||||||
++out;
|
CSGPart part{ std::make_unique<indexed_triangle_set>(std::move(its)),
|
||||||
} else {
|
meshes == &meshes_union ? CSGType::Union : CSGType::Difference,
|
||||||
|
(trafo * vol->get_matrix()).cast<float>() };
|
||||||
|
*out = std::move(part);
|
||||||
|
++out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSGPart part_end{{}};
|
||||||
|
part_end.stack_operation = CSGStackOp::Pop;
|
||||||
|
*out = std::move(part_end);
|
||||||
|
++out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! attempt_split || split_failed) {
|
||||||
CSGPart part{&(vol->mesh().its),
|
CSGPart part{&(vol->mesh().its),
|
||||||
vol->is_model_part() ? CSGType::Union : CSGType::Difference,
|
vol->is_model_part() ? CSGType::Union : CSGType::Difference,
|
||||||
(trafo * vol->get_matrix()).cast<float>()};
|
(trafo * vol->get_matrix()).cast<float>()};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user