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

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

Inheritance diagram for Slic3r::SupportLayer:
Collaboration diagram for Slic3r::SupportLayer:

Classes

struct  AreaGroup

Public Member Functions

virtual bool has_extrusions () const
size_t interface_id () const
void simplify_support_extrusion_path ()
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
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

ExPolygons support_islands
ExtrusionEntityCollection support_fills
SupportInnerType support_type = stInnerNormal
ExPolygons base_areas
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 Types

enum  AreaType { BaseType = 0 , RoofType = 1 , FloorType = 2 , Roof1stLayer = 3 }

Protected Member Functions

 SupportLayer (size_t id, size_t interface_id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z)
virtual ~SupportLayer ()=default
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)

Protected Attributes

size_t m_interface_id
ExPolygons roof_areas
ExPolygons roof_1st_layer
ExPolygons floor_areas
ExPolygons roof_gap_areas
std::vector< AreaGroup > area_groups

Private Attributes

size_t m_id
PrintObject * m_object
LayerRegionPtrs m_regions

Friends

class PrintObject
class TreeSupport

Detailed Description

Member Enumeration Documentation

◆ AreaType

Enumerator
BaseType 
RoofType 
FloorType 
Roof1stLayer 
341{ BaseType = 0, RoofType = 1, FloorType = 2, Roof1stLayer = 3 };
@ RoofType
Definition Layer.hpp:341
@ FloorType
Definition Layer.hpp:341
@ BaseType
Definition Layer.hpp:341
@ Roof1stLayer
Definition Layer.hpp:341

Constructor & Destructor Documentation

◆ SupportLayer()

Slic3r::SupportLayer::SupportLayer ( size_t id,
size_t interface_id,
PrintObject * object,
coordf_t height,
coordf_t print_z,
coordf_t slice_z )
inlineprotected
330 :
coordf_t slice_z
Definition Layer.hpp:149
coordf_t height
Definition Layer.hpp:151
Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z)
Definition Layer.hpp:278
coordf_t print_z
Definition Layer.hpp:150
size_t m_interface_id
Definition Layer.hpp:334
SupportInnerType support_type
Definition Layer.hpp:310
size_t interface_id() const
Definition Layer.hpp:320
@ stInnerNormal
Definition Layer.hpp:298

References Slic3r::Layer::Layer(), Slic3r::Layer::height, Slic3r::Layer::id(), interface_id(), m_interface_id, Slic3r::Layer::object(), Slic3r::Layer::print_z, PrintObject, Slic3r::Layer::slice_z, Slic3r::stInnerNormal, and support_type.

Here is the call graph for this function:

◆ ~SupportLayer()

virtual Slic3r::SupportLayer::~SupportLayer ( )
protectedvirtualdefault

Member Function Documentation

◆ add_region()

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

References m_regions.

◆ any_bottom_region_slice_contains()

template<class T>
bool Slic3r::Layer::any_bottom_region_slice_contains ( const T & item) const
inlineinherited
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
inlineinherited
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 ( )
inherited
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
inlineinherited
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 )
staticinherited
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
inherited
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
inherited
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
inherited
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
inherited
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
inherited
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
inherited

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
inherited
489{
490 return m_object->print()->get_extruder_id(filament_id);
491}
PrintObject * m_object
Definition Layer.hpp:293

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)
inlineinherited
183{ return m_regions[idx]; }

References m_regions.

◆ get_region() [2/2]

const LayerRegion * Slic3r::Layer::get_region ( int idx) const
inlineinherited
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 ( )
inherited
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::SupportLayer::has_extrusions ( ) const
inlinevirtual

Reimplemented from Slic3r::Layer.

317{ return ! support_fills.empty(); }
ExtrusionEntityCollection support_fills
Definition Layer.hpp:309

References support_fills.

Referenced by 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 )
inlinestaticinherited
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:

◆ interface_id()

size_t Slic3r::SupportLayer::interface_id ( ) const
inline
320{ return m_interface_id; }

References m_interface_id.

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

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 )
staticinherited
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)
inherited
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 ( )
inlineinherited
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 )
inherited
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 ( )
inherited
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 ( )
inherited
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 ( )
inherited
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
inherited
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
inlineinherited
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
inlineinherited
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
inlineinherited
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 ( )
inherited
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 ( )
inherited
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)
inlineinherited
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 ( )
inlineinherited
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)
protectedinherited
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_extrusion_path()

void Slic3r::SupportLayer::simplify_support_extrusion_path ( )
inline

References Slic3r::Layer::simplify_support_entity_collection().

Here is the call graph for this function:

◆ simplify_support_loop()

void Slic3r::Layer::simplify_support_loop ( ExtrusionLoop * loop)
protectedinherited
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)
protectedinherited
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)
protectedinherited
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 ( )
inlineinherited
232{ for (auto layerm : m_regions) layerm->simplify_wall_extrusion_entity();}

References m_regions.

◆ PrintObject

friend class PrintObject
friend

References PrintObject.

Referenced by SupportLayer(), and PrintObject.

◆ TreeSupport

friend class TreeSupport
friend

References TreeSupport.

Referenced by TreeSupport.

Member Data Documentation

◆ area_groups

std::vector<AreaGroup> Slic3r::SupportLayer::area_groups
protected

◆ base_areas

ExPolygons Slic3r::SupportLayer::base_areas

◆ cantilevers

ExPolygons Slic3r::Layer::cantilevers
mutableinherited

◆ curled_lines

CurledLines Slic3r::Layer::curled_lines
inherited

◆ floor_areas

ExPolygons Slic3r::SupportLayer::floor_areas
protected

◆ height

◆ loverhangs

◆ loverhangs_bbox

◆ lower_layer

◆ lslices

ExPolygons Slic3r::Layer::lslices
inherited

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
inherited

◆ lslices_separated_component_ids

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

◆ m_id

size_t Slic3r::Layer::m_id
privateinherited

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

◆ m_interface_id

size_t Slic3r::SupportLayer::m_interface_id
protected

Referenced by SupportLayer(), and interface_id().

◆ m_object

PrintObject* Slic3r::Layer::m_object
privateinherited

◆ m_regions

◆ print_z

coordf_t Slic3r::Layer::print_z
inherited

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().

◆ roof_1st_layer

ExPolygons Slic3r::SupportLayer::roof_1st_layer
protected

◆ roof_areas

ExPolygons Slic3r::SupportLayer::roof_areas
protected

◆ roof_gap_areas

ExPolygons Slic3r::SupportLayer::roof_gap_areas
protected

◆ sharp_tails

◆ sharp_tails_height

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

◆ slice_z

◆ slicing_errors

bool Slic3r::Layer::slicing_errors
inherited

Referenced by Layer().

◆ support_fills

◆ support_islands

◆ support_type

◆ upper_layer


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