FIX: solve tree support crash
jira: STUDIO-8509 Change-Id: I8658538d7919136efbbf0d48cbf3d366e0621ded
This commit is contained in:
parent
ebdfa82845
commit
d5b14e5c09
|
@ -2004,7 +2004,7 @@ void TreeSupport::draw_circles()
|
||||||
return;
|
return;
|
||||||
BOOST_LOG_TRIVIAL(info) << "draw_circles for object: " << m_object->model_object()->name;
|
BOOST_LOG_TRIVIAL(info) << "draw_circles for object: " << m_object->model_object()->name;
|
||||||
|
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, contact_nodes.size()),
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, m_ts_data->layer_heights.size()),
|
||||||
[&](const tbb::blocked_range<size_t>& range)
|
[&](const tbb::blocked_range<size_t>& range)
|
||||||
{
|
{
|
||||||
for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++)
|
for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++)
|
||||||
|
@ -2662,6 +2662,7 @@ void TreeSupport::drop_nodes()
|
||||||
// Remove all circle neighbours that are completely inside the polygon and merge them into this node.
|
// Remove all circle neighbours that are completely inside the polygon and merge them into this node.
|
||||||
for (const Point &neighbour : neighbours) {
|
for (const Point &neighbour : neighbours) {
|
||||||
SupportNode * neighbour_node = nodes_this_part[neighbour];
|
SupportNode * neighbour_node = nodes_this_part[neighbour];
|
||||||
|
if (neighbour_node->valid == false) continue;
|
||||||
if (neighbour_node->type == ePolygon) continue;
|
if (neighbour_node->type == ePolygon) continue;
|
||||||
coord_t neighbour_radius = scale_(neighbour_node->radius);
|
coord_t neighbour_radius = scale_(neighbour_node->radius);
|
||||||
Point pt_north = neighbour + Point(0, neighbour_radius), pt_south = neighbour - Point(0, neighbour_radius),
|
Point pt_north = neighbour + Point(0, neighbour_radius), pt_south = neighbour - Point(0, neighbour_radius),
|
||||||
|
@ -2938,8 +2939,6 @@ void TreeSupport::drop_nodes()
|
||||||
for (; i_node != nullptr; i_node = i_node->parent)
|
for (; i_node != nullptr; i_node = i_node->parent)
|
||||||
{
|
{
|
||||||
size_t i_layer = i_node->obj_layer_nr;
|
size_t i_layer = i_node->obj_layer_nr;
|
||||||
std::vector<SupportNode*>::iterator to_erase = std::find(contact_nodes[i_layer].begin(), contact_nodes[i_layer].end(), i_node);
|
|
||||||
if (to_erase != contact_nodes[i_layer].end())
|
|
||||||
{
|
{
|
||||||
// update the parent-child chain
|
// update the parent-child chain
|
||||||
if (i_node->parent) {
|
if (i_node->parent) {
|
||||||
|
@ -2954,20 +2953,24 @@ void TreeSupport::drop_nodes()
|
||||||
i_node->child->parents.erase(std::find(i_node->child->parents.begin(), i_node->child->parents.end(), i_node));
|
i_node->child->parents.erase(std::find(i_node->child->parents.begin(), i_node->child->parents.end(), i_node));
|
||||||
append(i_node->child->parents, i_node->parents);
|
append(i_node->child->parents, i_node->parents);
|
||||||
}
|
}
|
||||||
contact_nodes[i_layer].erase(to_erase);
|
i_node->is_processed = true; // mark to be deleted later
|
||||||
i_node->valid = false;
|
|
||||||
|
|
||||||
for (SupportNode* neighbour : i_node->merged_neighbours)
|
for (SupportNode* neighbour : i_node->merged_neighbours)
|
||||||
{
|
{
|
||||||
|
if (neighbour && !neighbour->is_processed)
|
||||||
unsupported_branch_leaves.push_front({ i_layer, neighbour });
|
unsupported_branch_leaves.push_front({ i_layer, neighbour });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (auto &layer_contact_nodes : contact_nodes) {
|
||||||
|
if (!layer_contact_nodes.empty())
|
||||||
|
layer_contact_nodes.erase(std::remove_if(layer_contact_nodes.begin(), layer_contact_nodes.end(), [](SupportNode *node) { return node->is_processed; }),
|
||||||
|
layer_contact_nodes.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "after m_avoidance_cache.size()=" << m_ts_data->m_avoidance_cache.size();
|
BOOST_LOG_TRIVIAL(debug) << "after m_avoidance_cache.size()=" << m_ts_data->m_avoidance_cache.size();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeSupport::smooth_nodes()
|
void TreeSupport::smooth_nodes()
|
||||||
|
@ -3607,35 +3610,21 @@ SupportNode* TreeSupportData::create_node(const Point position, const int distan
|
||||||
{
|
{
|
||||||
// this function may be called from multiple threads, need to lock
|
// this function may be called from multiple threads, need to lock
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
SupportNode* node = new SupportNode(position, distance_to_top, obj_layer_nr, support_roof_layers_below, to_buildplate, parent, print_z_, height_, dist_mm_to_top_, radius_);
|
std::unique_ptr<SupportNode> node = std::make_unique<SupportNode>(position, distance_to_top, obj_layer_nr, support_roof_layers_below, to_buildplate, parent, print_z_, height_, dist_mm_to_top_, radius_);
|
||||||
contact_nodes.emplace_back(node);
|
SupportNode* raw_ptr = node.get();
|
||||||
|
contact_nodes.emplace_back(std::move(node));
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
if (parent)
|
if (parent)
|
||||||
node->movement = position - parent->position;
|
raw_ptr->movement = position - parent->position;
|
||||||
return node;
|
return raw_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeSupportData::clear_nodes()
|
void TreeSupportData::clear_nodes()
|
||||||
{
|
{
|
||||||
for (auto node : contact_nodes) {
|
tbb::spin_mutex::scoped_lock guard(m_mutex);
|
||||||
delete node;
|
|
||||||
}
|
|
||||||
contact_nodes.clear();
|
contact_nodes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeSupportData::remove_invalid_nodes()
|
|
||||||
{
|
|
||||||
for (auto it = contact_nodes.begin(); it != contact_nodes.end();) {
|
|
||||||
if ((*it)->valid==false) {
|
|
||||||
delete (*it);
|
|
||||||
it = contact_nodes.erase(it);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
coordf_t TreeSupportData::ceil_radius(coordf_t radius) const
|
coordf_t TreeSupportData::ceil_radius(coordf_t radius) const
|
||||||
{
|
{
|
||||||
size_t factor = (size_t)(radius / m_radius_sample_resolution);
|
size_t factor = (size_t)(radius / m_radius_sample_resolution);
|
||||||
|
@ -3663,14 +3652,8 @@ const ExPolygons& TreeSupportData::calculate_avoidance(const RadiusLayerPair& ke
|
||||||
{
|
{
|
||||||
const auto &radius = key.radius;
|
const auto &radius = key.radius;
|
||||||
const auto &layer_nr = key.layer_nr;
|
const auto &layer_nr = key.layer_nr;
|
||||||
if (layer_nr == 0) {
|
ExPolygons avoidance_areas;
|
||||||
// avoid ExPolygons:~ExPolygons() in multi-threading case, as it's not thread-safe and may
|
if (layer_nr > 0) {
|
||||||
// cause crash in some cases. See STUDIO-8313.
|
|
||||||
if (m_avoidance_cache.find(key) == m_avoidance_cache.end())
|
|
||||||
m_avoidance_cache[key] = get_collision(radius, 0);
|
|
||||||
return m_avoidance_cache[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoidance for a given layer depends on all layers beneath it so could have very deep recursion depths if
|
// Avoidance for a given layer depends on all layers beneath it so could have very deep recursion depths if
|
||||||
// called at high layer heights. We can limit the reqursion depth to N by checking if the layer N
|
// called at high layer heights. We can limit the reqursion depth to N by checking if the layer N
|
||||||
// below the current one exists and if not, forcing the calculation of that layer. This may cause another recursion
|
// below the current one exists and if not, forcing the calculation of that layer. This may cause another recursion
|
||||||
|
@ -3683,7 +3666,8 @@ const ExPolygons& TreeSupportData::calculate_avoidance(const RadiusLayerPair& ke
|
||||||
get_avoidance(radius, layer_nr - max_recursion_depth);
|
get_avoidance(radius, layer_nr - max_recursion_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExPolygons avoidance_areas = std::move(offset_ex(get_avoidance(radius, layer_nr - 1), scale_(-m_max_move_distances[layer_nr-1])));
|
avoidance_areas = std::move(offset_ex(get_avoidance(radius, layer_nr - 1), scale_(-m_max_move_distances[layer_nr-1])));
|
||||||
|
}
|
||||||
const ExPolygons &collision = get_collision(radius, layer_nr);
|
const ExPolygons &collision = get_collision(radius, layer_nr);
|
||||||
avoidance_areas.insert(avoidance_areas.end(), collision.begin(), collision.end());
|
avoidance_areas.insert(avoidance_areas.end(), collision.begin(), collision.end());
|
||||||
avoidance_areas = std::move(union_ex(avoidance_areas));
|
avoidance_areas = std::move(union_ex(avoidance_areas));
|
||||||
|
|
|
@ -247,10 +247,9 @@ public:
|
||||||
SupportNode* create_node(const Point position, const int distance_to_top, const int obj_layer_nr, const int support_roof_layers_below, const bool to_buildplate, SupportNode* parent,
|
SupportNode* create_node(const Point position, const int distance_to_top, const int obj_layer_nr, const int support_roof_layers_below, const bool to_buildplate, SupportNode* parent,
|
||||||
coordf_t print_z_, coordf_t height_, coordf_t dist_mm_to_top_ = 0, coordf_t radius_ = 0);
|
coordf_t print_z_, coordf_t height_, coordf_t dist_mm_to_top_ = 0, coordf_t radius_ = 0);
|
||||||
void clear_nodes();
|
void clear_nodes();
|
||||||
void remove_invalid_nodes();
|
|
||||||
std::vector<LayerHeightData> layer_heights;
|
std::vector<LayerHeightData> layer_heights;
|
||||||
|
|
||||||
std::vector<SupportNode*> contact_nodes;
|
std::vector<std::unique_ptr<SupportNode>> contact_nodes;
|
||||||
// ExPolygon m_machine_border;
|
// ExPolygon m_machine_border;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue