本文整理汇总了C++中SliceMeshStorage类的典型用法代码示例。如果您正苦于以下问题:C++ SliceMeshStorage类的具体用法?C++ SliceMeshStorage怎么用?C++ SliceMeshStorage使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SliceMeshStorage类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: processFuzzyWalls
void FffPolygonGenerator::processFuzzyWalls(SliceMeshStorage& mesh)
{
if (mesh.getSettingAsCount("wall_line_count") == 0)
{
return;
}
int64_t fuzziness = mesh.getSettingInMicrons("magic_fuzzy_skin_thickness");
int64_t avg_dist_between_points = mesh.getSettingInMicrons("magic_fuzzy_skin_point_dist");
int64_t min_dist_between_points = avg_dist_between_points * 3 / 4; // hardcoded: the point distance may vary between 3/4 and 5/4 the supplied value
int64_t range_random_point_dist = avg_dist_between_points / 2;
for (unsigned int layer_nr = 0; layer_nr < mesh.layers.size(); layer_nr++)
{
SliceLayer& layer = mesh.layers[layer_nr];
for (SliceLayerPart& part : layer.parts)
{
Polygons results;
Polygons& skin = (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE)? part.outline : part.insets[0];
for (PolygonRef poly : skin)
{
// generate points in between p0 and p1
PolygonRef result = results.newPoly();
int64_t dist_left_over = rand() % (min_dist_between_points / 2); // the distance to be traversed on the line before making the first new point
Point* p0 = &poly.back();
for (Point& p1 : poly)
{ // 'a' is the (next) new point between p0 and p1
Point p0p1 = p1 - *p0;
int64_t p0p1_size = vSize(p0p1);
int64_t dist_last_point = dist_left_over + p0p1_size * 2; // so that p0p1_size - dist_last_point evaulates to dist_left_over - p0p1_size
for (int64_t p0pa_dist = dist_left_over; p0pa_dist < p0p1_size; p0pa_dist += min_dist_between_points + rand() % range_random_point_dist)
{
int r = rand() % (fuzziness * 2) - fuzziness;
Point perp_to_p0p1 = turn90CCW(p0p1);
Point fuzz = normal(perp_to_p0p1, r);
Point pa = *p0 + normal(p0p1, p0pa_dist) + fuzz;
result.add(pa);
dist_last_point = p0pa_dist;
}
dist_left_over = p0p1_size - dist_last_point;
p0 = &p1;
}
while (result.size() < 3 )
{
unsigned int point_idx = poly.size() - 2;
result.add(poly[point_idx]);
if (point_idx == 0) { break; }
point_idx--;
}
if (result.size() < 3)
{
result.clear();
for (Point& p : poly)
result.add(p);
}
}
skin = results;
}
}
}
示例2: generateSupportInterface
void AreaSupport::generateSupportInterface(SliceDataStorage& storage, const SliceMeshStorage& mesh, std::vector<Polygons>& support_areas, const unsigned int layer_count)
{
const unsigned int roof_layer_count = round_divide(mesh.getSettingInMicrons("support_roof_height"), storage.getSettingInMicrons("layer_height"));
const unsigned int bottom_layer_count = round_divide(mesh.getSettingInMicrons("support_bottom_height"), storage.getSettingInMicrons("layer_height"));
const unsigned int z_distance_bottom = round_up_divide(mesh.getSettingInMicrons("support_bottom_distance"), storage.getSettingInMicrons("layer_height"));
const unsigned int z_distance_top = round_up_divide(mesh.getSettingInMicrons("support_top_distance"), storage.getSettingInMicrons("layer_height"));
const int skip_layer_count = std::max(1u, round_divide(mesh.getSettingInMicrons("support_interface_skip_height"), storage.getSettingInMicrons("layer_height")));
const int interface_line_width = storage.meshgroup->getExtruderTrain(storage.getSettingAsIndex("support_interface_extruder_nr"))->getSettingInMicrons("support_interface_line_width");
std::vector<SupportLayer>& supportLayers = storage.support.supportLayers;
for (unsigned int layer_idx = 0; layer_idx < layer_count; layer_idx++)
{
SupportLayer& layer = supportLayers[layer_idx];
const unsigned int top_layer_idx_above = layer_idx + roof_layer_count + z_distance_top;
const unsigned int bottom_layer_idx_below = std::max(0, int(layer_idx) - int(bottom_layer_count) - int(z_distance_bottom));
if (top_layer_idx_above < supportLayers.size())
{
Polygons roofs;
if (roof_layer_count > 0)
{
Polygons model;
const unsigned int n_scans = std::max(1u, (roof_layer_count - 1) / skip_layer_count);
const float z_skip = std::max(1.0f, float(roof_layer_count - 1) / float(n_scans));
for (float layer_idx_above = top_layer_idx_above; layer_idx_above > layer_idx + z_distance_top; layer_idx_above -= z_skip)
{
const Polygons outlines_above = mesh.layers[std::round(layer_idx_above)].getOutlines();
model = model.unionPolygons(outlines_above);
}
roofs = support_areas[layer_idx].intersection(model);
}
Polygons bottoms;
if (bottom_layer_count > 0)
{
Polygons model;
const unsigned int n_scans = std::max(1u, (bottom_layer_count - 1) / skip_layer_count);
const float z_skip = std::max(1.0f, float(bottom_layer_count - 1) / float(n_scans));
for (float layer_idx_below = bottom_layer_idx_below; std::round(layer_idx_below) < (int)(layer_idx - z_distance_bottom); layer_idx_below += z_skip)
{
const Polygons outlines_below = mesh.layers[std::round(layer_idx_below)].getOutlines();
model = model.unionPolygons(outlines_below);
}
bottoms = support_areas[layer_idx].intersection(model);
}
// expand skin a bit so that we're sure it's not too thin to be printed.
Polygons skin = roofs.unionPolygons(bottoms).offset(interface_line_width).intersection(support_areas[layer_idx]);
skin.removeSmallAreas(1.0);
layer.skin.add(skin);
layer.supportAreas.add(support_areas[layer_idx].difference(layer.skin));
}
else
{
layer.skin.add(support_areas[layer_idx]);
}
}
}
示例3: getWallLineWidthX
coord_t SkinInfillAreaComputation::getWallLineWidthX(const SliceDataStorage& storage, const SliceMeshStorage& mesh, int layer_nr)
{
coord_t wall_line_width_x = mesh.getSettingInMicrons("wall_line_width_x");
if (layer_nr == 0)
{
const ExtruderTrain& train_wall_x = *storage.meshgroup->getExtruderTrain(mesh.getSettingAsExtruderNr("wall_x_extruder_nr"));
wall_line_width_x *= train_wall_x.getSettingAsRatio("initial_layer_line_width_factor");
}
return wall_line_width_x;
}
示例4: getSkinLineWidth
coord_t SkinInfillAreaComputation::getSkinLineWidth(const SliceDataStorage& storage, const SliceMeshStorage& mesh, int layer_nr)
{
coord_t skin_line_width = mesh.getSettingInMicrons("skin_line_width");
if (layer_nr == 0)
{
const ExtruderTrain& train_skin = *storage.meshgroup->getExtruderTrain(mesh.getSettingAsExtruderNr("top_bottom_extruder_nr"));
skin_line_width *= train_skin.getSettingAsRatio("initial_layer_line_width_factor");
}
return skin_line_width;
}
示例5: processDerivedWallsSkinInfill
void FffPolygonGenerator::processDerivedWallsSkinInfill(SliceMeshStorage& mesh, size_t total_layers)
{
// combine infill
unsigned int combined_infill_layers = mesh.getSettingInMicrons("infill_sparse_thickness") / std::max(mesh.getSettingInMicrons("layer_height"), 1); //How many infill layers to combine to obtain the requested sparse thickness.
combineInfillLayers(mesh,combined_infill_layers);
// fuzzy skin
if (mesh.getSettingBoolean("magic_fuzzy_skin_enabled"))
{
processFuzzyWalls(mesh);
}
}
示例6: processInsets
void FffPolygonGenerator::processInsets(SliceMeshStorage& mesh, unsigned int layer_nr)
{
SliceLayer* layer = &mesh.layers[layer_nr];
if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") != ESurfaceMode::SURFACE)
{
int inset_count = mesh.getSettingAsCount("wall_line_count");
if (mesh.getSettingBoolean("magic_spiralize") && static_cast<int>(layer_nr) < mesh.getSettingAsCount("bottom_layers") && layer_nr % 2 == 1)//Add extra insets every 2 layers when spiralizing, this makes bottoms of cups watertight.
inset_count += 5;
int line_width_x = mesh.getSettingInMicrons("wall_line_width_x");
int line_width_0 = mesh.getSettingInMicrons("wall_line_width_0");
if (mesh.getSettingBoolean("alternate_extra_perimeter"))
inset_count += layer_nr % 2;
bool recompute_outline_based_on_outer_wall = mesh.getSettingBoolean("support_enable");
WallsComputation walls_computation(mesh.getSettingInMicrons("wall_0_inset"), line_width_0, line_width_x, inset_count, recompute_outline_based_on_outer_wall);
walls_computation.generateInsets(layer);
}
if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") != ESurfaceMode::NORMAL)
{
for (PolygonRef polyline : layer->openPolyLines)
{
Polygons segments;
for (unsigned int point_idx = 1; point_idx < polyline.size(); point_idx++)
{
PolygonRef segment = segments.newPoly();
segment.add(polyline[point_idx-1]);
segment.add(polyline[point_idx]);
}
}
}
}
示例7: getInfillSkinOverlap
coord_t SkinInfillAreaComputation::getInfillSkinOverlap(const SliceDataStorage& storage, const SliceMeshStorage& mesh, int layer_nr, coord_t innermost_wall_line_width)
{
coord_t infill_skin_overlap = 0;
{ // compute infill_skin_overlap
const ExtruderTrain& train_infill = *storage.meshgroup->getExtruderTrain(mesh.getSettingAsExtruderNr("infill_extruder_nr"));
const coord_t infill_line_width_factor = (layer_nr == 0) ? train_infill.getSettingAsRatio("initial_layer_line_width_factor") : 1.0;
const bool infill_is_dense = mesh.getSettingInMicrons("infill_line_distance") < mesh.getSettingInMicrons("infill_line_width") * infill_line_width_factor + 10;
if (!infill_is_dense && mesh.getSettingAsFillMethod("infill_pattern") != EFillMethod::CONCENTRIC)
{
infill_skin_overlap = innermost_wall_line_width / 2;
}
}
return infill_skin_overlap;
}
示例8: precomputeOctree
void SubDivCube::precomputeOctree(SliceMeshStorage& mesh)
{
radius_addition = mesh.getSettingInMicrons("sub_div_rad_add");
double infill_angle = M_PI / 4.0;
coord_t furthest_dist_from_origin = std::sqrt(square(mesh.getSettingInMicrons("machine_height")) + square(mesh.getSettingInMicrons("machine_depth") / 2) + square(mesh.getSettingInMicrons("machine_width") / 2));
coord_t max_side_length = furthest_dist_from_origin * 2;
int curr_recursion_depth = 0;
const int64_t infill_line_distance = mesh.getSettingInMicrons("infill_line_distance");
if (infill_line_distance > 0)
{
for (int64_t curr_side_length = infill_line_distance * 2; curr_side_length < max_side_length * 2; curr_side_length *= 2)
{
cube_properties_per_recursion_step.emplace_back();
CubeProperties& cube_properties_here = cube_properties_per_recursion_step.back();
cube_properties_here.side_length = curr_side_length;
cube_properties_here.height = sqrt(3) * curr_side_length;
cube_properties_here.square_height = sqrt(2) * curr_side_length;
cube_properties_here.max_draw_z_diff = ONE_OVER_SQRT_3 * curr_side_length;
cube_properties_here.max_line_offset = ONE_OVER_SQRT_6 * curr_side_length;
curr_recursion_depth++;
}
}
Point3 center(0, 0, 0);
Point3Matrix tilt; // rotation matrix to get from axis aligned cubes to cubes standing on their tip
// The Z axis is transformed to go in positive Y direction
//
// cross section in a horizontal plane horizontal plane showing
// looking down at the origin O positive X and positive Y
// Z .
// /:\ Y .
// / : \ ^ .
// / : \ | .
// / .O. \ | .
// /.~' '~.\ O---->X .
// X """"""""""" Y .
tilt.matrix[0] = -ONE_OVER_SQRT_2; tilt.matrix[1] = ONE_OVER_SQRT_2; tilt.matrix[2] = 0;
tilt.matrix[3] = -ONE_OVER_SQRT_6; tilt.matrix[4] = -ONE_OVER_SQRT_6; tilt.matrix[5] = SQRT_TWO_THIRD ;
tilt.matrix[6] = ONE_OVER_SQRT_3; tilt.matrix[7] = ONE_OVER_SQRT_3; tilt.matrix[8] = ONE_OVER_SQRT_3;
infill_rotation_matrix = PointMatrix(infill_angle);
Point3Matrix infill_angle_mat(infill_rotation_matrix);
rotation_matrix = infill_angle_mat.compose(tilt);
mesh.base_subdiv_cube = new SubDivCube(mesh, center, curr_recursion_depth - 1);
}
示例9: combineInfillLayers
void combineInfillLayers(SliceMeshStorage& storage,unsigned int amount)
{
if(amount <= 1) //If we must combine 1 layer, nothing needs to be combined. Combining 0 layers is invalid.
{
return;
}
if(storage.layers.empty() || storage.layers.size() - 1 < static_cast<size_t>(storage.getSettingAsCount("top_layers")) || storage.getSettingAsCount("infill_line_distance") <= 0) //No infill is even generated.
{
return;
}
/* We need to round down the layer index we start at to the nearest
divisible index. Otherwise we get some parts that have infill at divisible
layers and some at non-divisible layers. Those layers would then miss each
other. */
size_t min_layer = storage.getSettingAsCount("bottom_layers") + amount - 1;
min_layer -= min_layer % amount; //Round upwards to the nearest layer divisible by infill_sparse_combine.
size_t max_layer = storage.layers.size() - 1 - storage.getSettingAsCount("top_layers");
max_layer -= max_layer % amount; //Round downwards to the nearest layer divisible by infill_sparse_combine.
for(size_t layer_idx = min_layer;layer_idx <= max_layer;layer_idx += amount) //Skip every few layers, but extrude more.
{
SliceLayer* layer = &storage.layers[layer_idx];
for(unsigned int n = 1;n < amount;n++)
{
if(layer_idx < n)
{
break;
}
SliceLayer* layer2 = &storage.layers[layer_idx - n];
for(SliceLayerPart& part : layer->parts)
{
Polygons result;
for(SliceLayerPart& part2 : layer2->parts)
{
if(part.boundaryBox.hit(part2.boundaryBox))
{
Polygons intersection = part.infill_area[n - 1].intersection(part2.infill_area[0]).offset(-200).offset(200);
result.add(intersection);
part.infill_area[n - 1] = part.infill_area[n - 1].difference(intersection);
part2.infill_area[0] = part2.infill_area[0].difference(intersection);
}
}
part.infill_area.push_back(result);
}
}
}
}
示例10: generateInfillSupport
void SkinInfillAreaComputation::generateInfillSupport(SliceMeshStorage& mesh)
{
const coord_t layer_height = mesh.getSettingInMicrons("layer_height");
const double support_angle = mesh.getSettingInAngleRadians("infill_support_angle");
const double tan_angle = tan(support_angle) - 0.01; //The X/Y component of the support angle. 0.01 to make 90 degrees work too.
const coord_t max_dist_from_lower_layer = tan_angle * layer_height; //Maximum horizontal distance that can be bridged.
for (int layer_idx = mesh.layers.size() - 2; layer_idx >= 0; layer_idx--)
{
SliceLayer& layer = mesh.layers[layer_idx];
SliceLayer& layer_above = mesh.layers[layer_idx + 1];
Polygons inside_above;
Polygons infill_above;
for (SliceLayerPart& part_above : layer_above.parts)
{
inside_above.add(part_above.infill_area);
infill_above.add(part_above.getOwnInfillArea());
}
for (SliceLayerPart& part : layer.parts)
{
const Polygons& infill_area = part.infill_area;
if (infill_area.empty())
{
continue;
}
const Polygons unsupported = infill_area.offset(-max_dist_from_lower_layer);
const Polygons basic_overhang = unsupported.difference(inside_above);
const Polygons overhang_extented = basic_overhang.offset(max_dist_from_lower_layer + 50); // +50 for easier joining with support from layer above
const Polygons full_overhang = overhang_extented.difference(inside_above);
const Polygons infill_support = infill_above.unionPolygons(full_overhang);
part.infill_area_own = infill_support.intersection(part.getOwnInfillArea());
}
}
}
示例11: processSkinsAndInfill
void FffPolygonGenerator::processSkinsAndInfill(SliceMeshStorage& mesh, unsigned int layer_nr)
{
if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE)
{
return;
}
int wall_line_count = mesh.getSettingAsCount("wall_line_count");
int skin_extrusion_width = mesh.getSettingInMicrons("skin_line_width");
int innermost_wall_extrusion_width = (wall_line_count == 1)? mesh.getSettingInMicrons("wall_line_width_0") : mesh.getSettingInMicrons("wall_line_width_x");
generateSkins(layer_nr, mesh, skin_extrusion_width, mesh.getSettingAsCount("bottom_layers"), mesh.getSettingAsCount("top_layers"), wall_line_count, innermost_wall_extrusion_width, mesh.getSettingAsCount("skin_outline_count"), mesh.getSettingBoolean("skin_no_small_gaps_heuristic"));
if (mesh.getSettingInMicrons("infill_line_distance") > 0)
{
int infill_skin_overlap = 0;
bool infill_is_dense = mesh.getSettingInMicrons("infill_line_distance") < mesh.getSettingInMicrons("infill_line_width") + 10;
if (!infill_is_dense && mesh.getSettingAsFillMethod("infill_pattern") != EFillMethod::CONCENTRIC)
{
infill_skin_overlap = skin_extrusion_width / 2;
}
generateInfill(layer_nr, mesh, innermost_wall_extrusion_width, infill_skin_overlap, wall_line_count);
}
}
示例12: mesh
SkinInfillAreaComputation::SkinInfillAreaComputation(int layer_nr, const SliceDataStorage& storage, SliceMeshStorage& mesh, bool process_infill)
: layer_nr(layer_nr)
, mesh(mesh)
, bottom_layer_count(mesh.getSettingAsCount("bottom_layers"))
, top_layer_count(mesh.getSettingAsCount("top_layers"))
, wall_line_count(mesh.getSettingAsCount("wall_line_count"))
, skin_line_width(getSkinLineWidth(storage, mesh, layer_nr))
, wall_line_width_0(getWallLineWidth0(storage, mesh, layer_nr))
, wall_line_width_x(getWallLineWidthX(storage, mesh, layer_nr))
, innermost_wall_line_width((wall_line_count == 1) ? wall_line_width_0 : wall_line_width_x)
, infill_skin_overlap(getInfillSkinOverlap(storage, mesh, layer_nr, innermost_wall_line_width))
, skin_inset_count(mesh.getSettingAsCount("skin_outline_count"))
, no_small_gaps_heuristic(mesh.getSettingBoolean("skin_no_small_gaps_heuristic"))
, process_infill(process_infill)
, top_reference_wall_expansion(mesh.getSettingInMicrons("top_skin_preshrink"))
, bottom_reference_wall_expansion(mesh.getSettingInMicrons("bottom_skin_preshrink"))
, top_skin_expand_distance(mesh.getSettingInMicrons("top_skin_expand_distance"))
, bottom_skin_expand_distance(mesh.getSettingInMicrons("bottom_skin_expand_distance"))
, top_reference_wall_idx(getReferenceWallIdx(top_reference_wall_expansion))
, bottom_reference_wall_idx(getReferenceWallIdx(bottom_reference_wall_expansion))
{
}
示例13: isValidSubdivision
bool SubDivCube::isValidSubdivision(SliceMeshStorage& mesh, Point3& center, int64_t radius)
{
int64_t distance2 = 0;
coord_t sphere_slice_radius2;//!< squared radius of bounding sphere slice on target layer
bool inside_somewhere = false;
bool outside_somewhere = false;
int inside;
double part_dist;//what percentage of the radius the target layer is away from the center along the z axis. 0 - 1
const coord_t layer_height = mesh.getSettingInMicrons("layer_height");
int bottom_layer = (center.z - radius) / layer_height;
int top_layer = (center.z + radius) / layer_height;
for (int test_layer = bottom_layer; test_layer <= top_layer; test_layer += 3) // steps of three. Low-hanging speed gain.
{
part_dist = (double)(test_layer * layer_height - center.z) / radius;
sphere_slice_radius2 = radius * radius * (1.0 - (part_dist * part_dist));
Point loc(center.x, center.y);
inside = distanceFromPointToMesh(mesh, test_layer, loc, &distance2);
if (inside == 1)
{
inside_somewhere = true;
}
else
{
outside_somewhere = true;
}
if (outside_somewhere && inside_somewhere)
{
return true;
}
if ((inside != 2) && distance2 < sphere_slice_radius2)
{
return true;
}
}
return false;
}
示例14: processSpaghettiInfill
bool SpaghettiInfillPathGenerator::processSpaghettiInfill(const SliceDataStorage& storage, const FffGcodeWriter& fff_gcode_writer, LayerPlan& gcode_layer, const SliceMeshStorage& mesh, const int extruder_nr, const PathConfigStorage::MeshPathConfigs& mesh_config, const SliceLayerPart& part, int infill_line_distance, int infill_overlap, int infill_angle, const Point& infill_origin)
{
if (extruder_nr != mesh.getSettingAsExtruderNr("infill_extruder_nr"))
{
return false;
}
bool added_something = false;
const GCodePathConfig& config = mesh_config.infill_config[0];
const EFillMethod pattern = mesh.getSettingAsFillMethod("infill_pattern");
const bool zig_zaggify_infill = mesh.getSettingBoolean("zig_zaggify_infill");
const bool connect_polygons = true; // spaghetti infill should have as least as possible travel moves
const unsigned int infill_line_width = config.getLineWidth();
constexpr int infill_multiplier = 1;
const int64_t infill_shift = 0;
constexpr int wall_line_count = 0;
const int64_t outline_offset = 0;
const double layer_height_mm = (gcode_layer.getLayerNr() == 0) ? mesh.getSettingInMillimeters("layer_height_0") : mesh.getSettingInMillimeters("layer_height");
// For each part on this layer which is used to fill that part and parts below:
for (const std::pair<Polygons, double>& filling_area : part.spaghetti_infill_volumes)
{
Polygons infill_lines;
Polygons infill_polygons;
const Polygons& area = filling_area.first; // Area of the top within which to move while extruding (might be empty if the spaghetti_inset was too large)
const double total_volume = filling_area.second * mesh.getSettingAsRatio("spaghetti_flow") + mesh.getSettingInCubicMillimeters("spaghetti_infill_extra_volume"); // volume to be extruded
if (total_volume <= 0.0)
{
continue;
}
// generate zigzag print head paths
Polygons* perimeter_gaps_output = nullptr;
const bool connected_zigzags = true;
const bool use_endpieces = false;
Infill infill_comp(pattern, zig_zaggify_infill, connect_polygons, area, outline_offset
, infill_line_width, infill_line_distance, infill_overlap, infill_multiplier, infill_angle, gcode_layer.z,
infill_shift, wall_line_count, infill_origin, perimeter_gaps_output, connected_zigzags, use_endpieces
, mesh.getSettingInMicrons("cross_infill_pocket_size"));
// cross_fill_patterns is only generated when spaghetti infill is not used,
// so we pass nullptr here.
infill_comp.generate(infill_polygons, infill_lines, nullptr, &mesh);
// add paths to plan with a higher flow ratio in order to extrude the required amount.
const coord_t total_length = infill_polygons.polygonLength() + infill_lines.polyLineLength();
if (total_length > 0)
{ // zigzag path generation actually generated paths
// calculate the normal volume extruded when using the layer height and line width to calculate extrusion
const double normal_volume = INT2MM(INT2MM(total_length * infill_line_width)) * layer_height_mm;
assert(normal_volume > 0.0);
const float flow_ratio = total_volume / normal_volume;
assert(flow_ratio / mesh.getSettingAsRatio("spaghetti_flow") >= 0.9);
assert(!std::isnan(flow_ratio) && !std::isinf(flow_ratio));
if (!infill_polygons.empty() || !infill_lines.empty())
{
added_something = true;
fff_gcode_writer.setExtruder_addPrime(storage, gcode_layer, extruder_nr);
if (!infill_polygons.empty())
{
constexpr bool force_comb_retract = false;
gcode_layer.addTravel(infill_polygons[0][0], force_comb_retract);
gcode_layer.addPolygonsByOptimizer(infill_polygons, config, nullptr, ZSeamConfig(), 0, false, flow_ratio);
}
const bool is_zigzag = mesh.getSettingBoolean("zig_zaggify_infill") || pattern == EFillMethod::ZIG_ZAG;
const coord_t wipe_dist = is_zigzag ? 0 : -mesh.getSettingInMicrons("infill_wipe_dist");
const SpaceFillType line_type = is_zigzag ? SpaceFillType::Lines : SpaceFillType::PolyLines;
gcode_layer.addLinesByOptimizer(infill_lines, config, line_type, false, wipe_dist, flow_ratio);
}
}
else
{ // zigzag path generation couldn't generate paths, probably because the area was too small
// generate small path near the middle of the filling area
// note that we need a path with positive length because that is currently the only way to insert an extrusion in a layer plan
constexpr int path_length = 10;
Point middle = AABB(area).getMiddle();
if (!area.inside(middle))
{
PolygonUtils::ensureInsideOrOutside(area, middle, infill_line_width / 2);
}
const double normal_volume = INT2MM(INT2MM(path_length * infill_line_width)) * layer_height_mm;
const float flow_ratio = total_volume / normal_volume;
gcode_layer.addTravel(middle);
gcode_layer.addExtrusionMove(middle + Point(0, path_length), config, SpaceFillType::Lines, flow_ratio);
}
}
return added_something;
}
示例15: combineInfillLayers
void combineInfillLayers(SliceMeshStorage& mesh, unsigned int amount)
{
if (mesh.layers.empty() || mesh.layers.size() - 1 < static_cast<size_t>(mesh.getSettingAsCount("top_layers")) || mesh.getSettingAsCount("infill_line_distance") <= 0) //No infill is even generated.
{
return;
}
if(amount <= 1) //If we must combine 1 layer, nothing needs to be combined. Combining 0 layers is invalid.
{
return;
}
/* We need to round down the layer index we start at to the nearest
divisible index. Otherwise we get some parts that have infill at divisible
layers and some at non-divisible layers. Those layers would then miss each
other. */
size_t min_layer = mesh.getSettingAsCount("bottom_layers") + amount - 1;
min_layer -= min_layer % amount; //Round upwards to the nearest layer divisible by infill_sparse_combine.
size_t max_layer = mesh.layers.size() - 1 - mesh.getSettingAsCount("top_layers");
max_layer -= max_layer % amount; //Round downwards to the nearest layer divisible by infill_sparse_combine.
for(size_t layer_idx = min_layer;layer_idx <= max_layer;layer_idx += amount) //Skip every few layers, but extrude more.
{
SliceLayer* layer = &mesh.layers[layer_idx];
for(unsigned int combine_count_here = 1; combine_count_here < amount; combine_count_here++)
{
if(layer_idx < combine_count_here)
{
break;
}
size_t lower_layer_idx = layer_idx - combine_count_here;
if (lower_layer_idx < min_layer)
{
break;
}
SliceLayer* lower_layer = &mesh.layers[lower_layer_idx];
for (SliceLayerPart& part : layer->parts)
{
for (unsigned int density_idx = 0; density_idx < part.infill_area_per_combine_per_density.size(); density_idx++)
{ // go over each density of gradual infill (these density areas overlap!)
std::vector<Polygons>& infill_area_per_combine = part.infill_area_per_combine_per_density[density_idx];
Polygons result;
for (SliceLayerPart& lower_layer_part : lower_layer->parts)
{
if (part.boundaryBox.hit(lower_layer_part.boundaryBox))
{
Polygons intersection = infill_area_per_combine[combine_count_here - 1].intersection(lower_layer_part.infill_area).offset(-200).offset(200);
result.add(intersection); // add area to be thickened
infill_area_per_combine[combine_count_here - 1] = infill_area_per_combine[combine_count_here - 1].difference(intersection); // remove thickened area from less thick layer here
if (density_idx < lower_layer_part.infill_area_per_combine_per_density.size())
{ // only remove from *same density* areas on layer below
// If there are no same density areas, then it's ok to print them anyway
// Don't remove other density areas
unsigned int lower_density_idx = density_idx;
std::vector<Polygons>& lower_infill_area_per_combine = lower_layer_part.infill_area_per_combine_per_density[lower_density_idx];
lower_infill_area_per_combine[0] = lower_infill_area_per_combine[0].difference(intersection); // remove thickened area from lower (thickened) layer
}
}
}
infill_area_per_combine.push_back(result);
}
}
}
}
}