Skip to content

Commit

Permalink
Update to Cura 5.2 and implement support_tree_max_diameter.
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasRahm committed Oct 20, 2022
1 parent ecd1ff1 commit a5406e7
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 62 deletions.
4 changes: 2 additions & 2 deletions include/TreeSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace cura

class TreeSupport
{
public:
public:
/*!
* \brief Creates an instance of the tree support generator.
*
Expand All @@ -66,7 +66,7 @@ class TreeSupport
void generateSupportAreas(SliceDataStorage& storage);


private:
private:
enum class LineStatus
{
INVALID,
Expand Down
16 changes: 10 additions & 6 deletions include/TreeSupportSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct TreeSupportSettings
layer_height(mesh_group_settings.get<coord_t>("layer_height")),
branch_radius(mesh_group_settings.get<coord_t>("support_tree_branch_diameter") / 2),
min_radius(mesh_group_settings.get<coord_t>("support_tree_tip_diameter") / 2), // The actual radius is 50 microns larger as the resulting branches will be increased by 50 microns to avoid rounding errors effectively increasing the xydistance
max_radius(mesh_group_settings.get<coord_t>("support_tree_max_diameter")/2),
maximum_move_distance((angle < TAU / 4) ? (coord_t)(tan(angle) * layer_height) : std::numeric_limits<coord_t>::max()),
maximum_move_distance_slow((angle_slow < TAU / 4) ? (coord_t)(tan(angle_slow) * layer_height) : std::numeric_limits<coord_t>::max()),
support_bottom_layers(mesh_group_settings.get<bool>("support_bottom_enable") ? round_divide(mesh_group_settings.get<coord_t>("support_bottom_height"), layer_height) : 0),
Expand All @@ -40,9 +41,7 @@ struct TreeSupportSettings
increase_radius_until_radius(mesh_group_settings.get<coord_t>("support_tree_branch_diameter") / 2),
increase_radius_until_dtt(increase_radius_until_radius <= branch_radius ? tip_layers * (increase_radius_until_radius / branch_radius) : (increase_radius_until_radius - branch_radius) / (branch_radius * diameter_angle_scale_factor)),
support_rests_on_model(mesh_group_settings.get<ESupportType>("support_type") == ESupportType::EVERYWHERE),
// support_rest_preference(support_rests_on_model? RestPreference::BUILDPLATE : mesh_group_settings.get<bool>("support_tree_no_rest_preference")?RestPreference::GRACEFUL:RestPreference::BUILDPLATE),
support_rest_preference((support_rests_on_model && mesh_group_settings.get<std::string>("support_tree_rest_preference") == "graceful") ? RestPreference::GRACEFUL : RestPreference::BUILDPLATE),

xy_distance(mesh_group_settings.get<coord_t>("support_xy_distance")),
bp_radius(mesh_group_settings.get<coord_t>("support_tree_bp_diameter") / 2),
diameter_scale_bp_radius(std::min(sin(0.7) * layer_height / branch_radius, 1.0 / (branch_radius / (support_line_width / 2.0)))), // Either 40° or as much as possible so that 2 lines will overlap by at least 50%, whichever is smaller.
Expand Down Expand Up @@ -141,9 +140,13 @@ struct TreeSupportSettings
*/
coord_t branch_radius;
/*!
* \brief smallest allowed radius, required to ensure that even at DTT 0 every circle will still be printed
* \brief The smallest allowed radius, required to ensure that even at DTT 0 every circle will still be printed.
*/
coord_t min_radius;
/*!
* \brief The largest allowed radius.
*/
coord_t max_radius;
/*!
* \brief How far an influence area may move outward every layer at most.
*/
Expand Down Expand Up @@ -315,7 +318,7 @@ struct TreeSupportSettings
support_bottom_offset == other.support_bottom_offset && support_wall_count == other.support_wall_count && support_pattern == other.support_pattern && roof_pattern == other.roof_pattern && // can not be set on a per-mesh basis currently, so code to enable processing different roof patterns in the same iteration seems useless.
support_roof_angles == other.support_roof_angles && support_infill_angles == other.support_infill_angles && increase_radius_until_radius == other.increase_radius_until_radius && support_bottom_layers == other.support_bottom_layers && layer_height == other.layer_height && z_distance_top_layers == other.z_distance_top_layers && maximum_deviation == other.maximum_deviation && // Infill generation depends on deviation and resolution.
maximum_resolution == other.maximum_resolution && support_roof_line_distance == other.support_roof_line_distance && skip_some_zags == other.skip_some_zags && zag_skip_count == other.zag_skip_count && connect_zigzags == other.connect_zigzags && interface_preference == other.interface_preference && min_feature_size == other.min_feature_size // interface_preference should be identical to ensure the tree will correctly interact with the roof.
&& support_rest_preference == other.support_rest_preference
&& support_rest_preference == other.support_rest_preference && max_radius == other.max_radius
// The infill class now wants the settings object and reads a lot of settings, and as the infill class is used to calculate support roof lines for interface-preference. Not all of these may be required to be identical, but as I am not sure, better safe than sorry
&& (interface_preference == InterfacePreference::INTERFACE_AREA_OVERWRITES_SUPPORT || interface_preference == InterfacePreference::SUPPORT_AREA_OVERWRITES_INTERFACE
|| (settings.get<bool>("fill_outline_gaps") == other.settings.get<bool>("fill_outline_gaps") && settings.get<coord_t>("min_bead_width") == other.settings.get<coord_t>("min_bead_width") && settings.get<AngleRadians>("wall_transition_angle") == other.settings.get<AngleRadians>("wall_transition_angle") && settings.get<coord_t>("wall_transition_length") == other.settings.get<coord_t>("wall_transition_length") && settings.get<Ratio>("wall_split_middle_threshold") == other.settings.get<Ratio>("wall_split_middle_threshold") && settings.get<Ratio>("wall_add_middle_threshold") == other.settings.get<Ratio>("wall_add_middle_threshold") && settings.get<int>("wall_distribution_count") == other.settings.get<int>("wall_distribution_count") && settings.get<coord_t>("wall_transition_filter_distance") == other.settings.get<coord_t>("wall_transition_filter_distance") && settings.get<coord_t>("wall_transition_filter_deviation") == other.settings.get<coord_t>("wall_transition_filter_deviation") && settings.get<coord_t>("wall_line_width_x") == other.settings.get<coord_t>("wall_line_width_x")
Expand All @@ -341,11 +344,12 @@ struct TreeSupportSettings
*/
[[nodiscard]] inline coord_t getRadius(size_t distance_to_top, const double buildplate_radius_increases = 0) const
{
return (distance_to_top <= tip_layers ? min_radius + (branch_radius - min_radius) * distance_to_top / tip_layers : // tip
coord_t uncapped_radius= (distance_to_top <= tip_layers ? min_radius + (branch_radius - min_radius) * distance_to_top / tip_layers : // tip
branch_radius + // base
branch_radius * (distance_to_top - tip_layers) * diameter_angle_scale_factor)
+ // gradual increase
branch_radius * buildplate_radius_increases * (std::max(diameter_scale_bp_radius - diameter_angle_scale_factor, 0.0));
return std::min(uncapped_radius,max_radius);
}

/*!
Expand Down Expand Up @@ -376,7 +380,7 @@ struct TreeSupportSettings
[[nodiscard]] inline coord_t recommendedMinRadius(LayerIndex layer_idx) const
{
double scale = (layer_start_bp_radius - layer_idx) * diameter_scale_bp_radius;
return scale > 0 ? branch_radius + branch_radius * scale : 0;
return scale > 0 ? std::min(coord_t(branch_radius + branch_radius * scale),max_radius) : 0;
}

/*!
Expand Down
29 changes: 15 additions & 14 deletions src/TreeModelVolumes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "sliceDataStorage.h"
#include "utils/ThreadPool.h"
#include "utils/algorithm.h"
#include "utils/logoutput.h"
#include <spdlog/spdlog.h>
namespace cura
{

Expand Down Expand Up @@ -185,14 +185,14 @@ void TreeModelVolumes::precalculate(coord_t max_layer)
std::deque<RadiusLayerPair> relevant_collision_radiis;
relevant_collision_radiis.insert(relevant_collision_radiis.end(), radius_until_layer.begin(), radius_until_layer.end()); // Now that required_avoidance_limit contains the maximum of ild and regular required radius just copy.


// ### Calculate the relevant collisions
calculateCollision(relevant_collision_radiis);

// calculate a separate Collisions with all holes removed. These are relevant for some avoidances that try to avoid holes (called safe)
std::deque<RadiusLayerPair> relevant_hole_collision_radiis;
for (RadiusLayerPair key : relevant_avoidance_radiis)
{
spdlog::debug("Calculating avoidance of radius {} up to layer {}",key.first,key.second);
if (key.first < increase_until_radius + current_min_xy_dist_delta)
{
relevant_hole_collision_radiis.emplace_back(key);
Expand Down Expand Up @@ -235,7 +235,7 @@ void TreeModelVolumes::precalculate(coord_t max_layer)
auto dur_col = 0.001 * std::chrono::duration_cast<std::chrono::microseconds>(t_coll - t_start).count();
auto dur_avo = 0.001 * std::chrono::duration_cast<std::chrono::microseconds>(t_end - t_coll).count();

log("Precalculating collision took %.3lf ms. Precalculating avoidance took %.3lf ms.\n", dur_col, dur_avo);
spdlog::info("Precalculating collision took {} ms. Precalculating avoidance took {} ms.", dur_col, dur_avo);
}

const Polygons& TreeModelVolumes::getCollision(coord_t radius, LayerIndex layer_idx, bool min_xy_dist)
Expand Down Expand Up @@ -264,7 +264,7 @@ const Polygons& TreeModelVolumes::getCollision(coord_t radius, LayerIndex layer_
}
if (precalculated)
{
logWarning("Had to calculate collision at radius %lld and layer %lld, but precalculate was called. Performance may suffer!\n", key.first, key.second);
spdlog::warn("Had to calculate collision at radius {} and layer {}, but precalculate was called. Performance may suffer!", key.first, key.second);
}
calculateCollision(key);
return getCollision(orig_radius, layer_idx, min_xy_dist);
Expand Down Expand Up @@ -294,12 +294,13 @@ const Polygons& TreeModelVolumes::getCollisionHolefree(coord_t radius, LayerInde
}
if (precalculated)
{
logWarning("Had to calculate collision holefree at radius %lld and layer %lld, but precalculate was called. Performance may suffer!\n", key.first, key.second);
spdlog::warn("Had to calculate collision holefree at radius {} and layer {}, but precalculate was called. Performance may suffer!", key.first, key.second);
}
calculateCollisionHolefree(key);
return getCollisionHolefree(orig_radius, layer_idx, min_xy_dist);
}


const Polygons& TreeModelVolumes::getAvoidance(coord_t radius, LayerIndex layer_idx, AvoidanceType type, bool to_model, bool min_xy_dist)
{
if (layer_idx == 0) // What on the layer directly above buildplate do i have to avoid to reach the buildplate ...
Expand Down Expand Up @@ -358,7 +359,7 @@ const Polygons& TreeModelVolumes::getAvoidance(coord_t radius, LayerIndex layer_
}
else
{
logError("Invalid Avoidance Request\n");
spdlog::error("Invalid Avoidance Request");
}


Expand All @@ -374,7 +375,7 @@ const Polygons& TreeModelVolumes::getAvoidance(coord_t radius, LayerIndex layer_
}
if (precalculated)
{
logWarning("Had to calculate Avoidance to model at radius %lld and layer %lld, but precalculate was called. Performance may suffer!\n", key.first, key.second);
spdlog::warn("Had to calculate Avoidance to model at radius {} and layer {}, but precalculate was called. Performance may suffer!", key.first, key.second);
}
calculateAvoidanceToModel(key);
}
Expand All @@ -390,7 +391,7 @@ const Polygons& TreeModelVolumes::getAvoidance(coord_t radius, LayerIndex layer_
}
if (precalculated)
{
logWarning("Had to calculate Avoidance at radius %lld and layer %lld, but precalculate was called. Performance may suffer!\n", key.first, key.second);
spdlog::warn("Had to calculate Avoidance at radius {} and layer {}, but precalculate was called. Performance may suffer!", key.first, key.second);
}
calculateAvoidance(key);
}
Expand All @@ -414,7 +415,7 @@ const Polygons& TreeModelVolumes::getPlaceableAreas(coord_t radius, LayerIndex l
}
if (precalculated)
{
logWarning("Had to calculate Placeable Areas at radius %lld and layer %lld, but precalculate was called. Performance may suffer!\n", radius, layer_idx);
spdlog::warn("Had to calculate Placeable Areas at radius {} and layer {}, but precalculate was called. Performance may suffer!", radius, layer_idx);
}
if (radius != 0)
{
Expand Down Expand Up @@ -466,7 +467,7 @@ const Polygons& TreeModelVolumes::getWallRestriction(coord_t radius, LayerIndex
}
if (precalculated)
{
logWarning("Had to calculate Wall restricions at radius %lld and layer %lld, but precalculate was called. Performance may suffer!\n", key.first, key.second);
spdlog::warn("Had to calculate Wall restricions at radius {} and layer {}, but precalculate was called. Performance may suffer!", key.first, key.second);
}
}
else
Expand All @@ -481,7 +482,7 @@ const Polygons& TreeModelVolumes::getWallRestriction(coord_t radius, LayerIndex
}
if (precalculated)
{
logWarning("Had to calculate Wall restricions at radius %lld and layer %lld, but precalculate was called. Performance may suffer!\n", key.first, key.second);
spdlog::warn("Had to calculate Wall restricions at radius {} and layer {}, but precalculate was called. Performance may suffer!", key.first, key.second);
}
}
calculateWallRestrictions(key);
Expand Down Expand Up @@ -770,7 +771,7 @@ void TreeModelVolumes::calculateAvoidance(std::deque<RadiusLayerPair> keys)
}
if (start_layer > max_required_layer)
{
logDebug("Requested calculation for value already calculated ?\n");
spdlog::debug("Requested calculation for value already calculated ?");
return;
}
start_layer = std::max(start_layer, LayerIndex(1)); // Ensure StartLayer is at least 1 as if no avoidance was calculated getMaxCalculatedLayer returns -1
Expand Down Expand Up @@ -832,7 +833,7 @@ void TreeModelVolumes::calculatePlaceables(std::deque<RadiusLayerPair> keys)
}
if (start_layer > max_required_layer)
{
logDebug("Requested calculation for value already calculated ?\n");
spdlog::debug("Requested calculation for value already calculated ?");
return;
}

Expand Down Expand Up @@ -904,7 +905,7 @@ void TreeModelVolumes::calculateAvoidanceToModel(std::deque<RadiusLayerPair> key
}
if (start_layer > max_required_layer)
{
logDebug("Requested calculation for value already calculated ?\n");
spdlog::debug("Requested calculation for value already calculated ?");
return;
}
start_layer = std::max(start_layer, LayerIndex(1));
Expand Down
Loading

0 comments on commit a5406e7

Please sign in to comment.