Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions include/TreeSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ constexpr auto SUPPORT_TREE_EXPONENTIAL_FACTOR = 1.5;
constexpr size_t SUPPORT_TREE_PRE_EXPONENTIAL_STEPS = 1;
constexpr coord_t SUPPORT_TREE_COLLISION_RESOLUTION = 500; // Only has an effect if SUPPORT_TREE_USE_EXPONENTIAL_COLLISION_RESOLUTION is false

using PropertyAreasUnordered = std::unordered_map<TreeSupportElement, Shape>;
using PropertyAreas = std::map<TreeSupportElement, Shape>;
using PropertyAreasUnordered = std::unordered_map<TreeSupportElement::Ptr, Shape>;
using PropertyAreas = std::map<TreeSupportElement::Ptr, Shape>;

struct FakeRoofArea
{
Expand Down Expand Up @@ -120,7 +120,7 @@ class TreeSupport
* \param move_bounds[out] Storage for the influence areas.
* \param storage[in] Background storage, required for adding roofs.
*/
void generateInitialAreas(const SliceMeshStorage& mesh, std::vector<std::set<TreeSupportElement*>>& move_bounds, SliceDataStorage& storage);
void generateInitialAreas(const SliceMeshStorage& mesh, std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds, SliceDataStorage& storage);


/*!
Expand All @@ -140,15 +140,15 @@ class TreeSupport
* of avoidance) \param erase[out] Elements that should be deleted from the above dictionaries. \param layer_idx[in] The Index of the current Layer.
*/
void mergeHelper(
std::map<TreeSupportElement, AABB>& reduced_aabb,
std::map<TreeSupportElement, AABB>& input_aabb,
std::map<TreeSupportElement::Ptr, AABB>& reduced_aabb,
std::map<TreeSupportElement::Ptr, AABB>& input_aabb,
const PropertyAreasUnordered& to_bp_areas,
const PropertyAreas& to_model_areas,
const PropertyAreas& influence_areas,
PropertyAreasUnordered& insert_bp_areas,
PropertyAreasUnordered& insert_model_areas,
PropertyAreasUnordered& insert_influence,
std::vector<TreeSupportElement>& erase,
std::vector<TreeSupportElement::Ptr>& erase,
const LayerIndex layer_idx);

/*!
Expand Down Expand Up @@ -188,10 +188,10 @@ class TreeSupport
* called on this layer. This information is required as some calculation can be avoided if they are not required for merging. \return A valid support element for the next
* layer regarding the calculated influence areas. Empty if no influence are can be created using the supplied influence area and settings.
*/
std::optional<TreeSupportElement> increaseSingleArea(
TreeSupportElement::Ptr increaseSingleArea(
AreaIncreaseSettings settings,
LayerIndex layer_idx,
TreeSupportElement* parent,
TreeSupportElement::Ptr parent,
const Shape& relevant_offset,
Shape& to_bp_data,
Shape& to_model_data,
Expand Down Expand Up @@ -222,8 +222,8 @@ class TreeSupport
PropertyAreasUnordered& to_bp_areas,
PropertyAreas& to_model_areas,
PropertyAreas& influence_areas,
std::vector<TreeSupportElement*>& bypass_merge_areas,
const std::vector<TreeSupportElement*>& last_layer,
std::vector<TreeSupportElement::Ptr>& bypass_merge_areas,
const std::vector<TreeSupportElement::Ptr>& last_layer,
const LayerIndex layer_idx,
const bool mergelayer);

Expand All @@ -233,15 +233,15 @@ class TreeSupport
* \param move_bounds[in,out] All currently existing influence areas
* \param time_keeper The object used to record the duration of the sub-steps
*/
void createLayerPathing(std::vector<std::set<TreeSupportElement*>>& move_bounds, TimeKeeper& time_keeper);
void createLayerPathing(std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds, TimeKeeper& time_keeper);


/*!
* \brief Sets the result_on_layer for all parents based on the SupportElement supplied.
*
* \param elem[in] The SupportElements, which parent's position should be determined.
*/
void setPointsOnAreas(const TreeSupportElement* elem);
void setPointsOnAreas(const TreeSupportElement::Ptr elem);

/*!
* \brief Get the best point to connect to the model and set the result_on_layer of the relevant SupportElement accordingly.
Expand All @@ -251,14 +251,14 @@ class TreeSupport
* \param layer_idx[in] The current layer.
* \return Should elem be deleted.
*/
bool setToModelContact(std::vector<std::set<TreeSupportElement*>>& move_bounds, TreeSupportElement* first_elem, const LayerIndex layer_idx);
bool setToModelContact(std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds, TreeSupportElement::Ptr first_elem, const LayerIndex layer_idx);

/*!
* \brief Set the result_on_layer point for all influence areas
*
* \param move_bounds[in,out] All currently existing influence areas
*/
void createNodesFromArea(std::vector<std::set<TreeSupportElement*>>& move_bounds);
void createNodesFromArea(std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds);

/*!
* \brief Draws circles around result_on_layer points of the influence areas
Expand All @@ -269,22 +269,22 @@ class TreeSupport
* corresponding branch area in layer_tree_polygons. \param inverse_tree_order[in] A mapping that returns the child of every influence area.
*/
void generateBranchAreas(
std::vector<std::pair<LayerIndex, TreeSupportElement*>>& linear_data,
std::vector<std::unordered_map<TreeSupportElement*, Shape>>& layer_tree_polygons,
const std::map<TreeSupportElement*, TreeSupportElement*>& inverse_tree_order);
std::vector<std::pair<LayerIndex, TreeSupportElement::Ptr>>& linear_data,
std::vector<std::unordered_map<TreeSupportElement::Ptr, Shape>>& layer_tree_polygons,
const std::map<TreeSupportElement::Ptr, TreeSupportElement::Ptr>& inverse_tree_order);

/*!
* \brief Applies some smoothing to the outer wall, intended to smooth out sudden jumps as they can happen when a branch moves though a hole.
*
* \param layer_tree_polygons[in,out] Resulting branch areas with the layerindex they appear on.
*/
void smoothBranchAreas(std::vector<std::unordered_map<TreeSupportElement*, Shape>>& layer_tree_polygons);
void smoothBranchAreas(std::vector<std::unordered_map<TreeSupportElement::Ptr, Shape>>& layer_tree_polygons);

/*!
* Smoothes the skeleton of the tree structure according to the smoothing factor
* @param layer_tree_polygons The base tree structure to be smoothed
*/
void smoothBranchSkeletons(std::vector<std::set<TreeSupportElement*>>& layer_tree_polygons);
void smoothBranchSkeletons(std::vector<std::set<TreeSupportElement::Ptr>>& layer_tree_polygons);

/*!
* \brief Drop down areas that do rest non-gracefully on the model to ensure the branch actually rests on something.
Expand All @@ -295,10 +295,10 @@ class TreeSupport
* \param inverse_tree_order[in] A mapping that returns the child of every influence area.
*/
void dropNonGraciousAreas(
std::vector<std::unordered_map<TreeSupportElement*, Shape>>& layer_tree_polygons,
const std::vector<std::pair<LayerIndex, TreeSupportElement*>>& linear_data,
std::vector<std::unordered_map<TreeSupportElement::Ptr, Shape>>& layer_tree_polygons,
const std::vector<std::pair<LayerIndex, TreeSupportElement::Ptr>>& linear_data,
std::vector<std::vector<std::pair<LayerIndex, Shape>>>& dropped_down_areas,
const std::map<TreeSupportElement*, TreeSupportElement*>& inverse_tree_order);
const std::map<TreeSupportElement::Ptr, TreeSupportElement::Ptr>& inverse_tree_order);


