OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::csg Namespace Reference

Namespaces

namespace  detail_cgal
namespace  detail_mcut
namespace  detail

Classes

struct  CSGPart

Enumerations

enum class  CSGType { Union , Difference , Intersection }
enum class  CSGStackOp { Push , Continue , Pop }
enum  ModelParts { mpartsPositive = 1 , mpartsNegative = 2 , mpartsDrillHoles = 4 , mpartsDoSplits = 8 }
enum class  BooleanFailReason {
  OK , MeshEmpty , NotBoundAVolume , SelfIntersect ,
  NoIntersection
}

Functions

template<class CSGPartT>
CSGType get_operation (const CSGPartT &part)
template<class CSGPartT>
CSGStackOp get_stack_operation (const CSGPartT &part)
template<class CSGPartT>
const indexed_triangle_set * get_mesh (const CSGPartT &part)
template<class CSGPartT>
Transform3f get_transform (const CSGPartT &part)
template<class Cont>
bool is_all_positive (const Cont &csgmesh)
template<class Cont>
indexed_triangle_set csgmesh_merge_positive_parts (const Cont &csgmesh)
template<class It, class OutIt>
void copy_csgrange_shallow (const Range< It > &csgrange, OutIt out)
template<class It, class OutIt>
void copy_csgrange_deep (const Range< It > &csgrange, OutIt out)
template<class ItA, class ItB>
bool is_same (const Range< ItA > &A, const Range< ItB > &B)
template<class OutIt>
bool model_to_csgmesh (const ModelObject &mo, const Transform3d &trafo, OutIt out, int parts_to_include=mpartsPositive)
template<class CSGPartT>
MeshBoolean::cgal::CGALMeshPtr get_cgalmesh (const CSGPartT &csgpart)
template<class CSGPartT>
MeshBoolean::mcut::McutMeshPtr get_mcutmesh (const CSGPartT &csgpart)
template<class It>
void perform_csgmesh_booleans_cgal (MeshBoolean::cgal::CGALMeshPtr &cgalm, const Range< It > &csgrange)
template<class It>
void perform_csgmesh_booleans_mcut (MeshBoolean::mcut::McutMeshPtr &mcutm, const Range< It > &csgrange)
template<class It, class Visitor>
std::tuple< BooleanFailReason, std::string, It > check_csgmesh_booleans (const Range< It > &csgrange, Visitor &&vfn)
template<class It>
std::tuple< BooleanFailReason, std::string, It > check_csgmesh_booleans (const Range< It > &csgrange, bool use_mcut=false)
template<class It>
MeshBoolean::cgal::CGALMeshPtr perform_csgmesh_booleans (const Range< It > &csgparts)
template<class It>
MeshBoolean::mcut::McutMeshPtr perform_csgmesh_booleans_mcut (const Range< It > &csgparts)
template<class ItCSG>
std::vector< ExPolygons > slice_csgmesh_ex (const Range< ItCSG > &csgrange, const std::vector< float > &slicegrid, const MeshSlicingParamsEx &params, const std::function< void()> &throw_on_cancel=[] {})
CSGType get_operation (const indexed_triangle_set &part)
CSGStackOp get_stack_operation (const indexed_triangle_set &part)
const indexed_triangle_set * get_mesh (const indexed_triangle_set &part)
Transform3f get_transform (const indexed_triangle_set &part)
CSGType get_operation (const indexed_triangle_set *const part)
CSGStackOp get_stack_operation (const indexed_triangle_set *const part)
const indexed_triangle_set * get_mesh (const indexed_triangle_set *const part)
Transform3f get_transform (const indexed_triangle_set *const part)
CSGType get_operation (const TriangleMesh &part)
CSGStackOp get_stack_operation (const TriangleMesh &part)
const indexed_triangle_set * get_mesh (const TriangleMesh &part)
Transform3f get_transform (const TriangleMesh &part)
CSGType get_operation (const TriangleMesh *const part)
CSGStackOp get_stack_operation (const TriangleMesh *const part)
const indexed_triangle_set * get_mesh (const TriangleMesh *const part)
Transform3f get_transform (const TriangleMesh *const part)

Enumeration Type Documentation

◆ BooleanFailReason

enum class Slic3r::csg::BooleanFailReason
strong
Enumerator
OK 
MeshEmpty 
NotBoundAVolume 
SelfIntersect 
NoIntersection 
@ OK
Definition uiAMSBestPositionPopup.hpp:121
@ MeshEmpty
Definition PerformCSGMeshBooleans.hpp:20
@ NotBoundAVolume
Definition PerformCSGMeshBooleans.hpp:20
@ NoIntersection
Definition PerformCSGMeshBooleans.hpp:20
@ SelfIntersect
Definition PerformCSGMeshBooleans.hpp:20

◆ CSGStackOp

