本文整理汇总了C++中PolygonRef类的典型用法代码示例。如果您正苦于以下问题:C++ PolygonRef类的具体用法?C++ PolygonRef怎么用?C++ PolygonRef使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了PolygonRef类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
void GCodeExport::writeMove(int x, int y, int z, double speed, double extrusion_mm3_per_mm)
{
if (currentPosition.x == x && currentPosition.y == y && currentPosition.z == z)
return;
#ifdef ASSERT_INSANE_OUTPUT
assert(speed < 200 && speed > 1); // normal F values occurring in UM2 gcode (this code should not be compiled for release)
assert(currentPosition != no_point3);
assert((Point3(x,y,z) - currentPosition).vSize() < MM2INT(300)); // no crazy positions (this code should not be compiled for release)
#endif //ASSERT_INSANE_OUTPUT
if (extrusion_mm3_per_mm < 0)
logWarning("Warning! Negative extrusion move!");
if (flavor == EGCodeFlavor::BFB)
{
writeMoveBFB(x, y, z, speed, extrusion_mm3_per_mm);
return;
}
double extrusion_per_mm = extrusion_mm3_per_mm;
if (!is_volumatric)
{
extrusion_per_mm = extrusion_mm3_per_mm / extruder_attr[current_extruder].filament_area;
}
Point gcode_pos = getGcodePos(x,y, current_extruder);
if (extrusion_mm3_per_mm > 0.000001)
{
Point3 diff = Point3(x,y,z) - getPosition();
if (isZHopped > 0)
{
*output_stream << std::setprecision(3) << "G1 Z" << INT2MM(currentPosition.z) << "\n";
isZHopped = 0;
}
double prime_volume = extruder_attr[current_extruder].prime_volume;
current_e_value += (is_volumatric) ? prime_volume : prime_volume / extruder_attr[current_extruder].filament_area;
if (extruder_attr[current_extruder].retraction_e_amount_current)
{
if (firmware_retract)
{ // note that BFB is handled differently
*output_stream << "G11\n";
//Assume default UM2 retraction settings.
if (prime_volume > 0)
{
*output_stream << "G1 F" << (extruder_attr[current_extruder].last_retraction_prime_speed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << current_e_value << "\n";
currentSpeed = extruder_attr[current_extruder].last_retraction_prime_speed;
}
estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), current_e_value), 25.0);
}
else
{
current_e_value += extruder_attr[current_extruder].retraction_e_amount_current;
*output_stream << "G1 F" << (extruder_attr[current_extruder].last_retraction_prime_speed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << current_e_value << "\n";
currentSpeed = extruder_attr[current_extruder].last_retraction_prime_speed;
estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), current_e_value), currentSpeed);
}
if (getCurrentExtrudedVolume() > 10000.0) //According to https://github.com/Ultimaker/CuraEngine/issues/14 having more then 21m of extrusion causes inaccuracies. So reset it every 10m, just to be sure.
{
resetExtrusionValue();
}
extruder_attr[current_extruder].retraction_e_amount_current = 0.0;
}
else if (prime_volume > 0.0)
{
current_e_value += prime_volume;
*output_stream << "G1 F" << (extruder_attr[current_extruder].last_retraction_prime_speed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << current_e_value << "\n";
currentSpeed = extruder_attr[current_extruder].last_retraction_prime_speed;
estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), current_e_value), currentSpeed);
}
extruder_attr[current_extruder].prime_volume = 0.0;
current_e_value += extrusion_per_mm * diff.vSizeMM();
*output_stream << "G1";
}
else
{
*output_stream << "G0";
if (commandSocket)
{
// we should send this travel as a non-retraction move
cura::Polygons travelPoly;
PolygonRef travel = travelPoly.newPoly();
travel.add(Point(currentPosition.x, currentPosition.y));
travel.add(Point(x, y));
commandSocket->sendPolygons(extruder_attr[current_extruder].retraction_e_amount_current ? PrintFeatureType::MoveRetraction : PrintFeatureType::MoveCombing, layer_nr, travelPoly, extruder_attr[current_extruder].retraction_e_amount_current ? MM2INT(0.2) : MM2INT(0.1));
}
}
if (currentSpeed != speed)
{
*output_stream << " F" << (speed * 60);
currentSpeed = speed;
}
*output_stream << std::setprecision(3) <<
" X" << INT2MM(gcode_pos.X) <<
" Y" << INT2MM(gcode_pos.Y);
if (z != currentPosition.z + isZHopped)
//.........这里部分代码省略.........
示例2: generateTroctInfill
void generateTroctInfill(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, int infillOverlap, double rotation, int posZ)
{
Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100);
PointMatrix matrix(rotation);
outline.applyMatrix(matrix);
AABB boundary(outline);
// ignore infill for areas smaller than line spacing
if((abs(boundary.min.X - boundary.max.X) + abs(boundary.min.Y - boundary.max.Y)) < lineSpacing){
return;
}
// fix to normalise against diagonal infill
lineSpacing = lineSpacing * 2;
uint64_t Zscale = SQRT2MUL(lineSpacing);
int offset = abs(posZ % (Zscale) - (Zscale/2)) - (Zscale/4);
boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
boundary.min.Y = ((boundary.min.Y / lineSpacing) - 1) * lineSpacing;
unsigned int lineCountX = (boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing;
unsigned int lineCountY = (boundary.max.Y - boundary.min.Y + (lineSpacing - 1)) / lineSpacing;
int rtMod = int(rotation / 90) % 2;
// with an odd number of lines, sides need to be swapped around
if(rtMod == 1){
rtMod = (lineCountX + int(rotation / 90)) % 2;
}
// draw non-horizontal walls of octohedrons
Polygons po;
PolygonRef p = po.newPoly();
for(unsigned int ly=0; ly < lineCountY;){
for(size_t it = 0; it < 2; ly++, it++){
int side = (2*((ly + it + rtMod) % 2) - 1);
int y = (ly * lineSpacing) + boundary.min.Y + lineSpacing / 2 - (offset/2 * side);
int x = boundary.min.X-(offset/2);
if(it == 1){
x = (lineCountX * (lineSpacing)) + boundary.min.X + lineSpacing / 2 - (offset/2);
}
p.add(Point(x,y));
for(unsigned int lx=0; lx < lineCountX; lx++){
if(it == 1){
side = (2*((lx + ly + it + rtMod + lineCountX) % 2) - 1);
y = (ly * lineSpacing) + boundary.min.Y + lineSpacing / 2 + (offset/2 * side);
x = ((lineCountX - lx - 1) * lineSpacing) + boundary.min.X + lineSpacing / 2;
p.add(Point(x+lineSpacing-abs(offset/2), y));
p.add(Point(x+abs(offset/2), y));
} else {
side = (2*((lx + ly + it + rtMod) % 2) - 1);
y = (ly * lineSpacing) + boundary.min.Y + lineSpacing / 2 + (offset/2 * side);
x = (lx * lineSpacing) + boundary.min.X + lineSpacing / 2;
p.add(Point(x+abs(offset/2), y));
p.add(Point(x+lineSpacing-abs(offset/2), y));
}
}
x = (lineCountX * lineSpacing) + boundary.min.X + lineSpacing / 2 - (offset/2);
if(it == 1){
x = boundary.min.X-(offset/2);
}
y = (ly * lineSpacing) + boundary.min.Y + lineSpacing / 2 - (offset/2 * side);
p.add(Point(x,y));
}
}
// Generate tops / bottoms of octohedrons
if(abs((abs(offset) - Zscale/4)) < (extrusionWidth/2)){
uint64_t startLine = (offset < 0) ? 0 : 1;
uint64_t coverWidth = OCTSLEN(lineSpacing);
vector<Point> points;
for(size_t xi = 0; xi < (lineCountX+1); xi++){
for(size_t yi = 0; yi < (lineCountY); yi += 2){
points.push_back(Point(boundary.min.X + OCTDLEN(lineSpacing)
+ (xi - startLine + rtMod) * lineSpacing,
boundary.min.Y + OCTDLEN(lineSpacing)
+ (yi + (xi%2)) * lineSpacing
+ extrusionWidth/2));
}
}
uint64_t order = 0;
for(Point pp : points){
PolygonRef p = po.newPoly();
for(size_t yi = 0; yi <= coverWidth; yi += extrusionWidth) {
if(order == 0){
p.add(Point(pp.X, pp.Y + yi));
p.add(Point(pp.X + coverWidth + extrusionWidth, pp.Y + yi));
} else {
p.add(Point(pp.X + coverWidth + extrusionWidth, pp.Y + yi));
p.add(Point(pp.X, pp.Y + yi));
}
order = (order + 1) % 2;
}
}
}
// intersect with outline polygon(s)
Polygons pi = po.intersection(outline);
// Hack to add intersection to result. There doesn't seem
// to be a direct way to do this
for(unsigned int polyNr=0; polyNr < pi.size(); polyNr++) {
PolygonRef p = result.newPoly(); // = result.newPoly()
for(unsigned int i=0; i < pi[polyNr].size(); i++) {
//.........这里部分代码省略.........
示例3: vSize2
void AreaSupport::handleWallStruts(
Polygons& supportLayer_this,
int supportMinAreaSqrt,
int supportTowerDiameter
)
{
for (unsigned int p = 0; p < supportLayer_this.size(); p++)
{
PolygonRef poly = supportLayer_this[p];
if (poly.size() < 6) // might be a single wall
{
PolygonRef poly = supportLayer_this[p];
int best = -1;
int best_length2 = -1;
for (unsigned int i = 0; i < poly.size(); i++)
{
int length2 = vSize2(poly[i] - poly[(i+1) % poly.size()]);
if (length2 > best_length2)
{
best = i;
best_length2 = length2;
}
}
if (best_length2 < supportMinAreaSqrt * supportMinAreaSqrt)
break; // this is a small area, not a wall!
// an estimate of the width of the area
int width = sqrt( poly.area() * poly.area() / best_length2 ); // sqrt (a^2 / l^2) instead of a / sqrt(l^2)
// add square tower (strut) in the middle of the wall
if (width < supportMinAreaSqrt)
{
Point mid = (poly[best] + poly[(best+1) % poly.size()] ) / 2;
Polygons struts;
PolygonRef strut = struts.newPoly();
strut.add(mid + Point( supportTowerDiameter/2, supportTowerDiameter/2));
strut.add(mid + Point(-supportTowerDiameter/2, supportTowerDiameter/2));
strut.add(mid + Point(-supportTowerDiameter/2, -supportTowerDiameter/2));
strut.add(mid + Point( supportTowerDiameter/2, -supportTowerDiameter/2));
supportLayer_this = supportLayer_this.unionPolygons(struts);
}
}
}
}
示例4: assert
//.........这里部分代码省略.........
// (Trick copied from KISSlicer, thanks Jonathan)
fspeed *= (rpm / (roundf(rpm * 100) / 100));
//Increase the extrusion amount to calculate the amount of filament used.
Point3 diff = Point3(x,y,z) - getPosition();
extrusion_amount += extrusion_per_mm * diff.vSizeMM();
}else{
//If we are not extruding, check if we still need to disable the extruder. This causes a retraction due to auto-retraction.
if (!isRetracted)
{
*output_stream << "M103\r\n";
isRetracted = true;
}
}
*output_stream << std::setprecision(3) <<
"G1 X" << INT2MM(gcode_pos.X) <<
" Y" << INT2MM(gcode_pos.Y) <<
" Z" << INT2MM(z) << std::setprecision(1) << " F" << fspeed << "\r\n";
}
else
{
//Normal E handling.
if (extrusion_mm3_per_mm > 0.000001)
{
Point3 diff = Point3(x,y,z) - getPosition();
if (isZHopped > 0)
{
// TinyG G1: Straight feed
*output_stream << std::setprecision(3) << "G1 Z" << INT2MM(currentPosition.z) << "\n";
isZHopped = 0;
}
extrusion_amount += (is_volumatric) ? last_coasted_amount_mm3 : last_coasted_amount_mm3 / getFilamentArea(current_extruder);
if (isRetracted)
{
if (flavor == EGCodeFlavor::ULTIGCODE || flavor == EGCodeFlavor::REPRAP_VOLUMATRIC)
{
*output_stream << "G11\n"; //TODO try this code and see what happens
//Assume default UM2 retraction settings.
if (last_coasted_amount_mm3 > 0)
{
*output_stream << "G1 F" << (retractionPrimeSpeed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount << "\n";
}
estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), 25.0);
}else{
// TinyG checked
*output_stream << "G1 F" << (retractionPrimeSpeed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount << "\n";
currentSpeed = retractionPrimeSpeed;
estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), currentSpeed);
}
if (getExtrusionAmountMM3(current_extruder) > 10000.0) //According to https://github.com/Ultimaker/CuraEngine/issues/14 having more then 21m of extrusion causes inaccuracies. So reset it every 10m, just to be sure.
resetExtrusionValue();
isRetracted = false;
}
else
{
if (last_coasted_amount_mm3 > 0)
{
*output_stream << "G1 F" << (retractionPrimeSpeed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount << "\n";
estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), currentSpeed);
}
}
last_coasted_amount_mm3 = 0;
extrusion_amount += extrusion_per_mm * diff.vSizeMM();
// TinyG TODO: add one axis
*output_stream << "G1";
}else{
*output_stream << "G0";
if (commandSocket) {
// we should send this travel as a non-retraction move
cura::Polygons travelPoly;
PolygonRef travel = travelPoly.newPoly();
travel.add(Point(currentPosition.x, currentPosition.y));
travel.add(Point(x, y));
commandSocket->sendPolygons(isRetracted ? MoveRetractionType : MoveCombingType, layer_nr, travelPoly, isRetracted ? MM2INT(0.2) : MM2INT(0.1));
}
}
if (currentSpeed != speed)
{
*output_stream << " F" << (speed * 60);
currentSpeed = speed;
}
*output_stream << std::setprecision(3) <<
" X" << INT2MM(gcode_pos.X) <<
" Y" << INT2MM(gcode_pos.Y);
if (z != currentPosition.z)
*output_stream << " Z" << INT2MM(z + isZHopped);
if (extrusion_mm3_per_mm > 0.000001)
*output_stream << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount;
*output_stream << "\n";
}
currentPosition = Point3(x, y, z);
startPosition = currentPosition;
estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), speed);
}
示例5: optimize
void PathOrderOptimizer::optimize()
{
std::vector<bool> picked;
for(unsigned int i=0;i<polygons.size(); i++)
{
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
PolygonRef poly = polygons[i];
for(unsigned int j=0; j<poly.size(); j++)
{
float dist = vSize2f(poly[j] - startPoint);
if (dist < bestDist)
{
best = j;
bestDist = dist;
}
}
polyStart.push_back(best);
picked.push_back(false);
}
Point p0 = startPoint;
for(unsigned int n=0; n<polygons.size(); n++)
{
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
for(unsigned int i=0;i<polygons.size(); i++)
{
if (picked[i] || polygons[i].size() < 1)
continue;
if (polygons[i].size() == 2)
{
float dist = vSize2f(polygons[i][0] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 0;
}
dist = vSize2f(polygons[i][1] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
polyStart[i] = 1;
}
}else{
float dist = vSize2f(polygons[i][polyStart[i]] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
}
}
}
if (best > -1)
{
if (polygons[best].size() == 2)
{
p0 = polygons[best][(polyStart[best] + 1) % 2];
}else{
p0 = polygons[best][polyStart[best]];
}
picked[best] = true;
polyOrder.push_back(best);
}
}
p0 = startPoint;
for(unsigned int n=0; n<polyOrder.size(); n++)
{
int nr = polyOrder[n];
int best = -1;
float bestDist = 0xFFFFFFFFFFFFFFFFLL;
for(unsigned int i=0;i<polygons[nr].size(); i++)
{
float dist = vSize2f(polygons[nr][i] - p0);
if (dist < bestDist)
{
best = i;
bestDist = dist;
}
}
polyStart[nr] = best;
if (polygons[nr].size() <= 2)
{
p0 = polygons[nr][(best + 1) % 2];
}else{
p0 = polygons[nr][best];
}
}
}
示例6: generateZigZagIninfill_noEndPieces
void generateZigZagIninfill_noEndPieces(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, double infillOverlap, double rotation)
{
if (in_outline.size() == 0) return;
Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100 - extrusionWidth / 2);
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> boundarySegment;
bool isFirstBoundarySegment = true;
bool firstBoundarySegmentEndsInEven;
bool isEvenScanSegment = false;
Point p0 = outline[polyNr][outline[polyNr].size()-1];
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) {
p0 = p1;
continue;
}
if (xMin > xMax) { xMin = p0.X; xMax = p1.X; }
int scanline_idx0 = (p0.X + ((p0.X > 0)? -1 : -lineSpacing)) / lineSpacing; // -1 cause a linesegment on scanline x counts as belonging to scansegment x-1 ...
int scanline_idx1 = (p1.X + ((p1.X > 0)? -1 : -lineSpacing)) / lineSpacing; // -linespacing because a line between scanline -n and -n-1 belongs to scansegment -n-1 (for n=positive natural number)
int direction = 1;
if (p0.X > p1.X)
{
direction = -1;
scanline_idx1 += 1; // only consider the scanlines in between the scansegments
} else scanline_idx0 += 1; // only consider the scanlines in between the scansegments
if (isFirstBoundarySegment) firstBoundarySegment.push_back(p0);
else boundarySegment.push_back(p0);
for(int scanline_idx = scanline_idx0; scanline_idx != scanline_idx1+direction; scanline_idx+=direction)
{
int x = scanline_idx * lineSpacing;
int y = p1.Y + (p0.Y - p1.Y) * (x - p1.X) / (p0.X - p1.X);
cutList[scanline_idx - scanline_min_idx].push_back(y);
bool last_isEvenScanSegment = isEvenScanSegment;
if (scanline_idx % 2 == 0) isEvenScanSegment = true;
else isEvenScanSegment = false;
if (!isFirstBoundarySegment)
{
if (last_isEvenScanSegment && !isEvenScanSegment)
{ // add whole boundarySegment (including the just obtained point)
for (unsigned int p = 1; p < boundarySegment.size(); p++)
{
addLine(boundarySegment[p-1], boundarySegment[p]);
}
addLine(boundarySegment[boundarySegment.size()-1], Point(x,y));
boundarySegment.clear();
}
else if (isEvenScanSegment) // we are either in an end piece or an uneven boundary segment
{
boundarySegment.clear();
boundarySegment.emplace_back(x,y);
} else
boundarySegment.clear();
}
if (isFirstBoundarySegment)
{
firstBoundarySegment.emplace_back(x,y);
firstBoundarySegmentEndsInEven = isEvenScanSegment;
isFirstBoundarySegment = false;
boundarySegment.emplace_back(x,y);
}
}
//.........这里部分代码省略.........
示例7: while
//.........这里部分代码省略.........
if (res.len > 0 && res.len < bestResult.len)
{
bestA = i;
bestB = i;
bestResult = res;
}
}
for(unsigned int j=0; j<openPolygonList.size(); j++)
{
if (openPolygonList[j].size() < 1 || i == j) continue;
gapCloserResult res = findPolygonGapCloser(openPolygonList[i][0], openPolygonList[j][openPolygonList[j].size()-1]);
if (res.len > 0 && res.len < bestResult.len)
{
bestA = i;
bestB = j;
bestResult = res;
}
}
}
if (bestResult.len < LLONG_MAX)
{
if (bestA == bestB)
{
if (bestResult.pointIdxA == bestResult.pointIdxB)
{
polygonList.add(openPolygonList[bestA]);
openPolygonList[bestA].clear();
}
else if (bestResult.AtoB)
{
PolygonRef poly = polygonList.newPoly();
for(unsigned int j = bestResult.pointIdxA; j != bestResult.pointIdxB; j = (j + 1) % polygonList[bestResult.polygonIdx].size())
poly.add(polygonList[bestResult.polygonIdx][j]);
for(unsigned int j = openPolygonList[bestA].size() - 1; int(j) >= 0; j--)
poly.add(openPolygonList[bestA][j]);
openPolygonList[bestA].clear();
}
else
{
unsigned int n = polygonList.size();
polygonList.add(openPolygonList[bestA]);
for(unsigned int j = bestResult.pointIdxB; j != bestResult.pointIdxA; j = (j + 1) % polygonList[bestResult.polygonIdx].size())
polygonList[n].add(polygonList[bestResult.polygonIdx][j]);
openPolygonList[bestA].clear();
}
}
else
{
if (bestResult.pointIdxA == bestResult.pointIdxB)
{
for(unsigned int n=0; n<openPolygonList[bestA].size(); n++)
openPolygonList[bestB].add(openPolygonList[bestA][n]);
openPolygonList[bestA].clear();
}
else if (bestResult.AtoB)
{
Polygon poly;
for(unsigned int n = bestResult.pointIdxA; n != bestResult.pointIdxB; n = (n + 1) % polygonList[bestResult.polygonIdx].size())
poly.add(polygonList[bestResult.polygonIdx][n]);
for(unsigned int n=poly.size()-1;int(n) >= 0; n--)
openPolygonList[bestB].add(poly[n]);
for(unsigned int n=0; n<openPolygonList[bestA].size(); n++)
openPolygonList[bestB].add(openPolygonList[bestA][n]);
示例8: boundary
/*
* 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
*
* rough explanation of the 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])
* (see infill/ZigzagConnectorProcessor.h for actual implementation details)
*
*
* we call the areas between two consecutive scanlines a 'scansegment'.
* Scansegment x is the area between scanline x and scanline x+1
* Edit: the term scansegment is wrong, since I call a boundary segment leaving from an even scanline to the left as belonging to an even scansegment,
* while I also call a boundary segment leaving from an even scanline toward the right as belonging to an even scansegment.
*/
void Infill::generateLinearBasedInfill(const int outline_offset, Polygons& result, const int line_distance, const PointMatrix& rotation_matrix, ZigzagConnectorProcessor& zigzag_connector_processor, const bool connected_zigzags, int64_t extra_shift)
{
if (line_distance == 0)
{
return;
}
if (in_outline.size() == 0)
{
return;
}
int shift = extra_shift + this->shift;
Polygons outline;
if (outline_offset != 0)
{
outline = in_outline.offset(outline_offset);
if (perimeter_gaps)
{
perimeter_gaps->add(in_outline.difference(outline.offset(infill_line_width / 2 + perimeter_gaps_extra_offset)));
}
}
else
{
outline = in_outline;
}
outline = outline.offset(infill_overlap);
if (outline.size() == 0)
{
return;
}
outline.applyMatrix(rotation_matrix);
if (shift < 0)
{
shift = line_distance - (-shift) % line_distance;
}
else
{
shift = shift % line_distance;
}
AABB boundary(outline);
int scanline_min_idx = computeScanSegmentIdx(boundary.min.X - shift, line_distance);
int line_count = computeScanSegmentIdx(boundary.max.X - shift, line_distance) + 1 - scanline_min_idx;
std::vector<std::vector<int64_t> > cut_list; // mapping from scanline to all intersections with polygon segments
for(int scanline_idx = 0; scanline_idx < line_count; scanline_idx++)
{
cut_list.push_back(std::vector<int64_t>());
}
for(unsigned int poly_idx = 0; poly_idx < outline.size(); poly_idx++)
{
PolygonRef poly = outline[poly_idx];
Point p0 = poly.back();
zigzag_connector_processor.registerVertex(p0); // always adds the first point to ZigzagConnectorProcessorEndPieces::first_zigzag_connector when using a zigzag infill type
for(unsigned int point_idx = 0; point_idx < poly.size(); point_idx++)
{
Point p1 = poly[point_idx];
if (p1.X == p0.X)
{
zigzag_connector_processor.registerVertex(p1);
// TODO: how to make sure it always adds the shortest line? (in order to prevent overlap with the zigzag connectors)
// note: this is already a problem for normal infill, but hasn't really cothered anyone so far.
p0 = p1;
continue;
}
int scanline_idx0;
int scanline_idx1;
// this way of handling the indices takes care of the case where a boundary line segment ends exactly on a scanline:
//.........这里部分代码省略.........
示例9: while
//.........这里部分代码省略.........
if (res.len > 0 && res.len < bestResult.len)
{
bestA = i;
bestB = i;
bestResult = res;
}
}
for(unsigned int j=0; j<openPolygonList.size(); j++)
{
if (openPolygonList[j].size() < 1 || i == j) continue;
gapCloserResult res = findPolygonGapCloser(openPolygonList[i][0], openPolygonList[j][openPolygonList[j].size()-1]);
if (res.len > 0 && res.len < bestResult.len)
{
bestA = i;
bestB = j;
bestResult = res;
}
}
}
if (bestResult.len < POINT_MAX)
{
if (bestA == bestB)
{
if (bestResult.pointIdxA == bestResult.pointIdxB)
{
polygonList.add(openPolygonList[bestA]);
openPolygonList[bestA].clear();
}
else if (bestResult.AtoB)
{
PolygonRef poly = polygonList.newPoly();
for(unsigned int j = bestResult.pointIdxA; j != bestResult.pointIdxB; j = (j + 1) % polygonList[bestResult.polygonIdx].size())
poly.add(polygonList[bestResult.polygonIdx][j]);
for(unsigned int j = openPolygonList[bestA].size() - 1; int(j) >= 0; j--)
poly.add(openPolygonList[bestA][j]);
openPolygonList[bestA].clear();
}
else
{
unsigned int n = polygonList.size();
polygonList.add(openPolygonList[bestA]);
for(unsigned int j = bestResult.pointIdxB; j != bestResult.pointIdxA; j = (j + 1) % polygonList[bestResult.polygonIdx].size())
polygonList[n].add(polygonList[bestResult.polygonIdx][j]);
openPolygonList[bestA].clear();
}
}
else
{
if (bestResult.pointIdxA == bestResult.pointIdxB)
{
for(unsigned int n=0; n<openPolygonList[bestA].size(); n++)
openPolygonList[bestB].add(openPolygonList[bestA][n]);
openPolygonList[bestA].clear();
}
else if (bestResult.AtoB)
{
Polygon poly;
for(unsigned int n = bestResult.pointIdxA; n != bestResult.pointIdxB; n = (n + 1) % polygonList[bestResult.polygonIdx].size())
poly.add(polygonList[bestResult.polygonIdx][n]);
for(unsigned int n=poly.size()-1;int(n) >= 0; n--)
openPolygonList[bestB].add(poly[n]);
for(unsigned int n=0; n<openPolygonList[bestA].size(); n++)
openPolygonList[bestB].add(openPolygonList[bestA][n]);
示例10: moveInside
unsigned int moveInside(Polygons& polygons, Point& from, int distance, int64_t maxDist2)
{
Point ret = from;
int64_t bestDist2 = maxDist2;
unsigned int bestPoly = NO_INDEX;
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++)
{
PolygonRef poly = polygons[poly_idx];
if (poly.size() < 2)
continue;
Point p0 = poly[poly.size()-2];
Point p1 = poly.back();
bool projected_p_beyond_prev_segment = dot(p1 - p0, from - p0) > vSize2(p1 - p0);
for(Point& p2 : poly)
{
// X = A + Normal( B - A ) * ((( B - A ) dot ( P - A )) / VSize( A - B ));
// X = P projected on AB
Point& a = p1;
Point& b = p2;
Point& p = from;
Point ab = b - a;
Point ap = p - a;
int64_t ab_length = vSize(ab);
int64_t ax_length = dot(ab, ap) / ab_length;
if (ax_length < 0) // x is projected to before ab
{
if (projected_p_beyond_prev_segment)
{ // case which looks like: > .
projected_p_beyond_prev_segment = false;
Point& x = p1;
int64_t dist2 = vSize2(x - p);
if (dist2 < bestDist2)
{
bestDist2 = dist2;
if (distance == 0) { ret = x; }
else { ret = x + normal(crossZ(normal(a, distance*4) + normal(p1 - p0, distance*4)), distance); } // *4 to retain more precision for the eventual normalization
bestPoly = poly_idx;
}
}
else
{
projected_p_beyond_prev_segment = false;
p0 = p1;
p1 = p2;
continue;
}
}
else if (ax_length > ab_length) // x is projected to beyond ab
{
projected_p_beyond_prev_segment = true;
p0 = p1;
p1 = p2;
continue;
}
else
{
projected_p_beyond_prev_segment = false;
Point x = a + ab * ax_length / ab_length;
int64_t dist2 = vSize2(x - from);
if (dist2 < bestDist2)
{
bestDist2 = dist2;
if (distance == 0) { ret = x; }
else { ret = x + crossZ(normal(ab, distance)); }
bestPoly = poly_idx;
}
}
p0 = p1;
p1 = p2;
}
}
if (bestDist2 < maxDist2)
{
from = ret;
return bestPoly;
}
return NO_INDEX;
}
示例11: size
unsigned int Polygons::findInside(Point p, bool border_result)
{
Polygons& thiss = *this;
if (size() < 1)
{
return false;
}
int64_t min_x[size()];
std::fill_n(min_x, size(), std::numeric_limits<int64_t>::max()); // initialize with int.max
int crossings[size()];
std::fill_n(crossings, size(), 0); // initialize with zeros
for (unsigned int poly_idx = 0; poly_idx < size(); poly_idx++)
{
PolygonRef poly = thiss[poly_idx];
Point p0 = poly.back();
for(Point& p1 : poly)
{
short comp = pointLiesOnTheRightOfLine(p, p0, p1);
if (comp == 1)
{
crossings[poly_idx]++;
int64_t x;
if (p1.Y == p0.Y)
{
x = p0.X;
}
else
{
x = p0.X + (p1.X-p0.X) * (p.Y-p0.Y) / (p1.Y-p0.Y);
}
if (x < min_x[poly_idx])
{
min_x[poly_idx] = x;
}
}
else if (border_result && comp == 0)
{
return poly_idx;
}
p0 = p1;
}
}
int64_t min_x_uneven = std::numeric_limits<int64_t>::max();
unsigned int ret = NO_INDEX;
unsigned int n_unevens = 0;
for (unsigned int array_idx = 0; array_idx < size(); array_idx++)
{
if (crossings[array_idx] % 2 == 1)
{
n_unevens++;
if (min_x[array_idx] < min_x_uneven)
{
min_x_uneven = min_x[array_idx];
ret = array_idx;
}
}
}
if (n_unevens % 2 == 0) { ret = NO_INDEX; }
return ret;
}
示例12: getNextPointWithDistance
bool getNextPointWithDistance(Point from, int64_t dist, const PolygonRef poly, int start_idx, int poly_start_idx, GivenDistPoint& result)
{
Point prev_poly_point = poly[(start_idx + poly_start_idx) % poly.size()];
for (unsigned int prev_idx = start_idx; prev_idx < poly.size(); prev_idx++)
{
int next_idx = (prev_idx + 1 + poly_start_idx) % poly.size(); // last checked segment is between last point in poly and poly[0]...
Point& next_poly_point = poly[next_idx];
if ( !shorterThen(next_poly_point - from, dist) )
{
/*
* x r
* p.---------+---+------------.n
* L| /
* | / dist
* |/
* f.
*
* f=from
* p=prev_poly_point
* n=next_poly_point
* x= f projected on pn
* r=result point at distance [dist] from f
*/
Point pn = next_poly_point - prev_poly_point;
if (shorterThen(pn, 100)) // when precision is limited
{
Point middle = (next_poly_point + prev_poly_point) / 2;
int64_t dist_to_middle = vSize(from - middle);
if (dist_to_middle - dist < 100 && dist_to_middle - dist > -100)
{
result.location = middle;
result.pos = prev_idx;
return true;
} else
{
prev_poly_point = next_poly_point;
continue;
}
}
Point pf = from - prev_poly_point;
Point px = dot(pf, pn) / vSize(pn) * pn / vSize(pn);
Point xf = pf - px;
if (!shorterThen(xf, dist)) // line lies wholly further than pn
{
prev_poly_point = next_poly_point;
continue;
}
int64_t xr_dist = std::sqrt(dist*dist - vSize2(xf)); // inverse Pythagoras
if (vSize(pn - px) - xr_dist < 1) // r lies beyond n
{
prev_poly_point = next_poly_point;
continue;
}
Point xr = xr_dist * pn / vSize(pn);
Point pr = px + xr;
result.location = prev_poly_point + pr;
result.pos = prev_idx;
return true;
}
prev_poly_point = next_poly_point;
}
return false;
}
示例13: line_bucket_grid
void LineOrderOptimizer::optimize()
{
int gridSize = 5000; // the size of the cells in the hash grid. TODO
SparsePointGridInclusive<unsigned int> line_bucket_grid(gridSize);
bool picked[polygons.size()];
memset(picked, false, sizeof(bool) * polygons.size());/// initialized as falses
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++) /// find closest point to initial starting point within each polygon +initialize picked
{
int best_point_idx = -1;
float best_point_dist = std::numeric_limits<float>::infinity();
PolygonRef poly = polygons[poly_idx];
for (unsigned int point_idx = 0; point_idx < poly.size(); point_idx++) /// get closest point from polygon
{
float dist = vSize2f(poly[point_idx] - startPoint);
if (dist < best_point_dist)
{
best_point_idx = point_idx;
best_point_dist = dist;
}
}
polyStart.push_back(best_point_idx);
assert(poly.size() == 2);
line_bucket_grid.insert(poly[0], poly_idx);
line_bucket_grid.insert(poly[1], poly_idx);
}
Point incoming_perpundicular_normal(0, 0);
Point prev_point = startPoint;
for (unsigned int order_idx = 0; order_idx < polygons.size(); order_idx++) /// actual path order optimizer
{
int best_line_idx = -1;
float best_score = std::numeric_limits<float>::infinity(); // distance score for the best next line
/// check if single-line-polygon is close to last point
for(unsigned int close_line_idx :
line_bucket_grid.getNearbyVals(prev_point, gridSize))
{
if (picked[close_line_idx] || polygons[close_line_idx].size() < 1)
{
continue;
}
updateBestLine(close_line_idx, best_line_idx, best_score, prev_point, incoming_perpundicular_normal);
}
if (best_line_idx == -1) /// if single-line-polygon hasn't been found yet
{
for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++)
{
if (picked[poly_idx] || polygons[poly_idx].size() < 1) /// skip single-point-polygons
{
continue;
}
assert(polygons[poly_idx].size() == 2);
updateBestLine(poly_idx, best_line_idx, best_score, prev_point, incoming_perpundicular_normal);
}
}
if (best_line_idx > -1) /// should always be true; we should have been able to identify the best next polygon
{
PolygonRef best_line = polygons[best_line_idx];
assert(best_line.size() == 2);
int line_start_point_idx = polyStart[best_line_idx];
int line_end_point_idx = line_start_point_idx * -1 + 1; /// 1 -> 0 , 0 -> 1
Point& line_start = best_line[line_start_point_idx];
Point& line_end = best_line[line_end_point_idx];
prev_point = line_end;
incoming_perpundicular_normal = turn90CCW(normal(line_end - line_start, 1000));
picked[best_line_idx] = true;
polyOrder.push_back(best_line_idx);
}
else
{
logError("Failed to find next closest line.\n");
}
}
}
示例14: 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 = crossZ(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;
sendPolygons(Inset0Type, layer_nr, skin, mesh.getSettingInMicrons("wall_line_width_0"));
}
}
}
示例15: line_bucket_grid
void LineOrderOptimizer::optimize()
{
int gridSize = 5000; // the size of the cells in the hash grid.
BucketGrid2D<unsigned int> line_bucket_grid(gridSize);
bool* picked = new bool[polygons.size()];
// bool picked[polygons.size()];
memset(picked, false, sizeof(bool) * polygons.size());/// initialized as falses
for(unsigned int i_polygon=0 ; i_polygon<polygons.size() ; i_polygon++) /// find closest point to initial starting point within each polygon +initialize picked
{
int best = -1;
float bestDist = std::numeric_limits<float>::infinity();
PolygonRef poly = polygons[i_polygon];
for(unsigned int i_point=0; i_point<poly.size(); i_point++) /// get closest point from polygon
{
float dist = vSize2f(poly[i_point] - startPoint);
if (dist < bestDist)
{
best = i_point;
bestDist = dist;
}
}
polyStart.push_back(best);
assert(poly.size() == 2);
line_bucket_grid.insert(poly[0], i_polygon);
line_bucket_grid.insert(poly[1], i_polygon);
}
Point incommingPerpundicularNormal(0, 0);
Point prev_point = startPoint;
for(unsigned int i_polygon=0 ; i_polygon<polygons.size() ; i_polygon++) /// actual path order optimizer
{
int best = -1;
float bestDist = std::numeric_limits<float>::infinity();
for(unsigned int i_close_line_polygon : line_bucket_grid.findNearbyObjects(prev_point)) /// check if single-line-polygon is close to last point
{
if (picked[i_close_line_polygon] || polygons[i_close_line_polygon].size() < 1)
continue;
checkIfLineIsBest(i_close_line_polygon, best, bestDist, prev_point, incommingPerpundicularNormal);
}
if (best == -1) /// if single-line-polygon hasn't been found yet
{
for(unsigned int i_polygon=0 ; i_polygon<polygons.size() ; i_polygon++)
{
if (picked[i_polygon] || polygons[i_polygon].size() < 1) /// skip single-point-polygons
continue;
assert(polygons[i_polygon].size() == 2);
checkIfLineIsBest(i_polygon, best, bestDist, prev_point, incommingPerpundicularNormal);
}
}
if (best > -1) /// should always be true; we should have been able to identify the best next polygon
{
assert(polygons[best].size() == 2);
int endIdx = polyStart[best] * -1 + 1; /// 1 -> 0 , 0 -> 1
prev_point = polygons[best][endIdx];
incommingPerpundicularNormal = crossZ(normal(polygons[best][endIdx] - polygons[best][polyStart[best]], 1000));
picked[best] = true;
polyOrder.push_back(best);
}
else
logError("Failed to find next closest line.\n");
}
prev_point = startPoint;
for(unsigned int n=0; n<polyOrder.size(); n++) /// decide final starting points in each polygon
{
int nr = polyOrder[n];
PolygonRef poly = polygons[nr];
int best = -1;
float bestDist = std::numeric_limits<float>::infinity();
bool orientation = poly.orientation();
for(unsigned int i=0;i<poly.size(); i++)
{
float dist = vSize2f(polygons[nr][i] - prev_point);
Point n0 = normal(poly[(i+poly.size()-1)%poly.size()] - poly[i], 2000);
Point n1 = normal(poly[i] - poly[(i + 1) % poly.size()], 2000);
float dot_score = dot(n0, n1) - dot(crossZ(n0), n1);
if (orientation)
dot_score = -dot_score;
if (dist + dot_score < bestDist)
{
best = i;
bestDist = dist + dot_score;
}
}
//.........这里部分代码省略.........