Merge branch 'master' into stable - no conflicts fixed
This commit is contained in:
commit
ebb9041041
1005 changed files with 1029738 additions and 138540 deletions
src/libslic3r/Fill
|
@ -25,16 +25,18 @@ struct SurfaceFillParams
|
|||
// in unscaled coordinates
|
||||
coordf_t spacing = 0.;
|
||||
// infill / perimeter overlap, in unscaled coordinates
|
||||
coordf_t overlap = 0.;
|
||||
// coordf_t overlap = 0.;
|
||||
// Angle as provided by the region config, in radians.
|
||||
float angle = 0.f;
|
||||
// Is bridging used for this fill? Bridging parameters may be used even if this->flow.bridge() is not set.
|
||||
bool bridge;
|
||||
// Non-negative for a bridge.
|
||||
float bridge_angle = 0.f;
|
||||
|
||||
// FillParams
|
||||
float density = 0.f;
|
||||
// Don't adjust spacing to fill the space evenly.
|
||||
bool dont_adjust = false;
|
||||
// bool dont_adjust = false;
|
||||
// Length of the infill anchor along the perimeter line.
|
||||
// 1000mm is roughly the maximum length line that fits into a 32bit coord_t.
|
||||
float anchor_length = 1000.f;
|
||||
|
@ -42,7 +44,7 @@ struct SurfaceFillParams
|
|||
|
||||
// width, height of extrusion, nozzle diameter, is bridge
|
||||
// For the output, for fill generator.
|
||||
Flow flow = Flow(0.f, 0.f, 0.f, false);
|
||||
Flow flow;
|
||||
|
||||
// For the output
|
||||
ExtrusionRole extrusion_role = ExtrusionRole(0);
|
||||
|
@ -64,29 +66,30 @@ struct SurfaceFillParams
|
|||
RETURN_COMPARE_NON_EQUAL(extruder);
|
||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, pattern);
|
||||
RETURN_COMPARE_NON_EQUAL(spacing);
|
||||
RETURN_COMPARE_NON_EQUAL(overlap);
|
||||
// RETURN_COMPARE_NON_EQUAL(overlap);
|
||||
RETURN_COMPARE_NON_EQUAL(angle);
|
||||
RETURN_COMPARE_NON_EQUAL(density);
|
||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust);
|
||||
// RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, dont_adjust);
|
||||
RETURN_COMPARE_NON_EQUAL(anchor_length);
|
||||
RETURN_COMPARE_NON_EQUAL(anchor_length_max);
|
||||
RETURN_COMPARE_NON_EQUAL(flow.width);
|
||||
RETURN_COMPARE_NON_EQUAL(flow.height);
|
||||
RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter);
|
||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, flow.bridge);
|
||||
RETURN_COMPARE_NON_EQUAL(flow.width());
|
||||
RETURN_COMPARE_NON_EQUAL(flow.height());
|
||||
RETURN_COMPARE_NON_EQUAL(flow.nozzle_diameter());
|
||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, bridge);
|
||||
RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, extrusion_role);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const SurfaceFillParams &rhs) const {
|
||||
return this->extruder == rhs.extruder &&
|
||||
this->pattern == rhs.pattern &&
|
||||
this->pattern == rhs.pattern &&
|
||||
this->spacing == rhs.spacing &&
|
||||
this->overlap == rhs.overlap &&
|
||||
// this->overlap == rhs.overlap &&
|
||||
this->angle == rhs.angle &&
|
||||
this->bridge == rhs.bridge &&
|
||||
// this->bridge_angle == rhs.bridge_angle &&
|
||||
this->density == rhs.density &&
|
||||
this->dont_adjust == rhs.dont_adjust &&
|
||||
// this->dont_adjust == rhs.dont_adjust &&
|
||||
this->anchor_length == rhs.anchor_length &&
|
||||
this->anchor_length_max == rhs.anchor_length_max &&
|
||||
this->flow == rhs.flow &&
|
||||
|
@ -119,15 +122,16 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
if (surface.surface_type == stInternalVoid)
|
||||
has_internal_voids = true;
|
||||
else {
|
||||
const PrintRegionConfig ®ion_config = layerm.region()->config();
|
||||
const PrintRegionConfig ®ion_config = layerm.region().config();
|
||||
FlowRole extrusion_role = surface.is_top() ? frTopSolidInfill : (surface.is_solid() ? frSolidInfill : frInfill);
|
||||
bool is_bridge = layer.id() > 0 && surface.is_bridge();
|
||||
params.extruder = layerm.region()->extruder(extrusion_role);
|
||||
params.extruder = layerm.region().extruder(extrusion_role);
|
||||
params.pattern = region_config.fill_pattern.value;
|
||||
params.density = float(region_config.fill_density);
|
||||
|
||||
if (surface.is_solid()) {
|
||||
params.density = 100.f;
|
||||
//FIXME for non-thick bridges, shall we allow a bottom surface pattern?
|
||||
params.pattern = (surface.is_external() && ! is_bridge) ?
|
||||
(surface.is_top() ? region_config.top_fill_pattern.value : region_config.bottom_fill_pattern.value) :
|
||||
region_config.top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
|
||||
|
@ -143,43 +147,31 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
params.bridge_angle = float(surface.bridge_angle);
|
||||
params.angle = float(Geometry::deg2rad(region_config.fill_angle.value));
|
||||
|
||||
// calculate the actual flow we'll be using for this infill
|
||||
params.flow = layerm.region()->flow(
|
||||
extrusion_role,
|
||||
(surface.thickness == -1) ? layer.height : surface.thickness, // extrusion height
|
||||
is_bridge || Fill::use_bridge_flow(params.pattern), // bridge flow?
|
||||
layer.id() == 0, // first layer?
|
||||
-1, // auto width
|
||||
*layer.object()
|
||||
);
|
||||
|
||||
// Calculate flow spacing for infill pattern generation.
|
||||
// Calculate the actual flow we'll be using for this infill.
|
||||
params.bridge = is_bridge || Fill::use_bridge_flow(params.pattern);
|
||||
params.flow = params.bridge ?
|
||||
layerm.bridging_flow(extrusion_role) :
|
||||
layerm.flow(extrusion_role, (surface.thickness == -1) ? layer.height : surface.thickness);
|
||||
|
||||
// Calculate flow spacing for infill pattern generation.
|
||||
if (surface.is_solid() || is_bridge) {
|
||||
params.spacing = params.flow.spacing();
|
||||
// Don't limit anchor length for solid or bridging infill.
|
||||
params.anchor_length = 1000.f;
|
||||
params.anchor_length_max = 1000.f;
|
||||
} else {
|
||||
// it's internal infill, so we can calculate a generic flow spacing
|
||||
// for all layers, for avoiding the ugly effect of
|
||||
// misaligned infill on first layer because of different extrusion width and
|
||||
// layer height
|
||||
params.spacing = layerm.region()->flow(
|
||||
frInfill,
|
||||
layer.object()->config().layer_height.value, // TODO: handle infill_every_layers?
|
||||
false, // no bridge
|
||||
false, // no first layer
|
||||
-1, // auto width
|
||||
*layer.object()
|
||||
).spacing();
|
||||
// Internal infill. Calculating infill line spacing independent of the current layer height and 1st layer status,
|
||||
// so that internall infill will be aligned over all layers of the current region.
|
||||
params.spacing = layerm.region().flow(*layer.object(), frInfill, layer.object()->config().layer_height, false).spacing();
|
||||
// Anchor a sparse infill to inner perimeters with the following anchor length:
|
||||
params.anchor_length = float(region_config.infill_anchor);
|
||||
if (region_config.infill_anchor.percent)
|
||||
params.anchor_length = float(params.anchor_length * 0.01 * params.spacing);
|
||||
params.anchor_length_max = float(region_config.infill_anchor_max);
|
||||
if (region_config.infill_anchor_max.percent)
|
||||
params.anchor_length_max = float(params.anchor_length_max * 0.01 * params.spacing);
|
||||
}
|
||||
params.anchor_length = std::min(params.anchor_length, params.anchor_length_max);
|
||||
if (region_config.infill_anchor.percent)
|
||||
params.anchor_length = float(params.anchor_length * 0.01 * params.spacing);
|
||||
params.anchor_length_max = float(region_config.infill_anchor_max);
|
||||
if (region_config.infill_anchor_max.percent)
|
||||
params.anchor_length_max = float(params.anchor_length_max * 0.01 * params.spacing);
|
||||
params.anchor_length = std::min(params.anchor_length, params.anchor_length_max);
|
||||
}
|
||||
|
||||
auto it_params = set_surface_params.find(params);
|
||||
if (it_params == set_surface_params.end())
|
||||
|
@ -219,7 +211,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
Polygons polys = to_polygons(std::move(fill.expolygons));
|
||||
// Make a union of polygons, use a safety offset, subtract the preceding polygons.
|
||||
// Bridges are processed first (see SurfaceFill::operator<())
|
||||
fill.expolygons = all_polygons.empty() ? union_ex(polys, true) : diff_ex(polys, all_polygons, true);
|
||||
fill.expolygons = all_polygons.empty() ? union_safety_offset_ex(polys) : diff_ex(polys, all_polygons, ApplySafetyOffset::Yes);
|
||||
append(all_polygons, std::move(polys));
|
||||
} else if (&fill != &surface_fills.back())
|
||||
append(all_polygons, to_polygons(fill.expolygons));
|
||||
|
@ -260,12 +252,11 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
// Corners of infill regions, which would not be filled with an extrusion path with a radius of distance_between_surfaces/2
|
||||
Polygons collapsed = diff(
|
||||
surfaces_polygons,
|
||||
offset2(surfaces_polygons, (float)-distance_between_surfaces/2, (float)+distance_between_surfaces/2),
|
||||
true);
|
||||
opening(surfaces_polygons, float(distance_between_surfaces /2), float(distance_between_surfaces / 2 + ClipperSafetyOffset)));
|
||||
//FIXME why the voids are added to collapsed here? First it is expensive, second the result may lead to some unwanted regions being
|
||||
// added if two offsetted void regions merge.
|
||||
// polygons_append(voids, collapsed);
|
||||
ExPolygons extensions = intersection_ex(offset(collapsed, (float)distance_between_surfaces), voids, true);
|
||||
ExPolygons extensions = intersection_ex(expand(collapsed, float(distance_between_surfaces)), voids, ApplySafetyOffset::Yes);
|
||||
// Now find an internal infill SurfaceFill to add these extrusions to.
|
||||
SurfaceFill *internal_solid_fill = nullptr;
|
||||
unsigned int region_id = 0;
|
||||
|
@ -277,26 +268,24 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
|||
region_id = region_some_infill;
|
||||
const LayerRegion& layerm = *layer.regions()[region_id];
|
||||
for (SurfaceFill &surface_fill : surface_fills)
|
||||
if (surface_fill.surface.surface_type == stInternalSolid && std::abs(layer.height - surface_fill.params.flow.height) < EPSILON) {
|
||||
if (surface_fill.surface.surface_type == stInternalSolid && std::abs(layer.height - surface_fill.params.flow.height()) < EPSILON) {
|
||||
internal_solid_fill = &surface_fill;
|
||||
break;
|
||||
}
|
||||
if (internal_solid_fill == nullptr) {
|
||||
// Produce another solid fill.
|
||||
<<<<<<< HEAD
|
||||
params.extruder = layerm.region()->extruder(frSolidInfill);
|
||||
params.pattern = layerm.region()->config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
|
||||
=======
|
||||
params.extruder = layerm.region().extruder(frSolidInfill);
|
||||
params.pattern = layerm.region().config().top_fill_pattern == ipMonotonic ? ipMonotonic : ipRectilinear;
|
||||
>>>>>>> master
|
||||
params.density = 100.f;
|
||||
params.extrusion_role = erInternalInfill;
|
||||
params.angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value));
|
||||
params.angle = float(Geometry::deg2rad(layerm.region().config().fill_angle.value));
|
||||
// calculate the actual flow we'll be using for this infill
|
||||
params.flow = layerm.region()->flow(
|
||||
frSolidInfill,
|
||||
layer.height, // extrusion height
|
||||
false, // bridge flow?
|
||||
layer.id() == 0, // first layer?
|
||||
-1, // auto width
|
||||
*layer.object()
|
||||
);
|
||||
params.flow = layerm.flow(frSolidInfill);
|
||||
params.spacing = params.flow.spacing();
|
||||
surface_fills.emplace_back(params);
|
||||
surface_fills.back().surface.surface_type = stInternalSolid;
|
||||
|
@ -345,7 +334,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||
|
||||
std::vector<SurfaceFill> surface_fills = group_fills(*this);
|
||||
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
|
||||
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
|
||||
const auto resolution = this->object()->print()->config().gcode_resolution.value;
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
{
|
||||
|
@ -364,9 +354,9 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||
f->adapt_fill_octree = (surface_fill.params.pattern == ipSupportCubic) ? support_fill_octree : adaptive_fill_octree;
|
||||
|
||||
// calculate flow spacing for infill pattern generation
|
||||
bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.flow.bridge;
|
||||
bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.bridge;
|
||||
double link_max_length = 0.;
|
||||
if (! surface_fill.params.flow.bridge) {
|
||||
if (! surface_fill.params.bridge) {
|
||||
#if 0
|
||||
link_max_length = layerm.region()->config().get_abs_value(surface.is_external() ? "external_fill_link_max_length" : "fill_link_max_length", flow.spacing());
|
||||
// printf("flow spacing: %f, is_external: %d, link_max_length: %lf\n", flow.spacing(), int(surface.is_external()), link_max_length);
|
||||
|
@ -379,14 +369,15 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||
// Maximum length of the perimeter segment linking two infill lines.
|
||||
f->link_max_length = (coord_t)scale_(link_max_length);
|
||||
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
||||
f->loop_clipping = coord_t(scale_(surface_fill.params.flow.nozzle_diameter) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER);
|
||||
f->loop_clipping = coord_t(scale_(surface_fill.params.flow.nozzle_diameter()) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER);
|
||||
|
||||
// apply half spacing using this flow's own spacing and generate infill
|
||||
FillParams params;
|
||||
params.density = float(0.01 * surface_fill.params.density);
|
||||
params.dont_adjust = surface_fill.params.dont_adjust; // false
|
||||
params.dont_adjust = false; // surface_fill.params.dont_adjust;
|
||||
params.anchor_length = surface_fill.params.anchor_length;
|
||||
params.anchor_length_max = surface_fill.params.anchor_length_max;
|
||||
params.resolution = resolution;
|
||||
|
||||
for (ExPolygon &expoly : surface_fill.expolygons) {
|
||||
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||
|
@ -401,15 +392,15 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||
// calculate actual flow from spacing (which might have been adjusted by the infill
|
||||
// pattern generator)
|
||||
double flow_mm3_per_mm = surface_fill.params.flow.mm3_per_mm();
|
||||
double flow_width = surface_fill.params.flow.width;
|
||||
double flow_width = surface_fill.params.flow.width();
|
||||
if (using_internal_flow) {
|
||||
// if we used the internal flow we're not doing a solid infill
|
||||
// so we can safely ignore the slight variation that might have
|
||||
// been applied to f->spacing
|
||||
} else {
|
||||
Flow new_flow = Flow::new_from_spacing(float(f->spacing), surface_fill.params.flow.nozzle_diameter, surface_fill.params.flow.height, surface_fill.params.flow.bridge);
|
||||
Flow new_flow = surface_fill.params.flow.with_spacing(float(f->spacing));
|
||||
flow_mm3_per_mm = new_flow.mm3_per_mm();
|
||||
flow_width = new_flow.width;
|
||||
flow_width = new_flow.width();
|
||||
}
|
||||
// Save into layer.
|
||||
ExtrusionEntityCollection* eec = nullptr;
|
||||
|
@ -419,7 +410,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||
extrusion_entities_append_paths(
|
||||
eec->entities, std::move(polylines),
|
||||
surface_fill.params.extrusion_role,
|
||||
flow_mm3_per_mm, float(flow_width), surface_fill.params.flow.height);
|
||||
flow_mm3_per_mm, float(flow_width), surface_fill.params.flow.height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -512,13 +503,12 @@ void Layer::make_ironing()
|
|||
};
|
||||
|
||||
std::vector<IroningParams> by_extruder;
|
||||
bool extruder_dont_care = this->object()->config().wipe_into_objects;
|
||||
double default_layer_height = this->object()->config().layer_height;
|
||||
|
||||
for (LayerRegion *layerm : m_regions)
|
||||
if (! layerm->slices.empty()) {
|
||||
IroningParams ironing_params;
|
||||
const PrintRegionConfig &config = layerm->region()->config();
|
||||
const PrintRegionConfig &config = layerm->region().config();
|
||||
if (config.ironing &&
|
||||
(config.ironing_type == IroningType::AllSolid ||
|
||||
(config.top_solid_layers > 0 &&
|
||||
|
@ -533,6 +523,7 @@ void Layer::make_ironing()
|
|||
}
|
||||
}
|
||||
if (ironing_params.extruder != -1) {
|
||||
//TODO just_infill is currently not used.
|
||||
ironing_params.just_infill = false;
|
||||
ironing_params.line_spacing = config.ironing_spacing;
|
||||
ironing_params.height = default_layer_height * 0.01 * config.ironing_flowrate;
|
||||
|
@ -553,7 +544,7 @@ void Layer::make_ironing()
|
|||
fill_params.density = 1.;
|
||||
fill_params.monotonic = true;
|
||||
|
||||
for (size_t i = 0; i < by_extruder.size(); ++ i) {
|
||||
for (size_t i = 0; i < by_extruder.size();) {
|
||||
// Find span of regions equivalent to the ironing operation.
|
||||
IroningParams &ironing_params = by_extruder[i];
|
||||
size_t j = i;
|
||||
|
@ -563,15 +554,55 @@ void Layer::make_ironing()
|
|||
ExPolygons ironing_areas;
|
||||
double nozzle_dmr = this->object()->print()->config().nozzle_diameter.values[ironing_params.extruder - 1];
|
||||
if (ironing_params.just_infill) {
|
||||
//TODO just_infill is currently not used.
|
||||
// Just infill.
|
||||
} else {
|
||||
// Infill and perimeter.
|
||||
// Merge top surfaces with the same ironing parameters.
|
||||
Polygons polys;
|
||||
for (size_t k = i; k < j; ++ k)
|
||||
for (const Surface &surface : by_extruder[k].layerm->slices.surfaces)
|
||||
if (surface.surface_type == stTop)
|
||||
Polygons infills;
|
||||
for (size_t k = i; k < j; ++ k) {
|
||||
const IroningParams &ironing_params = by_extruder[k];
|
||||
const PrintRegionConfig ®ion_config = ironing_params.layerm->region().config();
|
||||
bool iron_everything = region_config.ironing_type == IroningType::AllSolid;
|
||||
bool iron_completely = iron_everything;
|
||||
if (iron_everything) {
|
||||
// Check whether there is any non-solid hole in the regions.
|
||||
bool internal_infill_solid = region_config.fill_density.value > 95.;
|
||||
for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces)
|
||||
if ((! internal_infill_solid && surface.surface_type == stInternal) || surface.surface_type == stInternalBridge || surface.surface_type == stInternalVoid) {
|
||||
// Some fill region is not quite solid. Don't iron over the whole surface.
|
||||
iron_completely = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iron_completely) {
|
||||
// Iron everything. This is likely only good for solid transparent objects.
|
||||
for (const Surface &surface : ironing_params.layerm->slices.surfaces)
|
||||
polygons_append(polys, surface.expolygon);
|
||||
} else {
|
||||
for (const Surface &surface : ironing_params.layerm->slices.surfaces)
|
||||
if (surface.surface_type == stTop || (iron_everything && surface.surface_type == stBottom))
|
||||
// stBottomBridge is not being ironed on purpose, as it would likely destroy the bridges.
|
||||
polygons_append(polys, surface.expolygon);
|
||||
}
|
||||
if (iron_everything && ! iron_completely) {
|
||||
// Add solid fill surfaces. This may not be ideal, as one will not iron perimeters touching these
|
||||
// solid fill surfaces, but it is likely better than nothing.
|
||||
for (const Surface &surface : ironing_params.layerm->fill_surfaces.surfaces)
|
||||
if (surface.surface_type == stInternalSolid)
|
||||
polygons_append(infills, surface.expolygon);
|
||||
}
|
||||
}
|
||||
|
||||
if (! infills.empty() || j > i + 1) {
|
||||
// Ironing over more than a single region or over solid internal infill.
|
||||
if (! infills.empty())
|
||||
// For IroningType::AllSolid only:
|
||||
// Add solid infill areas for layers, that contain some non-ironable infil (sparse infill, bridge infill).
|
||||
append(polys, std::move(infills));
|
||||
polys = union_safety_offset(polys);
|
||||
}
|
||||
// Trim the top surfaces with half the nozzle diameter.
|
||||
ironing_areas = intersection_ex(polys, offset(this->lslices, - float(scale_(0.5 * nozzle_dmr))));
|
||||
}
|
||||
|
@ -580,9 +611,9 @@ void Layer::make_ironing()
|
|||
fill.spacing = ironing_params.line_spacing;
|
||||
fill.angle = float(ironing_params.angle + 0.25 * M_PI);
|
||||
fill.link_max_length = (coord_t)scale_(3. * fill.spacing);
|
||||
double height = ironing_params.height * fill.spacing / nozzle_dmr;
|
||||
Flow flow = Flow::new_from_spacing(float(nozzle_dmr), 0., float(height), false);
|
||||
double flow_mm3_per_mm = flow.mm3_per_mm();
|
||||
double extrusion_height = ironing_params.height * fill.spacing / nozzle_dmr;
|
||||
float extrusion_width = Flow::rounded_rectangle_extrusion_width_from_spacing(float(nozzle_dmr), float(extrusion_height));
|
||||
double flow_mm3_per_mm = nozzle_dmr * extrusion_height;
|
||||
Surface surface_fill(stTop, ExPolygon());
|
||||
for (ExPolygon &expoly : ironing_areas) {
|
||||
surface_fill.expolygon = std::move(expoly);
|
||||
|
@ -600,9 +631,12 @@ void Layer::make_ironing()
|
|||
extrusion_entities_append_paths(
|
||||
eec->entities, std::move(polylines),
|
||||
erIroning,
|
||||
flow_mm3_per_mm, float(flow.width), float(height));
|
||||
flow_mm3_per_mm, extrusion_width, float(extrusion_height));
|
||||
}
|
||||
}
|
||||
|
||||
// Regions up to j were processed.
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue