FIX: organic support may crash with some model

bad function call when calling empty function throw_on_cancel.

jira: STUDIO-6927
Change-Id: Ib37530b5cf155973d4e21d088e07d3110c2d36e4
(cherry picked from commit 53f27f5968a481bab1666fe0053f9753d585f0da)
This commit is contained in:
Arthur 2024-04-23 17:44:45 +08:00 committed by Lane.Wei
parent 71bbb371ba
commit 0d57da5530
3 changed files with 15 additions and 32 deletions

View File

@ -181,7 +181,8 @@ void TreeModelVolumes::precalculate(const PrintObject& print_object, const coord
m_ignorable_radii.emplace_back(radius_eval);
}
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
// it may seem that the required avoidance can be of a smaller radius when going to model (no initial layer diameter for to model branches)
// but as for every branch going towards the bp, the to model avoidance is required to check for possible merges with to model branches, this assumption is in-fact wrong.
@ -202,7 +203,8 @@ void TreeModelVolumes::precalculate(const PrintObject& print_object, const coord
update_radius_until_layer(ceilRadius(config.recommendedMinRadius(current_layer) + m_current_min_xy_dist_delta));
}
throw_on_cancel();
if (throw_on_cancel)
throw_on_cancel();
// Copy to deque to use in parallel for later.
std::vector<RadiusLayerPair> relevant_avoidance_radiis{ radius_until_layer.begin(), radius_until_layer.end() };
@ -296,7 +298,7 @@ const Polygons& TreeModelVolumes::getCollision(const coord_t orig_radius, LayerI
BOOST_LOG_TRIVIAL(error_level_not_in_cache) << "Had to calculate collision at radius " << radius << " and layer " << layer_idx << ", but precalculate was called. Performance may suffer!";
tree_supports_show_error("Not precalculated Collision requested."sv, false);
}
const_cast<TreeModelVolumes*>(this)->calculateCollision(radius, layer_idx, {});
const_cast<TreeModelVolumes*>(this)->calculateCollision(radius, layer_idx, []{});
return getCollision(orig_radius, layer_idx, min_xy_dist);
}
@ -458,6 +460,7 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
collision_areas_offsetted[layer_idx] = offset_value == 0 ?
union_(collision_areas) :
offset(union_ex(collision_areas), offset_value, ClipperLib::jtMiter, 1.2);
if(throw_on_cancel)
throw_on_cancel();
}
});

View File