enum class Slic3r::csg::CSGStackOp
strong
Enumerator
Push 
Continue 
Pop 
42{ Push, Continue, Pop };
@ Pop
Definition CSGMesh.hpp:42
@ Push
Definition CSGMesh.hpp:42
@ Continue
Definition CSGMesh.hpp:42

◆ CSGType

enum class Slic3r::csg::CSGType
strong
Enumerator
Union 
Difference 
Intersection 
@ Difference
Definition CSGMesh.hpp:24
@ Intersection
Definition CSGMesh.hpp:24
@ Union
Definition CSGMesh.hpp:24

◆ ModelParts

Enumerator
mpartsPositive 
mpartsNegative 
mpartsDrillHoles 
mpartsDoSplits 
18 {
19 mpartsPositive = 1, // Include positive parts
20 mpartsNegative = 2, // Include negative parts
21 mpartsDrillHoles = 4, // Include drill holes
22 mpartsDoSplits = 8, // Split each splitable mesh and export as a union of csg parts
23};
@ mpartsDrillHoles
Definition ModelToCSGMesh.hpp:21
@ mpartsDoSplits
Definition ModelToCSGMesh.hpp:22
@ mpartsPositive
Definition ModelToCSGMesh.hpp:19
@ mpartsNegative
Definition ModelToCSGMesh.hpp:20

Function Documentation

◆ check_csgmesh_booleans() [1/2]

template<class It>
std::tuple< BooleanFailReason, std::string, It > Slic3r::csg::check_csgmesh_booleans ( const Range< It > & csgrange,
bool use_mcut = false )
330{
331 if(!use_mcut)
332 return check_csgmesh_booleans(csgrange, [](auto &) {});
333 else {
334 using namespace detail_mcut;
336 std::string fail_part_name;
337
338 std::vector<McutMeshPtr> McutMeshes(csgrange.size());
339 auto check_part = [&csgrange, &McutMeshes,&fail_reason,&fail_part_name](size_t i) {
340 auto it = csgrange.begin();
341 std::advance(it, i);
342 auto& csgpart = *it;
343 auto m = get_mcutmesh(csgpart);
344
345 // mesh can be nullptr if this is a stack push or pull
346 if (!get_mesh(csgpart) && get_stack_operation(csgpart) != CSGStackOp::Continue) {
347 McutMeshes[i] = MeshBoolean::mcut::triangle_mesh_to_mcut(indexed_triangle_set{});
348 return;
349 }
350
351 try {
352 if (!m || MeshBoolean::mcut::empty(*m)) {
354 fail_part_name = csgpart.name;
355 return;
356 }
357 }
358 catch (...) { return; }
359
360 McutMeshes[i] = std::move(m);
361 };
362 execution::for_each(ex_tbb, size_t(0), csgrange.size(), check_part);
363 return { fail_reason,fail_part_name, csgrange.end() };
364 }
365}
It begin() const
Definition libslic3r.h:390
size_t size() const
Definition libslic3r.h:401
It end() const
Definition libslic3r.h:391
bool empty(const McutMesh &mesh)
Definition MeshBoolean.cpp:679
void triangle_mesh_to_mcut(const TriangleMesh &src_mesh, McutMesh &srcMesh, const Transform3d &src_nm=Transform3d::Identity())
Definition MeshBoolean.cpp:680
std::tuple< BooleanFailReason, std::string, It > check_csgmesh_booleans(const Range< It > &csgrange, Visitor &&vfn)
Definition PerformCSGMeshBooleans.hpp:266
const indexed_triangle_set * get_mesh(const CSGPartT &part)
Definition CSGMesh.hpp:58
CSGStackOp get_stack_operation(const CSGPartT &part)
Definition CSGMesh.hpp:51
BooleanFailReason
Definition PerformCSGMeshBooleans.hpp:20
@ OK
Definition PerformCSGMeshBooleans.hpp:20
MeshBoolean::mcut::McutMeshPtr get_mcutmesh(const CSGPartT &csgpart)
Definition PerformCSGMeshBooleans.hpp:51
void for_each(const EP &ep, It from, It to, Fn &&fn, size_t granularity=1)
Definition Execution.hpp:46
static constexpr ExecutionTBB ex_tbb
Definition ExecutionTBB.hpp:22

References Slic3r::Range< It >::begin(), check_csgmesh_booleans(), Continue, Slic3r::MeshBoolean::mcut::empty(), Slic3r::Range< It >::end(), Slic3r::ex_tbb, Slic3r::execution::for_each(), get_mcutmesh(), get_mesh(), get_stack_operation(), MeshEmpty, OK, Slic3r::Range< It >::size(), and Slic3r::MeshBoolean::mcut::triangle_mesh_to_mcut().

Here is the call graph for this function:

◆ check_csgmesh_booleans() [2/2]

