Skip to content

Commit

Permalink
Merge branch 'ms_fix_bridge_anchoring' (see SPE-2031 for list of issues)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasmatena committed Mar 5, 2024
2 parents 5dc1699 + 78cd2f9 commit b133579
Show file tree
Hide file tree
Showing 6 changed files with 660 additions and 364 deletions.
1 change: 1 addition & 0 deletions src/libslic3r/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ set(SLIC3R_SOURCES
KDTreeIndirect.hpp
Layer.cpp
Layer.hpp
LayerRegion.hpp
LayerRegion.cpp
libslic3r.h
"${CMAKE_CURRENT_BINARY_DIR}/libslic3r_version.h"
Expand Down
175 changes: 1 addition & 174 deletions src/libslic3r/Layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "Flow.hpp"
#include "SurfaceCollection.hpp"
#include "ExtrusionEntityCollection.hpp"
#include "LayerRegion.hpp"

#include <boost/container/small_vector.hpp>

Expand All @@ -39,42 +40,6 @@ namespace FillLightning {
class Generator;
};

// Range of indices, providing support for range based loops.
template<typename T>
class IndexRange
{
public:
IndexRange(T ibegin, T iend) : m_begin(ibegin), m_end(iend) {}
IndexRange() = default;

// Just a bare minimum functionality iterator required by range-for loop.
class Iterator {
public:
T operator*() const { return m_idx; }
bool operator!=(const Iterator &rhs) const { return m_idx != rhs.m_idx; }
void operator++() { ++ m_idx; }
private:
friend class IndexRange<T>;
Iterator(T idx) : m_idx(idx) {}
T m_idx;
};

Iterator begin() const { assert(m_begin <= m_end); return Iterator(m_begin); };
Iterator end() const { assert(m_begin <= m_end); return Iterator(m_end); };

bool empty() const { assert(m_begin <= m_end); return m_begin >= m_end; }
T size() const { assert(m_begin <= m_end); return m_end - m_begin; }

private:
// Index of the first extrusion in LayerRegion.
T m_begin { 0 };
// Index of the last extrusion in LayerRegion.
T m_end { 0 };
};

using ExtrusionRange = IndexRange<uint32_t>;
using ExPolygonRange = IndexRange<uint32_t>;

// Range of extrusions, referencing the source region by an index.
class LayerExtrusionRange : public ExtrusionRange
{
Expand All @@ -101,144 +66,6 @@ using LayerExtrusionRanges =
std::vector<LayerExtrusionRange>;
#endif // NDEBUG

class LayerRegion
{
public:
[[nodiscard]] Layer* layer() { return m_layer; }
[[nodiscard]] const Layer* layer() const { return m_layer; }
[[nodiscard]] const PrintRegion& region() const { return *m_region; }

// collection of surfaces generated by slicing the original geometry
// divided by type top/bottom/internal
[[nodiscard]] const SurfaceCollection& slices() const { return m_slices; }

// Unspecified fill polygons, used for overhang detection ("ensure vertical wall thickness feature")
// and for re-starting of infills.
[[nodiscard]] const ExPolygons& fill_expolygons() const { return m_fill_expolygons; }
// and their bounding boxes
[[nodiscard]] const BoundingBoxes& fill_expolygons_bboxes() const { return m_fill_expolygons_bboxes; }
// Storage for fill regions produced for a single LayerIsland, of which infill splits into multiple islands.
// Not used for a plain single material print with no infill modifiers.
[[nodiscard]] const ExPolygons& fill_expolygons_composite() const { return m_fill_expolygons_composite; }
// and their bounding boxes
[[nodiscard]] const BoundingBoxes& fill_expolygons_composite_bboxes() const { return m_fill_expolygons_composite_bboxes; }

// collection of surfaces generated by slicing the original geometry
// divided by type top/bottom/internal
[[nodiscard]] const SurfaceCollection& fill_surfaces() const { return m_fill_surfaces; }

// collection of extrusion paths/loops filling gaps
// These fills are generated by the perimeter generator.
// They are not printed on their own, but they are copied to this->fills during infill generation.
[[nodiscard]] const ExtrusionEntityCollection& thin_fills() const { return m_thin_fills; }

// collection of polylines representing the unsupported bridge edges
[[nodiscard]] const Polylines& unsupported_bridge_edges() const { return m_unsupported_bridge_edges; }

// ordered collection of extrusion paths/loops to build all perimeters
// (this collection contains only ExtrusionEntityCollection objects)
[[nodiscard]] const ExtrusionEntityCollection& perimeters() const { return m_perimeters; }

// ordered collection of extrusion paths to fill surfaces
// (this collection contains only ExtrusionEntityCollection objects)
[[nodiscard]] const ExtrusionEntityCollection& fills() const { return m_fills; }

Flow flow(FlowRole role) const;
Flow flow(FlowRole role, double layer_height) const;
Flow bridging_flow(FlowRole role, bool force_thick_bridges = false) const;

void slices_to_fill_surfaces_clipped();
void prepare_fill_surfaces();
// Produce perimeter extrusions, gap fill extrusions and fill polygons for input slices.
void make_perimeters(
// Input slices for which the perimeters, gap fills and fill expolygons are to be generated.
const SurfaceCollection &slices,
// Ranges of perimeter extrusions and gap fill extrusions per suface, referencing
// newly created extrusions stored at this LayerRegion.
std::vector<std::pair<ExtrusionRange, ExtrusionRange>> &perimeter_and_gapfill_ranges,
// All fill areas produced for all input slices above.
ExPolygons &fill_expolygons,
// Ranges of fill areas above per input slice.
std::vector<ExPolygonRange> &fill_expolygons_ranges);
void process_external_surfaces(const Layer *lower_layer, const Polygons *lower_layer_covered);
double infill_area_threshold() const;
// Trim surfaces by trimming polygons. Used by the elephant foot compensation at the 1st layer.
void trim_surfaces(const Polygons &trimming_polygons);
// Single elephant foot compensation step, used by the elephant foor compensation at the 1st layer.
// Trim surfaces by trimming polygons (shrunk by an elephant foot compensation step), but don't shrink narrow parts so much that no perimeter would fit.
void elephant_foot_compensation_step(const float elephant_foot_compensation_perimeter_step, const Polygons &trimming_polygons);

void export_region_slices_to_svg(const char *path) const;
void export_region_fill_surfaces_to_svg(const char *path) const;
// Export to "out/LayerRegion-name-%d.svg" with an increasing index with every export.
void export_region_slices_to_svg_debug(const char *name) const;
void export_region_fill_surfaces_to_svg_debug(const char *name) const;

// Is there any valid extrusion assigned to this LayerRegion?
bool has_extrusions() const { return ! this->perimeters().empty() || ! this->fills().empty(); }

protected:
friend class Layer;
friend class PrintObject;

LayerRegion(Layer *layer, const PrintRegion *region) : m_layer(layer), m_region(region) {}
~LayerRegion() = default;

private:
// Modifying m_slices
friend std::string fix_slicing_errors(LayerPtrs&, const std::function<void()>&);
template<typename ThrowOnCancel>
friend void apply_mm_segmentation(PrintObject& print_object, ThrowOnCancel throw_on_cancel);

Layer *m_layer;
const PrintRegion *m_region;

// Backed up slices before they are split into top/bottom/internal.
// Only backed up for multi-region layers or layers with elephant foot compensation.
//FIXME Review whether not to simplify the code by keeping the raw_slices all the time.
ExPolygons m_raw_slices;

//FIXME make m_slices public for unit tests
public:
// collection of surfaces generated by slicing the original geometry
// divided by type top/bottom/internal
SurfaceCollection m_slices;

private:
// Unspecified fill polygons, used for overhang detection ("ensure vertical wall thickness feature")
// and for re-starting of infills.
ExPolygons m_fill_expolygons;
// and their bounding boxes
BoundingBoxes m_fill_expolygons_bboxes;
// Storage for fill regions produced for a single LayerIsland, of which infill splits into multiple islands.
// Not used for a plain single material print with no infill modifiers.
ExPolygons m_fill_expolygons_composite;
// and their bounding boxes
BoundingBoxes m_fill_expolygons_composite_bboxes;

// Collection of surfaces for infill generation, created by splitting m_slices by m_fill_expolygons.
SurfaceCollection m_fill_surfaces;

// Collection of extrusion paths/loops filling gaps
// These fills are generated by the perimeter generator.
// They are not printed on their own, but they are copied to this->fills during infill generation.
ExtrusionEntityCollection m_thin_fills;

// collection of polylines representing the unsupported bridge edges
Polylines m_unsupported_bridge_edges;

// ordered collection of extrusion paths/loops to build all perimeters
// (this collection contains only ExtrusionEntityCollection objects)
ExtrusionEntityCollection m_perimeters;

// ordered collection of extrusion paths to fill surfaces
// (this collection contains only ExtrusionEntityCollection objects)
ExtrusionEntityCollection m_fills;

// collection of expolygons representing the bridged areas (thus not
// needing support material)
// Polygons bridged;
};

// LayerSlice contains one or more LayerIsland objects,
// each LayerIsland containing a set of perimeter extrusions extruded with one particular PrintRegionConfig parameters
Expand Down
Loading

0 comments on commit b133579

Please sign in to comment.