Export negative parts (#7024)

Porting from Prusa exporting negative parts.

Before:

![image](https://github.com/user-attachments/assets/a5e041ce-7f0f-44e5-95ea-0a8b11252cc4)

After:

![image](https://github.com/user-attachments/assets/f0a6f6bb-13c7-4a6e-afb3-7631e2f4f634)
This commit is contained in:
SoftFever 2024-10-07 16:42:12 +08:00 committed by GitHub
commit 17c0abbe32
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 78 additions and 21 deletions

View file

@ -82,6 +82,40 @@ struct CSGPart {
{}
};
//Prusa
// Check if there are only positive parts (Union) within the collection.
template<class Cont> bool is_all_positive(const Cont &csgmesh)
{
bool is_all_pos =
std::all_of(csgmesh.begin(),
csgmesh.end(),
[](auto &part) {
return csg::get_operation(part) == csg::CSGType::Union;
});
return is_all_pos;
}
//Prusa
// Merge all the positive parts of the collection into a single triangle mesh without performing
// any booleans.
template<class Cont>
indexed_triangle_set csgmesh_merge_positive_parts(const Cont &csgmesh)
{
indexed_triangle_set m;
for (auto &csgpart : csgmesh) {
auto op = csg::get_operation(csgpart);
const indexed_triangle_set * pmesh = csg::get_mesh(csgpart);
if (pmesh && op == csg::CSGType::Union) {
indexed_triangle_set mcpy = *pmesh;
its_transform(mcpy, csg::get_transform(csgpart), true);
its_merge(m, mcpy);
}
}
return m;
}
}} // namespace Slic3r::csg
#endif // CSGMESH_HPP

View file

@ -257,7 +257,7 @@ void perform_csgmesh_booleans_mcut(MeshBoolean::mcut::McutMeshPtr& mcutm,
template<class It, class Visitor>
std::tuple<BooleanFailReason,std::string> check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vfn)
std::tuple<BooleanFailReason,std::string, It> check_csgmesh_booleans(const Range<It> &csgrange, Visitor &&vfn)
{
using namespace detail_cgal;
BooleanFailReason fail_reason = BooleanFailReason::OK;
@ -304,23 +304,23 @@ std::tuple<BooleanFailReason,std::string> check_csgmesh_booleans(const Range<It>
};
execution::for_each(ex_tbb, size_t(0), csgrange.size(), check_part);
//It ret = csgrange.end();
//for (size_t i = 0; i < csgrange.size(); ++i) {
// if (!cgalmeshes[i]) {
// auto it = csgrange.begin();
// std::advance(it, i);
// vfn(it);
It ret = csgrange.end();
for (size_t i = 0; i < csgrange.size(); ++i) {
if (!cgalmeshes[i]) {
auto it = csgrange.begin();
std::advance(it, i);
vfn(it);
// if (ret == csgrange.end())
// ret = it;
// }
//}
if (ret == csgrange.end())
ret = it;
}
}
return { fail_reason,fail_part_name };
return { fail_reason,fail_part_name, ret};
}
template<class It>
std::tuple<BooleanFailReason, std::string> check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcut=false)
std::tuple<BooleanFailReason, std::string, It> check_csgmesh_booleans(const Range<It> &csgrange, bool use_mcut=false)
{
if(!use_mcut)
return check_csgmesh_booleans(csgrange, [](auto &) {});
@ -354,7 +354,7 @@ std::tuple<BooleanFailReason, std::string> check_csgmesh_booleans(const Range<It
McutMeshes[i] = std::move(m);
};
execution::for_each(ex_tbb, size_t(0), csgrange.size(), check_part);
return { fail_reason,fail_part_name };
return { fail_reason,fail_part_name, csgrange.end() };
}
}