void filterFloatingLines(std::vector<Shape>& support_layer_storage);
Expand All @@ -325,13 +325,13 @@ class TreeSupport
* \param storage[in,out] The storage where the support should be stored.
* \param time_keeper The object used to record the duration of the sub-steps
*/
void drawAreas(std::vector<std::set<TreeSupportElement*>>& move_bounds, SliceDataStorage& storage, TimeKeeper& time_keeper);
void drawAreas(std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds, SliceDataStorage& storage, TimeKeeper& time_keeper);

/*!
* Saves the influence areas and the resulting positions of all the given elements to a 3D object
* @para move_bounds The elements to be saved, sorted per layer
*/
void saveToObj(const std::vector<std::set<TreeSupportElement*>>& move_bounds, OBJ& obj) const;
void saveToObj(const std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds, OBJ& obj) const;

/*!
* \brief Settings with the indexes of meshes that use these settings.
Expand Down
105 changes: 42 additions & 63 deletions include/TreeSupportElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ struct AreaIncreaseSettings
bool operator==(const AreaIncreaseSettings& other) const = default;
};

class TreeSupportElement
class TreeSupportElement : public std::enable_shared_from_this<TreeSupportElement>
{
public:
using Ptr = std::shared_ptr<TreeSupportElement>;

TreeSupportElement(
coord_t distance_to_top,
size_t target_height,
Expand All @@ -61,61 +63,17 @@ class TreeSupportElement
bool influence_area_limit_active,
coord_t influence_area_limit_range);

TreeSupportElement(const TreeSupportElement& elem, Shape* newArea = nullptr);

/*!
* \brief Create a new Element for one layer below the element of the pointer supplied.
*/
TreeSupportElement(TreeSupportElement* element_above);

