mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-11-01 05:01:10 -06:00
Working small-to-normal support merging
Fixed fatal bug with anchors for mini supports Make the optimization cleaner in support generatior Much better widening behaviour Add an optimizer interface and the NLopt implementation into libslic3r New optimizer based only on nlopt C interfase Fix build and tests
This commit is contained in:
parent
8cb115a035
commit
927b81ea97
9 changed files with 831 additions and 395 deletions
|
|
@ -87,7 +87,7 @@ public:
|
|||
inline Vec3d position() const { return m_source + m_dir * m_t; }
|
||||
inline int face() const { return m_face_id; }
|
||||
inline bool is_valid() const { return m_mesh != nullptr; }
|
||||
inline bool is_hit() const { return !std::isinf(m_t); }
|
||||
inline bool is_hit() const { return m_face_id >= 0 && !std::isinf(m_t); }
|
||||
|
||||
inline const Vec3d& normal() const {
|
||||
assert(is_valid());
|
||||
|
|
|
|||
|
|
@ -156,6 +156,11 @@ const TriangleMesh &SupportTreeBuilder::merged_mesh(size_t steps) const
|
|||
merged.merge(get_mesh(bs, steps));
|
||||
}
|
||||
|
||||
for (auto &bs : m_diffbridges) {
|
||||
if (ctl().stopcondition()) break;
|
||||
merged.merge(get_mesh(bs, steps));
|
||||
}
|
||||
|
||||
for (auto &anch : m_anchors) {
|
||||
if (ctl().stopcondition()) break;
|
||||
merged.merge(get_mesh(anch, steps));
|
||||
|
|
|
|||
|
|
@ -177,6 +177,14 @@ struct Bridge: public SupportTreeNode {
|
|||
Vec3d get_dir() const { return (endp - startp).normalized(); }
|
||||
};
|
||||
|
||||
struct DiffBridge: public Bridge {
|
||||
double end_r;
|
||||
|
||||
DiffBridge(const Vec3d &p_s, const Vec3d &p_e, double r_s, double r_e)
|
||||
: Bridge{p_s, p_e, r_s}, end_r{r_e}
|
||||
{}
|
||||
};
|
||||
|
||||
// A wrapper struct around the pad
|
||||
struct Pad {
|
||||
TriangleMesh tmesh;
|
||||
|
|
@ -210,14 +218,15 @@ struct Pad {
|
|||
// merged mesh. It can be retrieved using a dedicated method (pad())
|
||||
class SupportTreeBuilder: public SupportTree {
|
||||
// For heads it is beneficial to use the same IDs as for the support points.
|
||||
std::vector<Head> m_heads;
|
||||
std::vector<size_t> m_head_indices;
|
||||
std::vector<Pillar> m_pillars;
|
||||
std::vector<Junction> m_junctions;
|
||||
std::vector<Bridge> m_bridges;
|
||||
std::vector<Bridge> m_crossbridges;
|
||||
std::vector<Pedestal> m_pedestals;
|
||||
std::vector<Anchor> m_anchors;
|
||||
std::vector<Head> m_heads;
|
||||
std::vector<size_t> m_head_indices;
|
||||
std::vector<Pillar> m_pillars;
|
||||
std::vector<Junction> m_junctions;
|
||||
std::vector<Bridge> m_bridges;
|
||||
std::vector<Bridge> m_crossbridges;
|
||||
std::vector<DiffBridge> m_diffbridges;
|
||||
std::vector<Pedestal> m_pedestals;
|
||||
std::vector<Anchor> m_anchors;
|
||||
|
||||
Pad m_pad;
|
||||
|
||||
|
|
@ -228,8 +237,8 @@ class SupportTreeBuilder: public SupportTree {
|
|||
mutable bool m_meshcache_valid = false;
|
||||
mutable double m_model_height = 0; // the full height of the model
|
||||
|
||||
template<class...Args>
|
||||
const Bridge& _add_bridge(std::vector<Bridge> &br, Args&&... args)
|
||||
template<class BridgeT, class...Args>
|
||||
const BridgeT& _add_bridge(std::vector<BridgeT> &br, Args&&... args)
|
||||
{
|
||||
std::lock_guard<Mutex> lk(m_mutex);
|
||||
br.emplace_back(std::forward<Args>(args)...);
|
||||
|
|
@ -331,17 +340,6 @@ public:
|
|||
return pillar.id;
|
||||
}
|
||||
|
||||
const Pillar& head_pillar(unsigned headid) const
|
||||
{
|
||||
std::lock_guard<Mutex> lk(m_mutex);
|
||||
assert(headid < m_head_indices.size());
|
||||
|
||||
const Head& h = m_heads[m_head_indices[headid]];
|
||||
assert(h.pillar_id >= 0 && h.pillar_id < long(m_pillars.size()));
|
||||
|
||||
return m_pillars[size_t(h.pillar_id)];
|
||||
}
|
||||
|
||||
template<class...Args> const Junction& add_junction(Args&&... args)
|
||||
{
|
||||
std::lock_guard<Mutex> lk(m_mutex);
|
||||
|
|
@ -374,6 +372,11 @@ public:
|
|||
{
|
||||
return _add_bridge(m_crossbridges, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<class...Args> const DiffBridge& add_diffbridge(Args&&... args)
|
||||
{
|
||||
return _add_bridge(m_diffbridges, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
Head &head(unsigned id)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -45,6 +45,11 @@ inline Vec3d spheric_to_dir(const std::pair<double, double> &v)
|
|||
return spheric_to_dir(v.first, v.second);
|
||||
}
|
||||
|
||||
inline Vec3d spheric_to_dir(const std::array<double, 2> &v)
|
||||
{
|
||||
return spheric_to_dir(v[0], v[1]);
|
||||
}
|
||||
|
||||
// Give points on a 3D ring with given center, radius and orientation
|
||||
// method based on:
|
||||
// https://math.stackexchange.com/questions/73237/parametric-equation-of-a-circle-in-3d-space
|
||||
|
|
@ -249,7 +254,8 @@ class SupportTreeBuildsteps {
|
|||
double width)
|
||||
{
|
||||
return pinhead_mesh_intersect(s, dir, r_pin, r_back, width,
|
||||
m_cfg.safety_distance_mm);
|
||||
r_back * m_cfg.safety_distance_mm /
|
||||
m_cfg.head_back_radius_mm);
|
||||
}
|
||||
|
||||
// Checking bridge (pillar and stick as well) intersection with the model.
|
||||
|
|
@ -271,7 +277,9 @@ class SupportTreeBuildsteps {
|
|||
const Vec3d& dir,
|
||||
double r)
|
||||
{
|
||||
return bridge_mesh_intersect(s, dir, r, m_cfg.safety_distance_mm);
|
||||
return bridge_mesh_intersect(s, dir, r,
|
||||
r * m_cfg.safety_distance_mm /
|
||||
m_cfg.head_back_radius_mm);
|
||||
}
|
||||
|
||||
template<class...Args>
|
||||
|
|
@ -311,6 +319,11 @@ class SupportTreeBuildsteps {
|
|||
m_builder.add_pillar_base(pid, m_cfg.base_height_mm, m_cfg.base_radius_mm);
|
||||
}
|
||||
|
||||
std::optional<DiffBridge> search_widening_path(const Vec3d &jp,
|
||||
const Vec3d &dir,
|
||||
double radius,
|
||||
double new_radius);
|
||||
|
||||
public:
|
||||
SupportTreeBuildsteps(SupportTreeBuilder & builder, const SupportableMesh &sm);
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,24 @@ inline Contour3D get_mesh(const Bridge &br, size_t steps)
|
|||
return mesh;
|
||||
}
|
||||
|
||||
inline Contour3D get_mesh(const DiffBridge &br, size_t steps)
|
||||
{
|
||||
double h = br.get_length();
|
||||
Contour3D mesh = halfcone(h, br.r, br.end_r, Vec3d::Zero(), steps);
|
||||
|
||||
using Quaternion = Eigen::Quaternion<double>;
|
||||
|
||||
// We rotate the head to the specified direction. The head's pointing
|
||||
// side is facing upwards so this means that it would hold a support
|
||||
// point with a normal pointing straight down. This is the reason of
|
||||
// the -1 z coordinate
|
||||
auto quatern = Quaternion::FromTwoVectors(Vec3d{0, 0, 1}, br.get_dir());
|
||||
|
||||
for(auto& p : mesh.points) p = quatern * p + br.startp;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::sla
|
||||
|
||||
#endif // SUPPORTTREEMESHER_HPP
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue