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

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

Inheritance diagram for Slic3r::Layer:
Collaboration diagram for Slic3r::Layer:

Public Member Functions

size_t id () const
void set_id (size_t id)
PrintObject * object ()
const PrintObject * object () const
coordf_t bottom_z () const
size_t region_count () const
const LayerRegion * get_region (int idx) const
LayerRegion * get_region (int idx)
LayerRegion * add_region (const PrintRegion *print_region)
const LayerRegionPtrs & regions () const
bool empty () const
void make_slices ()
void backup_untyped_slices ()
void restore_untyped_slices ()
void restore_untyped_slices_no_extra_perimeters ()
ExPolygons merged (float offset) const
template<class T>
bool any_internal_region_slice_contains (const T &item) const
template<class T>
bool any_bottom_region_slice_contains (const T &item) const
void make_perimeters ()
void make_fills ()
void make_fills (const FillAdaptive::RegionOctrees *fill_octrees, FillLightning::Generator *lightning_generator=nullptr)
Polylines generate_sparse_infill_polylines_for_anchoring (const FillAdaptive::RegionOctrees *fill_octrees, FillLightning::Generator *lightning_generator) const
void make_ironing ()
void make_contour_z (const sla::IndexedMesh &mesh)
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
virtual bool has_extrusions () const
void simplify_wall_extrusion_path ()
void simplify_infill_extrusion_path ()
coordf_t get_sparse_infill_max_void_area ()
size_t get_extruder_id (unsigned int filament_id) const

Static Public Member Functions

static bool is_perimeter_compatible (const Print &print, const PrintRegion &a, const PrintRegion &b)
static int choose_ironing_extruder (const PrintRegionConfig &cfg, bool spiral_mode, bool is_topmost_layer)
template<typename IteratorType, typename IndexType, typename FN_HIGHER_EQUAL>
static IndexType idx_higher_or_equal (IteratorType begin, IteratorType end, IndexType idx, FN_HIGHER_EQUAL fn_higher_equal)

Public Attributes

Layer * upper_layer
Layer * lower_layer
bool slicing_errors
coordf_t slice_z
coordf_t print_z
coordf_t height
CurledLines curled_lines
ExPolygons sharp_tails
ExPolygons cantilevers
std::vector< float > sharp_tails_height
ExPolygons lslices
ExPolygons lslices_extrudable
std::vector< BoundingBox > lslices_bboxes
std::vector< size_t > lslices_separated_component_ids
ExPolygons loverhangs
BoundingBox loverhangs_bbox

Protected Member Functions

 Layer (size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z)
virtual ~Layer ()
void simplify_support_entity_collection (ExtrusionEntityCollection *entity_collection)
void simplify_support_path (ExtrusionPath *path)
void simplify_support_multi_path (ExtrusionMultiPath *multipath)
void simplify_support_loop (ExtrusionLoop *loop)

Private Attributes

size_t m_id
PrintObject * m_object
LayerRegionPtrs m_regions

Friends

class PrintObject
std::vector< Layer * > new_layers (PrintObject *print_object, const std::vector< coordf_t > &object_layers)
std::string fix_slicing_errors (PrintObject *object, LayerPtrs &, const std::function< void()> &, int &)

Detailed Description

Constructor & Destructor Documentation

◆ Layer()

Slic3r::Layer::Layer ( size_t id,
PrintObject * object,
coordf_t height,
coordf_t print_z,
coordf_t slice_z )
inlineprotected
278 :
279 upper_layer(nullptr), lower_layer(nullptr), slicing_errors(false),
281 m_id(id), m_object(object) {}
Layer * upper_layer
Definition Layer.hpp:146
coordf_t slice_z
Definition Layer.hpp:149
coordf_t height
Definition Layer.hpp:151
coordf_t print_z
Definition Layer.hpp:150
size_t m_id
Definition Layer.hpp:292
bool slicing_errors
Definition Layer.hpp:148
PrintObject * m_object
Definition Layer.hpp:293
Layer * lower_layer
Definition Layer.hpp:147

References height, id(), lower_layer, m_id, m_object, object(), print_z, PrintObject, slice_z, slicing_errors, and upper_layer.

Referenced by Slic3r::SupportLayer::SupportLayer(), and new_layers.

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

◆ ~Layer()

Slic3r::Layer::~Layer ( )
protectedvirtual
32{
33 this->lower_layer = this->upper_layer = nullptr;
34 for (LayerRegion *region : m_regions)
35 delete region;
36 m_regions.clear();
37}
LayerRegionPtrs m_regions
Definition Layer.hpp:294

References lower_layer, m_regions, and upper_layer.

Member Function Documentation

◆ add_region()

LayerRegion * Slic3r::Layer::add_region ( const PrintRegion * print_region)
50{
51 m_regions.emplace_back(new LayerRegion(this, print_region));
52 return m_regions.back();
53}

References m_regions.

◆ any_bottom_region_slice_contains()

template<class T>
bool Slic3r::Layer::any_bottom_region_slice_contains ( const T & item) const
inline
201 {
202 for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_bottom_contains(item)) return true;
203 return false;
204 }

References m_regions.

◆ any_internal_region_slice_contains()

template<class T>
bool Slic3r::Layer::any_internal_region_slice_contains ( const T & item) const
inline
197 {
198 for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_internal_contains(item)) return true;
199 return false;
200 }

References m_regions.

◆ backup_untyped_slices()

void Slic3r::Layer::backup_untyped_slices ( )
94{
95 if (layer_needs_raw_backup(this)) {
96 for (LayerRegion *layerm : m_regions)
97 layerm->raw_slices = to_expolygons(layerm->slices.surfaces);
98 } else {
99 assert(m_regions.size() == 1);
100 m_regions.front()->raw_slices.clear();
101 }
102}
static bool layer_needs_raw_backup(const Layer *layer)
Definition Layer.cpp:86
ExPolygons to_expolygons(const Polygons &polys)
Definition ExPolygon.hpp:373

References Slic3r::layer_needs_raw_backup(), m_regions, and Slic3r::to_expolygons().

Here is the call graph for this function:

◆ bottom_z()

coordf_t Slic3r::Layer::bottom_z ( ) const
inline
152{ return this->print_z - this->height; }

Referenced by Slic3r::PrintObject::discover_horizontal_shells(), Slic3r::PrintObject::discover_vertical_shells(), Slic3r::TreeSupport::get_trim_support_regions(), Slic3r::getExtrusionPathsFromSupportLayer(), Slic3r::new_contact_layer(), and Slic3r::PrintObjectSupportMaterial::trim_support_layers_by_object().

Here is the caller graph for this function:

◆ choose_ironing_extruder()

int Slic3r::Layer::choose_ironing_extruder ( const PrintRegionConfig & cfg,
bool spiral_mode,
bool is_topmost_layer )
static
1694{
1695 if (cfg.ironing_type == IroningType::NoIroning)
1696 return -1;
1697 const bool gate = (cfg.ironing_type == IroningType::AllSolid)
1698 || ((cfg.top_shell_layers > 0 || (spiral_mode && cfg.bottom_shell_layers > 1))
1699 && (cfg.ironing_type == IroningType::TopSurfaces
1700 || (cfg.ironing_type == IroningType::TopmostOnly && is_topmost_layer)));
1701 if (!gate)
1702 return -1;
1703 return cfg.top_surface_filament_id;
1704}
@ TopmostOnly
Definition PrintConfig.hpp:205
@ NoIroning
Definition PrintConfig.hpp:203
@ AllSolid
Definition PrintConfig.hpp:206
@ TopSurfaces
Definition PrintConfig.hpp:204

References Slic3r::AllSolid, choose_ironing_extruder(), Slic3r::NoIroning, Slic3r::PrintRegionConfig, Slic3r::TopmostOnly, and Slic3r::TopSurfaces.

Referenced by choose_ironing_extruder(), and make_ironing().

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

◆ empty()

bool Slic3r::Layer::empty ( ) const
41{
42 for (const LayerRegion *layerm : m_regions)
43 if (layerm != nullptr && ! layerm->slices.empty())
44 // Non empty layer.
45 return false;
46 return true;
47}

References m_regions.

Referenced by Slic3r::PrintObject::apply_conical_overhang(), and Slic3r::PrintObject::slice_volumes().

Here is the caller graph for this function:

◆ export_region_fill_surfaces_to_svg()

void Slic3r::Layer::export_region_fill_surfaces_to_svg ( const char * path) const
344{
345 BoundingBox bbox;
346 for (const auto *region : m_regions)
347 for (const auto &surface : region->slices.surfaces)
348 bbox.merge(get_extents(surface.expolygon));
350 Point legend_pos(bbox.min(0), bbox.max(1));
351 bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
352
353 SVG svg(path, bbox);
354 const float transparency = 0.5f;
355 for (const auto *region : m_regions)
356 for (const auto &surface : region->slices.surfaces)
357 svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
358 export_surface_type_legend_to_svg(svg, legend_pos);
359 svg.Close();
360}
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::export_surface_type_legend_to_svg(), Slic3r::export_surface_type_legend_to_svg_box_size(), Slic3r::get_extents(), m_regions, Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, and Slic3r::surface_type_to_color_name().

Referenced by 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::Layer::export_region_fill_surfaces_to_svg_debug ( const char * name) const
430{
431 static size_t idx = 0;
432 this->export_region_fill_surfaces_to_svg(debug_out_path("Layer-fill_surfaces-%s-%d.svg", name, idx ++).c_str());
433}
void export_region_fill_surfaces_to_svg(const char *path) const
Definition Layer.cpp:343
std::string debug_out_path(const char *name,...)
Definition utils.cpp:382

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

Here is the call graph for this function:

◆ export_region_slices_to_svg()

void Slic3r::Layer::export_region_slices_to_svg ( const char * path) const
318{
319 BoundingBox bbox;
320 for (const auto *region : m_regions)
321 for (const auto &surface : region->slices.surfaces)
322 bbox.merge(get_extents(surface.expolygon));
324 Point legend_pos(bbox.min(0), bbox.max(1));
325 bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
326
327 SVG svg(path, bbox);
328 const float transparency = 0.5f;
329 for (const auto *region : m_regions)
330 for (const auto &surface : region->slices.surfaces)
331 svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
332 export_surface_type_legend_to_svg(svg, legend_pos);
333 svg.Close();
334}

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(), m_regions, Slic3r::BoundingBoxBase< PointType, APointsType >::max, Slic3r::BoundingBoxBase< PointType, APointsType >::merge(), Slic3r::BoundingBoxBase< PointType, APointsType >::min, and Slic3r::surface_type_to_color_name().

Referenced by 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::Layer::export_region_slices_to_svg_debug ( const char * name) const
338{
339 static size_t idx = 0;
340 this->export_region_slices_to_svg(debug_out_path("Layer-slices-%s-%d.svg", name, idx ++).c_str());
341}
void export_region_slices_to_svg(const char *path) const
Definition Layer.cpp:317

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

Here is the call graph for this function:

◆ generate_sparse_infill_polylines_for_anchoring()

Polylines Slic3r::Layer::generate_sparse_infill_polylines_for_anchoring ( const FillAdaptive::RegionOctrees * fill_octrees,
FillLightning::Generator * lightning_generator ) const

Generate sparse-infill polylines for anchoring/analysis purposes.