template<class It, class Visitor>
std::tuple< BooleanFailReason, std::string, It > Slic3r::csg::check_csgmesh_booleans ( const Range< It > & csgrange,
Visitor && vfn )
267{
268 using namespace detail_cgal;
270 std::string fail_part_name;
271 std::vector<CGALMeshPtr> cgalmeshes(csgrange.size());
272 auto check_part = [&csgrange, &cgalmeshes,&fail_reason,&fail_part_name](size_t i)
273 {
274 auto it = csgrange.begin();
275 std::advance(it, i);
276 auto &csgpart = *it;
277 auto m = get_cgalmesh(csgpart);
278
279 // mesh can be nullptr if this is a stack push or pull
280 if (!get_mesh(csgpart) && get_stack_operation(csgpart) != CSGStackOp::Continue) {
281 cgalmeshes[i] = MeshBoolean::cgal::triangle_mesh_to_cgal(indexed_triangle_set{});
282 return;
283 }
284
285 try {
286 if (!m || MeshBoolean::cgal::empty(*m)) {
287 BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh " << i << "/" << csgrange.size() << " is empty, cannot do boolean!";
288 fail_reason= BooleanFailReason::MeshEmpty;
289 fail_part_name = csgpart.name;
290 return;
291 }
292
294 BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh "<<i<<"/"<<csgrange.size()<<" does_bound_a_volume is false, cannot do boolean!";
296 fail_part_name = csgpart.name;
297 return;
298 }
299
301 BOOST_LOG_TRIVIAL(info) << "check_csgmesh_booleans fails! mesh " << i << "/" << csgrange.size() << " does_self_intersect is true, cannot do boolean!";
303 fail_part_name = csgpart.name;
304 return;
305 }
306 }
307 catch (...) { return; }
308
309 cgalmeshes[i] = std::move(m);
310 };
311 execution::for_each(ex_tbb, size_t(0), csgrange.size(), check_part);
312
313 It ret = csgrange.end();
314 for (size_t i = 0; i < csgrange.size(); ++i) {
315 if (!cgalmeshes[i]) {
316 auto it = csgrange.begin();
317 std::advance(it, i);
318 vfn(it);
319
320 if (ret == csgrange.end())
321 ret = it;
322 }
323 }
324
325 return { fail_reason,fail_part_name, ret};
326}
bool empty(const CGALMesh &mesh)
Definition MeshBoolean.cpp:653
void triangle_mesh_to_cgal(const TriangleMesh &M, _Mesh &out)
Definition MeshBoolean.cpp:167
bool does_bound_a_volume(const CGALMesh &mesh)
Definition MeshBoolean.cpp:648
bool does_self_intersect(const CGALMesh &mesh)
Definition MeshBoolean.cpp:478
Definition PerformCSGMeshBooleans.hpp:75
MeshBoolean::cgal::CGALMeshPtr get_cgalmesh(const CSGPartT &csgpart)
Definition PerformCSGMeshBooleans.hpp:25

References Slic3r::Range< It >::begin(), Continue, Slic3r::MeshBoolean::cgal::does_bound_a_volume(), Slic3r::MeshBoolean::cgal::does_self_intersect(), Slic3r::MeshBoolean::cgal::empty(), Slic3r::Range< It >::end(), Slic3r::ex_tbb, Slic3r::execution::for_each(), get_cgalmesh(), get_mesh(), get_stack_operation(), MeshEmpty, NotBoundAVolume, OK, SelfIntersect, Slic3r::Range< It >::size(), and Slic3r::MeshBoolean::cgal::triangle_mesh_to_cgal().

Referenced by check_csgmesh_booleans(), Slic3r::GUI::Plater::combine_mesh_fff(), and Slic3r::GUI::Plater::export_stl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_csgrange_deep()

template<class It, class OutIt>
void Slic3r::csg::copy_csgrange_deep ( const Range< It > & csgrange,
OutIt out )
42{
43 for (const auto &part : csgrange) {
44
45 CSGPart cpy{{}, get_operation(part), get_transform(part)};
46
47 if (auto meshptr = get_mesh(part)) {
48 cpy.its_ptr = std::make_unique<const indexed_triangle_set>(*meshptr);
49 }
50
52
53 *out = std::move(cpy);
54 ++out;
55 }
56}
Transform3f get_transform(const CSGPartT &part)
Definition CSGMesh.hpp:66
CSGType get_operation(const CSGPartT &part)
Definition CSGMesh.hpp:45
Definition CSGMesh.hpp:72
AnyPtr< const indexed_triangle_set > its_ptr
Definition CSGMesh.hpp:73
CSGStackOp stack_operation
Definition CSGMesh.hpp:76

References get_mesh(), get_operation(), get_stack_operation(), get_transform(), Slic3r::csg::CSGPart::its_ptr, and Slic3r::csg::CSGPart::stack_operation.

Referenced by Slic3r::GUI::MeshClipper::set_mesh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_csgrange_shallow()