// ONLY to be called in merge as it assumes a few assurances made by it.
TreeSupportElement(
const TreeSupportElement& first,
const TreeSupportElement& second,
size_t next_height,
Point2LL next_position,
coord_t increased_to_model_radius,
const std::function<coord_t(size_t, double)>& getRadius,
double diameter_scale_bp_radius,
coord_t branch_radius,
double diameter_angle_scale_factor);


bool operator==(const TreeSupportElement& other) const
{
return target_position_ == other.target_position_ && target_height_ == other.target_height_;
}

bool operator<(const TreeSupportElement& other) const // true if me < other
{
return ! (*this == other) && ! (*this > other);
}

bool operator>(const TreeSupportElement& other) const
{
// Doesn't really have to make sense, only required for ordering in maps to ensure deterministic behavior.
if (*this == other)
{
return false;
}
if (other.target_height_ != target_height_)
{
return other.target_height_ < target_height_;
}
return other.target_position_.X == target_position_.X ? other.target_position_.Y < target_position_.Y : other.target_position_.X < target_position_.X;
}

/*! \brief Gets the list of parent elements, which are those above the current element */
const std::vector<TreeSupportElement*>& getParents() const
const std::vector<TreeSupportElement::Ptr>& getParents() const
{
return parents_;
}

/*! \brief Adds the given elements to be parents of the current element. Parents will also be properly modified to have the element as a child. */
void addParents(const std::vector<TreeSupportElement*>& new_parents);
void addParents(const std::vector<TreeSupportElement::Ptr>& new_parents);

/*! \brief Gets the child element, which is the one beloe the current element. It could also be null if the element lies on the buildplate or on the model */
TreeSupportElement* getChild() const
TreeSupportElement::Ptr getChild() const
{
return child_;
}
Expand All @@ -137,6 +95,21 @@ class TreeSupportElement
*/
void saveToObj(OBJ& obj, const coord_t z, const coord_t layer_height) const;

static TreeSupportElement::Ptr makeFromElementAbove(const TreeSupportElement::Ptr& element_above);

static TreeSupportElement::Ptr makeCopy(const TreeSupportElement::Ptr& elem, Shape* newArea = nullptr);

static TreeSupportElement::Ptr makeMerged(
const TreeSupportElement::Ptr& first,
const TreeSupportElement::Ptr& second,
size_t next_height,
Point2LL next_position,
coord_t increased_to_model_radius,
const std::function<coord_t(size_t, double)>& getRadius,
double diameter_scale_bp_radius,
coord_t branch_radius,
double diameter_angle_scale_factor);

/*!
* \brief The layer this support elements wants reach
*/
Expand Down Expand Up @@ -261,30 +234,36 @@ class TreeSupportElement
std::vector<Point2LL> additional_ovalization_targets_;

private:
/*!
* \brief Create a new Element for one layer below the element of the pointer supplied.
*/
explicit TreeSupportElement(const TreeSupportElement::Ptr& element_above);

TreeSupportElement(const TreeSupportElement::Ptr& elem, Shape* newArea);

// ONLY to be called in merge as it assumes a few assurances made by it.
TreeSupportElement(
const TreeSupportElement::Ptr& first,
const TreeSupportElement::Ptr& second,
size_t next_height,
Point2LL next_position,
coord_t increased_to_model_radius,
const std::function<coord_t(size_t, double)>& getRadius,
double diameter_scale_bp_radius,
coord_t branch_radius,
double diameter_angle_scale_factor);

/*!
* \brief All elements in the layer above the current one that are supported by this element
*/
std::vector<TreeSupportElement*> parents_;
std::vector<TreeSupportElement::Ptr> parents_;

/*!
* \brief The element in the layer below that is supporting this element
*/
TreeSupportElement* child_{ nullptr };
TreeSupportElement::Ptr child_{ nullptr };
};

} // namespace cura

