本文整理汇总了C++中Polygons::difference方法的典型用法代码示例。如果您正苦于以下问题:C++ Polygons::difference方法的具体用法?C++ Polygons::difference怎么用?C++ Polygons::difference使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Polygons
的用法示例。
在下文中一共展示了Polygons::difference方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: generateSkins
void generateSkins(int layerNr, SliceVolumeStorage& storage, int extrusionWidth, int downSkinCount, int upSkinCount, int infillOverlap)
{
SliceLayer* layer = &storage.layers[layerNr];
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
SliceLayerPart* part = &layer->parts[partNr];
Polygons upskin = part->insets[part->insets.size() - 1].offset(-extrusionWidth/2);
Polygons downskin = upskin;
if (part->insets.size() > 1)
{
//Add thin wall filling by taking the area between the insets.
Polygons thinWalls = part->insets[0].offset(-extrusionWidth / 2 - extrusionWidth * infillOverlap / 100).difference(part->insets[1].offset(extrusionWidth * 6 / 10));
upskin.add(thinWalls);
downskin.add(thinWalls);
}
if (int(layerNr - downSkinCount) >= 0)
{
SliceLayer* layer2 = &storage.layers[layerNr - downSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
downskin = downskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1]);
}
}
if (int(layerNr + upSkinCount) < (int)storage.layers.size())
{
SliceLayer* layer2 = &storage.layers[layerNr + upSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
upskin = upskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1]);
}
}
part->skinOutline = upskin.unionPolygons(downskin);
double minAreaSize = (2 * M_PI * (double(extrusionWidth) / 1000.0) * (double(extrusionWidth) / 1000.0)) * 0.3;
for(unsigned int i=0; i<part->skinOutline.size(); i++)
{
double area = fabs(ClipperLib::Area(part->skinOutline[i])) / 1000.0 / 1000.0;
if (area < minAreaSize) // Only create an up/down skin if the area is large enough. So you do not create tiny blobs of "trying to fill"
{
part->skinOutline.remove(i);
i -= 1;
}
}
}
}
示例2: generateInfill
void generateInfill(int layerNr, SliceMeshStorage& mesh, const int innermost_wall_line_width, int infill_skin_overlap, int wall_line_count)
{
SliceLayer& layer = mesh.layers[layerNr];
for(SliceLayerPart& part : layer.parts)
{
if (int(part.insets.size()) < wall_line_count)
{
continue; // the last wall is not present, the part should only get inter preimeter gaps, but no infill.
}
Polygons infill = part.insets.back().offset(-innermost_wall_line_width / 2 - infill_skin_overlap);
for(SliceLayerPart& part2 : layer.parts)
{
if (part.boundaryBox.hit(part2.boundaryBox))
{
for(SkinPart& skin_part : part2.skin_parts)
{
infill = infill.difference(skin_part.outline);
}
}
}
infill.removeSmallAreas(MIN_AREA_SIZE);
part.infill_area = infill.offset(infill_skin_overlap);
}
}
示例3: join
Polygons AreaSupport::join(Polygons& supportLayer_up, Polygons& supportLayer_this, int64_t supportJoinDistance, int64_t smoothing_distance, int min_smoothing_area, bool conical_support, int64_t conical_support_offset, int64_t conical_smallest_breadth)
{
Polygons joined;
if (conical_support)
{
Polygons insetted = supportLayer_up.offset(-conical_smallest_breadth/2);
Polygons small_parts = supportLayer_up.difference(insetted.offset(conical_smallest_breadth/2+20));
joined = supportLayer_this.unionPolygons(supportLayer_up.offset(conical_support_offset))
.unionPolygons(small_parts);
}
else
{
joined = supportLayer_this.unionPolygons(supportLayer_up);
}
// join different parts
if (supportJoinDistance > 0)
{
joined = joined.offset(supportJoinDistance)
.offset(-supportJoinDistance);
}
if (smoothing_distance > 0)
joined = joined.smooth(smoothing_distance, min_smoothing_area);
return joined;
}
示例4: 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());
}
}
}
示例5: join
Polygons AreaSupport::join(Polygons& supportLayer_up, Polygons& supportLayer_this, int64_t supportJoinDistance, int64_t smoothing_distance, int max_smoothing_angle, bool conical_support, int64_t conical_support_offset, int64_t conical_smallest_breadth)
{
Polygons joined;
if (conical_support)
{
Polygons insetted = supportLayer_up.offset(-conical_smallest_breadth/2);
Polygons small_parts = supportLayer_up.difference(insetted.offset(conical_smallest_breadth/2+20));
joined = supportLayer_this.unionPolygons(supportLayer_up.offset(conical_support_offset))
.unionPolygons(small_parts);
}
else
{
joined = supportLayer_this.unionPolygons(supportLayer_up);
}
// join different parts
if (supportJoinDistance > 0)
{
joined = joined.offset(supportJoinDistance)
.offset(-supportJoinDistance);
}
// remove jagged line pieces introduced by unioning separate overhang areas for consectuive layers
//
// support may otherwise look like:
// _____________________ .
// / \ } dist_from_lower_layer
// /__ __\ /
// /''--...........--''\ `\ .
// / \ } dist_from_lower_layer
// /__ __\ ./
// /''--...........--''\ `\ .
// / \ } dist_from_lower_layer
// /_______________________\ ,/
// rather than
// _____________________
// / \ .
// / \ .
// | |
// | |
// | |
// | |
// | |
// |_______________________|
//
// dist_from_lower_layer may be up to max_dist_from_lower_layer (see below), but that value may be extremely high
joined = joined.smooth_outward(max_smoothing_angle, smoothing_distance);
return joined;
}
示例6: generateInfill
/*
* This function is executed in a parallel region based on layer_nr.
* When modifying make sure any changes does not introduce data races.
*
* generateInfill read mesh.layers[n].parts[*].{insets,skin_parts,boundingBox} and write mesh.layers[n].parts[*].infill_area
*/
void SkinInfillAreaComputation::generateInfill(SliceLayerPart& part, const Polygons& skin)
{
if (int(part.insets.size()) < wall_line_count)
{
return; // the last wall is not present, the part should only get inter perimeter gaps, but no infill.
}
const int wall_line_count = mesh.getSettingAsCount("wall_line_count");
const coord_t infill_line_distance = mesh.getSettingInMicrons("infill_line_distance");
coord_t offset_from_inner_wall = -infill_skin_overlap;
if (wall_line_count > 0)
{ // calculate offset_from_inner_wall
coord_t extra_perimeter_offset = 0; // to align concentric polygons across layers
EFillMethod fill_pattern = mesh.getSettingAsFillMethod("infill_pattern");
if ((fill_pattern == EFillMethod::CONCENTRIC || fill_pattern == EFillMethod::CONCENTRIC_3D)
&& infill_line_distance > mesh.getSettingInMicrons("infill_line_width") * 2)
{
if (mesh.getSettingBoolean("alternate_extra_perimeter")
&& layer_nr % 2 == 0)
{ // compensate shifts otherwise caused by alternating an extra perimeter
extra_perimeter_offset = -innermost_wall_line_width;
}
if (layer_nr == 0)
{ // compensate for shift caused by walls being expanded by the initial line width multiplier
const coord_t normal_wall_line_width_0 = mesh.getSettingInMicrons("wall_line_width_0");
const coord_t normal_wall_line_width_x = mesh.getSettingInMicrons("wall_line_width_x");
coord_t normal_walls_width = normal_wall_line_width_0 + (wall_line_count - 1) * normal_wall_line_width_x;
coord_t walls_width = normal_walls_width * mesh.getSettingAsRatio("initial_layer_line_width_factor");
extra_perimeter_offset += walls_width - normal_walls_width;
while (extra_perimeter_offset > 0)
{
extra_perimeter_offset -= infill_line_distance;
}
}
}
offset_from_inner_wall += extra_perimeter_offset - innermost_wall_line_width / 2;
}
Polygons infill = part.insets.back().offset(offset_from_inner_wall);
infill = infill.difference(skin);
infill.removeSmallAreas(MIN_AREA_SIZE);
part.infill_area = infill.offset(infill_skin_overlap);
}
示例7: calculateBottomSkin
/*
* This function is executed in a parallel region based on layer_nr.
* When modifying make sure any changes does not introduce data races.
*
* this function may only read/write the skin and infill from the *current* layer.
*/
void SkinInfillAreaComputation::calculateBottomSkin(const SliceLayerPart& part, int min_infill_area, Polygons& downskin)
{
if (static_cast<int>(layer_nr - bottom_layer_count) >= 0 && bottom_layer_count > 0)
{
Polygons not_air = getWalls(part, layer_nr - bottom_layer_count, bottom_reference_wall_idx).offset(bottom_reference_wall_expansion);
if (!no_small_gaps_heuristic)
{
for (int downskin_layer_nr = layer_nr - bottom_layer_count + 1; downskin_layer_nr < layer_nr; downskin_layer_nr++)
{
not_air = not_air.intersection(getWalls(part, downskin_layer_nr, bottom_reference_wall_idx).offset(bottom_reference_wall_expansion));
}
}
if (min_infill_area > 0)
{
not_air.removeSmallAreas(min_infill_area);
}
downskin = downskin.difference(not_air); // skin overlaps with the walls
}
}
示例8: calculateTopSkin
void SkinInfillAreaComputation::calculateTopSkin(const SliceLayerPart& part, int min_infill_area, Polygons& upskin)
{
if (static_cast<int>(layer_nr + top_layer_count) < static_cast<int>(mesh.layers.size()) && top_layer_count > 0)
{
Polygons not_air = getWalls(part, layer_nr + top_layer_count, top_reference_wall_idx).offset(top_reference_wall_expansion);
if (!no_small_gaps_heuristic)
{
for (int upskin_layer_nr = layer_nr + 1; upskin_layer_nr < layer_nr + top_layer_count; upskin_layer_nr++)
{
not_air = not_air.intersection(getWalls(part, upskin_layer_nr, top_reference_wall_idx).offset(top_reference_wall_expansion));
}
}
if (min_infill_area > 0)
{
not_air.removeSmallAreas(min_infill_area);
}
upskin = upskin.difference(not_air); // skin overlaps with the walls
}
}
示例9: generateConcentricInfill
void Infill::generateConcentricInfill(Polygons& first_concentric_wall, Polygons& result, int inset_value)
{
result.add(first_concentric_wall);
Polygons* prev_inset = &first_concentric_wall;
Polygons next_inset;
while (prev_inset->size() > 0)
{
next_inset = prev_inset->offset(-inset_value);
result.add(next_inset);
if (perimeter_gaps)
{
const Polygons outer = prev_inset->offset(-infill_line_width / 2 - perimeter_gaps_extra_offset);
const Polygons inner = next_inset.offset(infill_line_width / 2);
const Polygons gaps_here = outer.difference(inner);
perimeter_gaps->add(gaps_here);
}
prev_inset = &next_inset;
}
}
示例10: fillRoofs
void Weaver::fillRoofs(Polygons& supporting, Polygons& to_be_supported, int direction, int z, WeaveRoof& horizontals)
{
std::vector<WeaveRoofPart>& insets = horizontals.roof_insets;
if (supporting.size() == 0) return; // no parts to start the roof from!
Polygons roofs = supporting.difference(to_be_supported);
roofs = roofs.offset(-roof_inset).offset(roof_inset);
if (roofs.size() == 0) return;
Polygons roof_outlines;
Polygons roof_holes;
{ // split roofs into outlines and holes
std::vector<PolygonsPart> roof_parts = roofs.splitIntoParts();
for (PolygonsPart& roof_part : roof_parts)
{
roof_outlines.add(roof_part[0]);
for (unsigned int hole_idx = 1; hole_idx < roof_part.size(); hole_idx++)
{
roof_holes.add(roof_part[hole_idx]);
roof_holes.back().reverse();
}
}
}
Polygons supporting_outlines;
std::vector<PolygonsPart> supporting_parts = supporting.splitIntoParts();
for (PolygonsPart& supporting_part : supporting_parts)
supporting_outlines.add(supporting_part[0]); // only add outlines, not the holes
Polygons inset1;
Polygons last_inset;
Polygons last_supported = supporting;
for (Polygons inset0 = supporting_outlines; inset0.size() > 0; inset0 = last_inset)
{
last_inset = inset0.offset(direction * roof_inset, ClipperLib::jtRound);
inset1 = last_inset.intersection(roof_outlines); // stay within roof area
inset1 = inset1.unionPolygons(roof_holes);// make insets go around holes
if (inset1.size() == 0) break;
insets.emplace_back();
connect(last_supported, z, inset1, z, insets.back(), true);
inset1 = inset1.remove(roof_holes); // throw away holes which appear in every intersection
inset1 = inset1.remove(roof_outlines);// throw away fully filled regions
last_supported = insets.back().supported; // chainified
}
horizontals.roof_outlines.add(roofs); // TODO just add the new lines, not the lines of the roofs which are already supported ==> make outlines into a connection from which we only print the top, not the connection
}
示例11: generateSupportAreas
//.........这里部分代码省略.........
{
// compute basic overhang and put in right layer ([layerZdistanceTOp] layers below)
overhang = basic_and_full_overhang_above.back().second;
basic_and_full_overhang_above.pop_back();
}
Polygons& supportLayer_this = overhang;
if (extension_offset)
{
supportLayer_this = supportLayer_this.offset(extension_offset);
}
if (supportMinAreaSqrt > 0)
{
// handle straight walls
AreaSupport::handleWallStruts(supportLayer_this, supportMinAreaSqrt, supportTowerDiameter);
// handle towers
AreaSupport::handleTowers(supportLayer_this, towerRoofs, overhang_points, overhang_points_pos, layer_idx, towerRoofExpansionDistance, supportTowerDiameter, supportMinAreaSqrt, layer_count, z_layer_distance_tower);
}
if (layer_idx+1 < support_layer_count)
{ // join with support from layer up
supportLayer_this = AreaSupport::join(supportLayer_last, supportLayer_this, join_distance, smoothing_distance, max_smoothing_angle, conical_support, conical_support_offset, conical_smallest_breadth);
}
supportLayer_this = supportLayer_this.unionPolygons(storage.support.supportLayers[layer_idx].support_mesh);
// move up from model
if (layerZdistanceBottom > 0 && layer_idx >= layerZdistanceBottom)
{
int stepHeight = support_bottom_stair_step_height / supportLayerThickness + 1;
int bottomLayer = ((layer_idx - layerZdistanceBottom) / stepHeight) * stepHeight;
supportLayer_this = supportLayer_this.difference(storage.getLayerOutlines(bottomLayer, false));
}
supportLayer_last = supportLayer_this;
// inset using X/Y distance
if (supportLayer_this.size() > 0)
{
Polygons& basic_overhang = basic_and_full_overhang_above.front().first; // basic overhang on this layer
Polygons outlines = storage.getLayerOutlines(layer_idx, false);
if (use_support_xy_distance_overhang)
{
Polygons xy_overhang_disallowed = basic_overhang.offset(supportZDistanceTop * tanAngle);
Polygons xy_non_overhang_disallowed = outlines.difference(basic_overhang.offset(supportXYDistance)).offset(supportXYDistance);
Polygons xy_disallowed = xy_overhang_disallowed.unionPolygons(xy_non_overhang_disallowed.unionPolygons(outlines.offset(support_xy_distance_overhang)));
supportLayer_this = supportLayer_this.difference(xy_disallowed);
}
else
{
supportLayer_this = supportLayer_this.difference(outlines.offset(supportXYDistance));
}
if (storage.primeTower.enabled) //Don't intersect with prime tower.
{
supportLayer_this = supportLayer_this.difference(storage.primeTower.ground_poly.getOutsidePolygons());
}
}
supportAreas[layer_idx] = supportLayer_this;
示例12: generateSkinAreas
void generateSkinAreas(int layer_nr, SliceMeshStorage& mesh, const int innermost_wall_line_width, int downSkinCount, int upSkinCount, int wall_line_count, bool no_small_gaps_heuristic)
{
SliceLayer& layer = mesh.layers[layer_nr];
if (downSkinCount == 0 && upSkinCount == 0)
{
return;
}
for(unsigned int partNr = 0; partNr < layer.parts.size(); partNr++)
{
SliceLayerPart& part = layer.parts[partNr];
if (int(part.insets.size()) < wall_line_count)
{
continue; // the last wall is not present, the part should only get inter perimeter gaps, but no skin.
}
Polygons upskin = part.insets.back().offset(-innermost_wall_line_width / 2);
Polygons downskin = (downSkinCount == 0) ? Polygons() : upskin;
if (upSkinCount == 0) upskin = Polygons();
auto getInsidePolygons = [&part, wall_line_count](SliceLayer& layer2)
{
Polygons result;
for(SliceLayerPart& part2 : layer2.parts)
{
if (part.boundaryBox.hit(part2.boundaryBox))
{
unsigned int wall_idx = std::max(0, std::min(wall_line_count, (int) part2.insets.size()) - 1);
result.add(part2.insets[wall_idx]);
}
}
return result;
};
if (no_small_gaps_heuristic)
{
if (static_cast<int>(layer_nr - downSkinCount) >= 0)
{
downskin = downskin.difference(getInsidePolygons(mesh.layers[layer_nr - downSkinCount])); // skin overlaps with the walls
}
if (static_cast<int>(layer_nr + upSkinCount) < static_cast<int>(mesh.layers.size()))
{
upskin = upskin.difference(getInsidePolygons(mesh.layers[layer_nr + upSkinCount])); // skin overlaps with the walls
}
}
else
{
if (layer_nr >= downSkinCount && downSkinCount > 0)
{
Polygons not_air = getInsidePolygons(mesh.layers[layer_nr - 1]);
for (int downskin_layer_nr = layer_nr - downSkinCount; downskin_layer_nr < layer_nr - 1; downskin_layer_nr++)
{
not_air = not_air.intersection(getInsidePolygons(mesh.layers[downskin_layer_nr]));
}
downskin = downskin.difference(not_air); // skin overlaps with the walls
}
if (layer_nr < static_cast<int>(mesh.layers.size()) - 1 - upSkinCount && upSkinCount > 0)
{
Polygons not_air = getInsidePolygons(mesh.layers[layer_nr + 1]);
for (int upskin_layer_nr = layer_nr + 2; upskin_layer_nr < layer_nr + upSkinCount + 1; upskin_layer_nr++)
{
not_air = not_air.intersection(getInsidePolygons(mesh.layers[upskin_layer_nr]));
}
upskin = upskin.difference(not_air); // skin overlaps with the walls
}
}
Polygons skin = upskin.unionPolygons(downskin);
skin.removeSmallAreas(MIN_AREA_SIZE);
for (PolygonsPart& skin_area_part : skin.splitIntoParts())
{
part.skin_parts.emplace_back();
part.skin_parts.back().outline = skin_area_part;
}
}
}
示例13: generateSparse
void generateSparse(int layerNr, SliceVolumeStorage& storage, int extrusionWidth, int downSkinCount, int upSkinCount)
{
SliceLayer* layer = &storage.layers[layerNr];
for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
{
SliceLayerPart* part = &layer->parts[partNr];
Polygons sparse = part->insets[part->insets.size() - 1].offset(-extrusionWidth/2);
Polygons downskin = sparse;
Polygons upskin = sparse;
if (int(layerNr - downSkinCount) >= 0)
{
SliceLayer* layer2 = &storage.layers[layerNr - downSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
{
if (layer2->parts[partNr2].insets.size() > 1)
{
downskin = downskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 2]);
}else{
downskin = downskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1]);
}
}
}
}
if (int(layerNr + upSkinCount) < (int)storage.layers.size())
{
SliceLayer* layer2 = &storage.layers[layerNr + upSkinCount];
for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++)
{
if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox))
{
if (layer2->parts[partNr2].insets.size() > 1)
{
upskin = upskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 2]);
}else{
upskin = upskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1]);
}
}
}
}
Polygons result = upskin.unionPolygons(downskin);
double minAreaSize = 3.0;//(2 * M_PI * (double(config.extrusionWidth) / 1000.0) * (double(config.extrusionWidth) / 1000.0)) * 3;
for(unsigned int i=0; i<result.size(); i++)
{
double area = fabs(ClipperLib::Area(result[i])) / 1000.0 / 1000.0;
if (area < minAreaSize) /* Only create an up/down skin if the area is large enough. So you do not create tiny blobs of "trying to fill" */
{
result.remove(i);
i -= 1;
}
}
part->sparseOutline = sparse.difference(result);
}
}
示例14: generateSupportAreas
/*
* Algorithm:
* From top layer to bottom layer:
* - find overhang by looking at the difference between two consucutive layers
* - join with support areas from layer above
* - subtract current layer
* - use the result for the next lower support layer (without doing XY-distance and Z bottom distance, so that a single support beam may move around the model a bit => more stability)
* - perform inset using X/Y-distance and bottom Z distance
*
* for support buildplate only: purge all support not connected to buildplate
*/
void generateSupportAreas(SliceDataStorage& storage, SliceMeshStorage* object, int layer_count)
{
// given settings
ESupportType support_type = object->settings->getSettingAsSupportType("support_type");
storage.support.generated = false;
if (!object->settings->getSettingBoolean("support_enable"))
return;
if (support_type == Support_None)
return;
double supportAngle = object->settings->getSettingInAngleRadians("support_angle");
bool supportOnBuildplateOnly = support_type == Support_PlatformOnly;
int supportXYDistance = object->settings->getSettingInMicrons("support_xy_distance");
int supportZDistance = object->settings->getSettingInMicrons("support_z_distance");
int supportZDistanceBottom = object->settings->getSettingInMicrons("support_bottom_distance");
int supportZDistanceTop = object->settings->getSettingInMicrons("support_top_distance");
int supportJoinDistance = object->settings->getSettingInMicrons("support_join_distance");
int support_bottom_stair_step_height = object->settings->getSettingInMicrons("support_bottom_stair_step_height");
int smoothing_distance = object->settings->getSettingInMicrons("support_area_smoothing");
int supportTowerDiameter = object->settings->getSettingInMicrons("support_tower_diameter");
int supportMinAreaSqrt = object->settings->getSettingInMicrons("support_minimal_diameter");
double supportTowerRoofAngle = object->settings->getSettingInAngleRadians("support_tower_roof_angle");
//std::cerr <<" towerDiameter=" << towerDiameter <<", supportMinAreaSqrt=" << supportMinAreaSqrt << std::endl;
int min_smoothing_area = 100*100; // minimal area for which to perform smoothing
int z_layer_distance_tower = 1; // start tower directly below overhang point
int layerThickness = object->settings->getSettingInMicrons("layer_height");
int extrusionWidth = object->settings->getSettingInMicrons("wall_line_width_x"); // TODO check for layer0extrusionWidth!
// derived settings:
if (supportZDistanceBottom < 0) supportZDistanceBottom = supportZDistance;
if (supportZDistanceTop < 0) supportZDistanceTop = supportZDistance;
int supportLayerThickness = layerThickness;
int layerZdistanceTop = supportZDistanceTop / supportLayerThickness + 1; // support must always be 1 layer below overhang
int layerZdistanceBottom = supportZDistanceBottom / supportLayerThickness;
double tanAngle = tan(supportAngle) - 0.01; // the XY-component of the supportAngle
int maxDistFromLowerLayer = tanAngle * supportLayerThickness; // max dist which can be bridged
int support_layer_count = layer_count;
double tanTowerRoofAngle = tan(supportTowerRoofAngle);
int towerRoofExpansionDistance = layerThickness / tanTowerRoofAngle;
// computation
std::vector<Polygons> joinedLayers; // join model layers of all meshes into polygons and store small areas which need tower support
std::vector<std::pair<int, std::vector<Polygons>>> overhang_points; // stores overhang_points along with the layer index at which the overhang point occurs
AreaSupport::joinMeshesAndDetectOverhangPoints(storage, joinedLayers, overhang_points, layer_count, supportMinAreaSqrt, extrusionWidth);
// initialization of supportAreasPerLayer
for (int layer_idx = 0; layer_idx < layer_count ; layer_idx++)
storage.support.supportAreasPerLayer.emplace_back();
int overhang_points_pos = overhang_points.size() - 1;
Polygons supportLayer_last;
std::vector<Polygons> towerRoofs;
for (int layer_idx = support_layer_count - 1 - layerZdistanceTop; layer_idx >= 0 ; layer_idx--)
{
// compute basic overhang and put in right layer ([layerZdistanceTOp] layers below)
Polygons supportLayer_supportee = joinedLayers[layer_idx+layerZdistanceTop];
Polygons supportLayer_supported = joinedLayers[layer_idx-1+layerZdistanceTop].offset(maxDistFromLowerLayer);
Polygons basic_overhang = supportLayer_supportee.difference(supportLayer_supported);
Polygons support_extension = basic_overhang.offset(maxDistFromLowerLayer);
support_extension = support_extension.intersection(supportLayer_supported);
support_extension = support_extension.intersection(supportLayer_supportee);
Polygons overhang = basic_overhang.unionPolygons(support_extension);
/* supported
//.........这里部分代码省略.........
示例15: generateZigZagIninfill_endPieces
/*!
* adapted from generateLineInfill(.)
*
* generate lines within the area of [in_outline], at regular intervals of [lineSpacing]
* idea:
* intersect a regular grid of 'scanlines' with the area inside [in_outline]
* sigzag:
* include pieces of boundary, connecting the lines, forming an accordion like zigzag instead of separate lines |_|^|_|
*
* we call the areas between two consecutive scanlines a 'scansegment'
*
* algorithm:
* 1. for each line segment of each polygon:
* store the intersections of that line segment with all scanlines in a mapping (vector of vectors) from scanline to intersections
* (zigzag): add boundary segments to result
* 2. for each scanline:
* sort the associated intersections
* and connect them using the even-odd rule
*
* zigzag algorithm:
* while walking around (each) polygon (1.)
* if polygon intersects with even scanline
* start boundary segment (add each following segment to the [result])
* when polygon intersects with a scanline again
* stop boundary segment (stop adding segments to the [result])
* if polygon intersects with even scanline again (instead of odd)
* dont add the last line segment to the boundary (unless [connect_zigzags])
*
*
* <--
* ___
* | | |
* | | |
* | |___|
* -->
*
* ^ = even scanline
*
* start boundary from even scanline! :D
*
*
* _____
* | | | ,
* | | | |
* |_____| |__/
*
* ^ ^ ^ scanlines
* ^ disconnected end piece
*/
void generateZigZagIninfill_endPieces(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, double infillOverlap, double rotation, bool connect_zigzags)
{
// if (in_outline.size() == 0) return;
// Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100 - extrusionWidth / 2);
Polygons empty;
Polygons outline = in_outline.difference(empty); // copy
if (outline.size() == 0) return;
PointMatrix matrix(rotation);
outline.applyMatrix(matrix);
auto addLine = [&](Point from, Point to)
{
PolygonRef p = result.newPoly();
p.add(matrix.unapply(from));
p.add(matrix.unapply(to));
};
AABB boundary(outline);
int scanline_min_idx = boundary.min.X / lineSpacing;
int lineCount = (boundary.max.X + (lineSpacing - 1)) / lineSpacing - scanline_min_idx;
std::vector<std::vector<int64_t> > cutList; // mapping from scanline to all intersections with polygon segments
for(int n=0; n<lineCount; n++)
cutList.push_back(std::vector<int64_t>());
for(unsigned int polyNr=0; polyNr < outline.size(); polyNr++)
{
std::vector<Point> firstBoundarySegment;
std::vector<Point> unevenBoundarySegment; // stored cause for connected_zigzags a boundary segment which ends in an uneven scanline needs to be included
bool isFirstBoundarySegment = true;
bool firstBoundarySegmentEndsInEven;
bool isEvenScanSegment = false;
Point p0 = outline[polyNr][outline[polyNr].size()-1];
Point lastPoint = p0;
for(unsigned int i=0; i < outline[polyNr].size(); i++)
{
Point p1 = outline[polyNr][i];
int64_t xMin = p1.X, xMax = p0.X;
if (xMin == xMax) {
lastPoint = p1;
p0 = p1;
continue;
}
if (xMin > xMax) { xMin = p0.X; xMax = p1.X; }
//.........这里部分代码省略.........