template<class It, class OutIt>
void Slic3r::csg::copy_csgrange_shallow ( const Range< It > & csgrange,
OutIt out )
17{
18 for (const auto &part : csgrange) {
19 CSGPart cpy{{},
20 get_operation(part),
21 get_transform(part)};
22
24
25 if constexpr (std::is_convertible_v<decltype(part), const CSGPart&>) {
26 if (auto shptr = part.its_ptr.get_shared_cpy()) {
27 cpy.its_ptr = shptr;
28 }
29 }
30
31 if (!cpy.its_ptr)
32 cpy.its_ptr = AnyPtr<const indexed_triangle_set>{get_mesh(part)};
33
34 *out = std::move(cpy);
35 ++out;
36 }
37}

References get_mesh(), get_operation(), get_stack_operation(), get_transform(), Slic3r::csg::CSGPart::its_ptr, and Slic3r::csg::CSGPart::stack_operation.

Referenced by Slic3r::GUI::MeshClipper::set_mesh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ csgmesh_merge_positive_parts()

template<class Cont>
indexed_triangle_set Slic3r::csg::csgmesh_merge_positive_parts ( const Cont & csgmesh)
108{
109 indexed_triangle_set m;
110 for (auto &csgpart : csgmesh) {
111 auto op = csg::get_operation(csgpart);
112 const indexed_triangle_set * pmesh = csg::get_mesh(csgpart);
113 if (pmesh && op == csg::CSGType::Union) {
114 indexed_triangle_set mcpy = *pmesh;
115 its_transform(mcpy, csg::get_transform(csgpart), true);
116 its_merge(m, mcpy);
117 }
118 }
119
120 return m;
121}
void its_merge(indexed_triangle_set &A, const indexed_triangle_set &B)
Definition TriangleMesh.cpp:1448

References get_mesh(), get_operation(), get_transform(), Slic3r::its_merge(), and Union.

Referenced by Slic3r::GUI::Plater::export_stl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_cgalmesh()

template<class CSGPartT>
MeshBoolean::cgal::CGALMeshPtr Slic3r::csg::get_cgalmesh ( const CSGPartT & csgpart)
26{
27 const indexed_triangle_set *its = csg::get_mesh(csgpart);
28 indexed_triangle_set dummy;
29
30 if (!its)
31 its = &dummy;
32
34
35 indexed_triangle_set m = *its;
36 its_transform(m, get_transform(csgpart), true);
37
38 try {
40 } catch (...) {
41 // errors are ignored, simply return null
42 ret = nullptr;
43 }
44
45 return ret;
46}
std::unique_ptr< CGALMesh, CGALMeshDeleter > CGALMeshPtr
Definition MeshBoolean.hpp:35

References get_mesh(), get_transform(), and Slic3r::MeshBoolean::cgal::triangle_mesh_to_cgal().

Referenced by check_csgmesh_booleans().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mcutmesh()

template<class CSGPartT>
MeshBoolean::mcut::McutMeshPtr Slic3r::csg::get_mcutmesh ( const CSGPartT & csgpart)
52{
53 const indexed_triangle_set* its = csg::get_mesh(csgpart);
54 indexed_triangle_set dummy;
55
56 if (!its)
57 its = &dummy;
58
60
61 indexed_triangle_set m = *its;
62 its_transform(m, get_transform(csgpart), true);
63
64 try {
66 }
67 catch (...) {
68 // errors are ignored, simply return null
69 ret = nullptr;
70 }
71
72 return ret;
73}
std::unique_ptr< McutMesh, McutMeshDeleter > McutMeshPtr
Definition MeshBoolean.hpp:108

References get_mesh(), get_transform(), and Slic3r::MeshBoolean::mcut::triangle_mesh_to_mcut().

Referenced by check_csgmesh_booleans().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_mesh() [1/5]

template<class CSGPartT>
const indexed_triangle_set * Slic3r::csg::get_mesh ( const CSGPartT & part)
59{
60 return part.its_ptr.get();
61}

Referenced by check_csgmesh_booleans(), check_csgmesh_booleans(), copy_csgrange_deep(), copy_csgrange_shallow(), csgmesh_merge_positive_parts(), get_cgalmesh(), get_mcutmesh(), and is_same().

Here is the caller graph for this function:

◆ get_mesh() [2/5]

const indexed_triangle_set * Slic3r::csg::get_mesh ( const indexed_triangle_set & part)
inline
25{
26 return &part;
27}

◆ get_mesh() [3/5]

const indexed_triangle_set * Slic3r::csg::get_mesh ( const indexed_triangle_set *const part)
inline
45{
46 return part;
47}

◆ get_mesh() [4/5]

const indexed_triangle_set * Slic3r::csg::get_mesh ( const TriangleMesh & part)
inline
65{
66 return &part.its;
67}
indexed_triangle_set its
Definition TriangleMesh.hpp:164

References Slic3r::TriangleMesh::its.

◆ get_mesh() [5/5]

