Eliminate some race conditions in sla support tree
This commit is contained in:
parent
95e22d8fd4
commit
23a7e77a81
@ -208,11 +208,6 @@ struct Bridge {
|
|||||||
const Vec3d &j2,
|
const Vec3d &j2,
|
||||||
double r_mm = 0.8,
|
double r_mm = 0.8,
|
||||||
size_t steps = 45);
|
size_t steps = 45);
|
||||||
|
|
||||||
Bridge(const Head &h,
|
|
||||||
const Vec3d &j2,
|
|
||||||
size_t steps = 45)
|
|
||||||
: Bridge{h.junction_point(), j2, h.r_back_mm, steps} {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A bridge that spans from model surface to model surface with small connecting
|
// A bridge that spans from model surface to model surface with small connecting
|
||||||
@ -310,12 +305,12 @@ public:
|
|||||||
return m_heads.back();
|
return m_heads.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class...Args> Pillar& add_pillar(unsigned headid, Args&&... args)
|
template<class...Args> long add_pillar(long headid, Args&&... args)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lk(m_mutex);
|
std::lock_guard<Mutex> lk(m_mutex);
|
||||||
|
|
||||||
assert(headid < m_head_indices.size());
|
assert(headid >= 0 && headid < m_head_indices.size());
|
||||||
Head &head = m_heads[m_head_indices[headid]];
|
Head &head = m_heads[m_head_indices[size_t(headid)]];
|
||||||
|
|
||||||
m_pillars.emplace_back(head, std::forward<Args>(args)...);
|
m_pillars.emplace_back(head, std::forward<Args>(args)...);
|
||||||
Pillar& pillar = m_pillars.back();
|
Pillar& pillar = m_pillars.back();
|
||||||
@ -325,7 +320,14 @@ public:
|
|||||||
pillar.starts_from_head = true;
|
pillar.starts_from_head = true;
|
||||||
|
|
||||||
m_meshcache_valid = false;
|
m_meshcache_valid = false;
|
||||||
return m_pillars.back();
|
return pillar.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_pillar_base(long pid, double baseheight = 3, double radius = 2)
|
||||||
|
{
|
||||||
|
std::lock_guard<Mutex> lk(m_mutex);
|
||||||
|
assert(pid >= 0 && pid < m_pillars.size());
|
||||||
|
m_pillars[size_t(pid)].add_base(baseheight, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
void increment_bridges(const Pillar& pillar)
|
void increment_bridges(const Pillar& pillar)
|
||||||
@ -352,7 +354,7 @@ public:
|
|||||||
return pillar.bridges;
|
return pillar.bridges;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class...Args> Pillar& add_pillar(Args&&...args)
|
template<class...Args> long add_pillar(Args&&...args)
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lk(m_mutex);
|
std::lock_guard<Mutex> lk(m_mutex);
|
||||||
m_pillars.emplace_back(std::forward<Args>(args)...);
|
m_pillars.emplace_back(std::forward<Args>(args)...);
|
||||||
@ -360,7 +362,7 @@ public:
|
|||||||
pillar.id = long(m_pillars.size() - 1);
|
pillar.id = long(m_pillars.size() - 1);
|
||||||
pillar.starts_from_head = false;
|
pillar.starts_from_head = false;
|
||||||
m_meshcache_valid = false;
|
m_meshcache_valid = false;
|
||||||
return m_pillars.back();
|
return pillar.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Pillar& head_pillar(unsigned headid) const
|
const Pillar& head_pillar(unsigned headid) const
|
||||||
@ -383,21 +385,21 @@ public:
|
|||||||
return m_junctions.back();
|
return m_junctions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class...Args> const Bridge&
|
const Bridge& add_bridge(const Vec3d &s, const Vec3d &e, double r, size_t n = 45)
|
||||||
add_bridge(const Vec3d &sp, const Vec3d &ep, double r, size_t steps = 45)
|
|
||||||
{
|
{
|
||||||
return _add_bridge(m_bridges, sp, ep, r, steps);
|
return _add_bridge(m_bridges, s, e, r, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class...Args>
|
const Bridge& add_bridge(long headid, const Vec3d &endp, size_t s = 45)
|
||||||
const Bridge& add_bridge(const Head &h, const Vec3d &endp, size_t steps = 45)
|
|
||||||
{
|
{
|
||||||
std::lock_guard<Mutex> lk(m_mutex);
|
std::lock_guard<Mutex> lk(m_mutex);
|
||||||
m_bridges.emplace_back(h, endp, steps);
|
assert(headid >= 0 && headid < m_head_indices.size());
|
||||||
|
|
||||||
|
Head &h = m_heads[m_head_indices[size_t(headid)]];
|
||||||
|
m_bridges.emplace_back(h.junction_point(), endp, h.r_back_mm, s);
|
||||||
m_bridges.back().id = long(m_bridges.size() - 1);
|
m_bridges.back().id = long(m_bridges.size() - 1);
|
||||||
|
|
||||||
assert(h.id >= 0 && h.id < m_head_indices.size());
|
h.bridge_id = m_bridges.back().id;
|
||||||
m_heads[m_head_indices[size_t(h.id)]].bridge_id = m_bridges.back().id;
|
|
||||||
m_meshcache_valid = false;
|
m_meshcache_valid = false;
|
||||||
return m_bridges.back();
|
return m_bridges.back();
|
||||||
}
|
}
|
||||||
@ -444,6 +446,15 @@ public:
|
|||||||
return m_pillars[size_t(id)];
|
return m_pillars[size_t(id)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T> inline IntegerOnly<T, Pillar&> pillar(T id)
|
||||||
|
{
|
||||||
|
std::lock_guard<Mutex> lk(m_mutex);
|
||||||
|
assert(id >= 0 && size_t(id) < m_pillars.size() &&
|
||||||
|
size_t(id) < std::numeric_limits<size_t>::max());
|
||||||
|
|
||||||
|
return m_pillars[size_t(id)];
|
||||||
|
}
|
||||||
|
|
||||||
const Pad& pad() const { return m_pad; }
|
const Pad& pad() const { return m_pad; }
|
||||||
|
|
||||||
// WITHOUT THE PAD!!!
|
// WITHOUT THE PAD!!!
|
||||||
|
@ -508,15 +508,14 @@ bool SupportTreeBuildsteps::connect_to_nearpillar(const Head &head,
|
|||||||
if (m_builder.bridgecount(nearpillar()) < m_cfg.max_bridges_on_pillar) {
|
if (m_builder.bridgecount(nearpillar()) < m_cfg.max_bridges_on_pillar) {
|
||||||
// A partial pillar is needed under the starting head.
|
// A partial pillar is needed under the starting head.
|
||||||
if(zdiff > 0) {
|
if(zdiff > 0) {
|
||||||
m_builder.add_pillar(unsigned(head.id), bridgestart, r);
|
m_builder.add_pillar(head.id, bridgestart, r);
|
||||||
m_builder.add_junction(bridgestart, r);
|
m_builder.add_junction(bridgestart, r);
|
||||||
|
m_builder.add_bridge(bridgestart, bridgeend, head.r_back_mm);
|
||||||
|
} else {
|
||||||
|
m_builder.add_bridge(head.id, bridgeend);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &br = m_builder.add_bridge(bridgestart, bridgeend, r);
|
|
||||||
m_builder.increment_bridges(nearpillar());
|
m_builder.increment_bridges(nearpillar());
|
||||||
if (head.pillar_id == ID_UNSET)
|
|
||||||
m_builder.head(unsigned(head.id)).bridge_id = br.id;
|
|
||||||
|
|
||||||
} else return false;
|
} else return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -631,13 +630,11 @@ void SupportTreeBuildsteps::create_ground_pillar(const Vec3d &jp,
|
|||||||
auto hit = bridge_mesh_intersect(endp, DOWN, radius);
|
auto hit = bridge_mesh_intersect(endp, DOWN, radius);
|
||||||
if (!std::isinf(hit.distance())) abort_in_shame();
|
if (!std::isinf(hit.distance())) abort_in_shame();
|
||||||
|
|
||||||
Pillar &plr = m_builder.add_pillar(endp, pgnd, radius);
|
pillar_id = m_builder.add_pillar(endp, pgnd, radius);
|
||||||
|
|
||||||
if (can_add_base)
|
if (can_add_base)
|
||||||
plr.add_base(m_cfg.base_height_mm,
|
m_builder.add_pillar_base(pillar_id, m_cfg.base_height_mm,
|
||||||
m_cfg.base_radius_mm);
|
m_cfg.base_radius_mm);
|
||||||
|
|
||||||
pillar_id = plr.id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_builder.add_bridge(jp, endp, radius);
|
m_builder.add_bridge(jp, endp, radius);
|
||||||
@ -648,19 +645,17 @@ void SupportTreeBuildsteps::create_ground_pillar(const Vec3d &jp,
|
|||||||
// prevent from queries of head_pillar() to have non-existing
|
// prevent from queries of head_pillar() to have non-existing
|
||||||
// pillar when the head should have one.
|
// pillar when the head should have one.
|
||||||
if (head_id >= 0)
|
if (head_id >= 0)
|
||||||
m_builder.add_pillar(unsigned(head_id), jp, radius);
|
m_builder.add_pillar(head_id, jp, radius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normal_mode) {
|
if (normal_mode) {
|
||||||
Pillar &plr = head_id >= 0
|
pillar_id = head_id >= 0 ? m_builder.add_pillar(head_id, endp, radius) :
|
||||||
? m_builder.add_pillar(unsigned(head_id), endp, radius)
|
m_builder.add_pillar(jp, endp, radius);
|
||||||
: m_builder.add_pillar(jp, endp, radius);
|
|
||||||
|
|
||||||
if (can_add_base)
|
if (can_add_base)
|
||||||
plr.add_base(m_cfg.base_height_mm, m_cfg.base_radius_mm);
|
m_builder.add_pillar_base(pillar_id, m_cfg.base_height_mm,
|
||||||
|
m_cfg.base_radius_mm);
|
||||||
pillar_id = plr.id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pillar_id >= 0) // Save the pillar endpoint in the spatial index
|
if(pillar_id >= 0) // Save the pillar endpoint in the spatial index
|
||||||
@ -871,10 +866,8 @@ void SupportTreeBuildsteps::classify()
|
|||||||
return d2d < 2 * m_cfg.base_radius_mm
|
return d2d < 2 * m_cfg.base_radius_mm
|
||||||
&& d3d < m_cfg.max_bridge_length_mm;
|
&& d3d < m_cfg.max_bridge_length_mm;
|
||||||
};
|
};
|
||||||
|
|
||||||
m_pillar_clusters = cluster(ground_head_indices,
|
m_pillar_clusters = cluster(ground_head_indices, pointfn, predicate,
|
||||||
pointfn,
|
|
||||||
predicate,
|
|
||||||
m_cfg.max_bridges_on_pillar);
|
m_cfg.max_bridges_on_pillar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,7 +958,7 @@ void SupportTreeBuildsteps::routing_to_model()
|
|||||||
{
|
{
|
||||||
head.transform();
|
head.transform();
|
||||||
Vec3d endp = head.junction_point() + dist * dir;
|
Vec3d endp = head.junction_point() + dist * dir;
|
||||||
m_builder.add_bridge(head, endp);
|
m_builder.add_bridge(head.id, endp);
|
||||||
m_builder.add_junction(endp, head.r_back_mm);
|
m_builder.add_junction(endp, head.r_back_mm);
|
||||||
|
|
||||||
this->create_ground_pillar(endp, dir, head.r_back_mm);
|
this->create_ground_pillar(endp, dir, head.r_back_mm);
|
||||||
@ -1096,11 +1089,10 @@ void SupportTreeBuildsteps::routing_to_model()
|
|||||||
center_hit.position() : hit.position();
|
center_hit.position() : hit.position();
|
||||||
|
|
||||||
head.transform();
|
head.transform();
|
||||||
|
|
||||||
Pillar& pill = m_builder.add_pillar(unsigned(head.id),
|
long pillar_id = m_builder.add_pillar(head.id, endp, head.r_back_mm);
|
||||||
endp,
|
Pillar &pill = m_builder.pillar(pillar_id);
|
||||||
head.r_back_mm);
|
|
||||||
|
|
||||||
Vec3d taildir = endp - hitp;
|
Vec3d taildir = endp - hitp;
|
||||||
double dist = distance(endp, hitp) + m_cfg.head_penetration_mm;
|
double dist = distance(endp, hitp) + m_cfg.head_penetration_mm;
|
||||||
double w = dist - 2 * head.r_pin_mm - head.r_back_mm;
|
double w = dist - 2 * head.r_pin_mm - head.r_back_mm;
|
||||||
@ -1310,7 +1302,7 @@ void SupportTreeBuildsteps::interconnect_pillars()
|
|||||||
p.add_base(m_cfg.base_height_mm, m_cfg.base_radius_mm);
|
p.add_base(m_cfg.base_height_mm, m_cfg.base_radius_mm);
|
||||||
|
|
||||||
if (interconnect(pillar(), p)) {
|
if (interconnect(pillar(), p)) {
|
||||||
Pillar &pp = m_builder.add_pillar(p);
|
Pillar &pp = m_builder.pillar(m_builder.add_pillar(p));
|
||||||
m_pillar_index.insert(pp.endpoint(), unsigned(pp.id));
|
m_pillar_index.insert(pp.endpoint(), unsigned(pp.id));
|
||||||
|
|
||||||
m_builder.add_junction(s, pillar().r);
|
m_builder.add_junction(s, pillar().r);
|
||||||
|
@ -250,7 +250,7 @@ void test_support_model_collision(
|
|||||||
|
|
||||||
// Set head penetration to a small negative value which should ensure that
|
// Set head penetration to a small negative value which should ensure that
|
||||||
// the supports will not touch the model body.
|
// the supports will not touch the model body.
|
||||||
supportcfg.head_penetration_mm = -0.1;
|
supportcfg.head_penetration_mm = -input_supportcfg.head_front_radius_mm;
|
||||||
|
|
||||||
test_supports(obj_filename, supportcfg, byproducts);
|
test_supports(obj_filename, supportcfg, byproducts);
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ const char * const AROUND_PAD_TEST_OBJECTS[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char *const SUPPORT_TEST_MODELS[] = {
|
const char *const SUPPORT_TEST_MODELS[] = {
|
||||||
"cube_with_concave_hole_enlarged_standing.obj",
|
"cube_with_concave_hole_enlarged_standing.obj"
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user