This produces the geometric polylines of internal sparse infill for the current layer (using the same infill pattern, angle, rotation template, and spacing that normal slicing would use), but it does not create extrusion entities.

The returned polylines are consumed by internal-bridge detection on the next layer to derive anchor lines and compute the bridge direction over sparse infill.

Notes:

  • Only stInternal surfaces are considered.
  • Rotation templates (e.g. sparse_infill_rotate_template) are applied so the anchors reflect the actual infill orientation.
  • For lightning/adaptive patterns, the respective generators are wired so their polylines match the final infill layout.
1562{
1563 LockRegionParam skin_inner_param;
1564 std::vector<SurfaceFill> surface_fills = group_fills(*this, skin_inner_param);
1565 const Slic3r::BoundingBox bbox = this->object()->bounding_box();
1566 const auto resolution = this->object()->print()->config().resolution.value;
1567
1568 Polylines sparse_infill_polylines{};
1569
1570 for (SurfaceFill &surface_fill : surface_fills) {
1571 if (surface_fill.surface.surface_type != stInternal) {
1572 continue;
1573 }
1574
1575 switch (surface_fill.params.pattern) {
1576 case ipCount: continue; break;
1577 case ipSupportBase: continue; break;
1578 case ipConcentricInternal: continue; break;
1579 case ipLightning:
1580 case ipAdaptiveCubic:
1581 case ipSupportCubic:
1582 case ipRectilinear:
1583 case ipMonotonic:
1584 case ipMonotonicLine:
1586 case ipGrid:
1587 case ipLateralLattice:
1588 case ipTriangles:
1589 case ipStars:
1590 case ipCubic:
1591 case ipLine:
1592 case ipConcentric:
1593 case ipSpiralInset:
1594 case ipHoneycomb:
1595 case ipLateralHoneycomb:
1596 case ip3DHoneycomb:
1597 case ipGyroid:
1598 case ipTpmsD:
1599 case ipTpmsFK:
1600 case ipHilbertCurve:
1602 case ipOctagramSpiral:
1603 case ipZigZag:
1604 case ipCrossZag:
1605 case ipLockedZag: break;
1606 }
1607
1608 // Create the filler object.
1609 std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));
1610 f->set_bounding_box(bbox);
1611 f->layer_id = this->id() - this->object()->get_layer(0)->id(); // We need to subtract raft layers.
1612 {
1613 const auto &rcfg = m_regions[surface_fill.region_id]->region().config();
1614 f->dont_alternate_fill_direction = rcfg.zaa_enabled && rcfg.zaa_dont_alternate_fill_direction;
1615 }
1616 f->z = this->print_z;
1617 f->angle = surface_fill.params.angle;
1618 f->fixed_angle = surface_fill.params.fixed_angle;
1619 const FillAdaptive::Octrees *octrees = fill_octrees ? fill_octrees->region(surface_fill.region_id) : nullptr;
1620 f->adaptive_infill_field = this->object()->adaptive_infill_field(surface_fill.params.adaptive_infill_mode);
1621 f->print_config = &this->object()->print()->config();
1622 f->print_object_config = &this->object()->config();
1623
1624 if (surface_fill.params.pattern == ipLightning)
1625 dynamic_cast<FillLightning::Filler *>(f.get())->generator = lightning_generator;
1626
1627 // calculate flow spacing for infill pattern generation
1628 double link_max_length = 0.;
1629 if (!surface_fill.params.bridge) {
1630#if 0
1631 link_max_length = layerm.region()->config().get_abs_value(surface.is_external() ? "external_fill_link_max_length" : "fill_link_max_length", flow.spacing());
1632// printf("flow spacing: %f, is_external: %d, link_max_length: %lf\n", flow.spacing(), int(surface.is_external()), link_max_length);
1633#else
1634 if (surface_fill.params.density > 80.) // 80%
1635 link_max_length = 3. * f->spacing;
1636#endif
1637 }
1638
1639 LayerRegion &layerm = *m_regions[surface_fill.region_id];
1640
1641 // Maximum length of the perimeter segment linking two infill lines.
1642 f->link_max_length = (coord_t) scale_(link_max_length);
1643 // Used by the concentric infill pattern to clip the loops to create extrusion paths.
1644 f->loop_clipping = coord_t(scale_(layerm.region().config().seam_gap.get_abs_value(surface_fill.params.flow.nozzle_diameter())));
1645
1646 // apply half spacing using this flow's own spacing and generate infill
1647 FillParams params;
1648 params.density = float(0.01 * surface_fill.params.density);
1649 params.dont_adjust = false; // surface_fill.params.dont_adjust;
1650 params.anchor_length = surface_fill.params.anchor_length;
1651 params.anchor_length_max = surface_fill.params.anchor_length_max;
1652 params.resolution = resolution;
1653 params.use_arachne = false;
1654 params.layer_height = layerm.layer()->height;
1655 params.lateral_lattice_angle_1 = surface_fill.params.lateral_lattice_angle_1;
1656 params.lateral_lattice_angle_2 = surface_fill.params.lateral_lattice_angle_2;
1657 params.infill_overhang_angle = surface_fill.params.infill_overhang_angle;
1658 params.multiline = surface_fill.params.multiline;
1659 params.gyroid_optimized = surface_fill.params.gyroid_optimized;
1660 params.adaptive_infill_mode = surface_fill.params.adaptive_infill_mode;
1661 params.adaptive_infill_interior_density = float(0.01 * surface_fill.params.adaptive_infill_interior_density);
1662 params.adaptive_infill_gradient = surface_fill.params.adaptive_infill_gradient;
1663 params.smooth_factor = surface_fill.params.smooth_factor;
1664 // Orca: Match make_fills() when choosing the origin of plane-path patterns.
1665 // Without the sparse extrusion role, the filler uses each surface's bounds
1666 // instead of the object's bounds, so bridge anchors shift away from printed infill.
1667 params.extrusion_role = surface_fill.params.extrusion_role;
1668
1669 for (ExPolygon &expoly : surface_fill.expolygons) {
1670 // Orca: Match the per-body box and octree of make_fills() before generating physical anchors.
1671 const int body = infill_body(*this, surface_fill, expoly);
1672 f->set_bounding_box(body >= 0 ? this->object()->separated_body_bboxes()[body] : bbox);
1673 f->adapt_fill_octree = octrees ? octrees->get(body) : nullptr;
1674 // Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
1675 f->spacing = surface_fill.params.spacing;
1676 surface_fill.surface.expolygon = std::move(expoly);
1677 try {
1678 Polylines polylines = f->fill_surface(&surface_fill.surface, params);
1679 sparse_infill_polylines.insert(sparse_infill_polylines.end(), polylines.begin(), polylines.end());
1680 } catch (InfillFailedException &) {}
1681 }
1682 }
1683
1684 return sparse_infill_polylines;
1685}
static Fill * new_from_type(const InfillPattern type)
Definition FillBase.cpp:65
size_t id() const
Definition Layer.hpp:141
PrintObject * object()
Definition Layer.hpp:143
PrintType * print()
Definition PrintBase.hpp:637
BoundingBox bounding_box() const
Definition Print.hpp:403
const AdaptiveInfillField * adaptive_infill_field(AdaptiveInfillMode mode) const
Definition Print.hpp:410
const PrintObjectConfig & config() const
Definition Print.hpp:372
const Layer * get_layer(int idx) const
Definition Print.hpp:456
const PrintConfig & config() const
Definition Print.hpp:1131
#define scale_(val)
Definition libslic3r.h:106
int64_t coord_t
Definition libslic3r.h:48
@ ipStars
Definition PrintConfig.hpp:130
@ ipHilbertCurve
Definition PrintConfig.hpp:134
@ ipGrid
Definition PrintConfig.hpp:129
@ ipArchimedeanChords
Definition PrintConfig.hpp:134
@ ipConcentric
Definition PrintConfig.hpp:134
@ ipZigZag
Definition PrintConfig.hpp:128
@ ipTpmsD
Definition PrintConfig.hpp:133
@ ipLateralLattice
Definition PrintConfig.hpp:132
@ ipAlignedRectilinear
Definition PrintConfig.hpp:128
@ ipMonotonic
Definition PrintConfig.hpp:127
@ ip3DHoneycomb
Definition PrintConfig.hpp:132
@ ipAdaptiveCubic
Definition PrintConfig.hpp:131
@ ipCrossZag
Definition PrintConfig.hpp:128
@ ipMonotonicLine
Definition PrintConfig.hpp:127
@ ipCount
Definition PrintConfig.hpp:136
@ ipLine
Definition PrintConfig.hpp:129
@ ipHoneycomb
Definition PrintConfig.hpp:132
@ ipCubic
Definition PrintConfig.hpp:131
@ ipOctagramSpiral
Definition PrintConfig.hpp:134
@ ipTriangles
Definition PrintConfig.hpp:130
@ ipSupportCubic
Definition PrintConfig.hpp:131
@ ipTpmsFK
Definition PrintConfig.hpp:133
@ ipRectilinear
Definition PrintConfig.hpp:128
@ ipConcentricInternal
Definition PrintConfig.hpp:135
@ ipGyroid
Definition PrintConfig.hpp:133
@ ipSupportBase
Definition PrintConfig.hpp:135
@ ipLockedZag
Definition PrintConfig.hpp:128
@ ipLateralHoneycomb
Definition PrintConfig.hpp:132
@ ipLightning
Definition PrintConfig.hpp:131
@ ipSpiralInset
Definition PrintConfig.hpp:134
static int infill_body(const Layer &layer, const SurfaceFill &fill, const ExPolygon &expoly)
Definition Fill.cpp:1308
std::vector< Polyline > Polylines
Definition Polyline.hpp:22
zaa_minimize_perimeter_height resolution((ConfigOptionFloats, retraction_minimum_travel))((ConfigOptionBools
std::vector< SurfaceFill > group_fills(const Layer &layer, LockRegionParam &lock_param)
Definition Fill.cpp:909
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124
@ stInternal
Definition Surface.hpp:26
@ SurfaceFill
Definition CadDocument.hpp:26

References Slic3r::FillParams::adaptive_infill_gradient, Slic3r::FillParams::adaptive_infill_interior_density, Slic3r::FillParams::adaptive_infill_mode, Slic3r::FillParams::anchor_length, Slic3r::FillParams::anchor_length_max, Slic3r::PrintRegion::config(), Slic3r::FillParams::density, Slic3r::FillParams::dont_adjust, Slic3r::FillParams::extrusion_role, Slic3r::f(), generate_sparse_infill_polylines_for_anchoring(), Slic3r::FillLightning::Filler::generator, Slic3r::FillAdaptive::Octrees::get(), Slic3r::group_fills(), Slic3r::FillParams::gyroid_optimized, height, id(), Slic3r::infill_body(), Slic3r::FillParams::infill_overhang_angle, Slic3r::ip3DHoneycomb, Slic3r::ipAdaptiveCubic, Slic3r::ipAlignedRectilinear, Slic3r::ipArchimedeanChords, Slic3r::ipConcentric, Slic3r::ipConcentricInternal, Slic3r::ipCount, Slic3r::ipCrossZag, Slic3r::ipCubic, Slic3r::ipGrid, Slic3r::ipGyroid, Slic3r::ipHilbertCurve, Slic3r::ipHoneycomb, Slic3r::ipLateralHoneycomb, Slic3r::ipLateralLattice, Slic3r::ipLightning, Slic3r::ipLine, Slic3r::ipLockedZag, Slic3r::ipMonotonic, Slic3r::ipMonotonicLine, Slic3r::ipOctagramSpiral, Slic3r::ipRectilinear, Slic3r::ipSpiralInset, Slic3r::ipStars, Slic3r::ipSupportBase, Slic3r::ipSupportCubic, Slic3r::ipTpmsD, Slic3r::ipTpmsFK, Slic3r::ipTriangles, Slic3r::ipZigZag, Slic3r::FillParams::lateral_lattice_angle_1, Slic3r::FillParams::lateral_lattice_angle_2, Slic3r::LayerRegion::layer(), Slic3r::FillParams::layer_height, m_regions, Slic3r::FillParams::multiline, Slic3r::Fill::new_from_type(), object(), print_z, Slic3r::FillAdaptive::RegionOctrees::region(), Slic3r::LayerRegion::region(), Slic3r::FillParams::resolution, Slic3r::resolution(), scale_, Slic3r::FillParams::smooth_factor, Slic3r::stInternal, and Slic3r::FillParams::use_arachne.

Referenced by generate_sparse_infill_polylines_for_anchoring().

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

◆ get_extruder_id()

size_t Slic3r::Layer::get_extruder_id ( unsigned int filament_id) const
489{
490 return m_object->print()->get_extruder_id(filament_id);
491}

References m_object.

Referenced by Slic3r::group_fills().

Here is the caller graph for this function:

◆ get_region() [1/2]

LayerRegion * Slic3r::Layer::get_region ( int idx)
inline
183{ return m_regions[idx]; }

References m_regions.

◆ get_region() [2/2]

const LayerRegion * Slic3r::Layer::get_region ( int idx) const
inline
182{ return m_regions[idx]; }

References m_regions.

Referenced by Slic3r::PrintObject::belt_drop_unclaimed_fills(), Slic3r::extract_layer(), and Slic3r::LayerRegion::make_perimeters().

Here is the caller graph for this function:

◆ get_sparse_infill_max_void_area()

coordf_t Slic3r::Layer::get_sparse_infill_max_void_area ( )
436{
437 double max_void_area = 0.;
438 for (auto layerm : m_regions) {
439 Flow flow = layerm->flow(frInfill);
440 const PrintRegionConfig &config = layerm->region().config();
441 float density = config.sparse_infill_density;
442 InfillPattern pattern = config.sparse_infill_pattern;
443 if (density == 0.)
444 return -1;
445 // Orca: the adaptive TPMS infill is as sparse as its interior density.
446 if (density < 100.f && config.adaptive_infill_mode != AdaptiveInfillMode::Disabled && is_adaptive_infill_pattern(pattern))
447 density = std::min(density, std::max(1.f, float(config.adaptive_infill_interior_density)));
448
449 //BBS: rough estimation and need to be optimized
450 double spacing = flow.scaled_spacing() * (100 - density) / density;
451 switch (pattern) {
452 case ipConcentric:
453 case ipSpiralInset:
454 case ipRectilinear:
455 case ipLine:
456 case ipGyroid:
457 case ipTpmsD:
458 case ipTpmsFK:
460 case ipOctagramSpiral:
461 case ipHilbertCurve:
463 case ip3DHoneycomb:
465 max_void_area = std::max(max_void_area, spacing * spacing);
466 break;
467 case ipGrid:
468 case ipLateralLattice:
469 case ipHoneycomb:
470 case ipLightning:
471 max_void_area = std::max(max_void_area, 4.0 * spacing * spacing);
472 break;
473 case ipCubic:
474 case ipAdaptiveCubic:
475 case ipTriangles:
476 case ipStars:
477 case ipSupportCubic:
478 max_void_area = std::max(max_void_area, 4.5 * spacing * spacing);
479 break;
480 default:
481 max_void_area = std::max(max_void_area, spacing * spacing);
482 break;
483 }
484 };
485 return max_void_area;
486}
InfillPattern
Definition PrintConfig.hpp:126
bool is_adaptive_infill_pattern(InfillPattern pattern)
Definition PrintConfig.hpp:176
zaa_minimize_perimeter_height PrintRegionConfig
Definition PrintConfig.hpp:2183
@ frInfill
Definition Flow.hpp:21
@ Disabled
Definition PrintConfig.hpp:291

References Slic3r::Disabled, Slic3r::frInfill, Slic3r::ip3DHoneycomb, Slic3r::ipAdaptiveCubic, Slic3r::ipAlignedRectilinear, Slic3r::ipArchimedeanChords, Slic3r::ipConcentric, Slic3r::ipCubic, Slic3r::ipGrid, Slic3r::ipGyroid, Slic3r::ipHilbertCurve, Slic3r::ipHoneycomb, Slic3r::ipLateralHoneycomb, Slic3r::ipLateralLattice, Slic3r::ipLightning, Slic3r::ipLine, Slic3r::ipOctagramSpiral, Slic3r::ipRectilinear, Slic3r::ipSpiralInset, Slic3r::ipStars, Slic3r::ipSupportCubic, Slic3r::ipTpmsD, Slic3r::ipTpmsFK, Slic3r::ipTriangles, Slic3r::is_adaptive_infill_pattern(), m_regions, Slic3r::PrintRegionConfig, and Slic3r::Flow::scaled_spacing().

Here is the call graph for this function:

◆ has_extrusions()

virtual bool Slic3r::Layer::has_extrusions ( ) const
inlinevirtual

Reimplemented in Slic3r::SupportLayer.

229{ for (auto layerm : m_regions) if (layerm->has_extrusions()) return true; return false; }

References m_regions.

Referenced by Slic3r::belt_object_layer_prints_something(), and Slic3r::GCode::collect_layers_to_print().

Here is the caller graph for this function:

◆ id()

◆ idx_higher_or_equal()

template<typename IteratorType, typename IndexType, typename FN_HIGHER_EQUAL>
IndexType Slic3r::Layer::idx_higher_or_equal ( IteratorType begin,
IteratorType end,
IndexType idx,
FN_HIGHER_EQUAL fn_higher_equal )
inlinestatic
244 {
245 auto size = int(end - begin);
246 if (size == 0) {
247 idx = 0;
248 }
249 else if (idx == IndexType(-1)) {
250 // First of the batch of layers per thread pool invocation. Use binary search.
251 int idx_low = 0;
252 int idx_high = std::max(0, size - 1);
253 while (idx_low + 1 < idx_high) {
254 int idx_mid = (idx_low + idx_high) / 2;
255 if (fn_higher_equal(begin[idx_mid]))
256 idx_high = idx_mid;
257 else
258 idx_low = idx_mid;
259 }
260 idx = fn_higher_equal(begin[idx_low]) ? idx_low :
261 (fn_higher_equal(begin[idx_high]) ? idx_high : size);
262 }
263 else {
264 // For the other layers of this batch of layers, search incrementally, which is cheaper than the binary search.
265 while (int(idx) < size && !fn_higher_equal(begin[idx]))
266 ++idx;
267 }
268 return idx;
269 }

Referenced by Slic3r::TreeSupport::get_trim_support_regions().

Here is the caller graph for this function:

◆ is_perimeter_compatible()

bool Slic3r::Layer::is_perimeter_compatible ( const Print & print,
const PrintRegion & a,
const PrintRegion & b )
static
158{
159 const PrintRegionConfig& config = a.config();
160 const PrintRegionConfig& other_config = b.config();
161
162 return config.outer_wall_filament_id == other_config.outer_wall_filament_id
163 && config.inner_wall_filament_id == other_config.inner_wall_filament_id
164 && config.wall_loops == other_config.wall_loops
165 && config.wall_sequence == other_config.wall_sequence
166 && config.is_infill_first == other_config.is_infill_first
167 && config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.inner_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
168 && config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.outer_wall_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
169 && config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.small_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
170 && config.small_support_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.small_support_perimeter_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
171 && config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id)) == other_config.gap_infill_speed.get_at(print.get_extruder_id(config.outer_wall_filament_id))
172 && config.filter_out_gap_fill.value == other_config.filter_out_gap_fill.value
173 && config.detect_overhang_wall == other_config.detect_overhang_wall
174 && config.unsupported_wall_last == other_config.unsupported_wall_last
175 && config.overhang_reverse == other_config.overhang_reverse
176 && config.overhang_reverse_threshold == other_config.overhang_reverse_threshold
177 && config.wall_direction == other_config.wall_direction
178 && config.opt_serialize("inner_wall_line_width") == other_config.opt_serialize("inner_wall_line_width")
179 && config.opt_serialize("outer_wall_line_width") == other_config.opt_serialize("outer_wall_line_width")
180 && config.detect_thin_wall == other_config.detect_thin_wall
181 && config.infill_wall_overlap == other_config.infill_wall_overlap
182 && config.top_bottom_infill_wall_overlap == other_config.top_bottom_infill_wall_overlap
183 // Orca: these flags directly change the effective wall count produced by the perimeter
184 // generator. If two regions disagree on any of them, merging their slices into one shared make_perimeters
185 // call would silently use the first region's flag for both.
186 && config.only_one_wall_first_layer == other_config.only_one_wall_first_layer
187 && config.only_one_wall_top == other_config.only_one_wall_top
188 && config.min_width_top_surface == other_config.min_width_top_surface
189 && config.seam_slope_type == other_config.seam_slope_type
190 && config.seam_slope_conditional == other_config.seam_slope_conditional
191 && config.scarf_angle_threshold == other_config.scarf_angle_threshold
192 && config.scarf_overhang_threshold == other_config.scarf_overhang_threshold
193 && config.scarf_joint_speed == other_config.scarf_joint_speed
194 && config.scarf_joint_flow_ratio == other_config.scarf_joint_flow_ratio
195 && config.seam_slope_start_height == other_config.seam_slope_start_height
196 && config.seam_slope_entire_loop == other_config.seam_slope_entire_loop
197 && config.seam_slope_min_length == other_config.seam_slope_min_length
198 && config.seam_slope_steps == other_config.seam_slope_steps
199 && config.seam_slope_inner_walls == other_config.seam_slope_inner_walls;
200}

References Slic3r::PrintRegion::config(), Slic3r::Print::get_extruder_id(), and Slic3r::PrintRegionConfig.

Referenced by make_perimeters().

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

◆ make_contour_z()

void Slic3r::Layer::make_contour_z ( const sla::IndexedMesh & mesh)
243{
244 for (LayerRegion *region : this->regions()) {
245 if (!region->region().config().zaa_enabled)
246 continue;
247
248 handle_extrusion_collection(region, mesh, region->fills, {erTopSolidInfill, erIroning, erPerimeter, erExternalPerimeter, erMixed});
249 handle_extrusion_collection(region, mesh, region->perimeters, {erPerimeter, erExternalPerimeter, erMixed});
250 }
251}
const LayerRegionPtrs & regions() const
Definition Layer.hpp:185
static void handle_extrusion_collection(LayerRegion *region, const sla::IndexedMesh &mesh, ExtrusionEntityCollection &collection, std::initializer_list< ExtrusionRole > roles)
Definition ContourZ.cpp:232

References Slic3r::handle_extrusion_collection(), and regions().

Here is the call graph for this function:

◆ make_fills() [1/2]

void Slic3r::Layer::make_fills ( )
inline
210{ this->make_fills(nullptr); }
void make_fills()
Definition Layer.hpp:210

References make_fills().

Referenced by make_fills(), and make_fills().

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

◆ make_fills() [2/2]

void Slic3r::Layer::make_fills ( const FillAdaptive::RegionOctrees * fill_octrees,
FillLightning::Generator * lightning_generator = nullptr )
1354{
1355 for (LayerRegion *layerm : m_regions)
1356 layerm->fills.clear();
1357
1358
1359#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
1360// this->export_region_fill_surfaces_to_svg_debug("10_fill-initial");
1361#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
1362 LockRegionParam lock_param;
1363 std::vector<SurfaceFill> surface_fills = group_fills(*this, lock_param);
1364 const Slic3r::BoundingBox bbox = this->object()->bounding_box();
1365 const auto resolution = this->object()->print()->config().resolution.value;
1366
1367#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
1368 {
1369 static int iRun = 0;
1370 export_group_fills_to_svg(debug_out_path("Layer-fill_surfaces-10_fill-final-%d.svg", iRun ++).c_str(), surface_fills);
1371 }
1372#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
1373
1374 for (SurfaceFill &surface_fill : surface_fills) {
1375 // Create the filler object.
1376 std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));
1377 f->set_bounding_box(bbox);
1378 f->layer_id = this->id();
1379 {
1380 const auto &rcfg = m_regions[surface_fill.region_id]->region().config();
1381 f->dont_alternate_fill_direction = rcfg.zaa_enabled && rcfg.zaa_dont_alternate_fill_direction;
1382 }
1383 f->z = this->print_z;
1384 f->angle = surface_fill.params.angle;
1385 f->fixed_angle = surface_fill.params.fixed_angle;
1386 const FillAdaptive::Octrees *octrees = fill_octrees ? fill_octrees->region(surface_fill.region_id) : nullptr;
1387 f->adaptive_infill_field = this->object()->adaptive_infill_field(surface_fill.params.adaptive_infill_mode);
1388 f->print_config = &this->object()->print()->config();
1389 f->print_object_config = &this->object()->config();
1390 if (surface_fill.params.pattern == ipConcentricInternal) {
1391 FillConcentricInternal *fill_concentric = dynamic_cast<FillConcentricInternal *>(f.get());
1392 assert(fill_concentric != nullptr);
1393 fill_concentric->print_config = &this->object()->print()->config();
1394 fill_concentric->print_object_config = &this->object()->config();
1395 } else if (surface_fill.params.pattern == ipConcentric) {
1396 FillConcentric *fill_concentric = dynamic_cast<FillConcentric *>(f.get());
1397 assert(fill_concentric != nullptr);
1398 fill_concentric->print_config = &this->object()->print()->config();
1399 fill_concentric->print_object_config = &this->object()->config();
1400 } else if (surface_fill.params.pattern == ipLightning)
1401 dynamic_cast<FillLightning::Filler*>(f.get())->generator = lightning_generator;
1402 // calculate flow spacing for infill pattern generation
1403 bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.bridge;
1404 double link_max_length = 0.;
1405 if (! surface_fill.params.bridge) {
1406#if 0
1407 link_max_length = layerm.region()->config().get_abs_value(surface.is_external() ? "external_fill_link_max_length" : "fill_link_max_length", flow.spacing());
1408// printf("flow spacing: %f, is_external: %d, link_max_length: %lf\n", flow.spacing(), int(surface.is_external()), link_max_length);
1409#else
1410 if (surface_fill.params.density > 80.) // 80%
1411 link_max_length = 3. * f->spacing;
1412#endif
1413 }
1414
1415 LayerRegion* layerm = this->m_regions[surface_fill.region_id];
1416
1417 // Maximum length of the perimeter segment linking two infill lines.
1418 f->link_max_length = (coord_t)scale_(link_max_length);
1419 // Used by the concentric infill pattern to clip the loops to create extrusion paths.
1420 f->loop_clipping = coord_t(scale_(layerm->region().config().seam_gap.get_abs_value(surface_fill.params.flow.nozzle_diameter())));
1421
1422 // apply half spacing using this flow's own spacing and generate infill
1423 FillParams params;
1424 params.density = float(0.01 * surface_fill.params.density);
1425 params.multiline = surface_fill.params.multiline;
1426 params.dont_adjust = false; // surface_fill.params.dont_adjust;
1427 params.anchor_length = surface_fill.params.anchor_length;
1428 params.anchor_length_max = surface_fill.params.anchor_length_max;
1429 params.resolution = resolution;
1430 params.use_arachne = surface_fill.params.pattern == ipConcentric || surface_fill.params.pattern == ipSpiralInset ||
1431 surface_fill.params.pattern == ipConcentricInternal;
1432 params.layer_height = layerm->layer()->height;
1433 params.lateral_lattice_angle_1 = surface_fill.params.lateral_lattice_angle_1;
1434 params.lateral_lattice_angle_2 = surface_fill.params.lateral_lattice_angle_2;
1435 params.infill_overhang_angle = surface_fill.params.infill_overhang_angle;
1436 params.gyroid_optimized = surface_fill.params.gyroid_optimized;
1437 params.adaptive_infill_mode = surface_fill.params.adaptive_infill_mode;
1438 params.adaptive_infill_interior_density = float(0.01 * surface_fill.params.adaptive_infill_interior_density);
1439 params.adaptive_infill_gradient = surface_fill.params.adaptive_infill_gradient;
1440 params.smooth_factor = surface_fill.params.smooth_factor;
1441
1442 // BBS
1443 params.flow = surface_fill.params.flow;
1444 params.extrusion_role = surface_fill.params.extrusion_role;
1445 params.using_internal_flow = using_internal_flow;
1446 params.no_extrusion_overlap = surface_fill.params.overlap;
1447 auto &region_config = layerm->region().config();
1448 params.config = &region_config;
1449 params.pattern = surface_fill.params.pattern;
1450 params.fill_order = surface_fill.params.fill_order;
1451
1452 // Orca: Checking the filling of a centered surface by drawing for each model parts
1453 bool is_top_or_bottom = params.extrusion_role == erTopSolidInfill || params.extrusion_role == erBottomSurface;
1454 if (is_top_or_bottom) {
1455 params.center_of_surface_pattern = surface_fill.params.center_of_surface_pattern; // Orca: center of surface pattern
1456 }
1457 if( surface_fill.params.pattern == ipLockedZag ) {
1458 params.locked_zag = true;
1459 params.infill_lock_depth = surface_fill.params.infill_lock_depth;
1460 params.skin_infill_depth = surface_fill.params.skin_infill_depth;
1461 f->set_lock_region_param(lock_param);
1462 }
1463 if (surface_fill.params.pattern == ipCrossZag || surface_fill.params.pattern == ipLockedZag) {
1464 if (f->layer_id % 2 == 0) {
1465 params.horiz_move -= scale_(region_config.infill_shift_step) * (f->layer_id / 2);
1466 } else {
1467 params.horiz_move += scale_(region_config.infill_shift_step) * (f->layer_id / 2);
1468 }
1469
1470 params.symmetric_infill_y_axis = surface_fill.params.symmetric_infill_y_axis;
1471
1472 } else if (surface_fill.params.pattern == ipZigZag) {
1473 params.symmetric_infill_y_axis = surface_fill.params.symmetric_infill_y_axis;
1474
1475 } else if (surface_fill.params.pattern == ip3DHoneycomb) {
1476 params.infill_complete_top = surface_fill.params.infill_complete_top;
1477 }
1478 if (surface_fill.params.pattern == ipGrid)
1479 params.can_reverse = false;
1480 for (ExPolygon& expoly : surface_fill.expolygons) {
1481
1482 // Orca: Reuse the body box and octree used for bridge anchoring, resetting them for each surface.
1483 const int body = infill_body(*this, surface_fill, expoly);
1484 f->set_bounding_box(body >= 0 ? this->object()->separated_body_bboxes()[body] : bbox);
1485 f->adapt_fill_octree = octrees ? octrees->get(body) : nullptr;
1486
1487 // Only the part of the layer-wide no-overlap area under this expolygon matters, so clip it to the
1488 // expolygon's box first (padded past the safety offset, which grows the clip side). The result is
1489 // identical; the cost is not: a layer split into many small fills, e.g. by colour painting,
1490 // otherwise intersects every one of them with the whole layer.
1491 BoundingBox no_overlap_bbox = get_extents(expoly);
1492 no_overlap_bbox.offset(SCALED_EPSILON);
1493 f->no_overlap_expolygons = intersection_ex(
1494 ClipperUtils::clip_clipper_polygons_with_subject_bbox(surface_fill.no_overlap_expolygons, no_overlap_bbox),
1495 ExPolygons() = {expoly}, ApplySafetyOffset::Yes);
1496 if (params.symmetric_infill_y_axis) {
1497 params.symmetric_y_axis = f->extended_object_bounding_box().center().x();
1498 expoly.symmetric_y(params.symmetric_y_axis);
1499 }
1500
1501 // Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
1502 f->spacing = surface_fill.params.spacing;
1503 surface_fill.surface.expolygon = std::move(expoly);
1504
1505 if(surface_fill.params.bridge && surface_fill.surface.is_external() && surface_fill.params.density > 99.0){
1506 params.density = layerm->region().config().bridge_density.get_abs_value(1.0);
1507 params.dont_adjust = true;
1508 }
1509 if(surface_fill.surface.is_internal_bridge()){
1510 params.density = f->print_object_config->internal_bridge_density.get_abs_value(1.0);
1511 params.dont_adjust = true;
1512 }
1513 // Orca: Elephant foot compensation for solid layers above bottommost by infill density manipulation.
1514 float elefant_density = f->print_object_config->elefant_foot_layers_density.get_abs_value(1.0);
1515 if (!is_approx(elefant_density, 1.0f) && surface_fill.surface.is_solid_infill()) {
1516 size_t elefant_layers = f->print_object_config->elefant_foot_compensation_layers.value;
1517 if (f->layer_id > 0 && f->layer_id <= elefant_layers)
1518 params.density = 1.0f - (1.0f - elefant_density) * (elefant_layers - (f->layer_id - 1)) / elefant_layers; // Reverse calculation - The higher layer number means the higher density. Counting starts from the second layer.
1519 }
1520 // make fill
1521 f->fill_surface_extrusion(&surface_fill.surface,
1522 params,
1523 m_regions[surface_fill.region_id]->fills.entities);
1524 }
1525 }
1526
1527 // add thin fill regions
1528 // Unpacks the collection, creates multiple collections per path.
1529 // The path type could be ExtrusionPath, ExtrusionLoop or ExtrusionEntityCollection.
1530 // Why the paths are unpacked?
1531 for (LayerRegion *layerm : m_regions)
1532 for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities) {
1533 ExtrusionEntityCollection &collection = *(new ExtrusionEntityCollection());
1534 layerm->fills.entities.push_back(&collection);
1535 collection.entities.push_back(thin_fill->clone());
1536 }
1537
1538#ifndef NDEBUG
1539 for (LayerRegion *layerm : m_regions)
1540 for (size_t i = 0; i < layerm->fills.entities.size(); ++ i)
1541 assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities[i]) != nullptr);
1542#endif
1543}
#define SCALED_EPSILON
Definition libslic3r.h:109
Polygons clip_clipper_polygons_with_subject_bbox(const Polygons &src, const BoundingBox &bbox)
Definition ClipperUtils.cpp:132
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:20
@ erBottomSurface
Definition ExtrusionEntity.hpp:34
@ erTopSolidInfill
Definition ExtrusionEntity.hpp:33
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:320
Slic3r::ExPolygons intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:878
@ Yes
Definition ClipperUtils.hpp:51

References Slic3r::FillParams::adaptive_infill_gradient, Slic3r::FillParams::adaptive_infill_interior_density, Slic3r::FillParams::adaptive_infill_mode, Slic3r::FillParams::anchor_length, Slic3r::FillParams::anchor_length_max, Slic3r::FillParams::can_reverse, Slic3r::FillParams::center_of_surface_pattern, Slic3r::ClipperUtils::clip_clipper_polygons_with_subject_bbox(), Slic3r::ExtrusionEntity::clone(), Slic3r::FillParams::config, Slic3r::PrintRegion::config(), Slic3r::debug_out_path(), Slic3r::FillParams::density, Slic3r::FillParams::dont_adjust, Slic3r::ExtrusionEntityCollection::entities, Slic3r::erBottomSurface, Slic3r::erTopSolidInfill, Slic3r::FillParams::extrusion_role, Slic3r::f(), Slic3r::FillParams::fill_order, Slic3r::FillParams::flow, Slic3r::FillLightning::Filler::generator, Slic3r::FillAdaptive::Octrees::get(), Slic3r::get_extents(), Slic3r::group_fills(), Slic3r::FillParams::gyroid_optimized, height, Slic3r::FillParams::horiz_move, id(), Slic3r::infill_body(), Slic3r::FillParams::infill_complete_top, Slic3r::FillParams::infill_lock_depth, Slic3r::FillParams::infill_overhang_angle, Slic3r::intersection_ex(), Slic3r::ip3DHoneycomb, Slic3r::ipConcentric, Slic3r::ipConcentricInternal, Slic3r::ipCrossZag, Slic3r::ipGrid, Slic3r::ipLightning, Slic3r::ipLockedZag, Slic3r::ipSpiralInset, Slic3r::ipZigZag, Slic3r::is_approx(), Slic3r::FillParams::lateral_lattice_angle_1, Slic3r::FillParams::lateral_lattice_angle_2, Slic3r::LayerRegion::layer(), Slic3r::FillParams::layer_height, Slic3r::FillParams::locked_zag, m_regions, make_fills(), Slic3r::FillParams::multiline, Slic3r::Fill::new_from_type(), Slic3r::FillParams::no_extrusion_overlap, object(), Slic3r::BoundingBoxBase< PointType, APointsType >::offset(), Slic3r::FillParams::pattern, Slic3r::Fill::print_config, Slic3r::Fill::print_object_config, print_z, Slic3r::FillAdaptive::RegionOctrees::region(), Slic3r::LayerRegion::region(), Slic3r::FillParams::resolution, Slic3r::resolution(), scale_, SCALED_EPSILON, Slic3r::FillParams::skin_infill_depth, Slic3r::FillParams::smooth_factor, Slic3r::FillParams::symmetric_infill_y_axis, Slic3r::ExPolygon::symmetric_y(), Slic3r::FillParams::symmetric_y_axis, Slic3r::FillParams::use_arachne, Slic3r::FillParams::using_internal_flow, and Slic3r::Yes.

Here is the call graph for this function:

◆ make_ironing()

void Slic3r::Layer::make_ironing ( )
1708{
1709 // LayerRegion::slices contains surfaces marked with SurfaceType.
1710 // Here we want to collect top surfaces extruded with the same extruder.
1711 // A surface will be ironed with the same extruder to not contaminate the print with another material leaking from the nozzle.
1712
1713 // First classify regions based on the extruder used.
1714 struct IroningParams {
1715 InfillPattern pattern;
1716 int extruder = -1;
1717 bool just_infill = false;
1718 // Spacing of the ironing lines, also to calculate the extrusion flow from.
1719 double line_spacing;
1720 // Height of the extrusion, to calculate the extrusion flow from.
1721 double height;
1722 double speed;
1723 double angle;
1724 bool fixed_angle;
1725 double inset;
1726
1727 bool operator<(const IroningParams &rhs) const {
1728 RETURN_COMPARE_NON_EQUAL(extruder);
1729 RETURN_COMPARE_NON_EQUAL(just_infill);
1730 RETURN_COMPARE_NON_EQUAL(line_spacing);
1734 RETURN_COMPARE_NON_EQUAL(fixed_angle);
1736 return false;
1737 }
1738
1739 bool operator==(const IroningParams &rhs) const {
1740 return this->extruder == rhs.extruder &&
1741 this->just_infill == rhs.just_infill &&
1742 this->line_spacing == rhs.line_spacing &&
1743 this->height == rhs.height &&
1744 this->speed == rhs.speed &&
1745 this->angle == rhs.angle &&
1746 this->fixed_angle == rhs.fixed_angle &&
1747 this->pattern == rhs.pattern &&
1748 this->inset == rhs.inset;
1749 }
1750
1751 LayerRegion *layerm = nullptr;
1752
1753 // IdeaMaker: ironing
1754 // ironing flowrate (5% percent)
1755 // ironing speed (10 mm/sec)
1756
1757 // Kisslicer:
1758 // iron off, Sweep, Group
1759 // ironing speed: 15 mm/sec
1760
1761 // Cura:
1762 // Pattern (zig-zag / concentric)
1763 // line spacing (0.1mm)
1764 // flow: from normal layer height. 10%
1765 // speed: 20 mm/sec
1766 };
1767
1768 std::vector<IroningParams> by_extruder;
1769 double default_layer_height = this->object()->config().layer_height;
1770
1771 for (LayerRegion *layerm : m_regions)
1772 if (! layerm->slices.empty()) {
1773 IroningParams ironing_params;
1774 const PrintRegionConfig &config = layerm->region().config();
1775 ironing_params.extruder = Layer::choose_ironing_extruder(
1776 config,
1777 /*spiral_mode=*/this->object()->print()->config().spiral_mode,
1778 /*is_topmost_layer=*/layerm->layer()->upper_layer == nullptr);
1779 if (ironing_params.extruder != -1) {
1780 //TODO just_infill is currently not used.
1781 ironing_params.just_infill = false;
1782 // ORCA: Get filament-specific overrides if configured, otherwise use process values
1783 size_t extruder_idx = ironing_params.extruder - 1;
1784 ironing_params.line_spacing = std::max(IRONING_SPACING_MIN, !config.filament_ironing_spacing.is_nil(extruder_idx)
1785 ? config.filament_ironing_spacing.get_at(extruder_idx)
1786 : config.ironing_spacing.value);
1787 ironing_params.inset = (!config.filament_ironing_inset.is_nil(extruder_idx)
1788 ? config.filament_ironing_inset.get_at(extruder_idx)
1789 : config.ironing_inset);
1790 ironing_params.height = default_layer_height * 0.01 * (!config.filament_ironing_flow.is_nil(extruder_idx)
1791 ? config.filament_ironing_flow.get_at(extruder_idx)
1792 : config.ironing_flow);
1793 ironing_params.speed = (!config.filament_ironing_speed.is_nil(extruder_idx)
1794 ? config.filament_ironing_speed.get_at(extruder_idx)
1795 : config.ironing_speed);
1796 const bool top_layer_direction_set = config.top_layer_direction.value >= 0.;
1797 const double top_layer_base_angle = top_layer_direction_set ?
1798 Geometry::deg2rad(config.top_layer_direction.value) :
1799 calculate_infill_rotation_angle(this->object(), this->id(), config.solid_infill_direction.value, config.solid_infill_rotate_template.value);
1800 double ironing_angle = (config.ironing_angle_fixed ? 0. : top_layer_base_angle) + config.ironing_angle * M_PI / 180.;
1801 if (config.align_infill_direction_to_model) {
1802 auto m = this->object()->trafo().matrix();
1803 ironing_angle += atan2((double)m(1, 0), (double)m(0, 0));
1804 }
1805 ironing_params.angle = ironing_angle;
1806 ironing_params.fixed_angle = config.ironing_angle_fixed || top_layer_direction_set || !config.solid_infill_rotate_template.value.empty();
1807 ironing_params.pattern = config.ironing_pattern;
1808 ironing_params.layerm = layerm;
1809 by_extruder.emplace_back(ironing_params);
1810 }
1811 }
1812 std::sort(by_extruder.begin(), by_extruder.end());
1813
1814 FillParams fill_params;
1815 fill_params.density = 1.;
1816 fill_params.monotonic = true;
1817 InfillPattern f_pattern = ipRectilinear;
1818 std::unique_ptr<Fill> f = std::unique_ptr<Fill>(Fill::new_from_type(f_pattern));
1819 f->set_bounding_box(this->object()->bounding_box());
1820 f->layer_id = this->id();
1821 f->z = this->print_z;
1822 f->overlap = 0;
1823 for (size_t i = 0; i < by_extruder.size();) {
1824 // Find span of regions equivalent to the ironing operation.
1825 IroningParams &ironing_params = by_extruder[i];
1826 f->dont_alternate_fill_direction = ironing_params.layerm->region().config().zaa_enabled && ironing_params.layerm->region().config().zaa_dont_alternate_fill_direction;
1827 // Create the filler object.
1828 if( f_pattern != ironing_params.pattern )
1829 {
1830 f_pattern = ironing_params.pattern;
1831 f = std::unique_ptr<Fill>(Fill::new_from_type(f_pattern));
1832 f->set_bounding_box(this->object()->bounding_box());
1833 f->layer_id = this->id();
1834 f->z = this->print_z;
1835 f->overlap = 0;
1836 }
1837
1838 size_t j = i;
1839 for (++ j; j < by_extruder.size() && ironing_params == by_extruder[j]; ++ j) ;
1840
1841 // Create the ironing extrusions for regions <i, j)
1842 ExPolygons ironing_areas;
1843 double nozzle_dmr = nozzle_diameter_for_filament(this->object()->print()->config(), ironing_params.extruder, this->object()->print()->is_BBL_printer());
1844 if (ironing_params.just_infill) {
1845 //TODO just_infill is currently not used.
1846 // Just infill.
1847 } else {
1848 // Infill and perimeter.
1849 // Merge top surfaces with the same ironing parameters.
1850 Polygons polys;
1851 Polygons infills;
1852 for (size_t k = i; k < j; ++ k) {
1853 const IroningParams &ironing_params = by_extruder[k];
1854 const PrintRegionConfig &region_config = ironing_params.layerm->region().config();
1855 bool iron_everything = region_config.ironing_type == IroningType::AllSolid;
1856 bool iron_completely = iron_everything;
1857 if (iron_everything) {
1858 // Check whether there is any non-solid hole in the regions.
1859 bool internal_infill_solid = region_config.sparse_infill_density.value > 95.;
1860 for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces)
1861 if ((!internal_infill_solid && surface.surface_type == stInternal) || surface.surface_type == stInternalBridge || surface.surface_type == stInternalVoid) {
1862 // Some fill region is not quite solid. Don't iron over the whole surface.
1863 iron_completely = false;
1864 break;
1865 }
1866 }
1867 if (iron_completely) {
1868 // Iron everything. This is likely only good for solid transparent objects.
1869 for (const Surface &surface : ironing_params.layerm->slices.surfaces)
1870 polygons_append(polys, surface.expolygon);
1871 } else {
1872 for (const Surface &surface : ironing_params.layerm->slices.surfaces)
1873 if ((surface.surface_type == stTop && (region_config.top_shell_layers > 0 || this->object()->print()->config().spiral_mode)) || (iron_everything && surface.surface_type == stBottom && region_config.bottom_shell_layers > 0))
1874 // stBottomBridge is not being ironed on purpose, as it would likely destroy the bridges.
1875 polygons_append(polys, surface.expolygon);
1876 }
1877 if (iron_everything && ! iron_completely) {
1878 // Add solid fill surfaces. This may not be ideal, as one will not iron perimeters touching these
1879 // solid fill surfaces, but it is likely better than nothing.
1880 for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces)
1881 if (surface.surface_type == stInternalSolid)
1882 polygons_append(infills, surface.expolygon);
1883 }
1884 }
1885
1886 if (! infills.empty() || j > i + 1) {
1887 // Ironing over more than a single region or over solid internal infill.
1888 if (! infills.empty())
1889 // For IroningType::AllSolid only:
1890 // Add solid infill areas for layers, that contain some non-ironable infil (sparse infill, bridge infill).
1891 append(polys, std::move(infills));
1892 polys = union_safety_offset(polys);
1893 }
1894 // Trim the top surfaces with half the nozzle diameter.
1895 // BBS: ironing inset
1896 double ironing_areas_offset = ironing_params.inset == 0 ? float(scale_(0.5 * nozzle_dmr)) : scale_(ironing_params.inset);
1897 ironing_areas = intersection_ex(polys, offset(this->lslices, - ironing_areas_offset));
1898 }
1899
1900 // Create the filler object.
1901 f->spacing = ironing_params.line_spacing;
1902 f->angle = float(ironing_params.angle);
1903 f->fixed_angle = ironing_params.fixed_angle;
1904 f->link_max_length = (coord_t) scale_(3. * f->spacing);
1905 double extrusion_height = ironing_params.height * f->spacing / nozzle_dmr;
1906 float extrusion_width = Flow::rounded_rectangle_extrusion_width_from_spacing(float(nozzle_dmr), float(extrusion_height));
1907 double flow_mm3_per_mm = nozzle_dmr * extrusion_height;
1908 Surface surface_fill(stTop, ExPolygon());
1909 for (ExPolygon &expoly : ironing_areas) {
1910 surface_fill.expolygon = std::move(expoly);
1911 Polylines polylines;
1912 try {
1913 polylines = f->fill_surface(&surface_fill, fill_params);
1914 } catch (InfillFailedException &) {
1915 }
1916 if (! polylines.empty()) {
1917 // Save into layer.
1918 ExtrusionEntityCollection *eec = nullptr;
1919 ironing_params.layerm->fills.entities.push_back(eec = new ExtrusionEntityCollection());
1920 // Don't sort the ironing infill lines as they are monotonicly ordered.
1921 eec->no_sort = true;
1923 eec->entities, std::move(polylines),
1924 erIroning,
1925 flow_mm3_per_mm, extrusion_width, float(extrusion_height));
1926 }
1927 }
1928
1929 // Regions up to j were processed.
1930 i = j;
1931 }
1932}
#define M_PI
Definition ExtrusionSimulator.cpp:31
#define RETURN_COMPARE_NON_EQUAL(KEY)
static bool operator<(wxColour const &l, wxColour const &r)
Definition StateColor.cpp:11
static float rounded_rectangle_extrusion_width_from_spacing(float spacing, float height)
Definition Flow.cpp:215
ExPolygons lslices
Definition Layer.hpp:170
static int choose_ironing_extruder(const PrintRegionConfig &cfg, bool spiral_mode, bool is_topmost_layer)
Definition Fill.cpp:1691
constexpr T deg2rad(const T angle)
Definition Geometry.hpp:312
BoundingBox inset(BoundingBox box, const Point &by)
Definition IMEXArrange.cpp:38
coord_t height(const BoundingBox &box)
Definition Arrange.cpp:1185
double calculate_infill_rotation_angle(const PrintObject *object, size_t layer_id, const double &fixed_infill_angle, const std::string &template_string)
Definition Fill.cpp:84
void extrusion_entities_append_paths(ExtrusionEntitiesPtr &dst, Polylines &polylines, ExtrusionRole role, double mm3_per_mm, float width, float height, bool can_reverse=true)
Definition ExtrusionEntity.hpp:608
BoundingBoxf3 bounding_box(const TriangleMesh &m)
Definition TriangleMesh.hpp:391
double nozzle_diameter_for_filament(const PrintConfig &config, int filament_id, bool is_bbl_printer)
Definition PrintConfig.cpp:148
@ erIroning
Definition ExtrusionEntity.hpp:35
std::vector< Polygon, PointsAllocator< Polygon > > Polygons
Definition Polygon.hpp:22
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138
bool operator==(const clonable_ptr< T > &l, const clonable_ptr< U > &r) noexcept
Definition clonable_ptr.hpp:145
constexpr double IRONING_SPACING_MIN
Definition PrintConfig.hpp:212
solid_infill_direction((ConfigOptionFloat, top_layer_direction))((ConfigOptionFloat
Slic3r::Polygons union_safety_offset(const Slic3r::Polygons &polygons)
Definition ClipperUtils.hpp:386
void polygons_append(Polygons &dst, const ExPolygon &src)
Definition ExPolygon.hpp:411
@ stInternalSolid
Definition Surface.hpp:28
@ stTop
Definition Surface.hpp:18
@ stInternalBridge
Definition Surface.hpp:30
@ stBottom
Definition Surface.hpp:20
@ stInternalVoid
Definition Surface.hpp:35
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:157

References Slic3r::AllSolid, Slic3r::angle(), Slic3r::append(), Slic3r::bounding_box(), Slic3r::calculate_infill_rotation_angle(), choose_ironing_extruder(), Slic3r::Geometry::deg2rad(), Slic3r::FillParams::density, Slic3r::ExtrusionEntityCollection::entities, Slic3r::erIroning, Slic3r::Surface::expolygon, Slic3r::extrusion_entities_append_paths(), Slic3r::f(), height, id(), Slic3r::intersection_ex(), Slic3r::ipRectilinear, Slic3r::IRONING_SPACING_MIN, lslices, M_PI, m_regions, make_ironing(), Slic3r::FillParams::monotonic, Slic3r::Fill::new_from_type(), Slic3r::ExtrusionEntityCollection::no_sort, Slic3r::nozzle_diameter_for_filament(), object(), Slic3r::offset(), operator<(), Slic3r::operator==(), Slic3r::polygons_append(), print_z, Slic3r::PrintRegionConfig, RETURN_COMPARE_NON_EQUAL, Slic3r::Flow::rounded_rectangle_extrusion_width_from_spacing(), scale_, Slic3r::stBottom, Slic3r::stInternal, Slic3r::stInternalBridge, Slic3r::stInternalSolid, Slic3r::stInternalVoid, Slic3r::stTop, Slic3r::Surface::surface_type, and Slic3r::union_safety_offset().

Referenced by make_ironing().

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

◆ make_perimeters()

void Slic3r::Layer::make_perimeters ( )
206{
207 BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id();
208
209 const auto clear_generated_extrusions = [](LayerRegion *layer_region) {
210 layer_region->perimeters.clear();
211 layer_region->fills.clear();
212 layer_region->thin_fills.clear();
213 };
214
215 // keep track of regions whose perimeters we have already generated
216 std::vector<unsigned char> done(m_regions.size(), false);
217
218 for (LayerRegionPtrs::iterator layerm = m_regions.begin(); layerm != m_regions.end(); ++ layerm)
219 if ((*layerm)->slices.empty()) {
220 (*layerm)->perimeters.clear();
221 (*layerm)->fills.clear();
222 (*layerm)->thin_fills.clear();
223 } else {
224 size_t region_id = layerm - m_regions.begin();
225 if (done[region_id])
226 continue;
227 BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
228 done[region_id] = true;
229 const PrintRegion &this_region = (*layerm)->region();
230
231 // find compatible regions
232 LayerRegionPtrs layerms;
233 layerms.push_back(*layerm);
234 for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it)
235 if (! (*it)->slices.empty()) {
236 LayerRegion* other_layerm = *it;
237 const PrintRegion &other_region = other_layerm->region();
238 // Per-part gradient tags a region with its owning ModelVolume; merging two
239 // differently-tagged regions would collapse volumes that need independent
240 // gradient runs. Both tags are invalid unless per-part gradient is on, so
241 // this is a no-op for every other configuration.
242 if (this_region.gradient_volume_id() != other_region.gradient_volume_id())
243 continue;
244 if (is_perimeter_compatible(*m_object->print(), this_region, other_region))
245 {
246 clear_generated_extrusions(other_layerm);
247 layerms.push_back(other_layerm);
248 done[it - m_regions.begin()] = true;
249 }
250 }
251
252 if (layerms.size() == 1) { // optimization
253 (*layerm)->fill_surfaces.surfaces.clear();
254 (*layerm)->make_perimeters((*layerm)->slices, {*layerm}, &(*layerm)->fill_surfaces, &(*layerm)->fill_no_overlap_expolygons);
255 (*layerm)->fill_expolygons = to_expolygons((*layerm)->fill_surfaces.surfaces);
256 } else {
257 // Orca: Unlike the compatible regions above, the initiating region has not
258 // been cleared yet and may contain paths from a previous incompatible run.
259 clear_generated_extrusions(*layerm);
260
261 SurfaceCollection new_slices;
262 // Use the region with highest infill rate, as the make_perimeters() function below decides on the gap fill based on the infill existence.
263 LayerRegion *layerm_config = layerms.front();
264 {
265 // group slices (surfaces) according to number of extra perimeters
266 std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
267 for (LayerRegion *layerm : layerms) {
268 for (const Surface &surface : layerm->slices.surfaces)
269 slices[surface.extra_perimeters].emplace_back(surface);
270 if (layerm->region().config().sparse_infill_density > layerm_config->region().config().sparse_infill_density)
271 layerm_config = layerm;
272 }
273 // merge the surfaces assigned to each group
274 for (std::pair<const unsigned short,Surfaces> &surfaces_with_extra_perimeters : slices)
275 new_slices.append(offset_ex(surfaces_with_extra_perimeters.second, ClipperSafetyOffset), surfaces_with_extra_perimeters.second.front());
276 }
277
278 // make perimeters
279 SurfaceCollection fill_surfaces;
280 //BBS
281 ExPolygons fill_no_overlap;
282 layerm_config->make_perimeters(new_slices, layerms, &fill_surfaces, &fill_no_overlap);
283
284 // assign fill_surfaces to each layer
285 if (!fill_surfaces.surfaces.empty()) {
286 for (LayerRegionPtrs::iterator l = layerms.begin(); l != layerms.end(); ++l) {
287 // Separate the fill surfaces.
288 ExPolygons expp = intersection_ex(fill_surfaces.surfaces, (*l)->slices.surfaces);
289 (*l)->fill_expolygons = expp;
290 (*l)->fill_surfaces.set(std::move(expp), fill_surfaces.surfaces.front());
291 //BBS: Separate fill_no_overlap
292 (*l)->fill_no_overlap_expolygons = intersection_ex((*l)->slices.surfaces, fill_no_overlap);
293 }
294
295 // When counterbore hole bridging (chbFilled) is active, process_no_bridge may
296 // create fill surfaces that extend beyond all region slices (e.g. by clearing
297 // holes in the bridge expolygon). These "extra" fills are lost during the
298 // intersection-based splitting above. Recover them and assign to the first
299 // merged region so the sacrificial bridge layer is not broken.
300 if (layerm_config->region().config().counterbore_hole_bridging.value != chbNone) {
301 Polygons all_region_slices_p;
302 for (LayerRegion *l : layerms)
303 polygons_append(all_region_slices_p, to_polygons(l->slices.surfaces));
304 ExPolygons extra_fill = diff_ex(fill_surfaces.surfaces, all_region_slices_p, ApplySafetyOffset::Yes);
305 if (!extra_fill.empty()) {
306 append(layerms.front()->fill_expolygons, extra_fill);
307 layerms.front()->fill_expolygons = union_ex(layerms.front()->fill_expolygons);
308 layerms.front()->fill_surfaces.append(std::move(extra_fill), fill_surfaces.surfaces.front());
309 }
310 }
311 }
312 }
313 }
314 BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << " - Done";
315}
static bool is_perimeter_compatible(const Print &print, const PrintRegion &a, const PrintRegion &b)
Definition Layer.cpp:157
void trace(unsigned int level, const char *message)
Definition utils.cpp:247
Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:831
@ chbNone
Definition PrintConfig.hpp:602
Polygons to_polygons(const ExPolygon &src)
Definition ExPolygon.hpp:307
Slic3r::ExPolygons offset_ex(const Slic3r::Polygons &polygons, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:605
Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, PolyFillType fill_type)
Definition ClipperUtils.cpp:1011
static constexpr const float ClipperSafetyOffset
Definition ClipperUtils.hpp:30
std::vector< LayerRegion * > LayerRegionPtrs
Definition Layer.hpp:29

References Slic3r::append(), Slic3r::SurfaceCollection::append(), Slic3r::chbNone, Slic3r::ClipperSafetyOffset, Slic3r::PrintRegion::config(), Slic3r::diff_ex(), Slic3r::Surface::extra_perimeters, Slic3r::PrintRegion::gradient_volume_id(), id(), Slic3r::intersection_ex(), is_perimeter_compatible(), m_object, m_regions, Slic3r::LayerRegion::make_perimeters(), Slic3r::offset_ex(), Slic3r::polygons_append(), Slic3r::LayerRegion::region(), Slic3r::SurfaceCollection::surfaces, Slic3r::to_expolygons(), Slic3r::to_polygons(), Slic3r::trace(), Slic3r::union_ex(), and Slic3r::Yes.

Here is the call graph for this function:

◆ make_slices()

void Slic3r::Layer::make_slices ( )
57{
58 ExPolygons slices;
59 if (m_regions.size() == 1) {
60 // optimization: if we only have one region, take its slices
61 slices = to_expolygons(m_regions.front()->slices.surfaces);
62 } else {
63 Polygons slices_p;
64 for (LayerRegion *layerm : m_regions)
65 polygons_append(slices_p, to_polygons(layerm->slices.surfaces));
66 slices = union_safety_offset_ex(slices_p);
67 }
68
69 this->lslices.clear();
70 this->lslices.reserve(slices.size());
71
72 // prepare ordering points
73 Points ordering_points;
74 ordering_points.reserve(slices.size());
75 for (const ExPolygon &ex : slices)
76 ordering_points.push_back(ex.contour.first_point());
77
78 // sort slices
79 std::vector<Points::size_type> order = chain_points(ordering_points);
80
81 // populate slices vector
82 for (size_t i : order)
83 this->lslices.emplace_back(std::move(slices[i]));
84}
std::vector< size_t > chain_points(const Points &points, const Point *start_near)
Definition ShortestPath.cpp:1565
Slic3r::ExPolygons union_safety_offset_ex(const Slic3r::Polygons &polygons)
Definition ClipperUtils.hpp:388
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73

References Slic3r::chain_points(), lslices, m_regions, Slic3r::polygons_append(), Slic3r::to_expolygons(), Slic3r::to_polygons(), and Slic3r::union_safety_offset_ex().

Here is the call graph for this function:

◆ merged()

ExPolygons Slic3r::Layer::merged ( float offset) const
136{
137 assert(offset_scaled >= 0.f);
138 // If no offset is set, apply EPSILON offset before union, and revert it afterwards.
139 float offset_scaled2 = 0;
140 if (offset_scaled == 0.f) {
141 offset_scaled = float( EPSILON);
142 offset_scaled2 = float(- EPSILON);
143 }
144 Polygons polygons;
145 for (LayerRegion *layerm : m_regions) {
146 const PrintRegionConfig &config = layerm->region().config();
147 // Our users learned to bend Slic3r to produce empty volumes to act as subtracters. Only add the region if it is non-empty.
148 if (config.bottom_shell_layers > 0 || config.top_shell_layers > 0 || config.sparse_infill_density > 0. || config.wall_loops > 0)
149 append(polygons, offset(layerm->slices.surfaces, offset_scaled));
150 }
151 ExPolygons out = union_ex(polygons);
152 if (offset_scaled2 != 0.f)
153 out = offset_ex(out, offset_scaled2);
154 return out;
155}
#define EPSILON
Definition ColorUtils.cpp:64

References Slic3r::append(), EPSILON, m_regions, Slic3r::offset(), Slic3r::offset_ex(), Slic3r::PrintRegionConfig, and Slic3r::union_ex().

Referenced by Slic3r::PrintObject::apply_conical_overhang().

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

◆ object() [1/2]

◆ object() [2/2]

const PrintObject * Slic3r::Layer::object ( ) const
inline
144{ return m_object; }

References m_object, and PrintObject.

Here is the call graph for this function:

◆ region_count()

size_t Slic3r::Layer::region_count ( ) const
inline
181{ return m_regions.size(); }

References m_regions.

Referenced by Slic3r::extract_layer().

Here is the caller graph for this function:

◆ regions()

const LayerRegionPtrs & Slic3r::Layer::regions ( ) const
inline
185{ return m_regions; }

References m_regions.

Referenced by Slic3r::PrintObject::belt_drop_unclaimed_fills(), Slic3r::PrintObject::bridge_over_infill(), Slic3r::collect_region_slices_by_type(), Slic3r::detect_contacts(), Slic3r::detect_overhangs(), Slic3r::PrintObject::discover_horizontal_shells(), Slic3r::PrintObject::discover_vertical_shells(), Slic3r::WipingExtrusions::ensure_perimeters_infills_order(), Slic3r::SeamPlacerImpl::extract_perimeter_polygons(), Slic3r::ToolOrdering::generate_first_layer_tool_order(), Slic3r::ToolOrdering::generate_first_layer_tool_order(), Slic3r::FillLightning::Generator::generateInitialInternalOverhangs(), Slic3r::FillLightning::Generator::generateTrees(), Slic3r::get_boundary(), Slic3r::get_external_perimeter_width(), Slic3r::get_perimeter_spacing(), Slic3r::get_print_object_bottom_layer_expolygons(), Slic3r::TreeSupport::get_trim_support_regions(), Slic3r::getadhesionCoeff(), Slic3r::group_fills(), Slic3r::SupportMaterialInternal::has_bridging_extrusions(), make_contour_z(), Slic3r::new_contact_layer(), Slic3r::precompute_overhang_layer(), Slic3r::precompute_overhang_layers(), Slic3r::prepares_overhang_estimator(), Slic3r::PrintObject::process_external_surfaces(), Slic3r::PrintObject::remove_bridges_from_contacts(), Slic3r::segmentation_top_and_bottom_layers(), Slic3r::RetractWhenCrossingPerimeters::travel_inside_internal_regions(), and Slic3r::PrintObjectSupportMaterial::trim_support_layers_by_object().

Here is the caller graph for this function:

◆ restore_untyped_slices()

void Slic3r::Layer::restore_untyped_slices ( )
105{
106 if (layer_needs_raw_backup(this)) {
107 for (LayerRegion *layerm : m_regions)
108 layerm->slices.set(layerm->raw_slices, stInternal);
109 } else {
110 assert(m_regions.size() == 1);
111 m_regions.front()->slices.set(this->lslices, stInternal);
112 }
113}

References Slic3r::layer_needs_raw_backup(), lslices, m_regions, and Slic3r::stInternal.

Here is the call graph for this function:

◆ restore_untyped_slices_no_extra_perimeters()

void Slic3r::Layer::restore_untyped_slices_no_extra_perimeters ( )
120{
121 if (layer_needs_raw_backup(this)) {
122 for (LayerRegion *layerm : m_regions)
123 //BBS: remove extra_perimeters. Always false
124 //if (! layerm->region().config().extra_perimeters.value)
125 layerm->slices.set(layerm->raw_slices, stInternal);
126 } else {
127 assert(m_regions.size() == 1);
128 LayerRegion *layerm = m_regions.front();
129 // This optimization is correct, as extra_perimeters are only reused by prepare_infill() with multi-regions.
130 //if (! layerm->region().config().extra_perimeters.value)
131 layerm->slices.set(this->lslices, stInternal);
132 }
133}

References Slic3r::layer_needs_raw_backup(), lslices, m_regions, Slic3r::SurfaceCollection::set(), Slic3r::LayerRegion::slices, and Slic3r::stInternal.

Here is the call graph for this function:

◆ set_id()

void Slic3r::Layer::set_id ( size_t id)
inline
142{ m_id = id; }

References id(), and m_id.

Here is the call graph for this function:

◆ simplify_infill_extrusion_path()

void Slic3r::Layer::simplify_infill_extrusion_path ( )
inline
233{ for (auto layerm : m_regions) layerm->simplify_infill_extrusion_entity(); }

References m_regions.

◆ simplify_support_entity_collection()

void Slic3r::Layer::simplify_support_entity_collection ( ExtrusionEntityCollection * entity_collection)
protected
364{
365 for (size_t i = 0; i < entity_collection->entities.size(); i++) {
366 if (ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(entity_collection->entities[i]))
367 this->simplify_support_entity_collection(collection);
368 else if (ExtrusionPath* path = dynamic_cast<ExtrusionPath*>(entity_collection->entities[i]))
369 this->simplify_support_path(path);
370 else if (ExtrusionMultiPath* multipath = dynamic_cast<ExtrusionMultiPath*>(entity_collection->entities[i]))
371 this->simplify_support_multi_path(multipath);
372 else if (ExtrusionLoop* loop = dynamic_cast<ExtrusionLoop*>(entity_collection->entities[i]))
373 this->simplify_support_loop(loop);
374 else
375 throw Slic3r::InvalidArgument("Invalid extrusion entity supplied to simplify_support_entity_collection()");
376 }
377}
void simplify_support_path(ExtrusionPath *path)
Definition Layer.cpp:379
void simplify_support_multi_path(ExtrusionMultiPath *multipath)
Definition Layer.cpp:394
void simplify_support_entity_collection(ExtrusionEntityCollection *entity_collection)
Definition Layer.cpp:363
void simplify_support_loop(ExtrusionLoop *loop)
Definition Layer.cpp:411

References Slic3r::ExtrusionEntityCollection::entities, simplify_support_entity_collection(), simplify_support_loop(), simplify_support_multi_path(), and simplify_support_path().

Referenced by simplify_support_entity_collection(), and Slic3r::SupportLayer::simplify_support_extrusion_path().

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

◆ simplify_support_loop()

void Slic3r::Layer::simplify_support_loop ( ExtrusionLoop * loop)
protected
412{
413 const auto &print_config = this->object()->print()->config();
414 const bool spiral_mode = print_config.spiral_mode;
415 const bool enable_arc_fitting = print_config.enable_arc_fitting.value == ArcFittingMode::Enabled;
416 const auto scaled_resolution = scaled<double>(print_config.resolution.value);
417
418 for (size_t i = 0; i < loop->paths.size(); ++i) {
419 if (enable_arc_fitting &&
420 !spiral_mode) {
421 loop->paths[i].simplify_by_fitting_arc(SCALED_SUPPORT_RESOLUTION);
422 } else {
423 loop->paths[i].simplify(scaled_resolution);
424 }
425 }
426}
#define SCALED_SUPPORT_RESOLUTION
Definition libslic3r.h:92
BoundingBox scaled(const BoundingBoxf &bb)
Definition BoundingBox.hpp:284
@ Enabled
Definition PrintConfig.hpp:240

References Slic3r::Print::config(), Slic3r::Enabled, object(), Slic3r::ExtrusionLoop::paths, Slic3r::PrintObjectBaseWithState< PrintType, PrintObjectStepEnum, COUNT >::print(), Slic3r::scaled(), and SCALED_SUPPORT_RESOLUTION.

Referenced by simplify_support_entity_collection().

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

◆ simplify_support_multi_path()

void Slic3r::Layer::simplify_support_multi_path ( ExtrusionMultiPath * multipath)
protected
395{
396 const auto &print_config = this->object()->print()->config();
397 const bool spiral_mode = print_config.spiral_mode;
398 const bool enable_arc_fitting = print_config.enable_arc_fitting.value == ArcFittingMode::Enabled;
399 const auto scaled_resolution = scaled<double>(print_config.resolution.value);
400
401 for (size_t i = 0; i < multipath->paths.size(); ++i) {
402 if (enable_arc_fitting &&
403 !spiral_mode) {
404 multipath->paths[i].simplify_by_fitting_arc(SCALED_SUPPORT_RESOLUTION);
405 } else {
406 multipath->paths[i].simplify(scaled_resolution);
407 }
408 }
409}

References Slic3r::Print::config(), Slic3r::Enabled, object(), Slic3r::ExtrusionMultiPath::paths, Slic3r::PrintObjectBaseWithState< PrintType, PrintObjectStepEnum, COUNT >::print(), Slic3r::scaled(), and SCALED_SUPPORT_RESOLUTION.

Referenced by simplify_support_entity_collection().

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

◆ simplify_support_path()

void Slic3r::Layer::simplify_support_path ( ExtrusionPath * path)
protected
380{
381 const auto &print_config = this->object()->print()->config();
382 const bool spiral_mode = print_config.spiral_mode;
383 const bool enable_arc_fitting = print_config.enable_arc_fitting.value == ArcFittingMode::Enabled;
384 const auto scaled_resolution = scaled<double>(print_config.resolution.value);
385
386 if (enable_arc_fitting &&
387 !spiral_mode) {
388 path->simplify_by_fitting_arc(SCALED_SUPPORT_RESOLUTION);
389 } else {
390 path->simplify(scaled_resolution);
391 }
392}

References Slic3r::Print::config(), Slic3r::Enabled, object(), Slic3r::PrintObjectBaseWithState< PrintType, PrintObjectStepEnum, COUNT >::print(), Slic3r::scaled(), SCALED_SUPPORT_RESOLUTION, Slic3r::ExtrusionPath::simplify(), and Slic3r::ExtrusionPath::simplify_by_fitting_arc().

Referenced by simplify_support_entity_collection().

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

◆ simplify_wall_extrusion_path()

void Slic3r::Layer::simplify_wall_extrusion_path ( )
inline
232{ for (auto layerm : m_regions) layerm->simplify_wall_extrusion_entity();}

References m_regions.

◆ fix_slicing_errors

std::string fix_slicing_errors ( PrintObject * object,
LayerPtrs & ,
const std::function< void()> & ,
int &  )
friend

References PrintObject.

◆ new_layers

std::vector< Layer * > new_layers ( PrintObject * print_object,
const std::vector< coordf_t > & object_layers )
friend
86{
87 LayerPtrs out;
88 out.reserve(object_layers.size());
89 auto id = int(print_object->slicing_parameters().raft_layers());
90 coordf_t zmin = print_object->slicing_parameters().object_print_z_min;
91 Layer *prev = nullptr;
92 for (size_t i_layer = 0; i_layer < object_layers.size(); i_layer += 2) {
93 coordf_t lo = object_layers[i_layer];
94 coordf_t hi = object_layers[i_layer + 1];
95 coordf_t slice_z = compute_slice_z(print_object, i_layer, lo, hi);
96
97 Layer *layer = new Layer(id ++, print_object, hi - lo, hi + zmin, slice_z);
98 out.emplace_back(layer);
99 if (prev != nullptr) {
100 prev->upper_layer = layer;
101 layer->lower_layer = prev;
102 }
103 prev = layer;
104 }
105 return out;
106}
Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z)
Definition Layer.hpp:278
double coordf_t
Definition GUI_ObjectList.hpp:46
static coordf_t compute_slice_z(PrintObject *print_object, size_t i_layer, coordf_t lo, coordf_t hi)
Definition PrintObjectSlice.cpp:56
std::vector< Layer * > LayerPtrs
Definition Layer.hpp:27

References Layer(), Slic3r::compute_slice_z(), lower_layer, Slic3r::SlicingParameters::object_print_z_min, PrintObject, Slic3r::SlicingParameters::raft_layers(), slice_z, Slic3r::PrintObject::slicing_parameters(), and upper_layer.

◆ PrintObject

friend class PrintObject
friend

Member Data Documentation

◆ cantilevers

◆ curled_lines

CurledLines Slic3r::Layer::curled_lines

◆ height

◆ loverhangs

◆ loverhangs_bbox

◆ lower_layer

◆ lslices

ExPolygons Slic3r::Layer::lslices

Referenced by Slic3r::TreeSupport3D::TreeModelVolumes::TreeModelVolumes(), Slic3r::TreeSupportData::TreeSupportData(), Slic3r::GCode::_do_export(), Slic3r::Print::_make_skirt(), Slic3r::PrintObjectSupportMaterial::buildplate_covered(), Slic3r::calculate_layer_edge_grid(), Slic3r::GUI::check_color_change(), Slic3r::PrintObject::clip_fill_surfaces(), Slic3r::collect_slices_outer(), Slic3r::detect_contacts(), Slic3r::detect_overhangs(), Slic3r::PrintObject::detect_overhangs_for_lift(), Slic3r::PrintObject::discover_vertical_shells(), Slic3r::extract_layer(), Slic3r::TreeSupport3D::generate_raft_contact(), Slic3r::TreeSupport::generate_toolpaths(), Slic3r::get_boundary(), Slic3r::TreeSupport::get_trim_support_regions(), Slic3r::infill_body(), Slic3r::AvoidCrossingPerimeters::init_layer(), Slic3r::make_belt_brim(), make_ironing(), Slic3r::LayerRegion::make_perimeters(), make_slices(), Slic3r::outer_inner_brim_area(), Slic3r::ExtrusionQualityEstimator::prepare_for_new_layer(), Slic3r::PrintObject::prepare_infill(), Slic3r::GCode::process_layer(), Slic3r::project_support_to_grid(), Slic3r::anonymous_namespace{PluginHostSlicing.cpp}::refresh_lslices_bboxes(), Slic3r::PrintObject::remove_bridges_from_contacts(), Slic3r::SupportMaterialInternal::remove_bridges_from_contacts(), restore_untyped_slices(), restore_untyped_slices_no_extra_perimeters(), Slic3r::separated_body_at(), Slic3r::set_mass_locator(), Slic3r::PrintObjectSupportMaterial::top_contact_layers(), Slic3r::AvoidCrossingPerimeters::travel_to(), and Slic3r::PrintObjectSupportMaterial::trim_support_layers_by_object().