const indexed_triangle_set * Slic3r::csg::get_mesh ( const TriangleMesh *const part)
inline
85{
86 return &part->its;
87}

References Slic3r::TriangleMesh::its.

◆ get_operation() [1/5]

template<class CSGPartT>
CSGType Slic3r::csg::get_operation ( const CSGPartT & part)
46{
47 return part.operation;
48}

Referenced by copy_csgrange_deep(), copy_csgrange_shallow(), csgmesh_merge_positive_parts(), is_same(), perform_csgmesh_booleans_cgal(), and perform_csgmesh_booleans_mcut().

Here is the caller graph for this function:

◆ get_operation() [2/5]

CSGType Slic3r::csg::get_operation ( const indexed_triangle_set & part)
inline
15{
16 return CSGType::Union;
17}

References Union.

◆ get_operation() [3/5]

CSGType Slic3r::csg::get_operation ( const indexed_triangle_set *const part)
inline
35{
36 return CSGType::Union;
37}

References Union.

◆ get_operation() [4/5]

CSGType Slic3r::csg::get_operation ( const TriangleMesh & part)
inline
55{
56 return CSGType::Union;
57}

References Union.

◆ get_operation() [5/5]

CSGType Slic3r::csg::get_operation ( const TriangleMesh *const part)
inline
75{
76 return CSGType::Union;
77}

References Union.

◆ get_stack_operation() [1/5]

template<class CSGPartT>
CSGStackOp Slic3r::csg::get_stack_operation ( const CSGPartT & part)
52{
53 return part.stack_operation;
54}

Referenced by check_csgmesh_booleans(), check_csgmesh_booleans(), copy_csgrange_deep(), copy_csgrange_shallow(), is_same(), perform_csgmesh_booleans_cgal(), and perform_csgmesh_booleans_mcut().

Here is the caller graph for this function:

◆ get_stack_operation() [2/5]

CSGStackOp Slic3r::csg::get_stack_operation ( const indexed_triangle_set & part)
inline
20{
22}

References Continue.

◆ get_stack_operation() [3/5]

CSGStackOp Slic3r::csg::get_stack_operation ( const indexed_triangle_set *const part)
inline
40{
42}

References Continue.

◆ get_stack_operation() [4/5]

CSGStackOp Slic3r::csg::get_stack_operation ( const TriangleMesh & part)
inline
60{
62}

References Continue.

◆ get_stack_operation() [5/5]

CSGStackOp Slic3r::csg::get_stack_operation ( const TriangleMesh *const part)
inline
80{
82}

References Continue.

◆ get_transform() [1/5]

template<class CSGPartT>
Transform3f Slic3r::csg::get_transform ( const CSGPartT & part)
67{
68 return part.trafo;
69}

Referenced by copy_csgrange_deep(), copy_csgrange_shallow(), csgmesh_merge_positive_parts(), get_cgalmesh(), get_mcutmesh(), and is_same().

Here is the caller graph for this function:

◆ get_transform() [2/5]

Transform3f Slic3r::csg::get_transform ( const indexed_triangle_set & part)
inline
30{
31 return Transform3f::Identity();
32}

◆ get_transform() [3/5]

Transform3f Slic3r::csg::get_transform ( const indexed_triangle_set *const part)
inline
50{
51 return Transform3f::Identity();
52}

◆ get_transform() [4/5]

Transform3f Slic3r::csg::get_transform ( const TriangleMesh & part)
inline
70{
71 return Transform3f::Identity();
72}

◆ get_transform() [5/5]

Transform3f Slic3r::csg::get_transform ( const TriangleMesh *const part)
inline
90{
91 return Transform3f::Identity();
92}

◆ is_all_positive()

template<class Cont>
bool Slic3r::csg::is_all_positive ( const Cont & csgmesh)
92{
93 bool is_all_pos =
94 std::all_of(csgmesh.begin(),
95 csgmesh.end(),
96 [](auto &part) {
97 return csg::get_operation(part) == csg::CSGType::Union;
98 });
99
100 return is_all_pos;
101}

Referenced by Slic3r::GUI::Plater::export_stl().

Here is the caller graph for this function:

◆ is_same()

template<class ItA, class ItB>
bool Slic3r::csg::is_same ( const Range< ItA > & A,
const Range< ItB > & B )
60{
61 bool ret = true;
62
63 size_t s = A.size();
64
65 if (B.size() != s)
66 ret = false;
67
68 size_t i = 0;
69 auto itA = A.begin();
70 auto itB = B.begin();
71 for (; ret && i < s; ++itA, ++itB, ++i) {
72 ret = ret &&
73 get_mesh(*itA) == get_mesh(*itB) &&
74 get_operation(*itA) == get_operation(*itB) &&
76 get_transform(*itA).isApprox(get_transform(*itB));
77 }
78
79 return ret;
80}

References Slic3r::Range< It >::begin(), get_mesh(), get_operation(), get_stack_operation(), get_transform(), and Slic3r::Range< It >::size().

