WIP Lightning Infill, roughly integrated, untested, disabled with
HAS_LIGHTNING_INFILL
This commit is contained in:
parent
e8697d2fc2
commit
481def3205
@ -67,8 +67,8 @@ add_library(libslic3r STATIC
|
||||
Fill/FillPlanePath.hpp
|
||||
Fill/FillLine.cpp
|
||||
Fill/FillLine.hpp
|
||||
Fill/FillRectilinear.cpp
|
||||
Fill/FillRectilinear.hpp
|
||||
Fill/FillLightning.cpp
|
||||
Fill/FillLightning.hpp
|
||||
Fill/Lightning/DistanceField.cpp
|
||||
Fill/Lightning/DistanceField.hpp
|
||||
Fill/Lightning/Generator.cpp
|
||||
@ -77,6 +77,8 @@ add_library(libslic3r STATIC
|
||||
Fill/Lightning/Layer.hpp
|
||||
Fill/Lightning/TreeNode.cpp
|
||||
Fill/Lightning/TreeNode.hpp
|
||||
Fill/FillRectilinear.cpp
|
||||
Fill/FillRectilinear.hpp
|
||||
Flow.cpp
|
||||
Flow.hpp
|
||||
format.hpp
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "FillLine.hpp"
|
||||
#include "FillRectilinear.hpp"
|
||||
#include "FillAdaptive.hpp"
|
||||
#include "FillLightning.hpp"
|
||||
|
||||
// #define INFILL_DEBUG_OUTPUT
|
||||
|
||||
@ -45,6 +46,9 @@ Fill* Fill::new_from_type(const InfillPattern type)
|
||||
case ipAdaptiveCubic: return new FillAdaptive::Filler();
|
||||
case ipSupportCubic: return new FillAdaptive::Filler();
|
||||
case ipSupportBase: return new FillSupportBase();
|
||||
#if HAS_LIGHTNING_INFILL
|
||||
case ipLightning: return new FillLightning::Filler();
|
||||
#endif // HAS_LIGHTNING_INFILL
|
||||
default: throw Slic3r::InvalidArgument("unknown type");
|
||||
}
|
||||
}
|
||||
|
28
src/libslic3r/Fill/FillLightning.cpp
Normal file
28
src/libslic3r/Fill/FillLightning.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "../Print.hpp"
|
||||
|
||||
#include "FillLightning.hpp"
|
||||
#include "Lightning/Generator.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
namespace Slic3r::FillLightning {
|
||||
|
||||
Polylines Filler::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||
{
|
||||
const Layer &layer = generator->getTreesForLayer(this->layer_id);
|
||||
return layer.convertToLines(to_polygons(surface->expolygon), generator->infilll_extrusion_width());
|
||||
}
|
||||
|
||||
void GeneratorDeleter::operator()(Generator *p) {
|
||||
delete p;
|
||||
}
|
||||
|
||||
GeneratorPtr build_generator(const PrintObject &print_object)
|
||||
{
|
||||
return GeneratorPtr(new Generator(print_object));
|
||||
}
|
||||
|
||||
} // namespace Slic3r::FillAdaptive
|
36
src/libslic3r/Fill/FillLightning.hpp
Normal file
36
src/libslic3r/Fill/FillLightning.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef slic3r_FillLightning_hpp_
|
||||
#define slic3r_FillLightning_hpp_
|
||||
|
||||
#include "FillBase.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
|
||||
namespace FillLightning {
|
||||
|
||||
class Generator;
|
||||
// To keep the definition of Octree opaque, we have to define a custom deleter.
|
||||
struct GeneratorDeleter { void operator()(Generator *p); };
|
||||
using GeneratorPtr = std::unique_ptr<Generator, GeneratorDeleter>;
|
||||
|
||||
GeneratorPtr build_generator(const PrintObject &print_object);
|
||||
|
||||
class Filler : public Slic3r::Fill
|
||||
{
|
||||
public:
|
||||
~Filler() override = default;
|
||||
|
||||
Generator *generator { nullptr };
|
||||
protected:
|
||||
Fill* clone() const override { return new Filler(*this); }
|
||||
// Perform the fill.
|
||||
Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override;
|
||||
// Let the G-code export reoder the infill lines.
|
||||
bool no_sort() const override { return false; }
|
||||
};
|
||||
|
||||
} // namespace FillAdaptive
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // slic3r_FillLightning_hpp_
|
@ -4,12 +4,12 @@
|
||||
#include "DistanceField.hpp" //Class we're implementing.
|
||||
#include "../FillRectilinear.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
namespace Slic3r::FillLightning
|
||||
{
|
||||
|
||||
constexpr coord_t radius_per_cell_size = 6; // The cell-size should be small compared to the radius, but not so small as to be inefficient.
|
||||
|
||||
LightningDistanceField::LightningDistanceField(const coord_t& radius, const Polygons& current_outline, const Polygons& current_overhang) :
|
||||
DistanceField::DistanceField(const coord_t& radius, const Polygons& current_outline, const Polygons& current_overhang) :
|
||||
m_cell_size(radius / radius_per_cell_size),
|
||||
m_supporting_radius(radius)
|
||||
{
|
||||
@ -44,7 +44,7 @@ LightningDistanceField::LightningDistanceField(const coord_t& radius, const Poly
|
||||
}
|
||||
}
|
||||
|
||||
void LightningDistanceField::update(const Point& to_node, const Point& added_leaf)
|
||||
void DistanceField::update(const Point& to_node, const Point& added_leaf)
|
||||
{
|
||||
Vec2d v = (added_leaf - to_node).cast<double>();
|
||||
auto l2 = v.squaredNorm();
|
||||
@ -95,4 +95,4 @@ void LightningDistanceField::update(const Point& to_node, const Point& added_lea
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
} // namespace Slic3r::FillLightning
|
||||
|
@ -4,7 +4,7 @@
|
||||
#ifndef LIGHTNING_DISTANCE_FIELD_H
|
||||
#define LIGHTNING_DISTANCE_FIELD_H
|
||||
|
||||
namespace Slic3r
|
||||
namespace Slic3r::FillLightning
|
||||
{
|
||||
|
||||
/*!
|
||||
@ -15,7 +15,7 @@ namespace Slic3r
|
||||
* maintains how far it is removed from the edge, which is used to determine
|
||||
* how it gets supported by Lightning Infill.
|
||||
*/
|
||||
class LightningDistanceField
|
||||
class DistanceField
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
@ -26,7 +26,7 @@ public:
|
||||
* \param current_overhang The overhang that needs to be supported on this
|
||||
* layer.
|
||||
*/
|
||||
LightningDistanceField(const coord_t& radius, const Polygons& current_outline, const Polygons& current_overhang);
|
||||
DistanceField(const coord_t& radius, const Polygons& current_outline, const Polygons& current_overhang);
|
||||
|
||||
/*!
|
||||
* Gets the next unsupported location to be supported by a new branch.
|
||||
@ -92,6 +92,6 @@ protected:
|
||||
std::unordered_map<Point, std::list<UnsupportedCell>::iterator, PointHash> m_unsupported_points_grid;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
} // namespace Slic3r::FillLightning
|
||||
|
||||
#endif //LIGHTNING_DISTANCE_FIELD_H
|
||||
|
@ -20,12 +20,12 @@
|
||||
* - Make a pass with Arachne over the output. Somehow.
|
||||
* - Generate all to-be-supported points at once instead of sequentially: See branch interlocking_gen PolygonUtils::spreadDots (Or work with sparse grids.)
|
||||
* - Lots of magic values ... to many to parameterize. But are they the best?
|
||||
* - Move more complex computations from LightningGenerator constructor to elsewhere.
|
||||
* - Move more complex computations from Generator constructor to elsewhere.
|
||||
*/
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace Slic3r::FillLightning {
|
||||
|
||||
LightningGenerator::LightningGenerator(const PrintObject &print_object)
|
||||
Generator::Generator(const PrintObject &print_object)
|
||||
{
|
||||
const PrintConfig &print_config = print_object.print()->config();
|
||||
const PrintObjectConfig &object_config = print_object.config();
|
||||
@ -51,7 +51,7 @@ LightningGenerator::LightningGenerator(const PrintObject &print_object)
|
||||
generateTrees(print_object);
|
||||
}
|
||||
|
||||
void LightningGenerator::generateInitialInternalOverhangs(const PrintObject &print_object)
|
||||
void Generator::generateInitialInternalOverhangs(const PrintObject &print_object)
|
||||
{
|
||||
m_overhang_per_layer.resize(print_object.layers().size());
|
||||
const float infill_wall_offset = - m_infill_extrusion_width;
|
||||
@ -73,13 +73,13 @@ void LightningGenerator::generateInitialInternalOverhangs(const PrintObject &pri
|
||||
}
|
||||
}
|
||||
|
||||
const LightningLayer& LightningGenerator::getTreesForLayer(const size_t& layer_id) const
|
||||
const Layer& Generator::getTreesForLayer(const size_t& layer_id) const
|
||||
{
|
||||
assert(layer_id < m_lightning_layers.size());
|
||||
return m_lightning_layers[layer_id];
|
||||
}
|
||||
|
||||
void LightningGenerator::generateTrees(const PrintObject &print_object)
|
||||
void Generator::generateTrees(const PrintObject &print_object)
|
||||
{
|
||||
m_lightning_layers.resize(print_object.layers().size());
|
||||
const coord_t infill_wall_offset = - m_infill_extrusion_width;
|
||||
@ -101,11 +101,11 @@ void LightningGenerator::generateTrees(const PrintObject &print_object)
|
||||
// For-each layer from top to bottom:
|
||||
for (int layer_id = top_layer_id; layer_id >= 0; layer_id--)
|
||||
{
|
||||
LightningLayer& current_lightning_layer = m_lightning_layers[layer_id];
|
||||
Layer& current_lightning_layer = m_lightning_layers[layer_id];
|
||||
Polygons& current_outlines = infill_outlines[layer_id];
|
||||
|
||||
// register all trees propagated from the previous layer as to-be-reconnected
|
||||
std::vector<LightningTreeNodeSPtr> to_be_reconnected_tree_roots = current_lightning_layer.tree_roots;
|
||||
std::vector<NodeSPtr> to_be_reconnected_tree_roots = current_lightning_layer.tree_roots;
|
||||
|
||||
current_lightning_layer.generateNewTrees(m_overhang_per_layer[layer_id], current_outlines, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
|
||||
current_lightning_layer.reconnectRoots(to_be_reconnected_tree_roots, current_outlines, outlines_locator, m_supporting_radius, m_wall_supporting_radius);
|
||||
@ -118,8 +118,10 @@ void LightningGenerator::generateTrees(const PrintObject &print_object)
|
||||
outlines_locator.set_bbox(get_extents(below_outlines).inflated(SCALED_EPSILON));
|
||||
outlines_locator.create(below_outlines, locator_cell_size);
|
||||
|
||||
std::vector<LightningTreeNodeSPtr>& lower_trees = m_lightning_layers[layer_id - 1].tree_roots;
|
||||
std::vector<NodeSPtr>& lower_trees = m_lightning_layers[layer_id - 1].tree_roots;
|
||||
for (auto& tree : current_lightning_layer.tree_roots)
|
||||
tree->propagateToNextLayer(lower_trees, below_outlines, outlines_locator, m_prune_length, m_straightening_max_distance, locator_cell_size / 2);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r::FillLightning
|
||||
|
@ -14,6 +14,9 @@ namespace Slic3r
|
||||
{
|
||||
class PrintObject;
|
||||
|
||||
namespace FillLightning
|
||||
{
|
||||
|
||||
/*!
|
||||
* Generates the Lightning Infill pattern.
|
||||
*
|
||||
@ -31,7 +34,7 @@ class PrintObject;
|
||||
* Printing of Hollowed Objects" by Tricard, Claux and Lefebvre:
|
||||
* https://www.researchgate.net/publication/333808588_Ribbed_Support_Vaults_for_3D_Printing_of_Hollowed_Objects
|
||||
*/
|
||||
class LightningGenerator // "Just like Nicola used to make!"
|
||||
class Generator // "Just like Nicola used to make!"
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
@ -42,7 +45,7 @@ public:
|
||||
* already be calculated at this point.
|
||||
* \param mesh The mesh to generate infill for.
|
||||
*/
|
||||
LightningGenerator(const PrintObject &print_object);
|
||||
Generator(const PrintObject &print_object);
|
||||
|
||||
/*!
|
||||
* Get a tree of paths generated for a certain layer of the mesh.
|
||||
@ -53,7 +56,9 @@ public:
|
||||
* \return A tree structure representing paths to print to create the
|
||||
* Lightning Infill pattern.
|
||||
*/
|
||||
const LightningLayer& getTreesForLayer(const size_t& layer_id) const;
|
||||
const Layer& getTreesForLayer(const size_t& layer_id) const;
|
||||
|
||||
float infilll_extrusion_width() const { return m_infill_extrusion_width; }
|
||||
|
||||
protected:
|
||||
/*!
|
||||
@ -118,9 +123,10 @@ protected:
|
||||
*
|
||||
* This is generated by \ref generateTrees.
|
||||
*/
|
||||
std::vector<LightningLayer> m_lightning_layers;
|
||||
std::vector<Layer> m_lightning_layers;
|
||||
};
|
||||
|
||||
} // namespace FillLightning
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // LIGHTNING_GENERATOR_H
|
||||
|
@ -10,9 +10,9 @@
|
||||
|
||||
#include "../../Geometry.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace Slic3r::FillLightning {
|
||||
|
||||
coord_t LightningLayer::getWeightedDistance(const Point& boundary_loc, const Point& unsupported_location)
|
||||
coord_t Layer::getWeightedDistance(const Point& boundary_loc, const Point& unsupported_location)
|
||||
{
|
||||
return coord_t((boundary_loc - unsupported_location).cast<double>().norm());
|
||||
}
|
||||
@ -23,16 +23,16 @@ Point GroundingLocation::p() const
|
||||
return tree_node ? tree_node->getLocation() : *boundary_location;
|
||||
}
|
||||
|
||||
void LightningLayer::fillLocator(SparseLightningTreeNodeGrid &tree_node_locator)
|
||||
void Layer::fillLocator(SparseNodeGrid &tree_node_locator)
|
||||
{
|
||||
std::function<void(LightningTreeNodeSPtr)> add_node_to_locator_func = [&tree_node_locator](LightningTreeNodeSPtr node) {
|
||||
std::function<void(NodeSPtr)> add_node_to_locator_func = [&tree_node_locator](NodeSPtr node) {
|
||||
tree_node_locator.insert(std::make_pair(Point(node->getLocation().x() / locator_cell_size, node->getLocation().y() / locator_cell_size), node));
|
||||
};
|
||||
for (auto& tree : tree_roots)
|
||||
tree->visitNodes(add_node_to_locator_func);
|
||||
}
|
||||
|
||||
void LightningLayer::generateNewTrees
|
||||
void Layer::generateNewTrees
|
||||
(
|
||||
const Polygons& current_overhang,
|
||||
const Polygons& current_outlines,
|
||||
@ -41,9 +41,9 @@ void LightningLayer::generateNewTrees
|
||||
const coord_t wall_supporting_radius
|
||||
)
|
||||
{
|
||||
LightningDistanceField distance_field(supporting_radius, current_outlines, current_overhang);
|
||||
DistanceField distance_field(supporting_radius, current_outlines, current_overhang);
|
||||
|
||||
SparseLightningTreeNodeGrid tree_node_locator;
|
||||
SparseNodeGrid tree_node_locator;
|
||||
fillLocator(tree_node_locator);
|
||||
|
||||
// Until no more points need to be added to support all:
|
||||
@ -53,8 +53,8 @@ void LightningLayer::generateNewTrees
|
||||
GroundingLocation grounding_loc = getBestGroundingLocation(
|
||||
unsupported_location, current_outlines, outlines_locator, supporting_radius, wall_supporting_radius, tree_node_locator);
|
||||
|
||||
LightningTreeNodeSPtr new_parent;
|
||||
LightningTreeNodeSPtr new_child;
|
||||
NodeSPtr new_parent;
|
||||
NodeSPtr new_child;
|
||||
this->attach(unsupported_location, grounding_loc, new_child, new_parent);
|
||||
tree_node_locator.insert(std::make_pair(Point(new_child->getLocation().x() / locator_cell_size, new_child->getLocation().y() / locator_cell_size), new_child));
|
||||
if (new_parent)
|
||||
@ -93,15 +93,15 @@ static bool polygonCollidesWithLineSegment(const Point from, const Point to, con
|
||||
return visitor.intersect;
|
||||
}
|
||||
|
||||
GroundingLocation LightningLayer::getBestGroundingLocation
|
||||
GroundingLocation Layer::getBestGroundingLocation
|
||||
(
|
||||
const Point& unsupported_location,
|
||||
const Polygons& current_outlines,
|
||||
const EdgeGrid::Grid& outline_locator,
|
||||
const coord_t supporting_radius,
|
||||
const coord_t wall_supporting_radius,
|
||||
const SparseLightningTreeNodeGrid& tree_node_locator,
|
||||
const LightningTreeNodeSPtr& exclude_tree
|
||||
const SparseNodeGrid& tree_node_locator,
|
||||
const NodeSPtr& exclude_tree
|
||||
)
|
||||
{
|
||||
// Closest point on current_outlines to unsupported_location:
|
||||
@ -123,7 +123,7 @@ GroundingLocation LightningLayer::getBestGroundingLocation
|
||||
|
||||
const auto within_dist = coord_t((node_location - unsupported_location).cast<double>().norm());
|
||||
|
||||
LightningTreeNodeSPtr sub_tree{ nullptr };
|
||||
NodeSPtr sub_tree{ nullptr };
|
||||
coord_t current_dist = getWeightedDistance(node_location, unsupported_location);
|
||||
if (current_dist >= wall_supporting_radius) { // Only reconnect tree roots to other trees if they are not already close to the outlines.
|
||||
const coord_t search_radius = std::min(current_dist, within_dist);
|
||||
@ -154,15 +154,15 @@ GroundingLocation LightningLayer::getBestGroundingLocation
|
||||
GroundingLocation{ sub_tree, std::optional<Point>() };
|
||||
}
|
||||
|
||||
bool LightningLayer::attach(
|
||||
bool Layer::attach(
|
||||
const Point& unsupported_location,
|
||||
const GroundingLocation& grounding_loc,
|
||||
LightningTreeNodeSPtr& new_child,
|
||||
LightningTreeNodeSPtr& new_root)
|
||||
NodeSPtr& new_child,
|
||||
NodeSPtr& new_root)
|
||||
{
|
||||
// Update trees & distance fields.
|
||||
if (grounding_loc.boundary_location) {
|
||||
new_root = LightningTreeNode::create(grounding_loc.p(), std::make_optional(grounding_loc.p()));
|
||||
new_root = Node::create(grounding_loc.p(), std::make_optional(grounding_loc.p()));
|
||||
new_child = new_root->addChild(unsupported_location);
|
||||
tree_roots.push_back(new_root);
|
||||
return true;
|
||||
@ -172,9 +172,9 @@ bool LightningLayer::attach(
|
||||
}
|
||||
}
|
||||
|
||||
void LightningLayer::reconnectRoots
|
||||
void Layer::reconnectRoots
|
||||
(
|
||||
std::vector<LightningTreeNodeSPtr>& to_be_reconnected_tree_roots,
|
||||
std::vector<NodeSPtr>& to_be_reconnected_tree_roots,
|
||||
const Polygons& current_outlines,
|
||||
const EdgeGrid::Grid& outline_locator,
|
||||
const coord_t supporting_radius,
|
||||
@ -183,7 +183,7 @@ void LightningLayer::reconnectRoots
|
||||
{
|
||||
constexpr coord_t tree_connecting_ignore_offset = 100;
|
||||
|
||||
SparseLightningTreeNodeGrid tree_node_locator;
|
||||
SparseNodeGrid tree_node_locator;
|
||||
fillLocator(tree_node_locator);
|
||||
|
||||
const coord_t within_max_dist = outline_locator.resolution() * 2;
|
||||
@ -198,8 +198,8 @@ void LightningLayer::reconnectRoots
|
||||
{
|
||||
Point new_root_pt;
|
||||
// Find an intersection of the line segment from root_ptr->getLocation() to ground_loc, at within_max_dist from ground_loc.
|
||||
if (lineSegmentPolygonsIntersection(root_ptr->getLocation(), ground_loc, current_outlines, outline_locator, new_root_pt, within_max_dist)) {
|
||||
auto new_root = LightningTreeNode::create(new_root_pt, new_root_pt);
|
||||
if (lineSegmentPolygonsIntersection(root_ptr->getLocation(), ground_loc, outline_locator, new_root_pt, within_max_dist)) {
|
||||
auto new_root = Node::create(new_root_pt, new_root_pt);
|
||||
root_ptr->addChild(new_root);
|
||||
new_root->reroot();
|
||||
|
||||
@ -228,7 +228,7 @@ void LightningLayer::reconnectRoots
|
||||
if (ground.boundary_location.value() == root_ptr->getLocation())
|
||||
continue; // Already on the boundary.
|
||||
|
||||
auto new_root = LightningTreeNode::create(ground.p(), ground.p());
|
||||
auto new_root = Node::create(ground.p(), ground.p());
|
||||
auto attach_ptr = root_ptr->closestNode(new_root->getLocation());
|
||||
attach_ptr->reroot();
|
||||
|
||||
@ -375,14 +375,13 @@ static unsigned int moveInside(const Polygons& polygons, Point& from, int distan
|
||||
}
|
||||
|
||||
// Returns 'added someting'.
|
||||
Polygons LightningLayer::convertToLines(const Polygons& limit_to_outline, const coord_t line_width) const
|
||||
Polylines Layer::convertToLines(const Polygons& limit_to_outline, const coord_t line_width) const
|
||||
{
|
||||
Polygons result_lines;
|
||||
if (tree_roots.empty())
|
||||
return result_lines;
|
||||
return {};
|
||||
|
||||
for (const auto& tree : tree_roots)
|
||||
{
|
||||
Polygons result_lines;
|
||||
for (const auto& tree : tree_roots) {
|
||||
// If even the furthest location in the tree is inside the polygon, the entire tree must be inside of the polygon.
|
||||
// (Don't take the root as that may be on the edge and cause rounding errors to register as 'outside'.)
|
||||
constexpr coord_t epsilon = 5;
|
||||
@ -393,13 +392,12 @@ Polygons LightningLayer::convertToLines(const Polygons& limit_to_outline, const
|
||||
}
|
||||
|
||||
// TODO: allow for polylines!
|
||||
Polygons split_lines;
|
||||
for (Polygon &line : result_lines)
|
||||
{
|
||||
if (line.size() <= 1) continue;
|
||||
Polylines split_lines;
|
||||
for (Polygon &line : result_lines) {
|
||||
if (line.size() <= 1)
|
||||
continue;
|
||||
Point last = line[0];
|
||||
for (size_t point_idx = 1; point_idx < line.size(); point_idx++)
|
||||
{
|
||||
for (size_t point_idx = 1; point_idx < line.size(); point_idx++) {
|
||||
Point here = line[point_idx];
|
||||
split_lines.push_back({ last, here });
|
||||
last = here;
|
||||
@ -408,3 +406,5 @@ Polygons LightningLayer::convertToLines(const Polygons& limit_to_outline, const
|
||||
|
||||
return split_lines;
|
||||
}
|
||||
|
||||
} // namespace Slic3r::Lightning
|
||||
|
@ -12,16 +12,16 @@
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Slic3r
|
||||
namespace Slic3r::FillLightning
|
||||
{
|
||||
class LightningTreeNode;
|
||||
|
||||
using LightningTreeNodeSPtr = std::shared_ptr<LightningTreeNode>;
|
||||
using SparseLightningTreeNodeGrid = std::unordered_multimap<Point, std::weak_ptr<LightningTreeNode>, PointHash>;
|
||||
class Node;
|
||||
using NodeSPtr = std::shared_ptr<Node>;
|
||||
using SparseNodeGrid = std::unordered_multimap<Point, std::weak_ptr<Node>, PointHash>;
|
||||
|
||||
struct GroundingLocation
|
||||
{
|
||||
LightningTreeNodeSPtr tree_node; //!< not null if the gounding location is on a tree
|
||||
NodeSPtr tree_node; //!< not null if the gounding location is on a tree
|
||||
std::optional<Point> boundary_location; //!< in case the gounding location is on the boundary
|
||||
Point p() const;
|
||||
};
|
||||
@ -31,10 +31,10 @@ struct GroundingLocation
|
||||
*
|
||||
* Contains the trees to be printed and propagated to the next layer below.
|
||||
*/
|
||||
class LightningLayer
|
||||
class Layer
|
||||
{
|
||||
public:
|
||||
std::vector<LightningTreeNodeSPtr> tree_roots;
|
||||
std::vector<NodeSPtr> tree_roots;
|
||||
|
||||
void generateNewTrees
|
||||
(
|
||||
@ -55,8 +55,8 @@ public:
|
||||
const EdgeGrid::Grid& outline_locator,
|
||||
const coord_t supporting_radius,
|
||||
const coord_t wall_supporting_radius,
|
||||
const SparseLightningTreeNodeGrid& tree_node_locator,
|
||||
const LightningTreeNodeSPtr& exclude_tree = nullptr
|
||||
const SparseNodeGrid& tree_node_locator,
|
||||
const NodeSPtr& exclude_tree = nullptr
|
||||
);
|
||||
|
||||
/*!
|
||||
@ -64,24 +64,24 @@ public:
|
||||
* \param[out] new_root The new root node if one had been made
|
||||
* \return Whether a new root was added
|
||||
*/
|
||||
bool attach(const Point& unsupported_location, const GroundingLocation& ground, LightningTreeNodeSPtr& new_child, LightningTreeNodeSPtr& new_root);
|
||||
bool attach(const Point& unsupported_location, const GroundingLocation& ground, NodeSPtr& new_child, NodeSPtr& new_root);
|
||||
|
||||
void reconnectRoots
|
||||
(
|
||||
std::vector<LightningTreeNodeSPtr>& to_be_reconnected_tree_roots,
|
||||
std::vector<NodeSPtr>& to_be_reconnected_tree_roots,
|
||||
const Polygons& current_outlines,
|
||||
const EdgeGrid::Grid& outline_locator,
|
||||
const coord_t supporting_radius,
|
||||
const coord_t wall_supporting_radius
|
||||
);
|
||||
|
||||
Polygons convertToLines(const Polygons& limit_to_outline, const coord_t line_width) const;
|
||||
Polylines convertToLines(const Polygons& limit_to_outline, const coord_t line_width) const;
|
||||
|
||||
coord_t getWeightedDistance(const Point& boundary_loc, const Point& unsupported_location);
|
||||
|
||||
void fillLocator(SparseLightningTreeNodeGrid& tree_node_locator);
|
||||
void fillLocator(SparseNodeGrid& tree_node_locator);
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
} // namespace Slic3r::FillLightning
|
||||
|
||||
#endif // LIGHTNING_LAYER_H
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
#include "../../Geometry.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace Slic3r::FillLightning {
|
||||
|
||||
coord_t LightningTreeNode::getWeightedDistance(const Point& unsupported_location, const coord_t& supporting_radius) const
|
||||
coord_t Node::getWeightedDistance(const Point& unsupported_location, const coord_t& supporting_radius) const
|
||||
{
|
||||
constexpr coord_t min_valence_for_boost = 0;
|
||||
constexpr coord_t max_valence_for_boost = 4;
|
||||
@ -19,7 +19,7 @@ coord_t LightningTreeNode::getWeightedDistance(const Point& unsupported_location
|
||||
return dist_here - valence_boost;
|
||||
}
|
||||
|
||||
bool LightningTreeNode::hasOffspring(const LightningTreeNodeSPtr& to_be_checked) const
|
||||
bool Node::hasOffspring(const NodeSPtr& to_be_checked) const
|
||||
{
|
||||
if (to_be_checked == shared_from_this())
|
||||
return true;
|
||||
@ -31,14 +31,14 @@ bool LightningTreeNode::hasOffspring(const LightningTreeNodeSPtr& to_be_checked)
|
||||
return false;
|
||||
}
|
||||
|
||||
LightningTreeNodeSPtr LightningTreeNode::addChild(const Point& child_loc)
|
||||
NodeSPtr Node::addChild(const Point& child_loc)
|
||||
{
|
||||
assert(m_p != child_loc);
|
||||
LightningTreeNodeSPtr child = LightningTreeNode::create(child_loc);
|
||||
NodeSPtr child = Node::create(child_loc);
|
||||
return addChild(child);
|
||||
}
|
||||
|
||||
LightningTreeNodeSPtr LightningTreeNode::addChild(LightningTreeNodeSPtr& new_child)
|
||||
NodeSPtr Node::addChild(NodeSPtr& new_child)
|
||||
{
|
||||
assert(new_child != shared_from_this());
|
||||
//assert(p != new_child->p); // NOTE: No problem for now. Issue to solve later. Maybe even afetr final. Low prio.
|
||||
@ -48,8 +48,8 @@ LightningTreeNodeSPtr LightningTreeNode::addChild(LightningTreeNodeSPtr& new_chi
|
||||
return new_child;
|
||||
}
|
||||
|
||||
void LightningTreeNode::propagateToNextLayer(
|
||||
std::vector<LightningTreeNodeSPtr>& next_trees,
|
||||
void Node::propagateToNextLayer(
|
||||
std::vector<NodeSPtr>& next_trees,
|
||||
const Polygons& next_outlines,
|
||||
const EdgeGrid::Grid& outline_locator,
|
||||
const coord_t prune_distance,
|
||||
@ -65,7 +65,7 @@ void LightningTreeNode::propagateToNextLayer(
|
||||
|
||||
// NOTE: Depth-first, as currently implemented.
|
||||
// Skips the root (because that has no root itself), but all initial nodes will have the root point anyway.
|
||||
void LightningTreeNode::visitBranches(const std::function<void(const Point&, const Point&)>& visitor) const
|
||||
void Node::visitBranches(const std::function<void(const Point&, const Point&)>& visitor) const
|
||||
{
|
||||
for (const auto& node : m_children) {
|
||||
assert(node->m_parent.lock() == shared_from_this());
|
||||
@ -75,7 +75,7 @@ void LightningTreeNode::visitBranches(const std::function<void(const Point&, con
|
||||
}
|
||||
|
||||
// NOTE: Depth-first, as currently implemented.
|
||||
void LightningTreeNode::visitNodes(const std::function<void(LightningTreeNodeSPtr)>& visitor)
|
||||
void Node::visitNodes(const std::function<void(NodeSPtr)>& visitor)
|
||||
{
|
||||
visitor(shared_from_this());
|
||||
for (const auto& node : m_children) {
|
||||
@ -84,13 +84,13 @@ void LightningTreeNode::visitNodes(const std::function<void(LightningTreeNodeSPt
|
||||
}
|
||||
}
|
||||
|
||||
LightningTreeNode::LightningTreeNode(const Point& p, const std::optional<Point>& last_grounding_location /*= std::nullopt*/) :
|
||||
Node::Node(const Point& p, const std::optional<Point>& last_grounding_location /*= std::nullopt*/) :
|
||||
m_is_root(true), m_p(p), m_last_grounding_location(last_grounding_location)
|
||||
{}
|
||||
|
||||
LightningTreeNodeSPtr LightningTreeNode::deepCopy() const
|
||||
NodeSPtr Node::deepCopy() const
|
||||
{
|
||||
LightningTreeNodeSPtr local_root = LightningTreeNode::create(m_p);
|
||||
NodeSPtr local_root = Node::create(m_p);
|
||||
local_root->m_is_root = m_is_root;
|
||||
if (m_is_root)
|
||||
{
|
||||
@ -99,14 +99,14 @@ LightningTreeNodeSPtr LightningTreeNode::deepCopy() const
|
||||
local_root->m_children.reserve(m_children.size());
|
||||
for (const auto& node : m_children)
|
||||
{
|
||||
LightningTreeNodeSPtr child = node->deepCopy();
|
||||
NodeSPtr child = node->deepCopy();
|
||||
child->m_parent = local_root;
|
||||
local_root->m_children.push_back(child);
|
||||
}
|
||||
return local_root;
|
||||
}
|
||||
|
||||
void LightningTreeNode::reroot(LightningTreeNodeSPtr new_parent /*= nullptr*/)
|
||||
void Node::reroot(NodeSPtr new_parent /*= nullptr*/)
|
||||
{
|
||||
if (! m_is_root) {
|
||||
auto old_parent = m_parent.lock();
|
||||
@ -124,13 +124,13 @@ void LightningTreeNode::reroot(LightningTreeNodeSPtr new_parent /*= nullptr*/)
|
||||
}
|
||||
}
|
||||
|
||||
LightningTreeNodeSPtr LightningTreeNode::closestNode(const Point& loc)
|
||||
NodeSPtr Node::closestNode(const Point& loc)
|
||||
{
|
||||
LightningTreeNodeSPtr result = shared_from_this();
|
||||
NodeSPtr result = shared_from_this();
|
||||
auto closest_dist2 = coord_t((m_p - loc).cast<double>().norm());
|
||||
|
||||
for (const auto& child : m_children) {
|
||||
LightningTreeNodeSPtr candidate_node = child->closestNode(loc);
|
||||
NodeSPtr candidate_node = child->closestNode(loc);
|
||||
const auto child_dist2 = coord_t((candidate_node->m_p - loc).cast<double>().norm());
|
||||
if (child_dist2 < closest_dist2) {
|
||||
closest_dist2 = child_dist2;
|
||||
@ -183,7 +183,7 @@ bool lineSegmentPolygonsIntersection(const Point& a, const Point& b, const EdgeG
|
||||
return visitor.d2min < within_max_dist * within_max_dist;
|
||||
}
|
||||
|
||||
bool LightningTreeNode::realign(const Polygons& outlines, const EdgeGrid::Grid& outline_locator, std::vector<LightningTreeNodeSPtr>& rerooted_parts)
|
||||
bool Node::realign(const Polygons& outlines, const EdgeGrid::Grid& outline_locator, std::vector<NodeSPtr>& rerooted_parts)
|
||||
{
|
||||
if (outlines.empty())
|
||||
return false;
|
||||
@ -192,10 +192,10 @@ bool LightningTreeNode::realign(const Polygons& outlines, const EdgeGrid::Grid&
|
||||
// Only keep children that have an unbroken connection to here, realign will put the rest in rerooted parts due to recursion:
|
||||
Point coll;
|
||||
bool reground_me = false;
|
||||
m_children.erase(std::remove_if(m_children.begin(), m_children.end(), [&](const LightningTreeNodeSPtr &child) {
|
||||
m_children.erase(std::remove_if(m_children.begin(), m_children.end(), [&](const NodeSPtr &child) {
|
||||
bool connect_branch = child->realign(outlines, outline_locator, rerooted_parts);
|
||||
// Find an intersection of the line segment from p to child->p, at maximum outline_locator.resolution() * 2 distance from p.
|
||||
if (connect_branch && lineSegmentPolygonsIntersection(child->m_p, m_p, outlines, outline_locator, coll, outline_locator.resolution() * 2)) {
|
||||
if (connect_branch && lineSegmentPolygonsIntersection(child->m_p, m_p, outline_locator, coll, outline_locator.resolution() * 2)) {
|
||||
child->m_last_grounding_location.reset();
|
||||
child->m_parent.reset();
|
||||
child->m_is_root = true;
|
||||
@ -223,12 +223,12 @@ bool LightningTreeNode::realign(const Polygons& outlines, const EdgeGrid::Grid&
|
||||
return false;
|
||||
}
|
||||
|
||||
void LightningTreeNode::straighten(const coord_t magnitude, const coord_t max_remove_colinear_dist)
|
||||
void Node::straighten(const coord_t magnitude, const coord_t max_remove_colinear_dist)
|
||||
{
|
||||
straighten(magnitude, m_p, 0, max_remove_colinear_dist * max_remove_colinear_dist);
|
||||
}
|
||||
|
||||
LightningTreeNode::RectilinearJunction LightningTreeNode::straighten(
|
||||
Node::RectilinearJunction Node::straighten(
|
||||
const coord_t magnitude,
|
||||
const Point& junction_above,
|
||||
const coord_t accumulated_dist,
|
||||
@ -259,7 +259,7 @@ LightningTreeNode::RectilinearJunction LightningTreeNode::straighten(
|
||||
constexpr coord_t close_enough = 10;
|
||||
|
||||
child_p = m_children.front(); //recursive call to straighten might have removed the child
|
||||
const LightningTreeNodeSPtr& parent_node = m_parent.lock();
|
||||
const NodeSPtr& parent_node = m_parent.lock();
|
||||
if (parent_node &&
|
||||
(child_p->m_p - parent_node->m_p).cast<double>().squaredNorm() < max_remove_colinear_dist2 &&
|
||||
Line::distance_to_squared(m_p, parent_node->m_p, child_p->m_p) < close_enough * close_enough) {
|
||||
@ -306,7 +306,7 @@ LightningTreeNode::RectilinearJunction LightningTreeNode::straighten(
|
||||
}
|
||||
|
||||
// Prune the tree from the extremeties (leaf-nodes) until the pruning distance is reached.
|
||||
coord_t LightningTreeNode::prune(const coord_t& pruning_distance)
|
||||
coord_t Node::prune(const coord_t& pruning_distance)
|
||||
{
|
||||
if (pruning_distance <= 0)
|
||||
return 0;
|
||||
@ -343,7 +343,7 @@ coord_t LightningTreeNode::prune(const coord_t& pruning_distance)
|
||||
return max_distance_pruned;
|
||||
}
|
||||
|
||||
void LightningTreeNode::convertToPolylines(Polygons& output, const coord_t line_width) const
|
||||
void Node::convertToPolylines(Polygons& output, const coord_t line_width) const
|
||||
{
|
||||
Polygons result;
|
||||
output.emplace_back();
|
||||
@ -352,7 +352,7 @@ void LightningTreeNode::convertToPolylines(Polygons& output, const coord_t line_
|
||||
append(output, std::move(result));
|
||||
}
|
||||
|
||||
void LightningTreeNode::convertToPolylines(size_t long_line_idx, Polygons& output) const
|
||||
void Node::convertToPolylines(size_t long_line_idx, Polygons& output) const
|
||||
{
|
||||
if (m_children.empty()) {
|
||||
output[long_line_idx].points.push_back(m_p);
|
||||
@ -364,7 +364,7 @@ void LightningTreeNode::convertToPolylines(size_t long_line_idx, Polygons& outpu
|
||||
|
||||
for (size_t idx_offset = 1; idx_offset < m_children.size(); idx_offset++) {
|
||||
size_t child_idx = (first_child_idx + idx_offset) % m_children.size();
|
||||
const LightningTreeNode& child = *m_children[child_idx];
|
||||
const Node& child = *m_children[child_idx];
|
||||
output.emplace_back();
|
||||
size_t child_line_idx = output.size() - 1;
|
||||
child.convertToPolylines(child_line_idx, output);
|
||||
@ -372,7 +372,7 @@ void LightningTreeNode::convertToPolylines(size_t long_line_idx, Polygons& outpu
|
||||
}
|
||||
}
|
||||
|
||||
void LightningTreeNode::removeJunctionOverlap(Polygons& result_lines, const coord_t line_width) const
|
||||
void Node::removeJunctionOverlap(Polygons& result_lines, const coord_t line_width) const
|
||||
{
|
||||
const coord_t reduction = line_width / 2; // TODO make configurable?
|
||||
for (auto poly_it = result_lines.begin(); poly_it != result_lines.end(); ) {
|
||||
@ -406,3 +406,5 @@ void LightningTreeNode::removeJunctionOverlap(Polygons& result_lines, const coor
|
||||
++ poly_it;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Slic3r::FillLightning
|
||||
|
@ -12,14 +12,14 @@
|
||||
#include "../../EdgeGrid.hpp"
|
||||
#include "../../Polygon.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
namespace Slic3r::FillLightning
|
||||
{
|
||||
|
||||
constexpr auto locator_cell_size = scaled<coord_t>(4.);
|
||||
|
||||
class LightningTreeNode;
|
||||
class Node;
|
||||
|
||||
using LightningTreeNodeSPtr = std::shared_ptr<LightningTreeNode>;
|
||||
using NodeSPtr = std::shared_ptr<Node>;
|
||||
|
||||
// NOTE: As written, this struct will only be valid for a single layer, will have to be updated for the next.
|
||||
// NOTE: Reasons for implementing this with some separate closures:
|
||||
@ -35,15 +35,15 @@ using LightningTreeNodeSPtr = std::shared_ptr<LightningTreeNode>;
|
||||
* a tree. The class also has some helper functions specific to Lightning Infill
|
||||
* e.g. to straighten the paths around this node.
|
||||
*/
|
||||
class LightningTreeNode : public std::enable_shared_from_this<LightningTreeNode>
|
||||
class Node : public std::enable_shared_from_this<Node>
|
||||
{
|
||||
public:
|
||||
// Workaround for private/protected constructors and 'make_shared': https://stackoverflow.com/a/27832765
|
||||
template<typename ...Arg> LightningTreeNodeSPtr static create(Arg&&...arg)
|
||||
template<typename ...Arg> NodeSPtr static create(Arg&&...arg)
|
||||
{
|
||||
struct EnableMakeShared : public LightningTreeNode
|
||||
struct EnableMakeShared : public Node
|
||||
{
|
||||
EnableMakeShared(Arg&&...arg) : LightningTreeNode(std::forward<Arg>(arg)...) {}
|
||||
EnableMakeShared(Arg&&...arg) : Node(std::forward<Arg>(arg)...) {}
|
||||
};
|
||||
return std::make_shared<EnableMakeShared>(std::forward<Arg>(arg)...);
|
||||
}
|
||||
@ -62,19 +62,19 @@ public:
|
||||
void setLocation(const Point& p) { m_p = p; }
|
||||
|
||||
/*!
|
||||
* Construct a new ``LightningTreeNode`` instance and add it as a child of
|
||||
* Construct a new ``Node`` instance and add it as a child of
|
||||
* this node.
|
||||
* \param p The location of the new node.
|
||||
* \return A shared pointer to the new node.
|
||||
*/
|
||||
LightningTreeNodeSPtr addChild(const Point& p);
|
||||
NodeSPtr addChild(const Point& p);
|
||||
|
||||
/*!
|
||||
* Add an existing ``LightningTreeNode`` as a child of this node.
|
||||
* Add an existing ``Node`` as a child of this node.
|
||||
* \param new_child The node that must be added as a child.
|
||||
* \return Always returns \p new_child.
|
||||
*/
|
||||
LightningTreeNodeSPtr addChild(LightningTreeNodeSPtr& new_child);
|
||||
NodeSPtr addChild(NodeSPtr& new_child);
|
||||
|
||||
/*!
|
||||
* Propagate this node's sub-tree to the next layer.
|
||||
@ -96,7 +96,7 @@ public:
|
||||
*/
|
||||
void propagateToNextLayer
|
||||
(
|
||||
std::vector<LightningTreeNodeSPtr>& next_trees,
|
||||
std::vector<NodeSPtr>& next_trees,
|
||||
const Polygons& next_outlines,
|
||||
const EdgeGrid::Grid& outline_locator,
|
||||
const coord_t prune_distance,
|
||||
@ -127,7 +127,7 @@ public:
|
||||
* \param visitor A function to execute for every node in this node's sub-
|
||||
* tree.
|
||||
*/
|
||||
void visitNodes(const std::function<void(LightningTreeNodeSPtr)>& visitor);
|
||||
void visitNodes(const std::function<void(NodeSPtr)>& visitor);
|
||||
|
||||
/*!
|
||||
* Get a weighted distance from an unsupported point to this node (given the current supporting radius).
|
||||
@ -156,14 +156,14 @@ public:
|
||||
* This is then recursively bubbled up until it reaches the (former) root, which then will become a leaf.
|
||||
* \param new_parent The (new) parent-node of the root, useful for recursing or immediately attaching the node to another tree.
|
||||
*/
|
||||
void reroot(LightningTreeNodeSPtr new_parent = nullptr);
|
||||
void reroot(NodeSPtr new_parent = nullptr);
|
||||
|
||||
/*!
|
||||
* Retrieves the closest node to the specified location.
|
||||
* \param loc The specified location.
|
||||
* \result The branch that starts at the position closest to the location within this tree.
|
||||
*/
|
||||
LightningTreeNodeSPtr closestNode(const Point& loc);
|
||||
NodeSPtr closestNode(const Point& loc);
|
||||
|
||||
/*!
|
||||
* Returns whether the given tree node is a descendant of this node.
|
||||
@ -174,10 +174,10 @@ public:
|
||||
* \return ``true`` if the given node is a descendant or this node itself,
|
||||
* or ``false`` if it is not in the sub-tree.
|
||||
*/
|
||||
bool hasOffspring(const LightningTreeNodeSPtr& to_be_checked) const;
|
||||
bool hasOffspring(const NodeSPtr& to_be_checked) const;
|
||||
|
||||
protected:
|
||||
LightningTreeNode() = delete; // Don't allow empty contruction
|
||||
Node() = delete; // Don't allow empty contruction
|
||||
|
||||
/*!
|
||||
* Construct a new node, either for insertion in a tree or as root.
|
||||
@ -185,19 +185,19 @@ protected:
|
||||
* Connecting other nodes to this node indicates that a line segment should
|
||||
* be drawn between those two physical positions.
|
||||
*/
|
||||
LightningTreeNode(const Point& p, const std::optional<Point>& last_grounding_location = std::nullopt);
|
||||
Node(const Point& p, const std::optional<Point>& last_grounding_location = std::nullopt);
|
||||
|
||||
/*!
|
||||
* Copy this node and its entire sub-tree.
|
||||
* \return The equivalent of this node in the copy (the root of the new sub-
|
||||
* tree).
|
||||
*/
|
||||
LightningTreeNodeSPtr deepCopy() const;
|
||||
NodeSPtr deepCopy() const;
|
||||
|
||||
/*! Reconnect trees from the layer above to the new outlines of the lower layer.
|
||||
* \return Wether or not the root is kept (false is no, true is yes).
|
||||
*/
|
||||
bool realign(const Polygons& outlines, const EdgeGrid::Grid& outline_locator, std::vector<LightningTreeNodeSPtr>& rerooted_parts);
|
||||
bool realign(const Polygons& outlines, const EdgeGrid::Grid& outline_locator, std::vector<NodeSPtr>& rerooted_parts);
|
||||
|
||||
struct RectilinearJunction
|
||||
{
|
||||
@ -261,15 +261,15 @@ protected:
|
||||
|
||||
bool m_is_root;
|
||||
Point m_p;
|
||||
std::weak_ptr<LightningTreeNode> m_parent;
|
||||
std::vector<LightningTreeNodeSPtr> m_children;
|
||||
std::weak_ptr<Node> m_parent;
|
||||
std::vector<NodeSPtr> m_children;
|
||||
|
||||
std::optional<Point> m_last_grounding_location; //<! The last known grounding location, see 'getLastGroundingLocation()'.
|
||||
};
|
||||
|
||||
bool inside(const Polygons &polygons, const Point p);
|
||||
bool lineSegmentPolygonsIntersection(const Point& a, const Point& b, const Polygons& current_outlines, const EdgeGrid::Grid& outline_locator, Point& result, const coord_t within_max_dist);
|
||||
bool lineSegmentPolygonsIntersection(const Point& a, const Point& b, const EdgeGrid::Grid& outline_locator, Point& result, const coord_t within_max_dist);
|
||||
|
||||
} // namespace Slic3r
|
||||
} // namespace Slic3r::FillLightning
|
||||
|
||||
#endif // LIGHTNING_TREE_NODE_H
|
||||
|
@ -107,7 +107,10 @@ static t_config_enum_values s_keys_map_InfillPattern {
|
||||
{ "archimedeanchords", ipArchimedeanChords },
|
||||
{ "octagramspiral", ipOctagramSpiral },
|
||||
{ "adaptivecubic", ipAdaptiveCubic },
|
||||
{ "supportcubic", ipSupportCubic }
|
||||
{ "supportcubic", ipSupportCubic },
|
||||
#if HAS_LIGHTNING_INFILL
|
||||
{ "lightning", ipLightning }
|
||||
#endif // HAS_LIGHTNING_INFILL
|
||||
};
|
||||
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(InfillPattern)
|
||||
|
||||
@ -1135,6 +1138,9 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_values.push_back("octagramspiral");
|
||||
def->enum_values.push_back("adaptivecubic");
|
||||
def->enum_values.push_back("supportcubic");
|
||||
#if HAS_LIGHTNING_INFILL
|
||||
def->enum_values.push_back("lightning");
|
||||
#endif // HAS_LIGHTNING_INFILL
|
||||
def->enum_labels.push_back(L("Rectilinear"));
|
||||
def->enum_labels.push_back(L("Aligned Rectilinear"));
|
||||
def->enum_labels.push_back(L("Grid"));
|
||||
@ -1151,6 +1157,9 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_labels.push_back(L("Octagram Spiral"));
|
||||
def->enum_labels.push_back(L("Adaptive Cubic"));
|
||||
def->enum_labels.push_back(L("Support Cubic"));
|
||||
#if HAS_LIGHTNING_INFILL
|
||||
def->enum_labels.push_back(L("Lightning"));
|
||||
#endif // HAS_LIGHTNING_INFILL
|
||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipStars));
|
||||
|
||||
def = this->add("first_layer_acceleration", coFloat);
|
||||
|
@ -57,9 +57,15 @@ enum class FuzzySkinType {
|
||||
All,
|
||||
};
|
||||
|
||||
#define HAS_LIGHTNING_INFILL 0
|
||||
|
||||
enum InfillPattern : int {
|
||||
ipRectilinear, ipMonotonic, ipAlignedRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
|
||||
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipAdaptiveCubic, ipSupportCubic, ipSupportBase, ipCount,
|
||||
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipAdaptiveCubic, ipSupportCubic, ipSupportBase,
|
||||
#if HAS_LIGHTNING_INFILL
|
||||
ipLightning,
|
||||
#endif // HAS_LIGHTNING_INFILL
|
||||
ipCount,
|
||||
};
|
||||
|
||||
enum class IroningType {
|
||||
|
Loading…
Reference in New Issue
Block a user