namespace std
{
template<>
struct hash<cura::TreeSupportElement>
{
size_t operator()(const cura::TreeSupportElement& node) const
{
size_t hash_node = hash<cura::Point2LL>()(node.target_position_);
boost::hash_combine(hash_node, size_t(node.target_height_));
return hash_node;
}
};
} // namespace std
#endif /* TREESUPPORTELEMENT_H */
15 changes: 8 additions & 7 deletions include/TreeSupportSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,11 @@ struct TreeSupportSettings
* \brief Get the Distance to top regarding the real radius this part will have. This is different from distance_to_top, which is can be used to calculate the top most layer of
* the branch. \param elem[in] The SupportElement one wants to know the effectiveDTT \return The Effective DTT.
*/
[[nodiscard]] inline size_t getEffectiveDTT(const TreeSupportElement& elem) const
[[nodiscard]] inline size_t getEffectiveDTT(const TreeSupportElement::Ptr& elem) const
{
return elem.effective_radius_height_ < increase_radius_until_dtt ? (elem.distance_to_top_ < increase_radius_until_dtt ? elem.distance_to_top_ : increase_radius_until_dtt)
: elem.effective_radius_height_;
return elem->effective_radius_height_ < increase_radius_until_dtt
? (elem->distance_to_top_ < increase_radius_until_dtt ? elem->distance_to_top_ : increase_radius_until_dtt)
: elem->effective_radius_height_;
}

/*!
Expand All @@ -493,19 +494,19 @@ struct TreeSupportSettings
* \param elem[in] The Element.
* \return The radius the element has.
*/
[[nodiscard]] inline coord_t getRadius(const TreeSupportElement& elem) const
[[nodiscard]] inline coord_t getRadius(const TreeSupportElement::Ptr& elem) const
{
return getRadius(getEffectiveDTT(elem), (elem.isResultOnLayerSet() || ! support_rests_on_model) && elem.to_buildplate_ ? elem.buildplate_radius_increases_ : 0);
return getRadius(getEffectiveDTT(elem), (elem->isResultOnLayerSet() || ! support_rests_on_model) && elem->to_buildplate_ ? elem->buildplate_radius_increases_ : 0);
}

/*!
* \brief Get the collision Radius of this Element. This can be smaller then the actual radius, as the drawAreas will cut off areas that may collide with the model.
* \param elem[in] The Element.
* \return The collision radius the element has.
*/
[[nodiscard]] inline coord_t getCollisionRadius(const TreeSupportElement& elem) const
[[nodiscard]] inline coord_t getCollisionRadius(const TreeSupportElement::Ptr& elem) const
{
return getRadius(elem.effective_radius_height_, elem.buildplate_radius_increases_);
return getRadius(elem->effective_radius_height_, elem->buildplate_radius_increases_);
}

/*!
Expand Down
8 changes: 4 additions & 4 deletions include/TreeSupportTipGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class TreeSupportTipGenerator
void generateTips(
SliceDataStorage& storage,
const SliceMeshStorage& mesh,
std::vector<std::set<TreeSupportElement*>>& move_bounds,
std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds,
std::vector<Shape>& additional_support_areas,
std::vector<std::vector<FakeRoofArea>>& placed_fake_roof_areas);

Expand Down Expand Up @@ -141,7 +141,7 @@ class TreeSupportTipGenerator
* \param skip_ovalisation[in] Whether the tip may be ovalized when drawn later.
*/
void addPointAsInfluenceArea(
std::vector<std::set<TreeSupportElement*>>& move_bounds,
std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds,
std::pair<Point2LL, LineStatus> p,
size_t dtt,
LayerIndex insert_layer,
Expand All @@ -161,7 +161,7 @@ class TreeSupportTipGenerator
* \param dont_move_until[in] Until which dtt the branch should not move if possible.
*/
void addLinesAsInfluenceAreas(
std::vector<std::set<TreeSupportElement*>>& move_bounds,
std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds,
std::vector<TreeSupportTipGenerator::LineInformation> lines,
size_t roof_tip_layers,
LayerIndex insert_layer_idx,
Expand All @@ -175,7 +175,7 @@ class TreeSupportTipGenerator
* \param storage[in] Background storage, required for adding roofs.
* \param additional_support_areas[in] Areas that should have been roofs, but are now support, as they would not generate any lines as roof.
*/
void removeUselessAddedPoints(std::vector<std::set<TreeSupportElement*>>& move_bounds, SliceDataStorage& storage, std::vector<Shape>& additional_support_areas);
void removeUselessAddedPoints(std::vector<std::set<TreeSupportElement::Ptr>>& move_bounds, SliceDataStorage& storage, std::vector<Shape>& additional_support_areas);

/*!
* \brief Contains config settings to avoid loading them in every function. This was done to improve readability of the code.
Expand Down
Loading
Loading