OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::LayerRegion Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Layer.hpp>

Collaboration diagram for Slic3r::LayerRegion:

Public Member Functions

Layer * layer ()
const Layer * layer () const
const PrintRegion & region () const
const SurfaceCollection & get_slices () const
Flow flow (FlowRole role) const
Flow flow (FlowRole role, double layer_height) const
Flow bridging_flow (FlowRole role, bool thick_bridge=false) const
void slices_to_fill_surfaces_clipped ()
void prepare_fill_surfaces ()
void make_perimeters (const SurfaceCollection &slices, const LayerRegionPtrs &compatible_regions, SurfaceCollection *fill_surfaces, ExPolygons *fill_no_overlap)
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
void simplify_infill_extrusion_entity ()
void simplify_wall_extrusion_entity ()

Public Attributes

SurfaceCollection slices
ExPolygons raw_slices
ExtrusionEntityCollection thin_fills
ExPolygons fill_expolygons
SurfaceCollection fill_surfaces
ExPolygons fill_no_overlap_expolygons
Polylines unsupported_bridge_edges
ExtrusionEntityCollection perimeters
ExtrusionEntityCollection fills

Protected Member Functions

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

Private Member Functions

void simplify_entity_collection (ExtrusionEntityCollection *entity_collection)
void simplify_path (ExtrusionPath *path)
void simplify_multi_path (ExtrusionMultiPath *multipath)
void simplify_loop (ExtrusionLoop *loop)

Private Attributes

Layer * m_layer
const PrintRegion * m_region

Friends

class Layer
class PrintObject

Detailed Description

Constructor & Destructor Documentation

◆ LayerRegion()

Slic3r::LayerRegion::LayerRegion ( Layer * layer,
const PrintRegion * region )
inlineprotected
Layer * m_layer
Definition Layer.hpp:133
const PrintRegion & region() const
Definition Layer.hpp:52
Layer * layer()
Definition Layer.hpp:50
const PrintRegion * m_region
Definition Layer.hpp:134

References Layer, layer(), m_layer, m_region, and region().

Here is the call graph for this function:

◆ ~LayerRegion()

Slic3r::LayerRegion::~LayerRegion ( )
inlineprotected
130{}

Member Function Documentation

◆ bridging_flow()