Referenced by Slic3r::GUI::MeshClipper::set_mesh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ model_to_csgmesh()

template<class OutIt>
bool Slic3r::csg::model_to_csgmesh ( const ModelObject & mo,
const Transform3d & trafo,
OutIt out,
int parts_to_include = mpartsPositive )
32{
33 bool do_positives = parts_to_include & mpartsPositive;
34 bool do_negatives = parts_to_include & mpartsNegative;
35 bool do_drillholes = parts_to_include & mpartsDrillHoles;
36 bool do_splits = parts_to_include & mpartsDoSplits;
37 bool has_splitable_volume = false;
38
39 for (const ModelVolume *vol : mo.volumes) {
40 if (vol && vol->mesh_ptr() &&
41 ((do_positives && vol->is_model_part()) ||
42 (do_negatives && vol->is_negative_volume()))) {
43
44 if (do_splits && its_is_splittable(vol->mesh().its)) {
47 *out = std::move(part_begin);
48 ++out;
49
50 its_split(vol->mesh().its, SplitOutputFn{[&out, &vol, &trafo](indexed_triangle_set &&its) {
51 if (its.empty())
52 return;
53
54 CSGPart part{std::make_unique<indexed_triangle_set>(std::move(its)),
55 CSGType::Union,
56 (trafo * vol->get_matrix()).cast<float>()};
57
58 *out = std::move(part);
59 ++out;
60 }});
61
62 CSGPart part_end{{}};
64 *out = std::move(part_end);
65 ++out;
66 has_splitable_volume = true;
67 } else {
68 CSGPart part{&(vol->mesh().its),
70 (trafo * vol->get_matrix()).cast<float>()};
71 part.name = vol->name;
72 *out = std::move(part);
73 ++out;
74 }
75 }
76 }
77
78 //if (do_drillholes) {
79 // sla::DrainHoles drainholes = sla::transformed_drainhole_points(mo, trafo);
80
81 // for (const sla::DrainHole &dhole : drainholes) {
82 // CSGPart part{std::make_unique<const indexed_triangle_set>(
83 // dhole.to_mesh()),
84 // CSGType::Difference};
85
86 // *out = std::move(part);
87 // ++out;
88 // }
89 //}
90
91 return has_splitable_volume;
92}
ModelVolumePtrs volumes
Definition Model.hpp:393
Definition Model.hpp:832
const TriangleMesh & mesh() const
Definition Model.hpp:892
bool is_model_part() const
Definition Model.hpp:1025
const Transform3d & get_matrix() const
Definition Model.hpp:1139
std::string name
Definition Model.hpp:834
bool is_negative_volume() const
Definition Model.hpp:1026
std::shared_ptr< const TriangleMesh > mesh_ptr() const
Definition Model.hpp:893
void its_split(const Its &m, OutputIt out_it)
Definition MeshSplitImpl.hpp:143
bool its_is_splittable(const Its &m)
Definition MeshSplitImpl.hpp:203
std::string name
Definition CSGMesh.hpp:77

References Difference, Slic3r::ModelVolume::get_matrix(), Slic3r::ModelVolume::is_model_part(), Slic3r::ModelVolume::is_negative_volume(), Slic3r::TriangleMesh::its, Slic3r::its_is_splittable(), Slic3r::its_split(), Slic3r::ModelVolume::mesh(), Slic3r::ModelVolume::mesh_ptr(), mpartsDoSplits, mpartsDrillHoles, mpartsNegative, mpartsPositive, Slic3r::csg::CSGPart::name, Slic3r::ModelVolume::name, Pop, Push, Slic3r::csg::CSGPart::stack_operation, Union, and Slic3r::ModelObject::volumes.

Referenced by Slic3r::GUI::Plater::combine_mesh_fff(), and Slic3r::GUI::Plater::export_stl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ perform_csgmesh_booleans()

template<class It>
MeshBoolean::cgal::CGALMeshPtr Slic3r::csg::perform_csgmesh_booleans ( const Range< It > & csgparts)
369{
370 auto ret = MeshBoolean::cgal::triangle_mesh_to_cgal(indexed_triangle_set{});
371 if (ret)
372 perform_csgmesh_booleans_cgal(ret, csgparts);
373 return ret;
374}
void perform_csgmesh_booleans_cgal(MeshBoolean::cgal::CGALMeshPtr &cgalm, const Range< It > &csgrange)
Definition PerformCSGMeshBooleans.hpp:165

References perform_csgmesh_booleans_cgal(), and Slic3r::MeshBoolean::cgal::triangle_mesh_to_cgal().

Referenced by Slic3r::GUI::Plater::combine_mesh_fff(), and Slic3r::GUI::Plater::export_stl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ perform_csgmesh_booleans_cgal()

