OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::SupportSpotsGenerator Namespace Reference

Classes

struct  Params

Typedefs

using LD = AABBTreeLines::LinesDistancer<ExtrusionLine>

Enumerations

enum class  SupportPointCause {
  LongBridge , FloatingBridgeAnchor , FloatingExtrusion , SeparationFromBed ,
  UnstableFloatingPart , WeakObjectPart
}

Functions

float get_flow_width (const LayerRegion *region, ExtrusionRole role)
float estimate_curled_up_height (float distance, float curvature, float layer_height, float flow_width, float prev_line_curled_height, Params params)
void estimate_malformations (LayerPtrs &layers, const Params &params)
void estimate_malformations (std::vector< Layer * > &layers, const Params &params)

Typedef Documentation

◆ LD

Enumeration Type Documentation

◆ SupportPointCause

Enumerator
LongBridge 
FloatingBridgeAnchor 
FloatingExtrusion 
SeparationFromBed 
UnstableFloatingPart 
WeakObjectPart 
82 {
83 LongBridge, // point generated on bridge and straight perimeter extrusion longer than the allowed length
84 FloatingBridgeAnchor, // point generated on unsupported bridge endpoint
85 FloatingExtrusion, // point generated on extrusion that does not hold on its own
86 SeparationFromBed, // point generated for object parts that are connected to the bed, but the area is too small and there is a risk of separation (brim may help)
87 UnstableFloatingPart, // point generated for object parts not connected to the bed, holded only by the other support points (brim will not help here)
88 WeakObjectPart // point generated when some part of the object is too weak to hold the upper part and may break (imagine hourglass)
89 };
@ FloatingBridgeAnchor
Definition SupportSpotsGenerator.hpp:84
@ UnstableFloatingPart
Definition SupportSpotsGenerator.hpp:87
@ FloatingExtrusion
Definition SupportSpotsGenerator.hpp:85
@ LongBridge
Definition SupportSpotsGenerator.hpp:83
@ WeakObjectPart
Definition SupportSpotsGenerator.hpp:88
@ SeparationFromBed
Definition SupportSpotsGenerator.hpp:86

Function Documentation

◆ estimate_curled_up_height()

float Slic3r::SupportSpotsGenerator::estimate_curled_up_height ( float distance,
float curvature,
float layer_height,
float flow_width,
float prev_line_curled_height,
Params params )
95{
96 float curled_up_height = 0;
97 if (fabs(distance) < 3.0 * flow_width) {
98 curled_up_height = std::max(prev_line_curled_height - layer_height * 0.75f, 0.0f);
99 }
100
101 if (distance > params.malformation_distance_factors.first * flow_width &&
102 distance < params.malformation_distance_factors.second * flow_width) {
103 // imagine the extrusion profile. The part that has been glued (melted) with the previous layer will be called anchored section
104 // and the rest will be called curling section
105 // float anchored_section = flow_width - point.distance;
106 float curling_section = distance;
107
108 // after extruding, the curling (floating) part of the extrusion starts to shrink back to the rounded shape of the nozzle
109 // The anchored part not, because the melted material holds to the previous layer well.
110 // We can assume for simplicity perfect equalization of layer height and raising part width, from which:
111 float swelling_radius = (layer_height + curling_section) / 2.0f;
112 curled_up_height += std::max(0.f, (swelling_radius - layer_height) / 2.0f);
113
114 // On convex turns, there is larger tension on the floating edge of the extrusion then on the middle section.
115 // The tension is caused by the shrinking tendency of the filament, and on outer edge of convex trun, the expansion is greater and
116 // thus shrinking force is greater. This tension will cause the curling section to curle up
117 if (curvature > 0.01) {
118 float radius = (1.0 / curvature);
119 float curling_t = sqrt(radius / 100);
120 float b = curling_t * flow_width;
121 float a = curling_section;
122 float c = sqrt(std::max(0.0f, a * a - b * b));
123
124 curled_up_height += c;
125 }
126 curled_up_height = std::min(curled_up_height, params.max_curled_height_factor * layer_height);
127 }
128
129 return curled_up_height;
130}
layer_height((ConfigOptionInt, faded_layers))((ConfigOptionFloat
const std::pair< float, float > malformation_distance_factors
Definition SupportSpotsGenerator.hpp:48
const float max_curled_height_factor
Definition SupportSpotsGenerator.hpp:49

References Slic3r::layer_height(), Slic3r::SupportSpotsGenerator::Params::malformation_distance_factors, and Slic3r::SupportSpotsGenerator::Params::max_curled_height_factor.

Referenced by estimate_malformations().

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

◆ estimate_malformations() [1/2]

void Slic3r::SupportSpotsGenerator::estimate_malformations ( LayerPtrs & layers,
const Params & params )
133{
134#ifdef DEBUG_FILES
135 FILE *debug_file = boost::nowide::fopen(debug_out_path("object_malformations.obj").c_str(), "w");
136 FILE *full_file = boost::nowide::fopen(debug_out_path("object_full.obj").c_str(), "w");
137#endif
138
139 LD prev_layer_lines{};
140
141 for (Layer *l : layers) {
142 l->curled_lines.clear();
143 std::vector<Linef> boundary_lines = l->lower_layer != nullptr ? to_unscaled_linesf(l->lower_layer->lslices) : std::vector<Linef>();
144 AABBTreeLines::LinesDistancer<Linef> prev_layer_boundary{std::move(boundary_lines)};
145 std::vector<ExtrusionLine> current_layer_lines;
146 for (const LayerRegion *layer_region : l->regions()) {
147 for (const ExtrusionEntity *extrusion : layer_region->perimeters.flatten().entities) {
148 if (extrusion->role() != Slic3r::erExternalPerimeter)
149 continue;
150
151 Points extrusion_pts;
152 extrusion->collect_points(extrusion_pts);
153 float flow_width = get_flow_width(layer_region, extrusion->role());
154 auto annotated_points = estimate_points_properties<true, true, false, false>(extrusion_pts,
155 prev_layer_lines,
156 flow_width,
157 params.bridge_distance);
158 for (size_t i = 0; i < annotated_points.size(); ++i) {
159 const ExtendedPoint<2>& a = i > 0 ? annotated_points[i - 1] : annotated_points[i];
160 const ExtendedPoint<2>& b = annotated_points[i];
161 ExtrusionLine line_out{a.position.cast<float>(), b.position.cast<float>(), float((a.position - b.position).norm()),
162 extrusion};
163
164 Vec2f middle = 0.5 * (line_out.a + line_out.b);
165 auto [middle_distance, bottom_line_idx, x] = prev_layer_lines.distance_from_lines_extra<false>(middle);
166 ExtrusionLine bottom_line = prev_layer_lines.get_lines().empty() ? ExtrusionLine{} :
167 prev_layer_lines.get_line(bottom_line_idx);
168
169 // correctify the distance sign using slice polygons
170 float sign = (prev_layer_boundary.distance_from_lines<true>(middle.cast<double>()) + 0.5f * flow_width) < 0.0f ? -1.0f :
171 1.0f;
172
173 line_out.curled_up_height = estimate_curled_up_height(middle_distance * sign * params.curled_distance_expansion, 0.5 * (a.curvature + b.curvature),
174 l->height, flow_width, bottom_line.curled_up_height, params);
175
176 current_layer_lines.push_back(line_out);
177 }
178 }
179 }
180
181 for (const ExtrusionLine &line : current_layer_lines) {
182 if (line.curled_up_height > params.curling_tolerance_limit) {
183 l->curled_lines.push_back(CurledLine{Point::new_scale(line.a), Point::new_scale(line.b), line.curled_up_height});
184 }
185 }
186
187#ifdef DEBUG_FILES
188 for (const ExtrusionLine &line : current_layer_lines) {
189 if (line.curled_up_height > params.curling_tolerance_limit) {
190 Vec3f color = value_to_rgbf(-EPSILON, l->height * params.max_curled_height_factor, line.curled_up_height);
191 fprintf(debug_file, "v %f %f %f %f %f %f\n", line.b[0], line.b[1], l->print_z, color[0], color[1], color[2]);
192 }
193 }
194 for (const ExtrusionLine &line : current_layer_lines) {
195 Vec3f color = value_to_rgbf(-EPSILON, l->height * params.max_curled_height_factor, line.curled_up_height);
196 fprintf(full_file, "v %f %f %f %f %f %f\n", line.b[0], line.b[1], l->print_z, color[0], color[1], color[2]);
197 }
198#endif
199
200 prev_layer_lines = LD{current_layer_lines};
201 }
202
203#ifdef DEBUG_FILES
204 fclose(debug_file);
205 fclose(full_file);
206#endif
207}
#define EPSILON
Definition ColorUtils.cpp:64
Definition AABBTreeLines.hpp:307
Definition Layer.hpp:138
Definition Line.hpp:255
static Point new_scale(coordf_t x, coordf_t y)
Definition Point.hpp:214
AABBTreeLines::LinesDistancer< ExtrusionLine > LD
Definition SupportSpotsGenerator.cpp:78
std::string debug_out_path(const char *name,...)
Definition utils.cpp:382
Eigen::Matrix< float, 3, 1, Eigen::DontAlign > Vec3f
Definition Point.hpp:65
Linesf to_unscaled_linesf(const ExPolygons &src)
Definition ExPolygon.hpp:182
STL namespace.
const float curling_tolerance_limit
Definition SupportSpotsGenerator.hpp:51

References Slic3r::ExtrusionLine::a, Slic3r::ExtrusionLine::b, Slic3r::SupportSpotsGenerator::Params::bridge_distance, Slic3r::SupportSpotsGenerator::Params::curled_distance_expansion, Slic3r::ExtrusionLine::curled_up_height, Slic3r::SupportSpotsGenerator::Params::curling_tolerance_limit, Slic3r::ExtendedPoint< Dim >::curvature, Slic3r::debug_out_path(), Slic3r::AABBTreeLines::LinesDistancer< LineType >::distance_from_lines(), Slic3r::AABBTreeLines::LinesDistancer< LineType >::distance_from_lines_extra(), EPSILON, Slic3r::erExternalPerimeter, estimate_curled_up_height(), Slic3r::estimate_points_properties(), get_flow_width(), Slic3r::AABBTreeLines::LinesDistancer< LineType >::get_line(), Slic3r::AABBTreeLines::LinesDistancer< LineType >::get_lines(), Slic3r::SupportSpotsGenerator::Params::max_curled_height_factor, Slic3r::Point::new_scale(), Slic3r::ExtendedPoint< Dim >::position, and Slic3r::to_unscaled_linesf().

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

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

◆ estimate_malformations() [2/2]

void Slic3r::SupportSpotsGenerator::estimate_malformations ( std::vector< Layer * > & layers,
const Params & params )

◆ get_flow_width()

float Slic3r::SupportSpotsGenerator::get_flow_width ( const LayerRegion * region,
ExtrusionRole role )
81{
84 if (role == ExtrusionRole::erGapFill) return region->flow(FlowRole::frInfill).width();
85 if (role == ExtrusionRole::erPerimeter) return region->flow(FlowRole::frPerimeter).width();
87 if (role == ExtrusionRole::erInternalInfill) return region->flow(FlowRole::frInfill).width();
89 // default
90 return region->flow(FlowRole::frPerimeter).width();
91}
float width() const
Definition Flow.hpp:63
Flow flow(FlowRole role) const
Definition LayerRegion.cpp:48
@ frTopSolidInfill
Definition Flow.hpp:23
@ frExternalPerimeter
Definition Flow.hpp:19
@ frPerimeter
Definition Flow.hpp:20
@ frSolidInfill
Definition Flow.hpp:22
@ frInfill
Definition Flow.hpp:21
@ erExternalPerimeter
Definition ExtrusionEntity.hpp:29
@ erGapFill
Definition ExtrusionEntity.hpp:38
@ erSolidInfill
Definition ExtrusionEntity.hpp:32
@ erBridgeInfill
Definition ExtrusionEntity.hpp:36
@ erTopSolidInfill
Definition ExtrusionEntity.hpp:33
@ erPerimeter
Definition ExtrusionEntity.hpp:28
@ erInternalInfill
Definition ExtrusionEntity.hpp:31

References Slic3r::erBridgeInfill, Slic3r::erExternalPerimeter, Slic3r::erGapFill, Slic3r::erInternalInfill, Slic3r::erPerimeter, Slic3r::erSolidInfill, Slic3r::erTopSolidInfill, Slic3r::LayerRegion::flow(), Slic3r::frExternalPerimeter, Slic3r::frInfill, Slic3r::frPerimeter, Slic3r::frSolidInfill, Slic3r::frTopSolidInfill, and Slic3r::Flow::width().

Referenced by estimate_malformations().

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