◆ lslices_bboxes

◆ lslices_extrudable

ExPolygons Slic3r::Layer::lslices_extrudable

◆ lslices_separated_component_ids

std::vector<size_t> Slic3r::Layer::lslices_separated_component_ids

◆ m_id

size_t Slic3r::Layer::m_id
private

Referenced by Layer(), id(), and set_id().

◆ m_object

PrintObject* Slic3r::Layer::m_object
private

◆ m_regions

◆ print_z

coordf_t Slic3r::Layer::print_z

Referenced by Layer(), Slic3r::SupportLayer::SupportLayer(), Slic3r::TreeSupport3D::TreeModelVolumes::TreeModelVolumes(), Slic3r::GCode::_do_export(), Slic3r::Print::_make_skirt(), Slic3r::GCode::belt_layer_past_first_layer_band(), Slic3r::PrintObjectSupportMaterial::bottom_contact_layers_and_layer_support_areas(), Slic3r::GCode::collect_layers_to_print(), Slic3r::TimelapsePosPicker::collect_limit_areas_for_rod(), Slic3r::TimelapsePosPicker::collect_object_slices_data(), Slic3r::contour_extrusion_path(), Slic3r::convert_layer_region_from_json(), Slic3r::detect_belt_floor_bottom_contacts(), Slic3r::detect_bottom_contacts(), Slic3r::detect_contacts(), Slic3r::PrintObject::discover_horizontal_shells(), Slic3r::PrintObject::discover_vertical_shells(), Slic3r::extract_support_layer(), generate_sparse_infill_polylines_for_anchoring(), Slic3r::generate_support_toolpaths(), Slic3r::get_boundary(), Slic3r::get_boundary_external(), Slic3r::TimelapsePosPicker::get_is_clear_to_x0(), Slic3r::get_perimeter_spacing_external(), Slic3r::TreeSupport::get_trim_support_regions(), Slic3r::TreeSupport3D::group_meshes(), Slic3r::make_belt_brim(), make_fills(), make_ironing(), Slic3r::LayerRegion::make_perimeters(), Slic3r::new_contact_layer(), Slic3r::TimelapsePosPicker::pick_pos_for_all_layer(), Slic3r::OozePrevention::pre_toolchange(), Slic3r::LayerRegion::process_external_surfaces(), Slic3r::project_support_to_grid(), Slic3r::set_mass_locator(), Slic3r::to_json(), Slic3r::PrintObjectSupportMaterial::top_contact_layers(), and Slic3r::PrintObjectSupportMaterial::trim_support_layers_by_object().

◆ sharp_tails

◆ sharp_tails_height

std::vector<float> Slic3r::Layer::sharp_tails_height
mutable

◆ slice_z

◆ slicing_errors

bool Slic3r::Layer::slicing_errors

Referenced by Layer().

◆ upper_layer


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/ContourZ.cpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Fill/Fill.cpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Layer.cpp