template<class It>
void Slic3r::csg::perform_csgmesh_booleans_cgal ( MeshBoolean::cgal::CGALMeshPtr & cgalm,
const Range< It > & csgrange )
167{
170 using namespace detail_cgal;
171
172 struct Frame {
173 CSGType op; CGALMeshPtr cgalptr;
174 explicit Frame(CSGType csgop = CSGType::Union)
175 : op{ csgop }
176 , cgalptr{ MeshBoolean::cgal::triangle_mesh_to_cgal(indexed_triangle_set{}) }
177 {}
178 };
179
180 std::stack opstack{ std::vector<Frame>{} };
181
182 opstack.push(Frame{});
183
184 std::vector<CGALMeshPtr> cgalmeshes = get_cgalptrs(ex_tbb, csgrange);
185
186 size_t csgidx = 0;
187 for (auto& csgpart : csgrange) {
188
189 auto op = get_operation(csgpart);
190 CGALMeshPtr& cgalptr = cgalmeshes[csgidx++];
191
192 if (get_stack_operation(csgpart) == CSGStackOp::Push) {
193 opstack.push(Frame{ op });
194 op = CSGType::Union;
195 }
196
197 Frame* top = &opstack.top();
198
199 perform_csg(get_operation(csgpart), top->cgalptr, cgalptr);
200
201 if (get_stack_operation(csgpart) == CSGStackOp::Pop) {
202 CGALMeshPtr src = std::move(top->cgalptr);
203 auto popop = opstack.top().op;
204 opstack.pop();
205 CGALMeshPtr& dst = opstack.top().cgalptr;
206 perform_csg(popop, dst, src);
207 }
208 }
209
210 cgalm = std::move(opstack.top().cgalptr);
211}
Definition MeshBoolean.cpp:68
void perform_csg(CSGType op, CGALMeshPtr &dst, CGALMeshPtr &src)
Definition PerformCSGMeshBooleans.hpp:79
std::vector< CGALMeshPtr > get_cgalptrs(Ex policy, const Range< It > &csgrange)
Definition PerformCSGMeshBooleans.hpp:103
CSGType
Definition CSGMesh.hpp:24
Definition MeshBoolean.cpp:152

References Slic3r::ex_tbb, get_operation(), get_stack_operation(), Pop, Push, Slic3r::MeshBoolean::cgal::triangle_mesh_to_cgal(), and Union.

Referenced by perform_csgmesh_booleans().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ perform_csgmesh_booleans_mcut() [1/2]

template<class It>
MeshBoolean::mcut::McutMeshPtr Slic3r::csg::perform_csgmesh_booleans_mcut ( const Range< It > & csgparts)
378{
379 auto ret = MeshBoolean::mcut::triangle_mesh_to_mcut(indexed_triangle_set{});
380 if (ret)
381 perform_csgmesh_booleans_mcut(ret, csgparts);
382 return ret;
383}
void perform_csgmesh_booleans_mcut(MeshBoolean::mcut::McutMeshPtr &mcutm, const Range< It > &csgrange)
Definition PerformCSGMeshBooleans.hpp:215

References perform_csgmesh_booleans_mcut(), and Slic3r::MeshBoolean::mcut::triangle_mesh_to_mcut().

Here is the call graph for this function:

◆ perform_csgmesh_booleans_mcut() [2/2]

template<class It>
void Slic3r::csg::perform_csgmesh_booleans_mcut ( MeshBoolean::mcut::McutMeshPtr & mcutm,
const Range< It > & csgrange )
217{
220 using namespace detail_mcut;
221
222 struct Frame {
223 CSGType op; McutMeshPtr mcutptr;
224 explicit Frame(CSGType csgop = CSGType::Union)
225 : op{ csgop }
226 , mcutptr{ MeshBoolean::mcut::triangle_mesh_to_mcut(indexed_triangle_set{}) }
227 {}
228 };
229
230 std::stack opstack{ std::vector<Frame>{} };
231
232 opstack.push(Frame{});
233
234 std::vector<McutMeshPtr> McutMeshes = get_mcutptrs(ex_tbb, csgrange);
235
236 size_t csgidx = 0;
237 for (auto& csgpart : csgrange) {
238
239 auto op = get_operation(csgpart);
240 McutMeshPtr& mcutptr = McutMeshes[csgidx++];
241
242 if (get_stack_operation(csgpart) == CSGStackOp::Push) {
243 opstack.push(Frame{ op });
244 op = CSGType::Union;
245 }
246
247 Frame* top = &opstack.top();
248
249 perform_csg(get_operation(csgpart), top->mcutptr, mcutptr);
250
251 if (get_stack_operation(csgpart) == CSGStackOp::Pop) {
252 McutMeshPtr src = std::move(top->mcutptr);
253 auto popop = opstack.top().op;
254 opstack.pop();
255 McutMeshPtr& dst = opstack.top().mcutptr;
256 perform_csg(popop, dst, src);
257 }
258 }
259
260 mcutm = std::move(opstack.top().mcutptr);
261
262}
Definition MeshBoolean.cpp:671
Definition PerformCSGMeshBooleans.hpp:119
std::vector< McutMeshPtr > get_mcutptrs(Ex policy, const Range< It > &csgrange)
Definition PerformCSGMeshBooleans.hpp:147

