2022-07-19 08:59:10 +00:00
// Tree supports by Thomas Rahm, losely based on Tree Supports by CuraEngine.
// Original source of Thomas Rahm's tree supports:
// https://github.com/ThomasRahm/CuraEngine
//
// Original CuraEngine copyright:
// Copyright (c) 2021 Ultimaker B.V.
// CuraEngine is released under the terms of the AGPLv3 or higher.
2022-07-19 08:55:43 +00:00
2022-07-19 09:10:17 +00:00
# ifndef slic3r_TreeModelVolumes_hpp
# define slic3r_TreeModelVolumes_hpp
2022-07-19 08:55:43 +00:00
# include <mutex>
# include <unordered_map>
# include <unordered_set>
2022-07-27 06:54:26 +00:00
# include <boost/functional/hash.hpp>
# include "Point.hpp"
2022-07-20 09:21:53 +00:00
# include "Polygon.hpp"
# include "PrintConfig.hpp"
2022-07-19 09:10:17 +00:00
namespace Slic3r
2022-07-19 08:55:43 +00:00
{
2022-08-02 11:36:05 +00:00
using LayerIndex = int ;
2022-07-20 09:21:53 +00:00
using AngleRadians = double ;
2022-07-27 06:54:26 +00:00
class BuildVolume ;
class PrintObject ;
2022-07-20 09:21:53 +00:00
struct TreeSupportMeshGroupSettings {
2022-07-27 06:54:26 +00:00
TreeSupportMeshGroupSettings ( ) = default ;
2022-08-15 06:41:24 +00:00
explicit TreeSupportMeshGroupSettings ( const PrintObject & print_object ) ;
2022-07-27 06:54:26 +00:00
/*********************************************************************/
/* Print parameters, not support specific: */
/*********************************************************************/
coord_t layer_height { scaled < coord_t > ( 0.15 ) } ;
// Maximum Deviation (meshfix_maximum_deviation)
// The maximum deviation allowed when reducing the resolution for the Maximum Resolution setting. If you increase this,
// the print will be less accurate, but the g-code will be smaller. Maximum Deviation is a limit for Maximum Resolution,
// so if the two conflict the Maximum Deviation will always be held true.
coord_t resolution { scaled < coord_t > ( 0.025 ) } ;
// Minimum Feature Size (aka minimum line width)
// Minimum thickness of thin features. Model features that are thinner than this value will not be printed, while features thicker
// than the Minimum Feature Size will be widened to the Minimum Wall Line Width.
coord_t min_feature_size { scaled < coord_t > ( 0.1 ) } ;
/*********************************************************************/
/* General support parameters: */
/*********************************************************************/
// Support Overhang Angle
// The minimum angle of overhangs for which support is added. At a value of 0° all overhangs are supported, 90° will not provide any support.
AngleRadians support_angle { 50. * M_PI / 180. } ;
// Support Line Width
// Width of a single support structure line.
coord_t support_line_width { scaled < coord_t > ( 0.4 ) } ;
// Support Roof Line Width: Width of a single support roof line.
coord_t support_roof_line_width { scaled < coord_t > ( 0.4 ) } ;
// Enable Support Floor (aka bottom interfaces)
// Generate a dense slab of material between the bottom of the support and the model. This will create a skin between the model and support.
bool support_bottom_enable { false } ;
// Support Floor Thickness
// The thickness of the support floors. This controls the number of dense layers that are printed on top of places of a model on which support rests.
coord_t support_bottom_height { scaled < coord_t > ( 1. ) } ;
bool support_material_buildplate_only { false } ;
// Support Distance Priority
// Whether the Support X/Y Distance overrides the Support Z Distance or vice versa. When X/Y overrides Z the X/Y distance can push away
// the support from the model, influencing the actual Z distance to the overhang. We can disable this by not applying the X/Y distance around overhangs.
bool support_xy_overrides_z { false } ;
// Support X/Y Distance
// Distance of the support structure from the print in the X/Y directions.
// minimum: 0, maximum warning: 1.5 * machine_nozzle_tip_outer_diameter
coord_t support_xy_distance { scaled < coord_t > ( 0.7 ) } ;
// Minimum Support X/Y Distance
// Distance of the support structure from the overhang in the X/Y directions.
// minimum_value: 0, minimum warning": support_xy_distance - support_line_width * 2, maximum warning: support_xy_distance
// Used if ! support_xy_overrides_z.
coord_t support_xy_distance_overhang { scaled < coord_t > ( 0.2 ) } ;
// Support Top Distance
// Distance from the top of the support to the print.
coord_t support_top_distance { scaled < coord_t > ( 0.1 ) } ;
// Support Bottom Distance
// Distance from the print to the bottom of the support.
coord_t support_bottom_distance { scaled < coord_t > ( 0.1 ) } ;
//FIXME likely not needed, optimization for clipping of interface layers
// When checking where there's model above and below the support, take steps of the given height. Lower values will slice slower, while higher values
// may cause normal support to be printed in some places where there should have been support interface.
coord_t support_interface_skip_height { scaled < coord_t > ( 0.3 ) } ;
// Support Infill Line Directions
// A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end
// of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained
// in square brackets. Default is an empty list which means use the default angle 0 degrees.
std : : vector < AngleRadians > support_infill_angles { } ;
// Enable Support Roof
// Generate a dense slab of material between the top of support and the model. This will create a skin between the model and support.
bool support_roof_enable { false } ;
// Support Roof Thickness
// The thickness of the support roofs. This controls the amount of dense layers at the top of the support on which the model rests.
coord_t support_roof_height { scaled < coord_t > ( 1. ) } ;
// Minimum Support Roof Area
// Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will be printed as normal support.
double minimum_roof_area { scaled < double > ( scaled < double > ( 1. ) ) } ;
// A list of integer line directions to use. Elements from the list are used sequentially as the layers progress
// and when the end of the list is reached, it starts at the beginning again. The list items are separated
// by commas and the whole list is contained in square brackets. Default is an empty list which means
// use the default angles (alternates between 45 and 135 degrees if interfaces are quite thick or 90 degrees).
std : : vector < AngleRadians > support_roof_angles { } ;
// Support Roof Pattern (aka top interface)
// The pattern with which the roofs of the support are printed.
SupportMaterialInterfacePattern support_roof_pattern { smipAuto } ;
// Support Pattern
// The pattern of the support structures of the print. The different options available result in sturdy or easy to remove support.
SupportMaterialPattern support_pattern { smpRectilinear } ;
// Support Line Distance
// Distance between the printed support structure lines. This setting is calculated by the support density.
coord_t support_line_spacing { scaled < coord_t > ( 2.66 - 0.4 ) } ;
// Support Floor Horizontal Expansion
// Amount of offset applied to the floors of the support.
coord_t support_bottom_offset { scaled < coord_t > ( 0. ) } ;
// Support Wall Line Count
// The number of walls with which to surround support infill. Adding a wall can make support print more reliably
// and can support overhangs better, but increases print time and material used.
// tree: 1, zig-zag: 0, concentric: 1
int support_wall_count { 1 } ;
// Support Roof Line Distance
// Distance between the printed support roof lines. This setting is calculated by the Support Roof Density, but can be adjusted separately.
coord_t support_roof_line_distance { scaled < coord_t > ( 0.4 ) } ;
// Minimum Support Area
// Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated.
coord_t minimum_support_area { scaled < coord_t > ( 0. ) } ;
// Minimum Support Floor Area
// Minimum area size for the floors of the support. Polygons which have an area smaller than this value will be printed as normal support.
coord_t minimum_bottom_area { scaled < coord_t > ( 1.0 ) } ;
// Support Horizontal Expansion
// Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support.
coord_t support_offset { scaled < coord_t > ( 0. ) } ;
/*********************************************************************/
/* Parameters for the Cura tree supports implementation: */
/*********************************************************************/
// Tree Support Maximum Branch Angle
// The maximum angle of the branches, when the branches have to avoid the model. Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach.
// minimum: 0, minimum warning: 20, maximum: 89, maximum warning": 85
AngleRadians support_tree_angle { 60. * M_PI / 180. } ;
// Tree Support Branch Diameter Angle
// The angle of the branches' diameter as they gradually become thicker towards the bottom. An angle of 0 will cause the branches to have uniform thickness over their length.
// A bit of an angle can increase stability of the tree support.
// minimum: 0, maximum: 89.9999, maximum warning: 15
AngleRadians support_tree_branch_diameter_angle { 5. * M_PI / 180. } ;
// Tree Support Branch Distance
// How far apart the branches need to be when they touch the model. Making this distance small will cause
// the tree support to touch the model at more points, causing better overhang but making support harder to remove.
2022-08-15 06:41:24 +00:00
coord_t support_tree_branch_distance { scaled < coord_t > ( 1. ) } ;
2022-07-27 06:54:26 +00:00
// Tree Support Branch Diameter
// The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. Branches towards the base will be thicker than this.
// minimum: 0.001, minimum warning: support_line_width * 2
coord_t support_tree_branch_diameter { scaled < coord_t > ( 2. ) } ;
/*********************************************************************/
/* Parameters new to the Thomas Rahm's tree supports implementation: */
/*********************************************************************/
// Tree Support Preferred Branch Angle
// The preferred angle of the branches, when they do not have to avoid the model. Use a lower angle to make them more vertical and more stable. Use a higher angle for branches to merge faster.
// minimum: 0, minimum warning: 10, maximum: support_tree_angle, maximum warning: support_tree_angle-1
AngleRadians support_tree_angle_slow { 50. * M_PI / 180. } ;
// Tree Support Diameter Increase To Model
// The most the diameter of a branch that has to connect to the model may increase by merging with branches that could reach the buildplate.
// Increasing this reduces print time, but increases the area of support that rests on model
// minimum: 0
coord_t support_tree_max_diameter_increase_by_merges_when_support_to_model { scaled < coord_t > ( 1.0 ) } ;
// Tree Support Minimum Height To Model
// How tall a branch has to be if it is placed on the model. Prevents small blobs of support. This setting is ignored when a branch is supporting a support roof.
// minimum: 0, maximum warning: 5
coord_t support_tree_min_height_to_model { scaled < coord_t > ( 1.0 ) } ;
// Tree Support Inital Layer Diameter
// Diameter every branch tries to achieve when reaching the buildplate. Improves bed adhesion.
// minimum: 0, maximum warning: 20
coord_t support_tree_bp_diameter { scaled < coord_t > ( 7.5 ) } ;
// Tree Support Branch Density
// Adjusts the density of the support structure used to generate the tips of the branches. A higher value results in better overhangs,
// but the supports are harder to remove. Use Support Roof for very high values or ensure support density is similarly high at the top.
// 5%-35%
double support_tree_top_rate { 15. } ;
// Tree Support Tip Diameter
// The diameter of the top of the tip of the branches of tree support."
// minimum: min_wall_line_width, minimum warning: min_wall_line_width+0.05, maximum_value: support_tree_branch_diameter, value: support_line_width
coord_t support_tree_tip_diameter { scaled < coord_t > ( 0.4 ) } ;
// Support Interface Priority
// How support interface and support will interact when they overlap. Currently only implemented for support roof.
//enum support_interface_priority { support_lines_overwrite_interface_area };
2022-07-20 09:21:53 +00:00
} ;
inline coord_t round_up_divide ( const coord_t dividend , const coord_t divisor ) //!< Return dividend divided by divisor rounded to the nearest integer
{
return ( dividend + divisor - 1 ) / divisor ;
}
2022-07-19 08:55:43 +00:00
class TreeModelVolumes
{
2022-07-27 06:54:26 +00:00
public :
2022-07-19 08:55:43 +00:00
TreeModelVolumes ( ) = default ;
2022-08-15 06:41:24 +00:00
explicit TreeModelVolumes ( const PrintObject & print_object , const BuildVolume & build_volume ,
2022-07-27 06:54:26 +00:00
coord_t max_move , coord_t max_move_slow , size_t current_mesh_idx , double progress_multiplier , double progress_offset , const std : : vector < Polygons > & additional_excluded_areas = { } ) ;
2022-07-19 08:55:43 +00:00
TreeModelVolumes ( TreeModelVolumes & & ) = default ;
TreeModelVolumes & operator = ( TreeModelVolumes & & ) = default ;
TreeModelVolumes ( const TreeModelVolumes & ) = delete ;
TreeModelVolumes & operator = ( const TreeModelVolumes & ) = delete ;
enum class AvoidanceType
{
SLOW ,
FAST_SAFE ,
FAST
} ;
/*!
* \ brief Precalculate avoidances and collisions up to this layer .
*
* This uses knowledge about branch angle to only calculate avoidances and collisions that could actually be needed .
* Not calling this will cause the class to lazily calculate avoidances and collisions as needed , which will be a lot slower on systems with more then one or two cores !
*
*/
void precalculate ( coord_t max_layer ) ;
/*!
* \ brief Provides the areas that have to be avoided by the tree ' s branches to prevent collision with the model on this layer .
*
* The result is a 2 D area that would cause nodes of radius \ p radius to
* collide with the model .
*
* \ param radius The radius of the node of interest
* \ param layer_idx The layer of interest
* \ param min_xy_dist Is the minimum xy distance used .
* \ return Polygons object
*/
2022-07-27 06:54:26 +00:00
const Polygons & getCollision ( coord_t radius , LayerIndex layer_idx , bool min_xy_dist = false ) const ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Provides the areas that have to be avoided by the tree ' s branches to prevent collision with the model on this layer . Holes are removed .
*
* The result is a 2 D area that would cause nodes of given radius to
* collide with the model or be inside a hole .
2022-07-27 06:54:26 +00:00
* A Hole is defined as an area , in which a branch with m_increase_until_radius radius would collide with the wall .
2022-07-19 08:55:43 +00:00
* \ param radius The radius of the node of interest
* \ param layer_idx The layer of interest
* \ param min_xy_dist Is the minimum xy distance used .
* \ return Polygons object
*/
2022-07-27 06:54:26 +00:00
const Polygons & getCollisionHolefree ( coord_t radius , LayerIndex layer_idx , bool min_xy_dist = false ) const ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Provides the areas that have to be avoided by the tree ' s branches
* in order to reach the build plate .
*
* The result is a 2 D area that would cause nodes of radius \ p radius to
* collide with the model or be unable to reach the build platform .
*
* The input collision areas are inset by the maximum move distance and
* propagated upwards .
*
* \ param radius The radius of the node of interest
* \ param layer_idx The layer of interest
* \ param slow Is the propagation with the maximum move distance slow required .
* \ param to_model Does the avoidance allow good connections with the model .
* \ param min_xy_dist is the minimum xy distance used .
* \ return Polygons object
*/
2022-07-27 06:54:26 +00:00
const Polygons & getAvoidance ( coord_t radius , LayerIndex layer_idx , AvoidanceType type , bool to_model = false , bool min_xy_dist = false ) const ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Provides the area represents all areas on the model where the branch does completely fit on the given layer .
* \ param radius The radius of the node of interest
* \ param layer_idx The layer of interest
* \ return Polygons object
*/
2022-07-27 06:54:26 +00:00
const Polygons & getPlaceableAreas ( coord_t radius , LayerIndex layer_idx ) const ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Provides the area that represents the walls , as in the printed area , of the model . This is an abstract representation not equal with the outline . See calculateWallRestrictions for better description .
* \ param radius The radius of the node of interest .
* \ param layer_idx The layer of interest .
* \ param min_xy_dist is the minimum xy distance used .
* \ return Polygons object
*/
2022-07-27 06:54:26 +00:00
const Polygons & getWallRestriction ( coord_t radius , LayerIndex layer_idx , bool min_xy_dist ) const ;
2022-07-19 08:55:43 +00:00
/*!
2022-07-27 06:54:26 +00:00
* \ brief Round \ p radius upwards to either a multiple of m_radius_sample_resolution or a exponentially increasing value
2022-07-19 08:55:43 +00:00
*
* It also adds the difference between the minimum xy distance and the regular one .
*
* \ param radius The radius of the node of interest
* \ param min_xy_dist is the minimum xy distance used .
* \ return The rounded radius
*/
coord_t ceilRadius ( coord_t radius , bool min_xy_dist ) const ;
/*!
* \ brief Round \ p radius upwards to the maximum that would still round up to the same value as the provided one .
*
* \ param radius The radius of the node of interest
* \ param min_xy_dist is the minimum xy distance used .
* \ return The maximum radius , resulting in the same rounding .
*/
coord_t getRadiusNextCeil ( coord_t radius , bool min_xy_dist ) const ;
2022-07-27 06:54:26 +00:00
private :
2022-07-19 08:55:43 +00:00
/*!
* \ brief Convenience typedef for the keys to the caches
*/
2022-07-27 06:54:26 +00:00
using RadiusLayerPair = std : : pair < coord_t , LayerIndex > ;
using RadiusLayerPolygonCache = std : : unordered_map < RadiusLayerPair , Polygons , boost : : hash < RadiusLayerPair > > ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
friend std : : optional < std : : reference_wrapper < const Polygons > > getArea ( const TreeModelVolumes : : RadiusLayerPolygonCache & cache , const TreeModelVolumes : : RadiusLayerPair & key ) ;
2022-07-19 08:55:43 +00:00
/*!
2022-07-27 06:54:26 +00:00
* \ brief Round \ p radius upwards to either a multiple of m_radius_sample_resolution or a exponentially increasing value
2022-07-19 08:55:43 +00:00
*
* \ param radius The radius of the node of interest
*/
coord_t ceilRadius ( coord_t radius ) const ;
/*!
* \ brief Extracts the relevant outline from a mesh
* \ param [ in ] mesh The mesh which outline will be extracted
* \ param layer_idx The layer which should be extracted from the mesh
* \ return Polygons object representing the outline
*/
2022-07-27 06:54:26 +00:00
// Polygons extractOutlineFromMesh(const PrintObject &print_object, LayerIndex layer_idx) const;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model on this layer .
*
* The result is a 2 D area that would cause nodes of given radius to
* collide with the model . Result is saved in the cache .
* \ param keys RadiusLayerPairs of all requested areas . Every radius will be calculated up to the provided layer .
*/
void calculateCollision ( std : : deque < RadiusLayerPair > keys ) ;
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model on this layer .
*
* The result is a 2 D area that would cause nodes of given radius to
* collide with the model . Result is saved in the cache .
* \ param key RadiusLayerPairs the requested areas . The radius will be calculated up to the provided layer .
*/
void calculateCollision ( RadiusLayerPair key )
{
calculateCollision ( std : : deque < RadiusLayerPair > { RadiusLayerPair ( key ) } ) ;
}
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model on this layer . Holes are removed .
*
* The result is a 2 D area that would cause nodes of given radius to
* collide with the model or be inside a hole . Result is saved in the cache .
2022-07-27 06:54:26 +00:00
* A Hole is defined as an area , in which a branch with m_increase_until_radius radius would collide with the wall .
2022-07-19 08:55:43 +00:00
* \ param keys RadiusLayerPairs of all requested areas . Every radius will be calculated up to the provided layer .
*/
void calculateCollisionHolefree ( std : : deque < RadiusLayerPair > keys ) ;
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model on this layer . Holes are removed .
*
* The result is a 2 D area that would cause nodes of given radius to
* collide with the model or be inside a hole . Result is saved in the cache .
2022-07-27 06:54:26 +00:00
* A Hole is defined as an area , in which a branch with m_increase_until_radius radius would collide with the wall .
2022-07-19 08:55:43 +00:00
* \ param key RadiusLayerPairs the requested areas . The radius will be calculated up to the provided layer .
*/
void calculateCollisionHolefree ( RadiusLayerPair key )
{
calculateCollisionHolefree ( std : : deque < RadiusLayerPair > { RadiusLayerPair ( key ) } ) ;
}
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model .
*
* The result is a 2 D area that would cause nodes of radius \ p radius to
* collide with the model . Result is saved in the cache .
* \ param keys RadiusLayerPairs of all requested areas . Every radius will be calculated up to the provided layer .
*/
2022-07-19 15:14:07 +00:00
void calculateAvoidance ( std : : deque < RadiusLayerPair > keys ) ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model .
*
* The result is a 2 D area that would cause nodes of radius \ p radius to
* collide with the model . Result is saved in the cache .
* \ param key RadiusLayerPair of the requested areas . It will be calculated up to the provided layer .
*/
void calculateAvoidance ( RadiusLayerPair key )
{
2022-07-20 09:21:53 +00:00
calculateAvoidance ( std : : deque < RadiusLayerPair > { RadiusLayerPair ( key ) } ) ;
2022-07-19 08:55:43 +00:00
}
/*!
* \ brief Creates the areas where a branch of a given radius can be place on the model .
* Result is saved in the cache .
* \ param key RadiusLayerPair of the requested areas . It will be calculated up to the provided layer .
*/
void calculatePlaceables ( RadiusLayerPair key )
{
2022-07-20 09:21:53 +00:00
calculatePlaceables ( std : : deque < RadiusLayerPair > { key } ) ;
2022-07-19 08:55:43 +00:00
}
/*!
* \ brief Creates the areas where a branch of a given radius can be placed on the model .
* Result is saved in the cache .
* \ param keys RadiusLayerPair of the requested areas . The radius will be calculated up to the provided layer .
*/
2022-07-19 15:14:07 +00:00
void calculatePlaceables ( std : : deque < RadiusLayerPair > keys ) ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model without being able to place a branch with given radius on a single layer .
*
* The result is a 2 D area that would cause nodes of radius \ p radius to
* collide with the model in a not wanted way . Result is saved in the cache .
* \ param keys RadiusLayerPairs of all requested areas . Every radius will be calculated up to the provided layer .
*/
2022-07-19 15:14:07 +00:00
void calculateAvoidanceToModel ( std : : deque < RadiusLayerPair > keys ) ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Creates the areas that have to be avoided by the tree ' s branches to prevent collision with the model without being able to place a branch with given radius on a single layer .
*
* The result is a 2 D area that would cause nodes of radius \ p radius to
* collide with the model in a not wanted way . Result is saved in the cache .
* \ param key RadiusLayerPair of the requested areas . The radius will be calculated up to the provided layer .
*/
void calculateAvoidanceToModel ( RadiusLayerPair key )
{
2022-07-20 09:21:53 +00:00
calculateAvoidanceToModel ( std : : deque < RadiusLayerPair > { RadiusLayerPair ( key ) } ) ;
2022-07-19 08:55:43 +00:00
}
/*!
* \ brief Creates the areas that can not be passed when expanding an area downwards . As such these areas are an somewhat abstract representation of a wall ( as in a printed object ) .
*
* These areas are at least xy_min_dist wide . When calculating it is always assumed that every wall is printed on top of another ( as in has an overlap with the wall a layer below ) . Result is saved in the corresponding cache .
*
* \ param keys RadiusLayerPairs of all requested areas . Every radius will be calculated up to the provided layer .
*/
2022-07-19 15:14:07 +00:00
void calculateWallRestrictions ( std : : deque < RadiusLayerPair > keys ) ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Creates the areas that can not be passed when expanding an area downwards . As such these areas are an somewhat abstract representation of a wall ( as in a printed object ) .
* These areas are at least xy_min_dist wide . When calculating it is always assumed that every wall is printed on top of another ( as in has an overlap with the wall a layer below ) . Result is saved in the corresponding cache .
* \ param key RadiusLayerPair of the requested area . It well be will be calculated up to the provided layer .
*/
void calculateWallRestrictions ( RadiusLayerPair key )
{
2022-07-20 09:21:53 +00:00
calculateWallRestrictions ( std : : deque < RadiusLayerPair > { RadiusLayerPair ( key ) } ) ;
2022-07-19 08:55:43 +00:00
}
/*!
* \ brief Get the highest already calculated layer in the cache .
* \ param radius The radius for which the highest already calculated layer has to be found .
* \ param map The cache in which the lookup is performed .
*
* \ return A wrapped optional reference of the requested area ( if it was found , an empty optional if nothing was found )
*/
2022-07-27 06:54:26 +00:00
LayerIndex getMaxCalculatedLayer ( coord_t radius , const RadiusLayerPolygonCache & map ) const ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The maximum distance that the center point of a tree branch may move in consecutive layers if it has to avoid the model .
*/
2022-07-27 06:54:26 +00:00
coord_t m_max_move ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The maximum distance that the centre - point of a tree branch may
* move in consecutive layers if it does not have to avoid the model
*/
2022-07-27 06:54:26 +00:00
coord_t m_max_move_slow ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The smallest maximum resolution for simplify
*/
2022-07-27 06:54:26 +00:00
coord_t m_min_resolution ;
bool m_precalculated = false ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The index to access the outline corresponding with the currently processing mesh
*/
2022-07-27 06:54:26 +00:00
size_t m_current_outline_idx ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The minimum required clearance between the model and the tree branches
*/
2022-07-27 06:54:26 +00:00
coord_t m_current_min_xy_dist ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The difference between the minimum required clearance between the model and the tree branches and the regular one .
*/
2022-07-27 06:54:26 +00:00
coord_t m_current_min_xy_dist_delta ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Does at least one mesh allow support to rest on a model .
*/
2022-07-27 06:54:26 +00:00
bool m_support_rests_on_model ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The progress of the precalculate function for communicating it to the progress bar .
*/
2022-07-27 06:54:26 +00:00
coord_t m_precalculation_progress = 0 ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The progress multiplier of all values added progress bar .
* Required for the progress bar the behave as expected when areas have to be calculated multiple times
*/
2022-07-27 06:54:26 +00:00
double m_progress_multiplier ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief The progress offset added to all values communicated to the progress bar .
* Required for the progress bar the behave as expected when areas have to be calculated multiple times
*/
2022-07-27 06:54:26 +00:00
double m_progress_offset ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Increase radius in the resulting drawn branches , even if the avoidance does not allow it . Will be cut later to still fit .
*/
2022-07-27 06:54:26 +00:00
coord_t m_increase_until_radius ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Polygons representing the limits of the printable area of the
* machine
*/
2022-07-27 06:54:26 +00:00
Polygons m_machine_border ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Storage for layer outlines and the corresponding settings of the meshes grouped by meshes with identical setting .
*/
2022-07-27 06:54:26 +00:00
std : : vector < std : : pair < TreeSupportMeshGroupSettings , std : : vector < Polygons > > > m_layer_outlines ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Storage for areas that should be avoided , like support blocker or previous generated trees .
*/
2022-07-27 06:54:26 +00:00
std : : vector < Polygons > m_anti_overhang ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Radii that can be ignored by ceilRadius as they will never be requested .
*/
2022-07-27 06:54:26 +00:00
std : : unordered_set < coord_t > m_ignorable_radii ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Smallest radius a branch can have . This is the radius of a SupportElement with DTT = 0.
*/
2022-07-27 06:54:26 +00:00
coord_t m_radius_0 ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Caches for the collision , avoidance and areas on the model where support can be placed safely
* at given radius and layer indices .
*/
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_collision_cache ;
std : : unique_ptr < std : : mutex > m_critical_collision_cache { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_collision_cache_holefree ;
std : : unique_ptr < std : : mutex > m_critical_collision_cache_holefree { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_avoidance_cache ;
std : : unique_ptr < std : : mutex > m_critical_avoidance_cache { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_avoidance_cache_slow ;
std : : unique_ptr < std : : mutex > m_critical_avoidance_cache_slow { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_avoidance_cache_to_model ;
std : : unique_ptr < std : : mutex > m_critical_avoidance_cache_to_model { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_avoidance_cache_to_model_slow ;
std : : unique_ptr < std : : mutex > m_critical_avoidance_cache_to_model_slow { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_placeable_areas_cache ;
std : : unique_ptr < std : : mutex > m_critical_placeable_areas_cache { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
/*!
2022-07-27 06:54:26 +00:00
* \ brief Caches to avoid holes smaller than the radius until which the radius is always increased , as they are free of holes .
* Also called safe avoidances , as they are safe regarding not running into holes .
2022-07-19 08:55:43 +00:00
*/
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_avoidance_cache_hole ;
std : : unique_ptr < std : : mutex > m_critical_avoidance_cache_holefree { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_avoidance_cache_hole_to_model ;
std : : unique_ptr < std : : mutex > m_critical_avoidance_cache_holefree_to_model { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
/*!
* \ brief Caches to represent walls not allowed to be passed over .
*/
2022-07-27 06:54:26 +00:00
RadiusLayerPolygonCache m_wall_restrictions_cache ;
std : : unique_ptr < std : : mutex > m_critical_wall_restrictions_cache { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
// A different cache for min_xy_dist as the maximal safe distance an influence area can be increased(guaranteed overlap of two walls in consecutive layer)
// is much smaller when min_xy_dist is used. This causes the area of the wall restriction to be thinner and as such just using the min_xy_dist wall
// restriction would be slower.
RadiusLayerPolygonCache m_wall_restrictions_cache_min ;
std : : unique_ptr < std : : mutex > m_critical_wall_restrictions_cache_min = std : : make_unique < std : : mutex > ( ) ;
2022-07-19 08:55:43 +00:00
2022-07-27 06:54:26 +00:00
std : : unique_ptr < std : : mutex > m_critical_progress { std : : make_unique < std : : mutex > ( ) } ;
2022-07-19 08:55:43 +00:00
} ;
2022-08-15 06:41:24 +00:00
Polygons safeOffset ( const Polygons & me , coord_t distance , ClipperLib : : JoinType jt , coord_t max_safe_step_distance , const Polygons & collision ) ;
2022-07-27 08:41:11 +00:00
2022-07-19 08:55:43 +00:00
}
2022-07-27 06:54:26 +00:00
# endif //slic3r_TreeModelVolumes_hpp