Flow Slic3r::LayerRegion::bridging_flow ( FlowRole role,
bool thick_bridge = false ) const
59{
60 const PrintRegion &region = this->region();
61 const PrintRegionConfig &region_config = region.config();
62 const PrintObject &print_object = *this->layer()->object();
63 Flow bridge_flow;
64 // Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will fall back to zero'th element, so everything is all right.
65 auto nozzle_diameter = float(nozzle_diameter_for_filament(print_object.print()->config(), region.extruder(role), print_object.print()->is_BBL_printer()));
66 const ConfigOptionFloatOrPercent& bridge_width_opt = region_config.bridge_line_width;
67 const double bridge_width = bridge_width_opt.get_abs_value(nozzle_diameter);
68 const bool has_bridge_width = bridge_width > 0.;
69 const double bridge_flow_ratio = region_config.bridge_flow;
70
71 if (thick_bridge) {
72 // The old Slic3r way (different from all other slicers): Use rounded extrusions.
73 // Get the configured nozzle_diameter for the extruder associated to the flow role requested.
74 float thread_diameter = has_bridge_width ? float(bridge_width) : nozzle_diameter;
75 if (bridge_flow_ratio > 0.)
76 thread_diameter *= float(sqrt(bridge_flow_ratio));
78 } else {
79 // The same way as other slicers: Use normal extrusions. Apply bridge_flow while maintaining the original spacing.
80 Flow base_flow = this->flow(role);
81 if (has_bridge_width)
82 base_flow = Flow(float(bridge_width), base_flow.height(), nozzle_diameter);
83 bridge_flow = base_flow.with_flow_ratio(bridge_flow_ratio);
84 }
85 return bridge_flow;
86
87}
static Flow bridging_flow(float dmr, float nozzle_diameter)
Definition Flow.hpp:108
friend class PrintObject
Definition Layer.hpp:127
Flow flow(FlowRole role) const
Definition LayerRegion.cpp:48
PrintObject * object()
Definition Layer.hpp:143
zaa_minimize_perimeter_height nozzle_diameter((ConfigOptionBool, reduce_infill_retraction))((ConfigOptionBool
zaa_minimize_perimeter_height PrintRegionConfig
Definition PrintConfig.hpp:2183
double nozzle_diameter_for_filament(const PrintConfig &config, int filament_id, bool is_bbl_printer)
Definition PrintConfig.cpp:148
bridge_flow((ConfigOptionFloatOrPercent, bridge_line_width))((ConfigOptionFloat

References Slic3r::bridge_flow(), Slic3r::Flow::bridging_flow(), Slic3r::Print::config(), flow(), Slic3r::ConfigOptionFloatOrPercent::get_abs_value(), Slic3r::Flow::height(), Slic3r::Print::is_BBL_printer(), layer(), Slic3r::nozzle_diameter(), Slic3r::nozzle_diameter_for_filament(), Slic3r::Layer::object(), Slic3r::PrintObjectBaseWithState< PrintType, PrintObjectStepEnum, COUNT >::print(), PrintObject, Slic3r::PrintRegionConfig, region(), and Slic3r::Flow::with_flow_ratio().

Referenced by Slic3r::group_fills(), make_perimeters(), and Slic3r::SupportMaterialInternal::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 )
1021{
1022#ifndef NDEBUG
1023 for (const Surface &surface : this->slices.surfaces)
1024 assert(surface.surface_type == stInternal);
1025#endif /* NDEBUG */
1026 Polygons tmp = intersection(this->slices.surfaces, trimming_polygons);
1027 append(tmp, diff(this->slices.surfaces, opening(this->slices.surfaces, elephant_foot_compensation_perimeter_step)));
1028 this->slices.set(union_ex(tmp), stInternal);
1029}
SurfaceCollection slices
Definition Layer.hpp:58
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:769
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22
Slic3r::Polygons opening(const Slic3r::Polygons &polygons, const float delta1, const float delta2, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:696
Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, PolyFillType fill_type)
Definition ClipperUtils.cpp:1011
@ stInternal
Definition Surface.hpp:26
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:157
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:731

References Slic3r::append(), Slic3r::diff(), elephant_foot_compensation_step(), Slic3r::intersection(), Slic3r::opening(), slices, Slic3r::stInternal, Slic3r::Surface::surface_type, and Slic3r::union_ex().

Referenced by elephant_foot_compensation_step().

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

◆ export_region_fill_surfaces_to_svg()

void Slic3r::LayerRegion::export_region_fill_surfaces_to_svg ( const char * path) const
1059{
1060 BoundingBox bbox;
1061 for (Surfaces::const_iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
1062 bbox.merge(get_extents(surface->expolygon));
1064 Point legend_pos(bbox.min(0), bbox.max(1));
1065 bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
1066
1067 SVG svg(path, bbox);
1068 const float transparency = 0.5f;
1069 for (const Surface &surface : this->fill_surfaces.surfaces) {
1070 svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
1071 svg.draw_outline(surface.expolygon, "black", "blue", scale_(0.05));
1072 }
1073 export_surface_type_legend_to_svg(svg, legend_pos);
1074 svg.Close();
1075}
SurfaceCollection fill_surfaces
Definition Layer.hpp:73
#define scale_(val)
Definition libslic3r.h:106
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
BoundingBox get_extents(const ExPolygonsWithIds &e)
Definition Emboss.cpp:1374
const char * surface_type_to_color_name(const SurfaceType surface_type)
Definition Surface.cpp:39
void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
Definition Surface.cpp:59
Point export_surface_type_legend_to_svg_box_size()
Definition Surface.cpp:54

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

Referenced by export_region_fill_surfaces_to_svg(), and export_region_fill_surfaces_to_svg_debug().

Here is the call graph for this function:
Here is the caller 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
1079{
1080 static std::map<std::string, size_t> idx_map;
1081 size_t &idx = idx_map[name];
1082 this->export_region_fill_surfaces_to_svg(debug_out_path("LayerRegion-fill_surfaces-%s-%d.svg", name, idx ++).c_str());
1083}
void export_region_fill_surfaces_to_svg(const char *path) const
Definition LayerRegion.cpp:1058
std::string debug_out_path(const char *name,...)
Definition utils.cpp:382

References Slic3r::debug_out_path(), export_region_fill_surfaces_to_svg(), and export_region_fill_surfaces_to_svg_debug().

Referenced by Slic3r::PrintObject::clip_fill_surfaces(), Slic3r::PrintObject::discover_horizontal_shells(), Slic3r::PrintObject::discover_vertical_shells(), export_region_fill_surfaces_to_svg_debug(), prepare_fill_surfaces(), Slic3r::PrintObject::prepare_infill(), and process_external_surfaces().

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
1032{
1033 BoundingBox bbox;
1034 for (Surfaces::const_iterator surface = this->slices.surfaces.begin(); surface != this->slices.surfaces.end(); ++surface)
1035 bbox.merge(get_extents(surface->expolygon));
1037 Point legend_pos(bbox.min(0), bbox.max(1));
1038 bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
1039
1040 SVG svg(path, bbox);
1041 const float transparency = 0.5f;
1042 for (Surfaces::const_iterator surface = this->slices.surfaces.begin(); surface != this->slices.surfaces.end(); ++surface)
1043 svg.draw(surface->expolygon, surface_type_to_color_name(surface->surface_type), transparency);
1044 for (Surfaces::const_iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
1045 svg.draw(surface->expolygon.lines(), surface_type_to_color_name(surface->surface_type));
1046 export_surface_type_legend_to_svg(svg, legend_pos);
1047 svg.Close();
1048}

References Slic3r::SVG::Close(), Slic3r::SVG::draw(), Slic3r::Surface::expolygon, export_region_slices_to_svg(), Slic3r::export_surface_type_legend_to_svg(), Slic3r::export_surface_type_legend_to_svg_box_size(), fill_surfaces, Slic3r::get_extents(), Slic3r::ExPolygon::lines(), Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, slices, Slic3r::Surface::surface_type, and Slic3r::surface_type_to_color_name().

Referenced by export_region_slices_to_svg(), and export_region_slices_to_svg_debug().

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

◆ export_region_slices_to_svg_debug()

void Slic3r::LayerRegion::export_region_slices_to_svg_debug ( const char * name) const
1052{
1053 static std::map<std::string, size_t> idx_map;
1054 size_t &idx = idx_map[name];
1055 this->export_region_slices_to_svg(debug_out_path("LayerRegion-slices-%s-%d.svg", name, idx ++).c_str());
1056}
void export_region_slices_to_svg(const char *path) const
Definition LayerRegion.cpp:1031

References Slic3r::debug_out_path(), export_region_slices_to_svg(), and export_region_slices_to_svg_debug().

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

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

◆ flow() [1/2]

Flow Slic3r::LayerRegion::flow ( FlowRole role) const
49{
50 return this->flow(role, m_layer->height);
51}

References flow(), and m_layer.

Referenced by bridging_flow(), Slic3r::PrintObject::clip_fill_surfaces(), Slic3r::PrintObject::discover_horizontal_shells(), Slic3r::PrintObject::discover_vertical_shells(), flow(), Slic3r::SupportSpotsGenerator::get_flow_width(), Slic3r::group_fills(), infill_area_threshold(), make_perimeters(), process_external_surfaces(), 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
54{
55 return m_region->flow(*m_layer->object(), role, layer_height, m_layer->id() == 0);
56}
layer_height((ConfigOptionInt, faded_layers))((ConfigOptionFloat

References Slic3r::layer_height(), m_layer, and m_region.

Here is the call graph for this function:

◆ get_slices()

const SurfaceCollection & Slic3r::LayerRegion::get_slices ( ) const
inline
54{ return slices; }

References slices.

◆ has_extrusions()

bool Slic3r::LayerRegion::has_extrusions ( ) const
inline
115{ return ! this->perimeters.entities.empty() || ! this->fills.entities.empty(); }
ExtrusionEntityCollection perimeters
Definition Layer.hpp:86
ExtrusionEntityCollection fills
Definition Layer.hpp:90

References Slic3r::ExtrusionEntityCollection::entities.

◆ infill_area_threshold()

double Slic3r::LayerRegion::infill_area_threshold ( ) const
1006{
1007 double ss = this->flow(frSolidInfill).scaled_spacing();
1008 return ss*ss;
1009}
coord_t scaled_spacing() const
Definition Flow.hpp:71
@ frSolidInfill
Definition Flow.hpp:22

References flow(), Slic3r::frSolidInfill, and infill_area_threshold().

Referenced by infill_area_threshold().

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

◆ layer() [1/2]

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

References Layer, and m_layer.

Referenced by LayerRegion(), bridging_flow(), Slic3r::contour_extrusion_path(), Slic3r::convert_layer_region_from_json(), Slic3r::Layer::generate_sparse_infill_polylines_for_anchoring(), Slic3r::group_fills(), Slic3r::Layer::make_fills(), make_perimeters(), prepare_fill_surfaces(), process_external_surfaces(), Slic3r::SeamPlacerImpl::process_perimeter_polygon(), Slic3r::SupportMaterialInternal::remove_bridges_from_contacts(), simplify_path(), and Slic3r::to_json().

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

◆ layer() [2/2]

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

References Layer, and m_layer.

Here is the call graph for this function:

◆ make_perimeters()

void Slic3r::LayerRegion::make_perimeters ( const SurfaceCollection & slices,
const LayerRegionPtrs & compatible_regions,
SurfaceCollection * fill_surfaces,
ExPolygons * fill_no_overlap )
111{
112 this->perimeters.clear();
113 this->thin_fills.clear();
114
115 const PrintConfig &print_config = this->layer()->object()->print()->config();
116 const PrintRegionConfig &region_config = this->region().config();
117 const PrintObjectConfig& object_config = this->layer()->object()->config();
118 // This needs to be in sync with PrintObject::_slice() slicing_mode_normal_below_layer!
119 bool spiral_mode = print_config.spiral_mode &&
120 //FIXME account for raft layers.
121 (this->layer()->id() >= size_t(region_config.bottom_shell_layers.value) &&
122 this->layer()->print_z >= region_config.bottom_shell_thickness - EPSILON);
123
124 double model_rotation_rad = 0.0;
125 if (region_config.align_infill_direction_to_model) {
126 auto m = this->layer()->object()->trafo().matrix();
127 model_rotation_rad = std::atan2((double)m(1, 0), (double)m(0, 0));
128 }
129
130 PerimeterGenerator g(
131 // input:
132 &slices,
133 &compatible_regions,
134 this->layer()->height,
135 this->layer()->slice_z,
136 this->flow(frPerimeter),
137 &region_config,
138 &this->layer()->object()->config(),
139 &print_config,
140 spiral_mode,
141 model_rotation_rad,
142
143 // output:
144 &this->perimeters,
145 &this->thin_fills,
147 //BBS
148 fill_no_overlap
149 );
150
151 if (this->layer()->upper_layer != NULL)
152 g.upper_slices = &this->layer()->upper_layer->lslices;
153
154 int region_id = this->region().print_object_region_id();
155 if (this->layer()->upper_layer != NULL)
156 g.upper_slices_same_region = &this->layer()->upper_layer->get_region(region_id)->slices;
157
158 g.layer_id = (int)this->layer()->id();
159 g.ext_perimeter_flow = this->flow(frExternalPerimeter);
160 g.overhang_flow = this->bridging_flow(frPerimeter, object_config.thick_bridges);
161 g.solid_infill_flow = this->flow(frSolidInfill);
162
163 // Cumulative sum of polygons over all the regions, less what the lower layer could not print.
164 ExPolygons lower_slices;
165 if (this->layer()->lower_layer != nullptr) {
166 lower_slices = g.printable_slices(this->layer()->lower_layer->lslices);
167 g.lower_slices = &lower_slices;
168 }
169
170 if (this->layer()->object()->config().wall_generator.value == PerimeterGeneratorType::Arachne && !spiral_mode)
171 g.process_arachne();
172 else
173 g.process_classic();
174}
#define EPSILON
Definition ColorUtils.cpp:64
ExtrusionEntityCollection thin_fills
Definition Layer.hpp:67
Flow bridging_flow(FlowRole role, bool thick_bridge=false) const
Definition LayerRegion.cpp:58
Layer * upper_layer
Definition Layer.hpp:146
ExPolygons lslices
Definition Layer.hpp:170
size_t id() const
Definition Layer.hpp:141
coordf_t print_z
Definition Layer.hpp:150
const LayerRegion * get_region(int idx) const
Definition Layer.hpp:182
PrintType * print()
Definition PrintBase.hpp:637
const Transform3d & trafo() const
Definition Print.hpp:376
const PrintObjectConfig & config() const
Definition Print.hpp:372
const PrintRegionConfig & config() const
Definition Print.hpp:154
int print_object_region_id() const
Definition Print.hpp:158
const PrintConfig & config() const
Definition Print.hpp:1131
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:20
@ frExternalPerimeter
Definition Flow.hpp:19
@ frPerimeter
Definition Flow.hpp:20
zaa_minimize_perimeter_height PrintObjectConfig
Definition PrintConfig.hpp:2183
@ Arachne
Definition PrintConfig.hpp:487

References Slic3r::Arachne, bridging_flow(), Slic3r::Print::config(), Slic3r::PrintObject::config(), Slic3r::PrintRegion::config(), EPSILON, Slic3r::PerimeterGenerator::ext_perimeter_flow, fill_surfaces, flow(), Slic3r::frExternalPerimeter, Slic3r::frPerimeter, Slic3r::frSolidInfill, Slic3r::Layer::get_region(), Slic3r::Layer::id(), layer(), Slic3r::PerimeterGenerator::layer_id, Slic3r::PerimeterGenerator::lower_slices, Slic3r::Layer::lslices, Slic3r::Layer::object(), Slic3r::PerimeterGenerator::overhang_flow, perimeters, Slic3r::PrintObjectBaseWithState< PrintType, PrintObjectStepEnum, COUNT >::print(), Slic3r::PrintRegion::print_object_region_id(), Slic3r::Layer::print_z, Slic3r::PerimeterGenerator::printable_slices(), Slic3r::PrintObjectConfig, Slic3r::PrintRegionConfig, Slic3r::PerimeterGenerator::process_arachne(), Slic3r::PerimeterGenerator::process_classic(), region(), slices, Slic3r::PerimeterGenerator::solid_infill_flow, thin_fills, Slic3r::PrintObject::trafo(), Slic3r::Layer::upper_layer, Slic3r::PerimeterGenerator::upper_slices, and Slic3r::PerimeterGenerator::upper_slices_same_region.

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

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

◆ prepare_fill_surfaces()

void Slic3r::LayerRegion::prepare_fill_surfaces ( )
966{
967#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
968 export_region_slices_to_svg_debug("2_prepare_fill_surfaces-initial");
969 export_region_fill_surfaces_to_svg_debug("2_prepare_fill_surfaces-initial");
970#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
971
972 /* Note: in order to make the psPrepareInfill step idempotent, we should never
973 alter fill_surfaces boundaries on which our idempotency relies since that's
974 the only meaningful information returned by psPerimeters. */
975
976 bool spiral_mode = this->layer()->object()->print()->config().spiral_mode;
977
978 // if no solid layers are requested, turn top/bottom surfaces to internal
979 if (! spiral_mode && this->region().config().top_shell_layers == 0) {
980 for (Surface &surface : this->fill_surfaces.surfaces)
981 if (surface.is_top())
982 //BBS
983 //surface.surface_type = this->layer()->object()->config().infill_only_where_needed ? stInternalVoid : stInternal;
985 }
986 if (this->region().config().bottom_shell_layers == 0) {
987 for (Surface &surface : this->fill_surfaces.surfaces)
988 if (surface.is_bottom()) // (surface.surface_type == stBottom)
989 surface.surface_type = stInternal;
990 }
991
992 if (!spiral_mode && fabs(this->region().config().sparse_infill_density.value - 100.) < EPSILON) {
993 // Turn all internal sparse infill into solid infill, if sparse_infill_density is 100%
994 for (Surface &surface : this->fill_surfaces.surfaces)
995 if (surface.surface_type == stInternal)
996 surface.surface_type = stInternalSolid;
997 }
998
999#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
1000 export_region_slices_to_svg_debug("2_prepare_fill_surfaces-final");
1001 export_region_fill_surfaces_to_svg_debug("2_prepare_fill_surfaces-final");
1002#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
1003}
void export_region_fill_surfaces_to_svg_debug(const char *name) const
Definition LayerRegion.cpp:1078
void export_region_slices_to_svg_debug(const char *name) const
Definition LayerRegion.cpp:1051
static bool infill_only_where_needed
Definition Print.hpp:750
sparse_infill_density((ConfigOptionEnum< InfillPattern >, sparse_infill_pattern))((ConfigOptionPercent
bottom_shell_layers((ConfigOptionFloat, bottom_shell_thickness))((ConfigOptionInt
@ stInternalSolid
Definition Surface.hpp:28
@ stInternalVoid
Definition Surface.hpp:35

References Slic3r::bottom_shell_layers(), EPSILON, export_region_fill_surfaces_to_svg_debug(), export_region_slices_to_svg_debug(), fill_surfaces, Slic3r::PrintObject::infill_only_where_needed, Slic3r::Surface::is_bottom(), Slic3r::Surface::is_top(), layer(), prepare_fill_surfaces(), region(), Slic3r::sparse_infill_density(), Slic3r::stInternal, Slic3r::stInternalSolid, Slic3r::stInternalVoid, and Slic3r::Surface::surface_type.

Referenced by prepare_fill_surfaces().

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

◆ process_external_surfaces()

void Slic3r::LayerRegion::process_external_surfaces ( const Layer * lower_layer,
const Polygons * lower_layer_covered )
517{
518 using namespace Slic3r::Algorithm;
519
520#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
521 export_region_fill_surfaces_to_svg_debug("4_process_external_surfaces-initial");
522#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
523
524 // Width of the perimeters.
525 float shell_width = 0;
526 float expansion_min = 0;
527 if (int num_perimeters = this->region().config().wall_loops; num_perimeters > 0) {
528 Flow external_perimeter_flow = this->flow(frExternalPerimeter);
529 Flow perimeter_flow = this->flow(frPerimeter);
530 shell_width = 0.5f * external_perimeter_flow.scaled_width() + external_perimeter_flow.scaled_spacing();
531 shell_width += perimeter_flow.scaled_spacing() * (num_perimeters - 1);
532 expansion_min = perimeter_flow.scaled_spacing();
533 } else {
534 // TODO: Maybe there is better solution when printing with zero perimeters, but this works reasonably well, given the situation
535 shell_width = float(SCALED_EPSILON);
536 expansion_min = float(SCALED_EPSILON);;
537 }
538
539 // Scaled expansions of the respective external surfaces.
540 float expansion_top = shell_width * sqrt(2.);
541 float expansion_bottom = expansion_top;
542 float expansion_bottom_bridge = expansion_top;
543 // Expand by waves of expansion_step size (expansion_step is scaled), but with no more steps than max_nr_expansion_steps.
544 const float expansion_step = scaled<float>(0.1);
545 // Don't take more than max_nr_steps for small expansion_step.
546 static constexpr const size_t max_nr_expansion_steps = 5;
547 // 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;
548 const float closing_radius = 0.55f * 0.65f * 1.05f * this->flow(frSolidInfill).scaled_spacing();
549
550 // Expand the top / bottom / bridge surfaces into the shell thickness solid infills.
551 double layer_thickness;
552 ExPolygons shells = union_ex(fill_surfaces_extract_expolygons(this->fill_surfaces.surfaces, { stInternalSolid }, layer_thickness));
553 ExPolygons sparse = union_ex(fill_surfaces_extract_expolygons(this->fill_surfaces.surfaces, {stInternal}, layer_thickness));
554 ExPolygons top_expolygons = union_ex(fill_surfaces_extract_expolygons(this->fill_surfaces.surfaces, {stTop}, layer_thickness));
555 const auto expansion_params_into_sparse_infill = RegionExpansionParameters::build(expansion_min, expansion_step, max_nr_expansion_steps);
556 const auto expansion_params_into_solid_infill = RegionExpansionParameters::build(expansion_bottom_bridge, expansion_step, max_nr_expansion_steps);
557
558 std::vector<ExpansionZone> expansion_zones{
559 ExpansionZone{std::move(shells), expansion_params_into_solid_infill},
560 ExpansionZone{std::move(sparse), expansion_params_into_sparse_infill},
561 ExpansionZone{std::move(top_expolygons), expansion_params_into_solid_infill},
562 };
563
564 SurfaceCollection bridges;
565 {
566 BOOST_LOG_TRIVIAL(trace) << "Processing external surface, detecting bridges. layer" << this->layer()->print_z;
567 // ORCA: Relative/Align Bridge Angle
568 const auto &region_config = this->region().config();
569 const double custom_angle_deg = region_config.bridge_angle.value;
570 const bool relative_angle = region_config.relative_bridge_angle.value;
571 const double custom_angle_rad = Geometry::deg2rad(custom_angle_deg);
572
573 double align_offset_rad = 0.0;
574 if (region_config.align_infill_direction_to_model) {
575 auto m = this->layer()->object()->trafo().matrix();
576 align_offset_rad = std::atan2((double)m(1, 0), (double)m(0, 0));
577 }
578
579 bridges.surfaces = (custom_angle_deg > 0.0 && !relative_angle) ?
580 expand_merge_surfaces(this->fill_surfaces.surfaces, stBottomBridge, expansion_zones, closing_radius, custom_angle_rad + align_offset_rad) :
581 expand_bridges_detect_orientations(this->fill_surfaces.surfaces, expansion_zones, closing_radius);
582 if (custom_angle_deg > 0.0 && relative_angle) {
583 for (Surface &bridge_surface : bridges.surfaces) {
584 if (bridge_surface.bridge_angle >= 0)
585 bridge_surface.bridge_angle += custom_angle_rad;
586 }
587 }
588 BOOST_LOG_TRIVIAL(trace) << "Processing external surface, detecting bridges - done";
589#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
590 {
591 static int iRun = 0;
592 bridges.export_to_svg(debug_out_path("bridges-after-grouping-%d.svg", iRun++).c_str(), true);
593 }
594#endif
595 }
596
597 this->fill_surfaces.remove_types({stTop});
598 {
599 Surface top_templ(stTop, {});
600 top_templ.thickness = layer_thickness;
601 this->fill_surfaces.append(std::move(expansion_zones.back().expolygons), top_templ);
602 }
603
604 expansion_zones.pop_back();
605
606 expansion_zones.at(0).parameters = RegionExpansionParameters::build(expansion_bottom, expansion_step, max_nr_expansion_steps);
607 Surfaces bottoms = expand_merge_surfaces(this->fill_surfaces.surfaces, stBottom, expansion_zones, closing_radius);
608
609 expansion_zones.at(0).parameters = RegionExpansionParameters::build(expansion_top, expansion_step, max_nr_expansion_steps);
610 Surfaces tops = expand_merge_surfaces(this->fill_surfaces.surfaces, stTop, expansion_zones, closing_radius);
611
612 // turn too small internal regions into solid regions according to the user setting
613 if (!this->layer()->object()->print()->config().spiral_mode && this->region().config().sparse_infill_density.value > 0) {
614 // scaling an area requires two calls!
615 double min_area = scale_(scale_(this->region().config().minimum_sparse_infill_area.value));
616 ExPolygons small_regions{};
617 expansion_zones[1].expolygons.erase(std::remove_if(expansion_zones[1].expolygons.begin(), expansion_zones[1].expolygons.end(), [min_area, &small_regions](ExPolygon& ex_polygon) {
618 if (ex_polygon.area() <= min_area) {
619 small_regions.push_back(ex_polygon);
620 return true;
621 }
622 return false;
623 }), expansion_zones[1].expolygons.end());
624
625 if (!small_regions.empty()) {
626 expansion_zones[0].expolygons = union_ex(expansion_zones[0].expolygons, small_regions);
627 }
628 }
629
630// this->fill_surfaces.remove_types({ stBottomBridge, stBottom, stTop, stInternal, stInternalSolid });
631 this->fill_surfaces.clear();
632 unsigned zones_expolygons_count = 0;
633 for (const ExpansionZone& zone : expansion_zones)
634 zones_expolygons_count += zone.expolygons.size();
635 reserve_more(this->fill_surfaces.surfaces, zones_expolygons_count + bridges.size() + bottoms.size() + tops.size());
636 {
637 Surface solid_templ(stInternalSolid, {});
638 solid_templ.thickness = layer_thickness;
639 this->fill_surfaces.append(std::move(expansion_zones[0].expolygons), solid_templ);
640 }
641 {
642 Surface sparse_templ(stInternal, {});
643 sparse_templ.thickness = layer_thickness;
644 this->fill_surfaces.append(std::move(expansion_zones[1].expolygons), sparse_templ);
645 }
646 this->fill_surfaces.append(std::move(bridges.surfaces));
647 this->fill_surfaces.append(std::move(bottoms));
648 this->fill_surfaces.append(std::move(tops));
649
650#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
651 export_region_fill_surfaces_to_svg_debug("4_process_external_surfaces-final");
652#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
653}
coord_t scaled_width() const
Definition Flow.hpp:64
Surfaces surfaces
Definition SurfaceCollection.hpp:17
void export_to_svg(const char *path, bool show_labels)
Definition SurfaceCollection.cpp:150
size_t size() const
Definition SurfaceCollection.hpp:54
double bridge_angle
Definition Surface.hpp:49
#define SCALED_EPSILON
Definition libslic3r.h:109
constexpr T deg2rad(const T angle)
Definition Geometry.hpp:312
void trace(unsigned int level, const char *message)
Definition utils.cpp:247
static ExPolygons fill_surfaces_extract_expolygons(Surfaces &surfaces, std::initializer_list< SurfaceType > surface_types, double &thickness)
Definition LayerRegion.cpp:179
Surfaces expand_bridges_detect_orientations(Surfaces &surfaces, std::vector< ExpansionZone > &expansion_zones, const float closing_radius)
Definition LayerRegion.cpp:429
BoundingBox scaled(const BoundingBoxf &bb)
Definition BoundingBox.hpp:284
void reserve_more(VectorType &vector, size_t n)
Definition Utils.hpp:434
std::vector< Surface > Surfaces
Definition Surface.hpp:123
@ stTop
Definition Surface.hpp:18
@ stBottomBridge
Definition Surface.hpp:22
@ stBottom
Definition Surface.hpp:20
Surfaces expand_merge_surfaces(Surfaces &surfaces, SurfaceType surface_type, std::vector< ExpansionZone > &expansion_zones, const float closing_radius, const double bridge_angle=-1)
Definition LayerRegion.cpp:469

References Slic3r::Surface::bridge_angle, Slic3r::Algorithm::RegionExpansionParameters::build(), Slic3r::PrintRegion::config(), Slic3r::debug_out_path(), Slic3r::Geometry::deg2rad(), Slic3r::expand_bridges_detect_orientations(), Slic3r::expand_merge_surfaces(), export_region_fill_surfaces_to_svg_debug(), Slic3r::SurfaceCollection::export_to_svg(), fill_surfaces, Slic3r::fill_surfaces_extract_expolygons(), flow(), Slic3r::frExternalPerimeter, Slic3r::frPerimeter, Slic3r::frSolidInfill, Layer, layer(), Slic3r::Layer::object(), Slic3r::Layer::print_z, region(), scale_, Slic3r::scaled(), SCALED_EPSILON, Slic3r::Flow::scaled_spacing(), Slic3r::Flow::scaled_width(), Slic3r::sparse_infill_density(), Slic3r::stBottom, Slic3r::stBottomBridge, Slic3r::stTop, Slic3r::SurfaceCollection::surfaces, Slic3r::Surface::thickness, Slic3r::trace(), Slic3r::PrintObject::trafo(), and Slic3r::union_ex().

Here is the call graph for this function:

◆ region()

◆ simplify_entity_collection()

void Slic3r::LayerRegion::simplify_entity_collection ( ExtrusionEntityCollection * entity_collection)
private
1086{
1087 for (size_t i = 0; i < entity_collection->entities.size(); i++) {
1088 if (ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(entity_collection->entities[i]))
1089 this->simplify_entity_collection(collection);
1090 else if (ExtrusionPath* path = dynamic_cast<ExtrusionPath*>(entity_collection->entities[i]))
1091 this->simplify_path(path);
1092 else if (ExtrusionMultiPath* multipath = dynamic_cast<ExtrusionMultiPath*>(entity_collection->entities[i]))
1093 this->simplify_multi_path(multipath);
1094 else if (ExtrusionLoop* loop = dynamic_cast<ExtrusionLoop*>(entity_collection->entities[i]))
1095 this->simplify_loop(loop);
1096 else
1097 throw Slic3r::InvalidArgument("Invalid extrusion entity supplied to simplify_entity_collection()");
1098 }
1099}
void simplify_path(ExtrusionPath *path)
Definition LayerRegion.cpp:1101
void simplify_multi_path(ExtrusionMultiPath *multipath)
Definition LayerRegion.cpp:1116
void simplify_loop(ExtrusionLoop *loop)
Definition LayerRegion.cpp:1122
void simplify_entity_collection(ExtrusionEntityCollection *entity_collection)
Definition LayerRegion.cpp:1085

References Slic3r::ExtrusionEntityCollection::entities, simplify_entity_collection(), simplify_loop(), simplify_multi_path(), and simplify_path().

Referenced by simplify_entity_collection(), simplify_infill_extrusion_entity(), and simplify_wall_extrusion_entity().

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

◆ simplify_infill_extrusion_entity()

void Slic3r::LayerRegion::simplify_infill_extrusion_entity ( )
inline

References fills, and simplify_entity_collection().

Here is the call graph for this function:

◆ simplify_loop()

void Slic3r::LayerRegion::simplify_loop ( ExtrusionLoop * loop)
private
1123{
1124 for (ExtrusionPath &path : loop->paths)
1125 this->simplify_path(&path);
1126}

References Slic3r::ExtrusionLoop::paths, simplify_loop(), and simplify_path().

Referenced by simplify_entity_collection(), and simplify_loop().

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

◆ simplify_multi_path()

void Slic3r::LayerRegion::simplify_multi_path ( ExtrusionMultiPath * multipath)
private
1117{
1118 for (ExtrusionPath &path : multipath->paths)
1119 this->simplify_path(&path);
1120}

References Slic3r::ExtrusionMultiPath::paths, simplify_multi_path(), and simplify_path().

Referenced by simplify_entity_collection(), and simplify_multi_path().

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

◆ simplify_path()

void Slic3r::LayerRegion::simplify_path ( ExtrusionPath * path)
private
1102{
1103 const auto &print_config = this->layer()->object()->print()->config();
1104 const ArcFittingMode arc_fitting = print_config.enable_arc_fitting.value;
1105 const bool is_sparse_infill = path->role() == erInternalInfill;
1106 const auto scaled_resolution = scaled<double>(print_config.resolution.value);
1107
1108 if (!print_config.spiral_mode &&
1109 (arc_fitting == ArcFittingMode::Enabled || (arc_fitting == ArcFittingMode::SparseInfill && is_sparse_infill))) {
1110 path->simplify_by_fitting_arc(is_sparse_infill ? SCALED_SPARSE_INFILL_RESOLUTION : scaled_resolution);
1111 } else {
1112 path->simplify(scaled_resolution);
1113 }
1114}
#define SCALED_SPARSE_INFILL_RESOLUTION
Definition libslic3r.h:89
ArcFittingMode
Definition PrintConfig.hpp:238
@ Enabled
Definition PrintConfig.hpp:240
@ SparseInfill
Definition PrintConfig.hpp:241
@ erInternalInfill
Definition ExtrusionEntity.hpp:31

References Slic3r::Enabled, Slic3r::erInternalInfill, layer(), Slic3r::ExtrusionPath::role(), Slic3r::scaled(), SCALED_SPARSE_INFILL_RESOLUTION, Slic3r::ExtrusionPath::simplify(), Slic3r::ExtrusionPath::simplify_by_fitting_arc(), simplify_path(), and Slic3r::SparseInfill.

Referenced by simplify_entity_collection(), simplify_loop(), simplify_multi_path(), and simplify_path().

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

◆ simplify_wall_extrusion_entity()

void Slic3r::LayerRegion::simplify_wall_extrusion_entity ( )
inline

References perimeters, and simplify_entity_collection().

Here is the call graph for this function:

◆ slices_to_fill_surfaces_clipped()

void Slic3r::LayerRegion::slices_to_fill_surfaces_clipped ( )
91{
92 // Note: this method should be idempotent, but fill_surfaces gets modified
93 // in place. However we're now only using its boundaries (which are invariant)
94 // so we're safe. This guarantees idempotence of prepare_infill() also in case
95 // that combine_infill() turns some fill_surface into VOID surfaces.
96 // Collect polygons per surface type.
97 std::array<SurfacesPtr, size_t(stCount)> by_surface;
98 for (Surface &surface : this->slices.surfaces)
99 by_surface[size_t(surface.surface_type)].emplace_back(&surface);
100 // Trim surfaces by the fill_boundaries.
101 this->fill_surfaces.surfaces.clear();
102 const Polygons fill_boundaries = to_polygons(this->fill_expolygons);
103 for (size_t surface_type = 0; surface_type < size_t(stCount); ++ surface_type) {
104 const SurfacesPtr &this_surfaces = by_surface[surface_type];
105 if (! this_surfaces.empty())
106 this->fill_surfaces.append(intersection_ex_by_piece(to_expolygons(this_surfaces), fill_boundaries), SurfaceType(surface_type));
107 }
108}
ExPolygons fill_expolygons
Definition Layer.hpp:71
std::vector< const Surface * > SurfacesPtr
Definition Surface.hpp:124
ExPolygons to_expolygons(const Polygons &polys)
Definition ExPolygon.hpp:373
Polygons to_polygons(const ExPolygon &src)
Definition ExPolygon.hpp:307
SurfaceType
Definition Surface.hpp:16
@ stCount
Definition Surface.hpp:39
Slic3r::ExPolygons intersection_ex_by_piece(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:1008

References fill_expolygons, fill_surfaces, Slic3r::intersection_ex_by_piece(), slices, Slic3r::stCount, Slic3r::Surface::surface_type, Slic3r::to_expolygons(), and Slic3r::to_polygons().

Here is the call graph for this function:

◆ trim_surfaces()

void Slic3r::LayerRegion::trim_surfaces ( const Polygons & trimming_polygons)
1012{
1013#ifndef NDEBUG
1014 for (const Surface &surface : this->slices.surfaces)
1015 assert(surface.surface_type == stInternal);
1016#endif /* NDEBUG */
1017 this->slices.set(intersection_ex(this->slices.surfaces, trimming_polygons), stInternal);
1018}
Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:878

References Slic3r::intersection_ex(), slices, Slic3r::stInternal, Slic3r::Surface::surface_type, and trim_surfaces().

Referenced by trim_surfaces().

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

◆ Layer

friend class Layer
friend

◆ PrintObject

friend class PrintObject
friend

References PrintObject.

Referenced by bridging_flow(), and PrintObject.

Member Data Documentation

◆ fill_expolygons

◆ fill_no_overlap_expolygons

ExPolygons Slic3r::LayerRegion::fill_no_overlap_expolygons

◆ fill_surfaces

◆ fills

◆ m_layer

Layer* Slic3r::LayerRegion::m_layer
private

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

◆ m_region

const PrintRegion* Slic3r::LayerRegion::m_region
private

Referenced by LayerRegion(), flow(), and region().

◆ perimeters

◆ raw_slices

ExPolygons Slic3r::LayerRegion::raw_slices

◆ slices

◆ thin_fills

◆ unsupported_bridge_edges


The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Layer.hpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/LayerRegion.cpp