Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::LayerRegion Class Reference

#include <src/libslic3r/Layer.hpp>

+ Collaboration diagram for Slic3r::LayerRegion:

Public Member Functions

Layerlayer ()
 
const Layerlayer () const
 
const PrintRegionregion () const
 
const SurfaceCollectionslices () const
 
const ExPolygonsfill_expolygons () const
 
const BoundingBoxesfill_expolygons_bboxes () const
 
const ExPolygonsfill_expolygons_composite () const
 
const BoundingBoxesfill_expolygons_composite_bboxes () const
 
const SurfaceCollectionfill_surfaces () const
 
const ExtrusionEntityCollectionthin_fills () const
 
const Polylinesunsupported_bridge_edges () const
 
const ExtrusionEntityCollectionperimeters () const
 
const ExtrusionEntityCollectionfills () const
 
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 ()
 
void make_perimeters (const SurfaceCollection &slices, std::vector< std::pair< ExtrusionRange, ExtrusionRange > > &perimeter_and_gapfill_ranges, ExPolygons &fill_expolygons, std::vector< ExPolygonRange > &fill_expolygons_ranges)
 
void process_external_surfaces (const Layer *lower_layer, const Polygons *lower_layer_covered)
 
double infill_area_threshold () const
 
void trim_surfaces (const Polygons &trimming_polygons)
 
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
 
void export_region_slices_to_svg_debug (const char *name) const
 
void export_region_fill_surfaces_to_svg_debug (const char *name) const
 
bool has_extrusions () const
 

Public Attributes

SurfaceCollection m_slices
 

Protected Member Functions

 LayerRegion (Layer *layer, const PrintRegion *region)
 
 ~LayerRegion ()=default
 

Private Attributes

Layerm_layer
 
const PrintRegionm_region
 
ExPolygons m_raw_slices
 
ExPolygons m_fill_expolygons
 
BoundingBoxes m_fill_expolygons_bboxes
 
ExPolygons m_fill_expolygons_composite
 
BoundingBoxes m_fill_expolygons_composite_bboxes
 
SurfaceCollection m_fill_surfaces
 
ExtrusionEntityCollection m_thin_fills
 
Polylines m_unsupported_bridge_edges
 
ExtrusionEntityCollection m_perimeters
 
ExtrusionEntityCollection m_fills
 

Friends

class Layer
 
class PrintObject
 
std::string fix_slicing_errors (LayerPtrs &, const std::function< void()> &)
 
template<typename ThrowOnCancel >
void apply_mm_segmentation (PrintObject &print_object, ThrowOnCancel throw_on_cancel)
 

Detailed Description

Constructor & Destructor Documentation

◆ LayerRegion()

Slic3r::LayerRegion::LayerRegion ( Layer layer,
const PrintRegion region 
)
inlineprotected
Layer * m_layer
Definition Layer.hpp:183
const PrintRegion & region() const
Definition Layer.hpp:99
Layer * layer()
Definition Layer.hpp:97
const PrintRegion * m_region
Definition Layer.hpp:184

◆ ~LayerRegion()

Slic3r::LayerRegion::~LayerRegion ( )
protecteddefault

Member Function Documentation

◆ bridging_flow()

Flow Slic3r::LayerRegion::bridging_flow ( FlowRole  role,
bool  force_thick_bridges = false 
) const
33{
34 const PrintRegion &region = this->region();
35 const PrintRegionConfig &region_config = region.config();
36 const PrintObject &print_object = *this->layer()->object();
37 if (print_object.config().thick_bridges || force_thick_bridges) {
38 // The old Slic3r way (different from all other slicers): Use rounded extrusions.
39 // Get the configured nozzle_diameter for the extruder associated to the flow role requested.
40 // Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right.
41 auto nozzle_diameter = float(print_object.print()->config().nozzle_diameter.get_at(region.extruder(role) - 1));
42 // Applies default bridge spacing.
43 return Flow::bridging_flow(float(sqrt(region_config.bridge_flow_ratio)) * nozzle_diameter, nozzle_diameter);
44 } else {
45 // The same way as other slicers: Use normal extrusions. Apply bridge_flow_ratio while maintaining the original spacing.
46 return this->flow(role).with_flow_ratio(region_config.bridge_flow_ratio);
47 }
48}
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152
Flow with_flow_ratio(double ratio) const
Definition Flow.hpp:95
static Flow bridging_flow(float dmr, float nozzle_diameter)
Definition Flow.hpp:97
PrintObject * object()
Definition Layer.hpp:317
friend class PrintObject
Definition Layer.hpp:172
Flow flow(FlowRole role) const
Definition LayerRegion.cpp:22
const PrintRegionConfig & config() const
Definition Print.hpp:87
unsigned int extruder(FlowRole role) const
Definition PrintRegion.cpp:7
PrintRegionConfig
Definition PrintConfig.hpp:840

References Slic3r::Flow::bridging_flow(), Slic3r::PrintRegion::config(), Slic3r::PrintObject::config(), Slic3r::Print::config(), Slic3r::PrintRegion::extruder(), flow(), layer(), Slic3r::Layer::object(), Slic3r::PrintObjectBaseWithState< PrintType, PrintObjectStepEnumType, COUNT >::print(), Slic3r::PrintRegionConfig, region(), sqrt(), and Slic3r::Flow::with_flow_ratio().

Referenced by Slic3r::group_fills(), make_perimeters(), and Slic3r::FFFSupport::remove_bridges_from_contacts().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ elephant_foot_compensation_step()

void Slic3r::LayerRegion::elephant_foot_compensation_step ( const float  elephant_foot_compensation_perimeter_step,
const Polygons trimming_polygons 
)
845{
846#ifndef NDEBUG
847 for (const Surface &surface : this->slices())
848 assert(surface.surface_type == stInternal);
849#endif /* NDEBUG */
850 Polygons tmp = intersection(this->slices().surfaces, trimming_polygons);
851 append(tmp, diff(this->slices().surfaces, opening(this->slices().surfaces, elephant_foot_compensation_perimeter_step)));
853}
const SurfaceCollection & slices() const
Definition Layer.hpp:103
SurfaceCollection m_slices
Definition Layer.hpp:195
void set(const SurfaceCollection &coll)
Definition SurfaceCollection.hpp:59
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:15
Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, ClipperLib::PolyFillType fill_type)
Definition ClipperUtils.cpp:774
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:686
@ stInternal
Definition Surface.hpp:17
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:110
Slic3r::Polygons opening(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:608
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:672

References Slic3r::diff(), Slic3r::intersection(), Slic3r::opening(), Slic3r::stInternal, and Slic3r::union_ex().

+ Here is the call graph for this function:

◆ export_region_fill_surfaces_to_svg()

void Slic3r::LayerRegion::export_region_fill_surfaces_to_svg ( const char *  path) const
883{
884 BoundingBox bbox;
885 for (const Surface &surface : this->fill_surfaces())
886 bbox.merge(get_extents(surface.expolygon));
888 Point legend_pos(bbox.min(0), bbox.max(1));
889 bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
890
891 SVG svg(path, bbox);
892 const float transparency = 0.5f;
893 for (const Surface &surface : this->fill_surfaces()) {
894 svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
895 svg.draw_outline(surface.expolygon, "black", "blue", scale_(0.05));
896 }
897 export_surface_type_legend_to_svg(svg, legend_pos);
898 svg.Close();
899}
const SurfaceCollection & fill_surfaces() const
Definition Layer.hpp:118
#define scale_(val)
Definition libslic3r.h:69
BoundingBox get_extents(const ExPolygon &expolygon)
Definition ExPolygon.cpp:352
const char * surface_type_to_color_name(const SurfaceType surface_type)
Definition Surface.cpp:34
void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
Definition Surface.cpp:54
Point export_surface_type_legend_to_svg_box_size()
Definition Surface.cpp:49
TMultiShape< PolygonImpl > merge(const TMultiShape< PolygonImpl > &shapes)
Definition geometries.hpp:259
Kernel::Point_2 Point
Definition point_areas.cpp:20

References Slic3r::SVG::Close(), Slic3r::SVG::draw(), Slic3r::SVG::draw_outline(), Slic3r::export_surface_type_legend_to_svg(), Slic3r::export_surface_type_legend_to_svg_box_size(), Slic3r::get_extents(), Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, scale_, and Slic3r::surface_type_to_color_name().

+ Here is the call graph for this function:

◆ export_region_fill_surfaces_to_svg_debug()

void Slic3r::LayerRegion::export_region_fill_surfaces_to_svg_debug ( const char *  name) const
903{
904 static std::map<std::string, size_t> idx_map;
905 size_t &idx = idx_map[name];
906 this->export_region_fill_surfaces_to_svg(debug_out_path("LayerRegion-fill_surfaces-%s-%d.svg", name, idx ++).c_str());
907}
void export_region_fill_surfaces_to_svg(const char *path) const
Definition LayerRegion.cpp:882
std::string debug_out_path(const char *name,...)
Definition utils.cpp:218

References Slic3r::debug_out_path().

Referenced by Slic3r::PrintObject::discover_horizontal_shells(), Slic3r::PrintObject::discover_vertical_shells(), and Slic3r::PrintObject::prepare_infill().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ export_region_slices_to_svg()

void Slic3r::LayerRegion::export_region_slices_to_svg ( const char *  path) const
856{
857 BoundingBox bbox;
858 for (const Surface &surface : this->slices())
859 bbox.merge(get_extents(surface.expolygon));
861 Point legend_pos(bbox.min(0), bbox.max(1));
862 bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
863
864 SVG svg(path, bbox);
865 const float transparency = 0.5f;
866 for (const Surface &surface : this->slices())
867 svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
868 for (const Surface &surface : this->fill_surfaces())
869 svg.draw(surface.expolygon.lines(), surface_type_to_color_name(surface.surface_type));
870 export_surface_type_legend_to_svg(svg, legend_pos);
871 svg.Close();
872}
void draw(const IconManager::Icon &icon, const ImVec2 &size, const ImVec4 &tint_col, const ImVec4 &border_col)
Draw imgui image with icon.
Definition IconManager.cpp:164

References Slic3r::SVG::Close(), Slic3r::SVG::draw(), Slic3r::export_surface_type_legend_to_svg(), Slic3r::export_surface_type_legend_to_svg_box_size(), Slic3r::get_extents(), Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, and Slic3r::surface_type_to_color_name().

+ Here is the call graph for this function:

◆ export_region_slices_to_svg_debug()

void Slic3r::LayerRegion::export_region_slices_to_svg_debug ( const char *  name) const
876{
877 static std::map<std::string, size_t> idx_map;
878 size_t &idx = idx_map[name];
879 this->export_region_slices_to_svg(debug_out_path("LayerRegion-slices-%s-%d.svg", name, idx ++).c_str());
880}
void export_region_slices_to_svg(const char *path) const
Definition LayerRegion.cpp:855

References Slic3r::debug_out_path().

Referenced by Slic3r::PrintObject::detect_surfaces_type(), Slic3r::PrintObject::discover_horizontal_shells(), Slic3r::PrintObject::discover_vertical_shells(), and Slic3r::PrintObject::prepare_infill().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fill_expolygons()

const ExPolygons & Slic3r::LayerRegion::fill_expolygons ( ) const
inline
107{ return m_fill_expolygons; }
ExPolygons m_fill_expolygons
Definition Layer.hpp:200

References m_fill_expolygons.

Referenced by Slic3r::PrintObject::discover_vertical_shells(), Slic3r::insert_fills_into_islands(), make_perimeters(), slices_to_fill_surfaces_clipped(), and Slic3r::Layer::sort_perimeters_into_islands().

+ Here is the caller graph for this function:

◆ fill_expolygons_bboxes()

const BoundingBoxes & Slic3r::LayerRegion::fill_expolygons_bboxes ( ) const
inline
109{ return m_fill_expolygons_bboxes; }
BoundingBoxes m_fill_expolygons_bboxes
Definition Layer.hpp:202

References m_fill_expolygons_bboxes.

Referenced by Slic3r::insert_fills_into_islands().

+ Here is the caller graph for this function:

◆ fill_expolygons_composite()

const ExPolygons & Slic3r::LayerRegion::fill_expolygons_composite ( ) const
inline
ExPolygons m_fill_expolygons_composite
Definition Layer.hpp:205

References m_fill_expolygons_composite.

Referenced by Slic3r::Layer::sort_perimeters_into_islands().

+ Here is the caller graph for this function:

◆ fill_expolygons_composite_bboxes()

const BoundingBoxes & Slic3r::LayerRegion::fill_expolygons_composite_bboxes ( ) const
inline
BoundingBoxes m_fill_expolygons_composite_bboxes
Definition Layer.hpp:207

References m_fill_expolygons_composite_bboxes.

◆ fill_surfaces()

const SurfaceCollection & Slic3r::LayerRegion::fill_surfaces ( ) const
inline
118{ return m_fill_surfaces; }
SurfaceCollection m_fill_surfaces
Definition Layer.hpp:210

References m_fill_surfaces.

Referenced by Slic3r::PrintObject::discover_vertical_shells(), Slic3r::group_fills(), and Slic3r::FFFSupport::remove_bridges_from_contacts().

+ Here is the caller graph for this function:

◆ fills()

const ExtrusionEntityCollection & Slic3r::LayerRegion::fills ( ) const
inline
134{ return m_fills; }
ExtrusionEntityCollection m_fills
Definition Layer.hpp:226

References m_fills.

Referenced by Slic3r::DoExport::autospeed_volumetric_limit(), Slic3r::SupportSpotsGenerator::build_object_part_from_slice(), Slic3r::SupportSpotsGenerator::check_stability(), has_extrusions(), Slic3r::insert_fills_into_islands(), Slic3r::Layer::make_fills(), and Slic3r::GCode::process_layer_single_object().

+ Here is the caller graph for this function:

◆ flow() [1/2]

Flow Slic3r::LayerRegion::flow ( FlowRole  role) const
23{
24 return this->flow(role, m_layer->height);
25}
coordf_t height
Definition Layer.hpp:325

References flow(), Slic3r::Layer::height, and m_layer.

Referenced by bridging_flow(), Slic3r::detect_overhangs(), Slic3r::PrintObject::detect_surfaces_type(), Slic3r::PrintObject::discover_vertical_shells(), flow(), Slic3r::SupportSpotsGenerator::get_flow_width(), Slic3r::group_fills(), make_perimeters(), and Slic3r::SeamPlacerImpl::process_perimeter_polygon().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flow() [2/2]

Flow Slic3r::LayerRegion::flow ( FlowRole  role,
double  layer_height 
) const
28{
29 return m_region->flow(*m_layer->object(), role, layer_height, m_layer->id() == 0);
30}
size_t id() const
Definition Layer.hpp:315
Flow flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer=false) const
Definition PrintRegion.cpp:21
layer_height((ConfigOptionInt, faded_layers))((ConfigOptionFloat

References Slic3r::PrintRegion::flow(), Slic3r::Layer::id(), Slic3r::layer_height(), m_layer, m_region, and Slic3r::Layer::object().

+ Here is the call graph for this function:

◆ has_extrusions()

bool Slic3r::LayerRegion::has_extrusions ( ) const
inline
168{ return ! this->perimeters().empty() || ! this->fills().empty(); }
bool empty() const
Definition ExtrusionEntityCollection.hpp:65
const ExtrusionEntityCollection & fills() const
Definition Layer.hpp:134
const ExtrusionEntityCollection & perimeters() const
Definition Layer.hpp:130

References Slic3r::ExtrusionEntityCollection::empty(), fills(), and perimeters().

+ Here is the call graph for this function:

◆ infill_area_threshold()

double Slic3r::LayerRegion::infill_area_threshold ( ) const
830{
831 double ss = this->flow(frSolidInfill).scaled_spacing();
832 return ss*ss;
833}
coord_t scaled_spacing() const
Definition Flow.hpp:67
@ frSolidInfill
Definition Flow.hpp:20

References Slic3r::frSolidInfill.

◆ layer() [1/2]

Layer * Slic3r::LayerRegion::layer ( )
inline
97{ return m_layer; }

References m_layer.

Referenced by bridging_flow(), Slic3r::SupportSpotsGenerator::check_extrusion_entity_stability(), Slic3r::Layer::generate_sparse_infill_polylines_for_anchoring(), Slic3r::Layer::make_fills(), and make_perimeters().

+ Here is the caller graph for this function:

◆ layer() [2/2]

const Layer * Slic3r::LayerRegion::layer ( ) const
inline
98{ return m_layer; }

References m_layer.

◆ make_perimeters()

void Slic3r::LayerRegion::make_perimeters ( const SurfaceCollection slices,
std::vector< std::pair< ExtrusionRange, ExtrusionRange > > &  perimeter_and_gapfill_ranges,
ExPolygons fill_expolygons,
std::vector< ExPolygonRange > &  fill_expolygons_ranges 
)
77{
80
81 perimeter_and_gapfill_ranges.reserve(perimeter_and_gapfill_ranges.size() + slices.size());
82 // There may be more expolygons produced per slice, thus this reserve is conservative.
83 fill_expolygons.reserve(fill_expolygons.size() + slices.size());
84 fill_expolygons_ranges.reserve(fill_expolygons_ranges.size() + slices.size());
85
86 const PrintConfig &print_config = this->layer()->object()->print()->config();
87 const PrintRegionConfig &region_config = this->region().config();
88 // This needs to be in sync with PrintObject::_slice() slicing_mode_normal_below_layer!
89 bool spiral_vase = print_config.spiral_vase &&
90 //FIXME account for raft layers.
91 (this->layer()->id() >= size_t(region_config.bottom_solid_layers.value) &&
92 this->layer()->print_z >= region_config.bottom_solid_min_thickness - EPSILON);
93
94 PerimeterGenerator::Parameters params(
95 this->layer()->height,
96 int(this->layer()->id()),
97 this->flow(frPerimeter),
100 this->flow(frSolidInfill),
101 region_config,
102 this->layer()->object()->config(),
103 print_config,
104 spiral_vase
105 );
106
107 // Cummulative sum of polygons over all the regions.
108 const ExPolygons *lower_slices = this->layer()->lower_layer ? &this->layer()->lower_layer->lslices : nullptr;
109 // Cache for offsetted lower_slices
110 Polygons lower_layer_polygons_cache;
111
112 for (const Surface &surface : slices) {
113 auto perimeters_begin = uint32_t(m_perimeters.size());
114 auto gap_fills_begin = uint32_t(m_thin_fills.size());
115 auto fill_expolygons_begin = uint32_t(fill_expolygons.size());
116 if (this->layer()->object()->config().perimeter_generator.value == PerimeterGeneratorType::Arachne && !spiral_vase)
118 // input:
119 params,
120 surface,
121 lower_slices,
122 lower_layer_polygons_cache,
123 // output:
127 else
129 // input:
130 params,
131 surface,
132 lower_slices,
133 lower_layer_polygons_cache,
134 // output:
138 perimeter_and_gapfill_ranges.emplace_back(
139 ExtrusionRange{ perimeters_begin, uint32_t(m_perimeters.size()) },
140 ExtrusionRange{ gap_fills_begin, uint32_t(m_thin_fills.size()) });
141 fill_expolygons_ranges.emplace_back(ExtrusionRange{ fill_expolygons_begin, uint32_t(fill_expolygons.size()) });
142 }
143}
size_t size() const
Definition ExtrusionEntityCollection.hpp:117
void clear()
Definition ExtrusionEntityCollection.cpp:42
ExPolygons lslices
Definition Layer.hpp:339
coordf_t print_z
Definition Layer.hpp:324
Layer * lower_layer
Definition Layer.hpp:321
Flow bridging_flow(FlowRole role, bool force_thick_bridges=false) const
Definition LayerRegion.cpp:32
const ExPolygons & fill_expolygons() const
Definition Layer.hpp:107
ExtrusionEntityCollection m_perimeters
Definition Layer.hpp:222
ExtrusionEntityCollection m_thin_fills
Definition Layer.hpp:215
const PrintConfig & config() const
Definition Print.hpp:597
PrintType * print()
Definition PrintBase.hpp:735
size_t size() const
Definition SurfaceCollection.hpp:45
static constexpr double EPSILON
Definition libslic3r.h:51
void process_classic(const Parameters &params, const Surface &surface, const ExPolygons *lower_slices, Polygons &lower_slices_polygons_cache, ExtrusionEntityCollection &out_loops, ExtrusionEntityCollection &out_gap_fill, ExPolygons &out_fill_expolygons)
Definition PerimeterGenerator.cpp:1321
void process_arachne(const Parameters &params, const Surface &surface, const ExPolygons *lower_slices, Polygons &lower_slices_polygons_cache, ExtrusionEntityCollection &out_loops, ExtrusionEntityCollection &out_gap_fill, ExPolygons &out_fill_expolygons)
Definition PerimeterGenerator.cpp:1075
IndexRange< uint32_t > ExtrusionRange
Definition Layer.hpp:65
@ frExternalPerimeter
Definition Flow.hpp:17
@ frPerimeter
Definition Flow.hpp:18
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:13
unsigned __int32 uint32_t
Definition unistd.h:79

References Slic3r::Arachne, bridging_flow(), Slic3r::ExtrusionEntityCollection::clear(), Slic3r::PrintRegion::config(), Slic3r::Print::config(), EPSILON, fill_expolygons(), flow(), Slic3r::frExternalPerimeter, Slic3r::frPerimeter, Slic3r::frSolidInfill, Slic3r::Layer::id(), layer(), Slic3r::Layer::lower_layer, Slic3r::Layer::lslices, m_perimeters, m_thin_fills, Slic3r::Layer::object(), Slic3r::PrintObjectBaseWithState< PrintType, PrintObjectStepEnumType, COUNT >::print(), Slic3r::Layer::print_z, Slic3r::PrintRegionConfig, Slic3r::PerimeterGenerator::process_arachne(), Slic3r::PerimeterGenerator::process_classic(), region(), Slic3r::ExtrusionEntityCollection::size(), Slic3r::SurfaceCollection::size(), and slices().

Referenced by Slic3r::Layer::make_perimeters().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ perimeters()

const ExtrusionEntityCollection & Slic3r::LayerRegion::perimeters ( ) const
inline

◆ prepare_fill_surfaces()

void Slic3r::LayerRegion::prepare_fill_surfaces ( )
788{
789#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
790 export_region_slices_to_svg_debug("2_prepare_fill_surfaces-initial");
791 export_region_fill_surfaces_to_svg_debug("2_prepare_fill_surfaces-initial");
792#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
793
794 /* Note: in order to make the psPrepareInfill step idempotent, we should never
795 alter fill_surfaces boundaries on which our idempotency relies since that's
796 the only meaningful information returned by psPerimeters. */
797
798 bool spiral_vase = this->layer()->object()->print()->config().spiral_vase;
799
800 // if no solid layers are requested, turn top/bottom surfaces to internal
801 // For Lightning infill, infill_only_where_needed is ignored because both
802 // do a similar thing, and their combination doesn't make much sense.
803 if (! spiral_vase && this->region().config().top_solid_layers == 0) {
804 for (Surface &surface : m_fill_surfaces)
805 if (surface.is_top())
806 surface.surface_type = /*this->layer()->object()->config().infill_only_where_needed && this->region().config().fill_pattern != ipLightning ? stInternalVoid :*/ stInternal;
807 }
808 if (this->region().config().bottom_solid_layers == 0) {
809 for (Surface &surface : m_fill_surfaces)
810 if (surface.is_bottom()) // (surface.surface_type == stBottom)
811 surface.surface_type = stInternal;
812 }
813
814 // turn too small internal regions into solid regions according to the user setting
815 if (! spiral_vase && this->region().config().fill_density.value > 0) {
816 // scaling an area requires two calls!
817 double min_area = scale_(scale_(this->region().config().solid_infill_below_area.value));
818 for (Surface &surface : m_fill_surfaces)
819 if (surface.surface_type == stInternal && surface.area() <= min_area)
820 surface.surface_type = stInternalSolid;
821 }
822
823#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
824 export_region_slices_to_svg_debug("2_prepare_fill_surfaces-final");
825 export_region_fill_surfaces_to_svg_debug("2_prepare_fill_surfaces-final");
826#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
827}
void export_region_fill_surfaces_to_svg_debug(const char *name) const
Definition LayerRegion.cpp:902
void export_region_slices_to_svg_debug(const char *name) const
Definition LayerRegion.cpp:875
if(!(yy_init))
Definition lexer.c:1190
top_solid_layers((ConfigOptionFloat, top_solid_min_thickness))((ConfigOptionFloatOrPercent
fill_density((ConfigOptionEnum< InfillPattern >, fill_pattern))((ConfigOptionEnum< FuzzySkinType >
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:467
@ stInternalSolid
Definition Surface.hpp:19

References Slic3r::fill_density(), scale_, Slic3r::stInternal, Slic3r::stInternalSolid, and Slic3r::top_solid_layers().

+ Here is the call graph for this function:

◆ process_external_surfaces()

void Slic3r::LayerRegion::process_external_surfaces ( const Layer lower_layer,
const Polygons lower_layer_covered 
)
404{
405 using namespace Slic3r::Algorithm;
406
407#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
408 export_region_fill_surfaces_to_svg_debug("4_process_external_surfaces-initial");
409#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
410
411 // Width of the perimeters.
412 float shell_width = 0;
413 float expansion_min = 0;
414 if (int num_perimeters = this->region().config().perimeters; num_perimeters > 0) {
415 Flow external_perimeter_flow = this->flow(frExternalPerimeter);
416 Flow perimeter_flow = this->flow(frPerimeter);
417 shell_width = 0.5f * external_perimeter_flow.scaled_width() + external_perimeter_flow.scaled_spacing();
418 shell_width += perimeter_flow.scaled_spacing() * (num_perimeters - 1);
419 expansion_min = perimeter_flow.scaled_spacing();
420 } else {
421 // TODO: Maybe there is better solution when printing with zero perimeters, but this works reasonably well, given the situation
422 shell_width = float(SCALED_EPSILON);
423 expansion_min = float(SCALED_EPSILON);;
424 }
425
426 // Scaled expansions of the respective external surfaces.
427 float expansion_top = shell_width * sqrt(2.);
428 float expansion_bottom = expansion_top;
429 float expansion_bottom_bridge = expansion_top;
430 // Expand by waves of expansion_step size (expansion_step is scaled), but with no more steps than max_nr_expansion_steps.
431 static constexpr const float expansion_step = scaled<float>(0.1);
432 // Don't take more than max_nr_steps for small expansion_step.
433 static constexpr const size_t max_nr_expansion_steps = 5;
434 // Radius (with added epsilon) to absorb empty regions emering from regularization of ensuring, viz const float narrow_ensure_vertical_wall_thickness_region_radius = 0.5f * 0.65f * min_perimeter_infill_spacing;
435 const float closing_radius = 0.55f * 0.65f * 1.05f * this->flow(frSolidInfill).scaled_spacing();
436
437 // Expand the top / bottom / bridge surfaces into the shell thickness solid infills.
438 double layer_thickness;
439 ExPolygons shells = union_ex(fill_surfaces_extract_expolygons(m_fill_surfaces.surfaces, { stInternalSolid }, layer_thickness));
441
442 SurfaceCollection bridges;
443 const auto expansion_params_into_sparse_infill = RegionExpansionParameters::build(expansion_min, expansion_step, max_nr_expansion_steps);
444 {
445 BOOST_LOG_TRIVIAL(trace) << "Processing external surface, detecting bridges. layer" << this->layer()->print_z;
446 const double custom_angle = this->region().config().bridge_angle.value;
447 const auto expansion_params_into_solid_infill = RegionExpansionParameters::build(expansion_bottom_bridge, expansion_step, max_nr_expansion_steps);
448 bridges.surfaces = custom_angle > 0 ?
449 expand_merge_surfaces(m_fill_surfaces.surfaces, stBottomBridge, shells, expansion_params_into_solid_infill, sparse, expansion_params_into_sparse_infill, closing_radius, Geometry::deg2rad(custom_angle)) :
450 expand_bridges_detect_orientations(m_fill_surfaces.surfaces, shells, expansion_params_into_solid_infill, sparse, expansion_params_into_sparse_infill, closing_radius);
451 BOOST_LOG_TRIVIAL(trace) << "Processing external surface, detecting bridges - done";
452#if 0
453 {
454 static int iRun = 0;
455 bridges.export_to_svg(debug_out_path("bridges-after-grouping-%d.svg", iRun++), true);
456 }
457#endif
458 }
459
461 RegionExpansionParameters::build(expansion_bottom, expansion_step, max_nr_expansion_steps),
462 sparse, expansion_params_into_sparse_infill, closing_radius);
464 RegionExpansionParameters::build(expansion_top, expansion_step, max_nr_expansion_steps),
465 sparse, expansion_params_into_sparse_infill, closing_radius);
466
467// m_fill_surfaces.remove_types({ stBottomBridge, stBottom, stTop, stInternal, stInternalSolid });
469 reserve_more(m_fill_surfaces.surfaces, shells.size() + sparse.size() + bridges.size() + bottoms.size() + tops.size());
470 {
471 Surface solid_templ(stInternalSolid, {});
472 solid_templ.thickness = layer_thickness;
473 m_fill_surfaces.append(std::move(shells), solid_templ);
474 }
475 {
476 Surface sparse_templ(stInternal, {});
477 sparse_templ.thickness = layer_thickness;
478 m_fill_surfaces.append(std::move(sparse), sparse_templ);
479 }
480 m_fill_surfaces.append(std::move(bridges.surfaces));
481 m_fill_surfaces.append(std::move(bottoms));
482 m_fill_surfaces.append(std::move(tops));
483
484#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
485 export_region_fill_surfaces_to_svg_debug("4_process_external_surfaces-final");
486#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
487}
Definition Flow.hpp:52
coord_t scaled_width() const
Definition Flow.hpp:61
Definition SurfaceCollection.hpp:12
Surfaces surfaces
Definition SurfaceCollection.hpp:14
void export_to_svg(const char *path, bool show_labels)
Definition SurfaceCollection.cpp:140
void append(const SurfaceCollection &coll)
Definition SurfaceCollection.hpp:68
void clear()
Definition SurfaceCollection.hpp:43
Definition Surface.hpp:32
double thickness
Definition Surface.hpp:36
#define SCALED_EPSILON
Definition libslic3r.h:71
Definition PathSorting.hpp:18
constexpr T deg2rad(const T angle)
Definition Geometry.hpp:289
static ExPolygons fill_surfaces_extract_expolygons(Surfaces &surfaces, std::initializer_list< SurfaceType > surface_types, double &thickness)
Definition LayerRegion.cpp:148
void reserve_more(VectorType &vector, size_t n)
Definition Utils.hpp:184
Surfaces expand_bridges_detect_orientations(Surfaces &surfaces, ExPolygons &shells, const Algorithm::RegionExpansionParameters &expansion_params_into_solid_infill, ExPolygons &sparse, const Algorithm::RegionExpansionParameters &expansion_params_into_sparse_infill, const float closing_radius)
Definition LayerRegion.cpp:170
std::vector< Surface > Surfaces
Definition Surface.hpp:97
@ stTop
Definition Surface.hpp:11
@ stBottomBridge
Definition Surface.hpp:15
@ stBottom
Definition Surface.hpp:13
static Surfaces expand_merge_surfaces(Surfaces &surfaces, SurfaceType surface_type, ExPolygons &shells, const Algorithm::RegionExpansionParameters &expansion_params_into_solid_infill, ExPolygons &sparse, const Algorithm::RegionExpansionParameters &expansion_params_into_sparse_infill, const float closing_radius, const double bridge_angle=-1.)
Definition LayerRegion.cpp:353
IGL_INLINE void sparse(const IndexVector &I, const IndexVector &J, const ValueVector &V, Eigen::SparseMatrix< T > &X)
Definition sparse.cpp:14

References Slic3r::debug_out_path(), Slic3r::expand_bridges_detect_orientations(), Slic3r::expand_merge_surfaces(), Slic3r::SurfaceCollection::export_to_svg(), Slic3r::fill_surfaces_extract_expolygons(), Slic3r::frExternalPerimeter, Slic3r::frPerimeter, Slic3r::frSolidInfill, Slic3r::reserve_more(), SCALED_EPSILON, Slic3r::Flow::scaled_spacing(), Slic3r::Flow::scaled_width(), Slic3r::SurfaceCollection::size(), sqrt(), Slic3r::stBottom, Slic3r::stBottomBridge, Slic3r::stInternal, Slic3r::stInternalSolid, Slic3r::stTop, Slic3r::SurfaceCollection::surfaces, Slic3r::Surface::thickness, and Slic3r::union_ex().

+ Here is the call graph for this function:

◆ region()

const PrintRegion & Slic3r::LayerRegion::region ( ) const
inline

◆ slices()

const SurfaceCollection & Slic3r::LayerRegion::slices ( ) const
inline
103{ return m_slices; }

References m_slices.

Referenced by Slic3r::detect_overhangs(), Slic3r::PrintObject::detect_surfaces_type(), Slic3r::PrintObject::discover_vertical_shells(), Slic3r::get_extents(), Slic3r::Layer::make_ironing(), Slic3r::Layer::make_perimeters(), make_perimeters(), slices_to_fill_surfaces_clipped(), and Slic3r::Layer::sort_perimeters_into_islands().

+ Here is the caller graph for this function:

◆ slices_to_fill_surfaces_clipped()

void Slic3r::LayerRegion::slices_to_fill_surfaces_clipped ( )
52{
53 // Collect polygons per surface type.
54 std::array<std::vector<const Surface*>, size_t(stCount)> by_surface;
55 for (const Surface &surface : this->slices())
56 by_surface[size_t(surface.surface_type)].emplace_back(&surface);
57 // Trim surfaces by the fill_boundaries.
59 for (size_t surface_type = 0; surface_type < size_t(stCount); ++ surface_type) {
60 const std::vector<const Surface*> &this_surfaces = by_surface[surface_type];
61 if (! this_surfaces.empty())
62 m_fill_surfaces.append(intersection_ex(this_surfaces, this->fill_expolygons()), SurfaceType(surface_type));
63 }
64}
Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:755
SurfaceType
Definition Surface.hpp:9
@ stCount
Definition Surface.hpp:28

References Slic3r::SurfaceCollection::append(), fill_expolygons(), Slic3r::intersection_ex(), m_fill_surfaces, slices(), Slic3r::stCount, and Slic3r::SurfaceCollection::surfaces.

+ Here is the call graph for this function:

◆ thin_fills()

const ExtrusionEntityCollection & Slic3r::LayerRegion::thin_fills ( ) const
inline
123{ return m_thin_fills; }

References m_thin_fills.

Referenced by Slic3r::SupportSpotsGenerator::build_object_part_from_slice(), Slic3r::Layer::make_fills(), and Slic3r::Layer::sort_perimeters_into_islands().

+ Here is the caller graph for this function:

◆ trim_surfaces()

void Slic3r::LayerRegion::trim_surfaces ( const Polygons trimming_polygons)
836{
837#ifndef NDEBUG
838 for (const Surface &surface : this->slices())
839 assert(surface.surface_type == stInternal);
840#endif /* NDEBUG */
841 m_slices.set(intersection_ex(this->slices().surfaces, trimming_polygons), stInternal);
842}

References Slic3r::intersection_ex(), and Slic3r::stInternal.

+ Here is the call graph for this function:

◆ unsupported_bridge_edges()

const Polylines & Slic3r::LayerRegion::unsupported_bridge_edges ( ) const
inline
Polylines m_unsupported_bridge_edges
Definition Layer.hpp:218

References m_unsupported_bridge_edges.

Referenced by Slic3r::FFFSupport::remove_bridges_from_contacts().

+ Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ apply_mm_segmentation

template<typename ThrowOnCancel >
void apply_mm_segmentation ( PrintObject print_object,
ThrowOnCancel  throw_on_cancel 
)
friend
551{
552 // Returns MMU segmentation based on painting in MMU segmentation gizmo
553 std::vector<std::vector<ExPolygons>> segmentation = multi_material_segmentation_by_painting(print_object, throw_on_cancel);
554 assert(segmentation.size() == print_object.layer_count());
555 tbb::parallel_for(
556 tbb::blocked_range<size_t>(0, segmentation.size(), std::max(segmentation.size() / 128, size_t(1))),
557 [&print_object, &segmentation, throw_on_cancel](const tbb::blocked_range<size_t> &range) {
558 const auto &layer_ranges = print_object.shared_regions()->layer_ranges;
559 double z = print_object.get_layer(range.begin())->slice_z;
560 auto it_layer_range = layer_range_first(layer_ranges, z);
561 const size_t num_extruders = print_object.print()->config().nozzle_diameter.size();
562 struct ByExtruder {
563 ExPolygons expolygons;
564 BoundingBox bbox;
565 };
566 std::vector<ByExtruder> by_extruder;
567 struct ByRegion {
568 ExPolygons expolygons;
569 bool needs_merge { false };
570 };
571 std::vector<ByRegion> by_region;
572 for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
573 throw_on_cancel();
574 Layer *layer = print_object.get_layer(layer_id);
575 it_layer_range = layer_range_next(layer_ranges, it_layer_range, layer->slice_z);
576 const PrintObjectRegions::LayerRangeRegions &layer_range = *it_layer_range;
577 // Gather per extruder expolygons.
578 by_extruder.assign(num_extruders, ByExtruder());
579 by_region.assign(layer->region_count(), ByRegion());
580 bool layer_split = false;
581 for (size_t extruder_id = 0; extruder_id < num_extruders; ++ extruder_id) {
582 ByExtruder &region = by_extruder[extruder_id];
583 append(region.expolygons, std::move(segmentation[layer_id][extruder_id]));
584 if (! region.expolygons.empty()) {
585 region.bbox = get_extents(region.expolygons);
586 layer_split = true;
587 }
588 }
589 if (! layer_split)
590 continue;
591 // Split LayerRegions by by_extruder regions.
592 // layer_range.painted_regions are sorted by extruder ID and parent PrintObject region ID.
593 auto it_painted_region = layer_range.painted_regions.begin();
594 for (int region_id = 0; region_id < int(layer->region_count()); ++ region_id)
595 if (LayerRegion &layerm = *layer->get_region(region_id); ! layerm.slices().empty()) {
596 assert(layerm.region().print_object_region_id() == region_id);
597 const BoundingBox bbox = get_extents(layerm.slices().surfaces);
598 assert(it_painted_region < layer_range.painted_regions.end());
599 // Find the first it_painted_region which overrides this region.
600 for (; layer_range.volume_regions[it_painted_region->parent].region->print_object_region_id() < region_id; ++ it_painted_region)
601 assert(it_painted_region != layer_range.painted_regions.end());
602 assert(it_painted_region != layer_range.painted_regions.end());
603 assert(layer_range.volume_regions[it_painted_region->parent].region == &layerm.region());
604 // 1-based extruder ID
605 bool self_trimmed = false;
606 int self_extruder_id = -1;
607 for (int extruder_id = 1; extruder_id <= int(by_extruder.size()); ++ extruder_id)
608 if (ByExtruder &segmented = by_extruder[extruder_id - 1]; segmented.bbox.defined && bbox.overlap(segmented.bbox)) {
609 // Find the target region.
610 for (; int(it_painted_region->extruder_id) < extruder_id; ++ it_painted_region)
611 assert(it_painted_region != layer_range.painted_regions.end());
612 assert(layer_range.volume_regions[it_painted_region->parent].region == &layerm.region() && int(it_painted_region->extruder_id) == extruder_id);
613 //FIXME Don't trim by self, it is not reliable.
614 if (&layerm.region() == it_painted_region->region) {
615 self_extruder_id = extruder_id;
616 continue;
617 }
618 // Steal from this region.
619 int target_region_id = it_painted_region->region->print_object_region_id();
620 ExPolygons stolen = intersection_ex(layerm.slices().surfaces, segmented.expolygons);
621 if (! stolen.empty()) {
622 ByRegion &dst = by_region[target_region_id];
623 if (dst.expolygons.empty()) {
624 dst.expolygons = std::move(stolen);
625 } else {
626 append(dst.expolygons, std::move(stolen));
627 dst.needs_merge = true;
628 }
629 }
630#if 0
631 if (&layerm.region() == it_painted_region->region)
632 // Slices of this LayerRegion were trimmed by a MMU region of the same PrintRegion.
633 self_trimmed = true;
634#endif
635 }
636 if (! self_trimmed) {
637 // Trim slices of this LayerRegion with all the MMU regions.
638 Polygons mine = to_polygons(std::move(layerm.slices().surfaces));
639 for (auto &segmented : by_extruder)
640 if (&segmented - by_extruder.data() + 1 != self_extruder_id && segmented.bbox.defined && bbox.overlap(segmented.bbox)) {
641 mine = diff(mine, segmented.expolygons);
642 if (mine.empty())
643 break;
644 }
645 // Filter out unprintable polygons produced by subtraction multi-material painted regions from layerm.region().
646 // ExPolygon returned from multi-material segmentation does not precisely match ExPolygons in layerm.region()
647 // (because of preprocessing of the input regions in multi-material segmentation). Therefore, subtraction from
648 // layerm.region() could produce a huge number of small unprintable regions for the model's base extruder.
649 // This could, on some models, produce bulges with the model's base color (#7109).
650 if (! mine.empty())
651 mine = opening(union_ex(mine), float(scale_(5 * EPSILON)), float(scale_(5 * EPSILON)));
652 if (! mine.empty()) {
653 ByRegion &dst = by_region[layerm.region().print_object_region_id()];
654 if (dst.expolygons.empty()) {
655 dst.expolygons = union_ex(mine);
656 } else {
657 append(dst.expolygons, union_ex(mine));
658 dst.needs_merge = true;
659 }
660 }
661 }
662 }
663 // Re-create Surfaces of LayerRegions.
664 for (size_t region_id = 0; region_id < layer->region_count(); ++ region_id) {
665 ByRegion &src = by_region[region_id];
666 if (src.needs_merge)
667 // Multiple regions were merged into one.
668 src.expolygons = closing_ex(src.expolygons, float(scale_(10 * EPSILON)));
669 layer->get_region(region_id)->m_slices.set(std::move(src.expolygons), stInternal);
670 }
671 }
672 });
673}
coordf_t slice_z
Definition Layer.hpp:323
const LayerRegion * get_region(int idx) const
Definition Layer.hpp:344
size_t region_count() const
Definition Layer.hpp:343
friend class Layer
Definition Layer.hpp:171
bool empty() const
Definition SurfaceCollection.hpp:44
static std::vector< PrintObjectRegions::LayerRangeRegions >::const_iterator layer_range_next(const std::vector< PrintObjectRegions::LayerRangeRegions > &layer_ranges, std::vector< PrintObjectRegions::LayerRangeRegions >::const_iterator it, double z)
Definition PrintObjectSlice.cpp:223
auto range(Cont &&cont)
Definition libslic3r.h:356
Slic3r::ExPolygons closing_ex(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:593
Polygons to_polygons(const ExPolygon &src)
Definition ExPolygon.hpp:281
std::vector< std::vector< ExPolygons > > multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function< void()> &throw_on_cancel_callback)
Definition MultiMaterialSegmentation.cpp:1679
constexpr auto data(C &c) -> decltype(c.data())
Definition span.hpp:195

◆ fix_slicing_errors

std::string fix_slicing_errors ( LayerPtrs ,
const std::function< void()> &   
)
friend

◆ Layer

friend class Layer
friend

◆ PrintObject

friend class PrintObject
friend

Member Data Documentation

◆ m_fill_expolygons

ExPolygons Slic3r::LayerRegion::m_fill_expolygons
private

◆ m_fill_expolygons_bboxes

BoundingBoxes Slic3r::LayerRegion::m_fill_expolygons_bboxes
private

◆ m_fill_expolygons_composite

ExPolygons Slic3r::LayerRegion::m_fill_expolygons_composite
private

◆ m_fill_expolygons_composite_bboxes

BoundingBoxes Slic3r::LayerRegion::m_fill_expolygons_composite_bboxes
private

◆ m_fill_surfaces

◆ m_fills

ExtrusionEntityCollection Slic3r::LayerRegion::m_fills
private

Referenced by fills(), and Slic3r::Layer::make_fills().

◆ m_layer

Layer* Slic3r::LayerRegion::m_layer
private

Referenced by flow(), flow(), layer(), and layer().

◆ m_perimeters

ExtrusionEntityCollection Slic3r::LayerRegion::m_perimeters
private

Referenced by make_perimeters(), and perimeters().

◆ m_raw_slices

ExPolygons Slic3r::LayerRegion::m_raw_slices
private

◆ m_region

const PrintRegion* Slic3r::LayerRegion::m_region
private

Referenced by flow(), and region().

◆ m_slices

◆ m_thin_fills

ExtrusionEntityCollection Slic3r::LayerRegion::m_thin_fills
private

Referenced by make_perimeters(), and thin_fills().

◆ m_unsupported_bridge_edges

Polylines Slic3r::LayerRegion::m_unsupported_bridge_edges
private

The documentation for this class was generated from the following files: