Doxygen Documentation for Layer.hpp, Layer.cpp, LayerRegion.cpp, LayerRegionFill.cpp (#3979)

* Migrated comments in Layer.hpp

* Comments for Layer Class

* Comments for LayerRegion

* Comments for LayerRegionFill
This commit is contained in:
Daniel Goldman 2017-05-29 23:06:57 -04:00 committed by Joseph Lenox
parent 6fb8a91522
commit af6b094d29
4 changed files with 127 additions and 66 deletions

View File

@ -5,6 +5,8 @@
namespace Slic3r { namespace Slic3r {
/// Initialises upper_layer, lower_layer to NULL
/// Initialises slicing_errors to false
Layer::Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, Layer::Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z,
coordf_t slice_z) coordf_t slice_z)
: upper_layer(NULL), : upper_layer(NULL),
@ -20,6 +22,7 @@ Layer::Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z,
{ {
} }
/// Removes references to self and clears regions
Layer::~Layer() Layer::~Layer()
{ {
// remove references to self // remove references to self
@ -34,25 +37,28 @@ Layer::~Layer()
this->clear_regions(); this->clear_regions();
} }
/// Getter for this->_id
size_t size_t
Layer::id() const Layer::id() const
{ {
return this->_id; return this->_id;
} }
/// Setter for this->_id
void void
Layer::set_id(size_t id) Layer::set_id(size_t id)
{ {
this->_id = id; this->_id = id;
} }
/// Getter for this->regions.size()
size_t size_t
Layer::region_count() const Layer::region_count() const
{ {
return this->regions.size(); return this->regions.size();
} }
/// Deletes all regions using this->delete_region()
void void
Layer::clear_regions() Layer::clear_regions()
{ {
@ -60,6 +66,7 @@ Layer::clear_regions()
this->delete_region(i); this->delete_region(i);
} }
/// Creates a LayerRegion from a PrintRegion and adds it to this->regions
LayerRegion* LayerRegion*
Layer::add_region(PrintRegion* print_region) Layer::add_region(PrintRegion* print_region)
{ {
@ -68,6 +75,7 @@ Layer::add_region(PrintRegion* print_region)
return region; return region;
} }
/// Deletes an individual region
void void
Layer::delete_region(int idx) Layer::delete_region(int idx)
{ {
@ -77,7 +85,8 @@ Layer::delete_region(int idx)
delete item; delete item;
} }
// merge all regions' slices to get islands /// Merge all regions' slices to get islands
//TODO: is this right?
void void
Layer::make_slices() Layer::make_slices()
{ {
@ -115,6 +124,7 @@ Layer::make_slices()
this->slices.expolygons.push_back(slices[o]); this->slices.expolygons.push_back(slices[o]);
} }
/// Iterates over all of the LayerRegion and invokes LayerRegion->merge_slices()
void void
Layer::merge_slices() Layer::merge_slices()
{ {
@ -123,6 +133,7 @@ Layer::merge_slices()
} }
} }
/// Uses LayerRegion->slices.any_internal_contains(item)
template <class T> template <class T>
bool bool
Layer::any_internal_region_slice_contains(const T &item) const Layer::any_internal_region_slice_contains(const T &item) const
@ -134,6 +145,7 @@ Layer::any_internal_region_slice_contains(const T &item) const
} }
template bool Layer::any_internal_region_slice_contains<Polyline>(const Polyline &item) const; template bool Layer::any_internal_region_slice_contains<Polyline>(const Polyline &item) const;
/// Uses LayerRegion->slices.any_bottom_contains(item)
template <class T> template <class T>
bool bool
Layer::any_bottom_region_slice_contains(const T &item) const Layer::any_bottom_region_slice_contains(const T &item) const
@ -145,10 +157,8 @@ Layer::any_bottom_region_slice_contains(const T &item) const
} }
template bool Layer::any_bottom_region_slice_contains<Polyline>(const Polyline &item) const; template bool Layer::any_bottom_region_slice_contains<Polyline>(const Polyline &item) const;
/// The perimeter paths and the thin fills (ExtrusionEntityCollection) are assigned to the first compatible layer region.
// Here the perimeters are created cummulatively for all layer regions sharing the same parameters influencing the perimeters. /// The resulting fill surface is split back among the originating regions.
// The perimeter paths and the thin fills (ExtrusionEntityCollection) are assigned to the first compatible layer region.
// The resulting fill surface is split back among the originating regions.
void void
Layer::make_perimeters() Layer::make_perimeters()
{ {
@ -232,6 +242,8 @@ Layer::make_perimeters()
} }
} }
/// Iterates over all of the LayerRegion and invokes LayerRegion->make_fill()
/// Asserts that the fills created are not NULL
void void
Layer::make_fills() Layer::make_fills()
{ {
@ -249,15 +261,15 @@ Layer::make_fills()
} }
} }
// This function analyzes slices of a region (SurfaceCollection slices). /// Analyzes slices of a region (SurfaceCollection slices).
// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface. /// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface.
// Initially all slices are of type S_TYPE_INTERNAL. /// Initially all slices are of type S_TYPE_INTERNAL.
// Slices are compared against the top / bottom slices and regions and classified to the following groups: /// Slices are compared against the top / bottom slices and regions and classified to the following groups:
// S_TYPE_TOP - Part of a region, which is not covered by any upper layer. This surface will be filled with a top solid infill. /// S_TYPE_TOP - Part of a region, which is not covered by any upper layer. This surface will be filled with a top solid infill.
// S_TYPE_BOTTOMBRIDGE - Part of a region, which is not fully supported, but it hangs in the air, or it hangs losely on a support or a raft. /// S_TYPE_BOTTOMBRIDGE - Part of a region, which is not fully supported, but it hangs in the air, or it hangs losely on a support or a raft.
// S_TYPE_BOTTOM - Part of a region, which is not supported by the same region, but it is supported either by another region, or by a soluble interface layer. /// S_TYPE_BOTTOM - Part of a region, which is not supported by the same region, but it is supported either by another region, or by a soluble interface layer.
// S_TYPE_INTERNAL - Part of a region, which is supported by the same region type. /// S_TYPE_INTERNAL - Part of a region, which is supported by the same region type.
// If a part of a region is of S_TYPE_BOTTOM and S_TYPE_TOP, the S_TYPE_BOTTOM wins. /// If a part of a region is of S_TYPE_BOTTOM and S_TYPE_TOP, the S_TYPE_BOTTOM wins.
void void
Layer::detect_surfaces_type() Layer::detect_surfaces_type()
{ {
@ -270,7 +282,7 @@ Layer::detect_surfaces_type()
// unless internal shells are requested // unless internal shells are requested
// We call layer->slices or layerm->slices on these neighbor layers // We call layer->slices or layerm->slices on these neighbor layers
// and we convert them into Polygons so we only care about their total // and we convert them into Polygons so we only care about their total
// coverage. We only write to layerm->slices so we can read layer->slices safely. // coverage. We only write to layerm->slices so we can read layer->slices safely.
Layer* const &upper_layer = this->upper_layer; Layer* const &upper_layer = this->upper_layer;
Layer* const &lower_layer = this->lower_layer; Layer* const &lower_layer = this->lower_layer;
@ -315,7 +327,7 @@ Layer::detect_surfaces_type()
if (lower_layer != NULL) { if (lower_layer != NULL) {
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating // If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
// the support from the print. // the support from the print.
const SurfaceType surface_type_bottom = const SurfaceType surface_type_bottom =
(object.config.support_material.value && object.config.support_material_contact_distance.value == 0) (object.config.support_material.value && object.config.support_material_contact_distance.value == 0)
? stBottom ? stBottom
: stBottomBridge; : stBottomBridge;
@ -323,7 +335,7 @@ Layer::detect_surfaces_type()
// Any surface lying on the void is a true bottom bridge (an overhang) // Any surface lying on the void is a true bottom bridge (an overhang)
bottom.append( bottom.append(
offset2_ex( offset2_ex(
diff(layerm_slices_surfaces, lower_layer->slices, true), diff(layerm_slices_surfaces, lower_layer->slices, true),
-offs, offs -offs, offs
), ),
surface_type_bottom surface_type_bottom
@ -332,7 +344,7 @@ Layer::detect_surfaces_type()
// if user requested internal shells, we need to identify surfaces // if user requested internal shells, we need to identify surfaces
// lying on other slices not belonging to this region // lying on other slices not belonging to this region
if (object.config.interface_shells) { if (object.config.interface_shells) {
// non-bridging bottom surfaces: any part of this layer lying // non-bridging bottom surfaces: any part of this layer lying
// on something else, excluding those lying on our own region // on something else, excluding those lying on our own region
const LayerRegion* lower_layerm = lower_layer->get_region(region_id); const LayerRegion* lower_layerm = lower_layer->get_region(region_id);
boost::lock_guard<boost::mutex> l(lower_layerm->_slices_mutex); boost::lock_guard<boost::mutex> l(lower_layerm->_slices_mutex);
@ -340,9 +352,9 @@ Layer::detect_surfaces_type()
offset2_ex( offset2_ex(
diff( diff(
intersection(layerm_slices_surfaces, lower_layer->slices), // supported intersection(layerm_slices_surfaces, lower_layer->slices), // supported
lower_layerm->slices, lower_layerm->slices,
true true
), ),
-offs, offs -offs, offs
), ),
stBottom stBottom
@ -355,7 +367,7 @@ Layer::detect_surfaces_type()
// if we have raft layers, consider bottom layer as a bridge // if we have raft layers, consider bottom layer as a bridge
// just like any other bottom surface lying on the void // just like any other bottom surface lying on the void
const SurfaceType surface_type_bottom = const SurfaceType surface_type_bottom =
(object.config.raft_layers.value > 0 && object.config.support_material_contact_distance.value > 0) (object.config.raft_layers.value > 0 && object.config.support_material_contact_distance.value > 0)
? stBottomBridge ? stBottomBridge
: stBottom; : stBottom;
@ -405,7 +417,7 @@ Layer::detect_surfaces_type()
{ {
/* Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces. /* Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces.
Note: this method should be idempotent, but fill_surfaces gets modified Note: this method should be idempotent, but fill_surfaces gets modified
in place. However we're now only using its boundaries (which are invariant) in place. However we're now only using its boundaries (which are invariant)
so we're safe. This guarantees idempotence of prepare_infill() also in case so we're safe. This guarantees idempotence of prepare_infill() also in case
that combine_infill() turns some fill_surface into VOID surfaces. */ that combine_infill() turns some fill_surface into VOID surfaces. */
@ -423,6 +435,7 @@ Layer::detect_surfaces_type()
} }
} }
///Iterates over all LayerRegions and invokes LayerRegion->process_external_surfaces
void void
Layer::process_external_surfaces() Layer::process_external_surfaces()
{ {

View File

@ -31,97 +31,126 @@ class LayerRegion
PrintRegion* region() { return this->_region; }; PrintRegion* region() { return this->_region; };
const PrintRegion* region() const { return this->_region; }; const PrintRegion* region() const { return this->_region; };
// collection of surfaces generated by slicing the original geometry /// Collection of surfaces generated by slicing the original geometry
// divided by type top/bottom/internal /// Divided by type top/bottom/internal
SurfaceCollection slices; SurfaceCollection slices;
// collection of extrusion paths/loops filling gaps /// Collection of extrusion paths/loops filling gaps
ExtrusionEntityCollection thin_fills; ExtrusionEntityCollection thin_fills;
// collection of surfaces for infill generation /// Collection of surfaces for infill generation
SurfaceCollection fill_surfaces; SurfaceCollection fill_surfaces;
// collection of expolygons representing the bridged areas (thus not /// Collection of expolygons representing the bridged areas (thus not
// needing support material) /// needing support material)
Polygons bridged; Polygons bridged;
// collection of polylines representing the unsupported bridge edges /// Collection of polylines representing the unsupported bridge edges
PolylineCollection unsupported_bridge_edges; PolylineCollection unsupported_bridge_edges;
// ordered collection of extrusion paths/loops to build all perimeters /// Ordered collection of extrusion paths/loops to build all perimeters
// (this collection contains only ExtrusionEntityCollection objects) /// (this collection contains only ExtrusionEntityCollection objects)
ExtrusionEntityCollection perimeters; ExtrusionEntityCollection perimeters;
// ordered collection of extrusion paths to fill surfaces /// Ordered collection of extrusion paths to fill surfaces
// (this collection contains only ExtrusionEntityCollection objects) /// (this collection contains only ExtrusionEntityCollection objects)
ExtrusionEntityCollection fills; ExtrusionEntityCollection fills;
/// Flow object which provides methods to predict material spacing.
Flow flow(FlowRole role, bool bridge = false, double width = -1) const; Flow flow(FlowRole role, bool bridge = false, double width = -1) const;
/// Merges this->slices
void merge_slices(); void merge_slices();
/// Preprocesses fill surfaces
void prepare_fill_surfaces(); void prepare_fill_surfaces();
/// Generates and stores the perimeters and thin fills
void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces); void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces);
/// Generate infills for a LayerRegion.
void make_fill(); void make_fill();
/// Processes external surfaces for bridges and top/bottom surfaces
void process_external_surfaces(); void process_external_surfaces();
/// Gets the smallest fillable area
double infill_area_threshold() const; double infill_area_threshold() const;
private: private:
/// Pointer to associated Layer
Layer *_layer; Layer *_layer;
/// Pointer to associated PrintRegion
PrintRegion *_region; PrintRegion *_region;
/// Mutex object for slices.
mutable boost::mutex _slices_mutex; mutable boost::mutex _slices_mutex;
///Constructor
LayerRegion(Layer *layer, PrintRegion *region) LayerRegion(Layer *layer, PrintRegion *region)
: _layer(layer), _region(region) {}; : _layer(layer), _region(region) {};
///Destructor
~LayerRegion() {}; ~LayerRegion() {};
}; };
/// A std::vector of LayerRegion Pointers
typedef std::vector<LayerRegion*> LayerRegionPtrs; typedef std::vector<LayerRegion*> LayerRegionPtrs;
class Layer { class Layer {
friend class PrintObject; friend class PrintObject;
public: public:
/// ID number
size_t id() const; size_t id() const;
/// Setter for this->_id
void set_id(size_t id); void set_id(size_t id);
/// Getter for _object
PrintObject* object() { return this->_object; }; PrintObject* object() { return this->_object; };
const PrintObject* object() const { return this->_object; }; const PrintObject* object() const { return this->_object; };
Layer *upper_layer; Layer *upper_layer; ///< Pointer to layer above
Layer *lower_layer; Layer *lower_layer; ///< Pointer to layer below
LayerRegionPtrs regions; LayerRegionPtrs regions; ///< Vector of pointers to the LayerRegions of this layer
bool slicing_errors; bool slicing_errors; ///< Presence of slicing errors
coordf_t slice_z; // Z used for slicing in unscaled coordinates coordf_t slice_z; ///< Z used for slicing in unscaled coordinates
coordf_t print_z; // Z used for printing in unscaled coordinates coordf_t print_z; ///< Z used for printing in unscaled coordinates
coordf_t height; // layer height in unscaled coordinates coordf_t height; ///< layer height in unscaled coordinates
// collection of expolygons generated by slicing the original geometry;
// also known as 'islands' (all regions and surface types are merged here)
ExPolygonCollection slices;
ExPolygonCollection slices; ///< collection of expolygons generated by slicing the original geometry;
///< also known as 'islands' (all regions and surface types are merged here)
/// Returns the number of regions
size_t region_count() const; size_t region_count() const;
/// Gets a region at a specific id
LayerRegion* get_region(size_t idx) { return this->regions.at(idx); }; LayerRegion* get_region(size_t idx) { return this->regions.at(idx); };
/// Gets a region at a specific id as const
const LayerRegion* get_region(size_t idx) const { return this->regions.at(idx); }; const LayerRegion* get_region(size_t idx) const { return this->regions.at(idx); };
LayerRegion* add_region(PrintRegion* print_region);
/// Adds a PrintRegion
LayerRegion* add_region(PrintRegion* print_region);
/// Merge all regions' slices to get islands
void make_slices(); void make_slices();
/// Merges all of the LayerRegions' slices
void merge_slices(); void merge_slices();
/// Template which iterates over all of the LayerRegion for internally containing the argument
template <class T> bool any_internal_region_slice_contains(const T &item) const; template <class T> bool any_internal_region_slice_contains(const T &item) const;
/// Template which iterates over all of the LayerRegion for containing on the bottom the argument
template <class T> bool any_bottom_region_slice_contains(const T &item) const; template <class T> bool any_bottom_region_slice_contains(const T &item) const;
/// Creates the perimeters cummulatively for all layer regions sharing the same parameters influencing the perimeters.
void make_perimeters(); void make_perimeters();
/// Makes fills for all the LayerRegion
void make_fills(); void make_fills();
/// Determines the type of surface (top/bottombridge/bottom/internal) each region is
void detect_surfaces_type(); void detect_surfaces_type();
/// Processes the external surfaces
void process_external_surfaces(); void process_external_surfaces();
protected: protected:
size_t _id; // sequential number of layer, 0-based size_t _id; ///< sequential number of layer, 0-based
PrintObject* _object; PrintObject* _object; ///< Associated PrintObject
/// Constructor
Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z,
coordf_t slice_z); coordf_t slice_z);
/// Destructor
virtual ~Layer(); virtual ~Layer();
/// Deletes all regions
void clear_regions(); void clear_regions();
/// Deletes a specific region
void delete_region(int idx); void delete_region(int idx);
}; };
@ -130,14 +159,22 @@ class SupportLayer : public Layer {
friend class PrintObject; friend class PrintObject;
public: public:
/// Collection of support islands.
/// Populated in SupportMaterial.pm in sub generate_toolpaths
ExPolygonCollection support_islands; ExPolygonCollection support_islands;
/// Collection of support fills.
/// Populated in SupportMaterial.pm in sub generate_toolpaths
ExtrusionEntityCollection support_fills; ExtrusionEntityCollection support_fills;
/// Collection of support interface fills.
/// Populated in SupportMaterial.pm in sub generate_toolpaths
ExtrusionEntityCollection support_interface_fills; ExtrusionEntityCollection support_interface_fills;
protected: protected:
/// Constructor
SupportLayer(size_t id, PrintObject *object, coordf_t height, SupportLayer(size_t id, PrintObject *object, coordf_t height,
coordf_t print_z, coordf_t slice_z) coordf_t print_z, coordf_t slice_z)
: Layer(id, object, height, print_z, slice_z) {}; : Layer(id, object, height, print_z, slice_z) {};
/// Destructor
virtual ~SupportLayer() {}; virtual ~SupportLayer() {};
}; };

View File

@ -8,6 +8,7 @@
namespace Slic3r { namespace Slic3r {
/// Creates a new Flow object with the arguments and the variables of this LayerRegion
Flow Flow
LayerRegion::flow(FlowRole role, bool bridge, double width) const LayerRegion::flow(FlowRole role, bool bridge, double width) const
{ {
@ -21,6 +22,7 @@ LayerRegion::flow(FlowRole role, bool bridge, double width) const
); );
} }
/// Merges this->slices with union_ex, and then repopulates this->slices.surfaces
void void
LayerRegion::merge_slices() LayerRegion::merge_slices()
{ {
@ -33,6 +35,8 @@ LayerRegion::merge_slices()
this->slices.surfaces.push_back(Surface(stInternal, *expoly)); this->slices.surfaces.push_back(Surface(stInternal, *expoly));
} }
/// Creates a new PerimeterGenerator object
/// Which will return the perimeters by its construction
void void
LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces) LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces)
{ {
@ -66,8 +70,11 @@ LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollection*
g.process(); g.process();
} }
// This function reads layer->slices and lower_layer->slices /// Processes bridges with holes which are internal features.
// and writes this->bridged and this->fill_surfaces, so it's thread-safe. /// Detects same-orientation bridges and merges them.
/// Processes and groups top and bottom surfaces
/// This function reads layer->slices and lower_layer->slices
/// and writes this->bridged and this->fill_surfaces, so it's thread-safe.
void void
LayerRegion::process_external_surfaces() LayerRegion::process_external_surfaces()
{ {
@ -79,7 +86,7 @@ LayerRegion::process_external_surfaces()
if (this->layer()->lower_layer != NULL && surfaces[j].is_bridge()) { if (this->layer()->lower_layer != NULL && surfaces[j].is_bridge()) {
// If this bridge has one or more holes that are internal surfaces // If this bridge has one or more holes that are internal surfaces
// (thus not visible from the outside), like a slab sustained by // (thus not visible from the outside), like a slab sustained by
// pillars, include them in the bridge in order to have better and // pillars, include them in the bridge in order to have better and
// more continuous bridging. // more continuous bridging.
for (int i = 0; i < surfaces[j].expolygon.holes.size(); ++i) { for (int i = 0; i < surfaces[j].expolygon.holes.size(); ++i) {
@ -132,7 +139,7 @@ LayerRegion::process_external_surfaces()
if (this->layer()->object()->config.support_material) { if (this->layer()->object()->config.support_material) {
append_to(this->bridged, bd.coverage()); append_to(this->bridged, bd.coverage());
this->unsupported_bridge_edges.append(bd.unsupported_edges()); this->unsupported_bridge_edges.append(bd.unsupported_edges());
} }
} }
} }
@ -220,6 +227,8 @@ LayerRegion::process_external_surfaces()
this->fill_surfaces = std::move(new_surfaces); this->fill_surfaces = std::move(new_surfaces);
} }
/// If no solid layers are requested, turns top/bottom surfaces to internal
/// Turns too small internal regions into solid regions according to the user setting
void void
LayerRegion::prepare_fill_surfaces() LayerRegion::prepare_fill_surfaces()
{ {
@ -259,6 +268,7 @@ LayerRegion::prepare_fill_surfaces()
} }
} }
/// Gets smallest area by squaring the Flow's scaled spacing
double double
LayerRegion::infill_area_threshold() const LayerRegion::infill_area_threshold() const
{ {

View File

@ -8,23 +8,24 @@
namespace Slic3r { namespace Slic3r {
/// Struct for the main attributes of a Surface
/// Used for comparing properties
struct SurfaceGroupAttrib struct SurfaceGroupAttrib
{ {
SurfaceGroupAttrib() : is_solid(false), fw(0.f), pattern(-1) {} SurfaceGroupAttrib() : is_solid(false), fw(0.f), pattern(-1) {}
/// True iff all all three attributes are the same
bool operator==(const SurfaceGroupAttrib &other) const bool operator==(const SurfaceGroupAttrib &other) const
{ return is_solid == other.is_solid && fw == other.fw && pattern == other.pattern; } { return is_solid == other.is_solid && fw == other.fw && pattern == other.pattern; }
bool is_solid; bool is_solid; ///< if a solid infill should be used
float fw; float fw; ///< flow Width
// pattern is of type InfillPattern, -1 for an unset pattern. int pattern; ///< pattern is of type InfillPattern, -1 for an unset pattern.
int pattern;
}; };
// Generate infills for a LayerRegion. /// The LayerRegion at this point of time may contain
// The LayerRegion at this point of time may contain /// surfaces of various types (internal/bridge/top/bottom/solid).
// surfaces of various types (internal/bridge/top/bottom/solid). /// The infills are generated on the groups of surfaces with a compatible type.
// The infills are generated on the groups of surfaces with a compatible type. /// Fills an array of ExtrusionPathCollection objects containing the infills generated now
// Fills an array of ExtrusionPathCollection objects containing the infills generated now /// and the thin fills generated by generate_perimeters().
// and the thin fills generated by generate_perimeters().
void void
LayerRegion::make_fill() LayerRegion::make_fill()
{ {
@ -210,7 +211,7 @@ LayerRegion::make_fill()
// calculate flow spacing for infill pattern generation // calculate flow spacing for infill pattern generation
bool using_internal_flow = false; bool using_internal_flow = false;
if (!surface.is_solid() && !is_bridge) { if (!surface.is_solid() && !is_bridge) {
// it's internal infill, so we can calculate a generic flow spacing // it's internal infill, so we can calculate a generic flow spacing
// for all layers, for avoiding the ugly effect of // for all layers, for avoiding the ugly effect of
// misaligned infill on first layer because of different extrusion width and // misaligned infill on first layer because of different extrusion width and
// layer height // layer height