References Slic3r::ex_tbb, get_operation(), get_stack_operation(), Pop, Push, Slic3r::MeshBoolean::mcut::triangle_mesh_to_mcut(), and Union.

Referenced by Slic3r::GUI::Plater::combine_mesh_fff(), and perform_csgmesh_booleans_mcut().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ slice_csgmesh_ex()

template<class ItCSG>
std::vector< ExPolygons > Slic3r::csg::slice_csgmesh_ex ( const Range< ItCSG > & csgrange,
const std::vector< float > & slicegrid,
const MeshSlicingParamsEx & params,
const std::function< void()> & throw_on_cancel = [] {} )
61 {})
62{
63 using namespace detail;
64
65 struct Frame { CSGType op; std::vector<ExPolygons> slices; };
66
67 std::stack opstack{std::vector<Frame>{}};
68
69 MeshSlicingParamsEx params_cpy = params;
70 auto trafo = params.trafo;
71 auto nonempty_indices = reserve_vector<size_t>(slicegrid.size());
72
73 opstack.push({CSGType::Union, std::vector<ExPolygons>(slicegrid.size())});
74
75 for (const auto &csgpart : csgrange) {
76 const indexed_triangle_set *its = csg::get_mesh(csgpart);
77
78 auto op = get_operation(csgpart);
79
80 if (get_stack_operation(csgpart) == CSGStackOp::Push) {
81 opstack.push({op, std::vector<ExPolygons>(slicegrid.size())});
82 op = CSGType::Union;
83 }
84
85 Frame *top = &opstack.top();
86
87 if (its) {
88 params_cpy.trafo = trafo * csg::get_transform(csgpart).template cast<double>();
89 std::vector<ExPolygons> slices = slice_mesh_ex(*its,
90 slicegrid, params_cpy,
91 throw_on_cancel);
92
93 assert(slices.size() == slicegrid.size());
94
95 collect_nonempty_indices(op, slicegrid, slices, nonempty_indices);
96
98 ex_tbb, nonempty_indices.begin(), nonempty_indices.end(),
99 [op, &slices, &top](size_t i) {
100 merge_slices(op, i, top->slices, slices);
102 }
103
104 if (get_stack_operation(csgpart) == CSGStackOp::Pop) {
105 std::vector<ExPolygons> popslices = std::move(top->slices);
106 auto popop = opstack.top().op;
107 opstack.pop();
108 std::vector<ExPolygons> &prev_slices = opstack.top().slices;
109
110 collect_nonempty_indices(popop, slicegrid, popslices, nonempty_indices);
111
113 ex_tbb, nonempty_indices.begin(), nonempty_indices.end(),
114 [&popslices, &prev_slices, popop](size_t i) {
115 merge_slices(popop, i, prev_slices, popslices);
117 }
118 }
119
120 std::vector<ExPolygons> ret = std::move(opstack.top().slices);
121
122 // TODO: verify if this part can be omitted or not.
123 execution::for_each(ex_tbb, ret.begin(), ret.end(), [](ExPolygons &slice) {
124 auto it = std::remove_if(slice.begin(), slice.end(), [](const ExPolygon &p){
125 return p.area() < double(SCALED_EPSILON) * double(SCALED_EPSILON);
126 });
127
128 // Hopefully, ExPolygons are moved, not copied to new positions
129 // and that is cheap for expolygons
130 slice.erase(it, slice.end());
131 slice = union_ex(slice);
133
134 return ret;
135}
void collect_nonempty_indices(csg::CSGType op, const std::vector< float > &slicegrid, const std::vector< ExPolygons > &slices, std::vector< size_t > &indices)
Definition SliceCSGMesh.hpp:42
Definition LifecycleEvents.hpp:174
size_t max_concurrency(const EP &ep)
Definition Execution.hpp:38
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:20
IntegerOnly< I, std::vector< T, Args... > > reserve_vector(I capacity)
Definition libslic3r.h:370
Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, PolyFillType fill_type)
Definition ClipperUtils.cpp:1011
auto cast(const BoundingBoxBase< Tin > &b)
Definition BoundingBox.hpp:299
std::vector< ExPolygons > slice_mesh_ex(const indexed_triangle_set &mesh, const std::vector< float > &zs, const MeshSlicingParamsEx &params, std::function< void()> throw_on_cancel)
Definition TriangleMeshSlicer.cpp:2142
Transform3d trafo
Definition TriangleMeshSlicer.hpp:41

Referenced by Slic3r::GUI::MeshClipper::recalculate_triangles().

Here is the caller graph for this function: