1 #ifndef SUPPORTTREEMESHER_HPP
2 #define SUPPORTTREEMESHER_HPP
3 
4 #include "libslic3r/Point.hpp"
5 
6 #include "libslic3r/SLA/SupportTreeBuilder.hpp"
7 #include "libslic3r/SLA/Contour3D.hpp"
8 
9 namespace Slic3r { namespace sla {
10 
11 using Portion = std::tuple<double, double>;
12 
make_portion(double a,double b)13 inline Portion make_portion(double a, double b)
14 {
15     return std::make_tuple(a, b);
16 }
17 
18 Contour3D sphere(double  rho,
19                  Portion portion = make_portion(0., 2. * PI),
20                  double  fa      = (2. * PI / 360.));
21 
22 // Down facing cylinder in Z direction with arguments:
23 // r: radius
24 // h: Height
25 // ssteps: how many edges will create the base circle
26 // sp: starting point
27 Contour3D cylinder(double       r,
28                    double       h,
29                    size_t       steps = 45,
30                    const Vec3d &sp    = Vec3d::Zero());
31 
32 Contour3D pinhead(double r_pin, double r_back, double length, size_t steps = 45);
33 
34 Contour3D halfcone(double       baseheight,
35                    double       r_bottom,
36                    double       r_top,
37                    const Vec3d &pt    = Vec3d::Zero(),
38                    size_t       steps = 45);
39 
get_mesh(const Head & h,size_t steps)40 inline Contour3D get_mesh(const Head &h, size_t steps)
41 {
42     Contour3D mesh = pinhead(h.r_pin_mm, h.r_back_mm, h.width_mm, steps);
43 
44     for(auto& p : mesh.points) p.z() -= (h.fullwidth() - h.r_back_mm);
45 
46     using Quaternion = Eigen::Quaternion<double>;
47 
48     // We rotate the head to the specified direction. The head's pointing
49     // side is facing upwards so this means that it would hold a support
50     // point with a normal pointing straight down. This is the reason of
51     // the -1 z coordinate
52     auto quatern = Quaternion::FromTwoVectors(Vec3d{0, 0, -1}, h.dir);
53 
54     for(auto& p : mesh.points) p = quatern * p + h.pos;
55 
56     return mesh;
57 }
58 
get_mesh(const Pillar & p,size_t steps)59 inline Contour3D get_mesh(const Pillar &p, size_t steps)
60 {
61     if(p.height > EPSILON) { // Endpoint is below the starting point
62         // We just create a bridge geometry with the pillar parameters and
63         // move the data.
64         return cylinder(p.r, p.height, steps, p.endpoint());
65     }
66 
67     return {};
68 }
69 
get_mesh(const Pedestal & p,size_t steps)70 inline Contour3D get_mesh(const Pedestal &p, size_t steps)
71 {
72     return halfcone(p.height, p.r_bottom, p.r_top, p.pos, steps);
73 }
74 
get_mesh(const Junction & j,size_t steps)75 inline Contour3D get_mesh(const Junction &j, size_t steps)
76 {
77     Contour3D mesh = sphere(j.r, make_portion(0, PI), 2 *PI / steps);
78     for(auto& p : mesh.points) p += j.pos;
79     return mesh;
80 }
81 
get_mesh(const Bridge & br,size_t steps)82 inline Contour3D get_mesh(const Bridge &br, size_t steps)
83 {
84     using Quaternion = Eigen::Quaternion<double>;
85     Vec3d v = (br.endp - br.startp);
86     Vec3d dir = v.normalized();
87     double d = v.norm();
88 
89     Contour3D mesh = cylinder(br.r, d, steps);
90 
91     auto quater = Quaternion::FromTwoVectors(Vec3d{0,0,1}, dir);
92     for(auto& p : mesh.points) p = quater * p + br.startp;
93 
94     return mesh;
95 }
96 
get_mesh(const DiffBridge & br,size_t steps)97 inline Contour3D get_mesh(const DiffBridge &br, size_t steps)
98 {
99     double h = br.get_length();
100     Contour3D mesh = halfcone(h, br.r, br.end_r, Vec3d::Zero(), steps);
101 
102     using Quaternion = Eigen::Quaternion<double>;
103 
104     // We rotate the head to the specified direction. The head's pointing
105     // side is facing upwards so this means that it would hold a support
106     // point with a normal pointing straight down. This is the reason of
107     // the -1 z coordinate
108     auto quatern = Quaternion::FromTwoVectors(Vec3d{0, 0, 1}, br.get_dir());
109 
110     for(auto& p : mesh.points) p = quatern * p + br.startp;
111 
112     return mesh;
113 }
114 
115 }} // namespace Slic3r::sla
116 
117 #endif // SUPPORTTREEMESHER_HPP
118