@ -356,7 +356,7 @@ private:
*/
void calculateCollisionHolefree(RadiusLayerPair key)
{
calculateCollisionHolefree(std::vector<RadiusLayerPair>{ RadiusLayerPair(key) }, {});
calculateCollisionHolefree(std::vector<RadiusLayerPair>{ RadiusLayerPair(key) }, []{});
}
/*!
@ -377,7 +377,7 @@ private:
*/
void calculateAvoidance(RadiusLayerPair key, bool to_build_plate, bool to_model)
{
calculateAvoidance(std::vector<RadiusLayerPair>{ RadiusLayerPair(key) }, to_build_plate, to_model, {});
calculateAvoidance(std::vector<RadiusLayerPair>{ RadiusLayerPair(key) }, to_build_plate, to_model, []{});
}
/*!
@ -411,7 +411,7 @@ private:
*/
void calculateWallRestrictions(RadiusLayerPair key)
{
calculateWallRestrictions(std::vector<RadiusLayerPair>{ RadiusLayerPair(key) }, {});
calculateWallRestrictions(std::vector<RadiusLayerPair>{ RadiusLayerPair(key) }, []{});
}
/*!

View File

@ -3556,15 +3556,8 @@ static std::pair<float, float> extrude_branch(
result.vertices.emplace_back((p1 - nprev * radius).cast<float>());
zmin = result.vertices.back().z();
float angle = angle_step;
std::pair<int, int> strip;
if (current.state.type == TreeNodeType::ePolygon) {
strip = discretize_polygon(p1.cast<float>(), current.influence_area, result.vertices);
prev_strip = strip;
strip = discretize_polygon(p2.cast<float>(), current.influence_area, result.vertices);
}
else {
for (int i = 1; i < nsteps; ++i, angle += angle_step) {
strip = discretize_circle((p1 - nprev * radius * cos(angle)).cast<float>(), nprev.cast<float>(), radius * sin(angle), eps, result.vertices);
std::pair<int, int> strip = discretize_circle((p1 - nprev * radius * cos(angle)).cast<float>(), nprev.cast<float>(), radius * sin(angle), eps, result.vertices);
if (i == 1)
triangulate_fan<false>(result, ifan, strip.first, strip.second);
else
@ -3572,7 +3565,6 @@ static std::pair<float, float> extrude_branch(
// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++ irun);
// its_write_obj(result, fname);
prev_strip = strip;
}
}
}
if (ipath + 1 == path.size()) {
@ -3584,13 +3576,8 @@ static std::pair<float, float> extrude_branch(
auto nsteps = int(ceil(M_PI / (2. * angle_step)));
angle_step = M_PI / (2. * nsteps);
auto angle = float(M_PI / 2.);
std::pair<int, int> strip;
if (current.state.type == TreeNodeType::ePolygon) {
strip = discretize_polygon(p2.cast<float>(), current.influence_area, result.vertices);
}
else {
for (int i = 0; i < nsteps; ++i, angle -= angle_step) {
strip = discretize_circle((p2 + ncurrent * radius * cos(angle)).cast<float>(), ncurrent.cast<float>(), radius * sin(angle), eps, result.vertices);
std::pair<int, int> strip = discretize_circle((p2 + ncurrent * radius * cos(angle)).cast<float>(), ncurrent.cast<float>(), radius * sin(angle), eps, result.vertices);
triangulate_strip(result, prev_strip.first, prev_strip.second, strip.first, strip.second);
// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++ irun);
// its_write_obj(result, fname);
@ -3602,7 +3589,6 @@ static std::pair<float, float> extrude_branch(
triangulate_fan<true>(result, ifan, prev_strip.first, prev_strip.second);
// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++ irun);
// its_write_obj(result, fname);
}
} else {
const SupportElement &next = *path[ipath + 1];
assert(current.state.layer_idx + 1 == next.state.layer_idx);
@ -3610,13 +3596,7 @@ static std::pair<float, float> extrude_branch(
v2 = (p3 - p2).normalized();
ncurrent = (v1 + v2).normalized();
float radius = unscaled<float>(support_element_radius(config, current));
std::pair<int, int> strip;
if (current.state.type == TreeNodeType::ePolygon) {
strip = discretize_polygon(p2.cast<float>(), current.influence_area, result.vertices);
}
else {
strip = discretize_circle(p2.cast<float>(), ncurrent.cast<float>(), radius, eps, result.vertices);
}
std::pair<int, int> strip = discretize_circle(p2.cast<float>(), ncurrent.cast<float>(), radius, eps, result.vertices);
triangulate_strip(result, prev_strip.first, prev_strip.second, strip.first, strip.second);
prev_strip = strip;
// sprintf(fname, "d:\\temp\\meshes\\tree-partial-%d.obj", ++irun);
@ -4052,9 +4032,9 @@ indexed_triangle_set draw_branches(
// Triangulate the tube.
partial_mesh.clear();
extrude_branch(path, config, slicing_params, move_bounds, partial_mesh);
#if 1
#if 0
char fname[2048];
sprintf(fname, "SVG\\tree-raw-%d.obj", ++ irun);
sprintf(fname, "%s\\SVG\\tree-raw-%d.obj",data_dir().c_str(), ++irun);
its_write_obj(partial_mesh, fname);
#if 0
temp_mesh.clear();
@ -4561,7 +4541,7 @@ void organic_draw_branches(
MeshSlicingParams mesh_slicing_params;
mesh_slicing_params.mode = MeshSlicingParams::SlicingMode::Positive;
tbb::parallel_for(tbb::blocked_range<size_t>(0, trees.size(), trees.size()),
tbb::parallel_for(tbb::blocked_range<size_t>(0, trees.size(), 1),
[&trees, &volumes, &config, &slicing_params, &move_bounds, &mesh_slicing_params, &throw_on_cancel](const tbb::blocked_range<size_t>& range) {
indexed_triangle_set partial_mesh;
std::vector<float> slice_z;