Пример #1
0
void MakePolygonFromInts(int *ints, int size, ClipperLib::Polygon &p)
{
  p.clear();
  p.reserve(size / 2);
  for (int i = 0; i < size; i +=2)
    p.push_back(IntPoint(ints[i], ints[i+1]));
}
Пример #2
0
void
Slic3rPolygon_to_ClipperPolygon(const Slic3r::Polygon &input, ClipperLib::Polygon &output)
{
    output.clear();
    for (Slic3r::Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit) {
        output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
    }
}
Пример #3
0
void
ClipperPolygon_to_Slic3rPolygon(const ClipperLib::Polygon &input, Slic3r::Polygon &output)
{
    output.points.clear();
    for (ClipperLib::Polygon::const_iterator pit = input.begin(); pit != input.end(); ++pit) {
        output.points.push_back(Slic3r::Point( (*pit).X, (*pit).Y ));
    }
}
Пример #4
0
		ClipperLib::Polygon Rectangle::toClipperPolygon() const
		{
			ClipperLib::Polygon ret;
			ret.push_back(topleft);
			ret.push_back(glm::vec2(topleft.x, bottomright.y));
			ret.push_back(bottomright);
			ret.push_back(glm::vec2(bottomright.x, topleft.y));
			return ret;
		}
Пример #5
0
void polygonFromQxClipper(const QPolygonF& qxPolygon,
                          ClipperLib::Polygon &clipperPolygon)
{
  clipperPolygon.clear();
  clipperPolygon.reserve(qxPolygon.size());
  foreach(const QPointF &point, qxPolygon)
  {
    clipperPolygon.push_back(ClipperLib::IntPoint(point.x()*ConversionFactor,
                                                  point.y()*ConversionFactor));
  }
Пример #6
0
TPPLPoly TPPLPoly_To_Polygon(const ClipperLib::Polygon& B)
{
    TPPLPoly poly;
    poly.Init(B.size());
    for(unsigned int i=0; i < B.size() ; ++i)
    {
        poly[i].x = B[i].X;
        poly[i].y = B[i].Y;
    }
    return poly;
}
Пример #7
0
//--------------------------------------------------------------
ofPolyline ofxClipper::polygon_to_ofPolyline(ClipperLib::Polygon& polygon) {
    vector<ClipperLib::IntPoint>::iterator iter;
    ofPolyline polyline;
    for(iter = polygon.begin(); iter != polygon.end(); iter++) {
        ofPoint pnt((*iter).X / double(clipperGlobalScale),  // bring back to our coords
                    (*iter).Y / double(clipperGlobalScale)); // bring back to our coords
        polyline.addVertex(pnt);
    }
    polyline.close(); // close it
    return polyline;
}
Пример #8
0
//--------------------------------------------------------------
ClipperLib::Polygon ofxClipper::ofPolyline_to_Polygon(ofPolyline& polyline) {
	vector<ofPoint> verts = polyline.getVertices();
    vector<ofPoint>::iterator iter;
    ClipperLib::Polygon polygon;
    for(iter = verts.begin(); iter != verts.end(); iter++) {
        ClipperLib::IntPoint ip((*iter).x * clipperGlobalScale, 
                                (*iter).y * clipperGlobalScale);
        polygon.push_back(ip);
    }
    return polygon;
}
Пример #9
0
void GCodePlanner::addPolygon(ClipperLib::Polygon& polygon, int startIdx, GCodePathConfig* config)
{
    Point p0 = polygon[startIdx];
    addTravel(p0);
    for(unsigned int i=1; i<polygon.size(); i++)
    {
        Point p1 = polygon[(startIdx + i) % polygon.size()];
        addExtrusionMove(p1, config);
        p0 = p1;
    }
    if (polygon.size() > 2)
        addExtrusionMove(polygon[startIdx], config);
}
Пример #10
0
void Slice::fillPolygonLayer(){
    //for every layer
    for(int j=0; j<this->pointLayer.size(); j++){
        Polygons layer;
        for(int k=0; k<this->pointLayer.at(j)->size(); k++){
            ClipperLib::Polygon p;
            for(int i=0; i<this->pointLayer.at(j)->at(k)->size(); i++){
                p.push_back(ClipperLib::IntPoint((int)(this->pointLayer.at(j)->at(k)->at(i).x()*1000),(int)(this->pointLayer.at(j)->at(k)->at(i).y()*1000)));
            }
            layer.push_back(p);
        }
        this->polygonLayer.append(layer);
    }
}
Пример #11
0
int main(int argc, char* argv[]) {
	if (argc != 3) {
		cout<<"Usage: offset.exe <input.poly> <output.poly>\n\n  Input and output files should be different.\n  Only one ring poly files are accepted now without inner rings.\n  Default offset is 0.001 degree\n";
		return 0;

	}
	ifstream f(argv[1], ifstream::in);
	ofstream outfile(argv[2], ofstream::out);
	outfile.precision(9);
	string s;
	for (int i=0;i<3;i++) {
		getline(f, s);
		outfile<<s<<"\n";
	}
	ClipperLib::Polygons polygons;
	ClipperLib::Polygon polygon;
	while(!f.eof()) {
		f>>s;
		if (s == "END") {
			break;
		}
		double c1 = ::atof(s.c_str());
		f>>s;
		double c2 = ::atof(s.c_str());
		ClipperLib::IntPoint point(c1 * MUL, c2 * MUL);
		polygon.push_back(point);
	}
	polygons.push_back(polygon);
	double distance = 0.001 * MUL;

	ClipperLib::Polygons res_polygons;
	ClipperLib::OffsetPolygons (polygons, res_polygons, distance, ClipperLib::jtMiter);

	if (res_polygons.size() < 1) { cerr<<"Bad output of OffsetPolygons!\n";return 1;}
	ClipperLib::Polygon result = res_polygons.front();

	for (ClipperLib::Polygon::iterator it = result.begin(); it != result.end(); ++it) {
		ClipperLib::IntPoint point = *it;
		outfile << "   " << (point.X/MUL) << "   " << (point.Y/MUL) << " \n";
	}

	outfile<<s;
	while (!f.eof()) {
		getline(f, s);
		outfile<<s<<"\n";
	}

	return 0;
}
Пример #12
0
void TranslatePolygon(ClipperLib::Polygon &p, int dx, int dy)
{
  for (size_t i = 0; i < p.size(); ++i)
  {
    p[i].X += dx;
    p[i].Y += dy;
  }
}
Пример #13
0
void optimizePolygon(ClipperLib::Polygon& poly)
{
    Point p0 = poly[poly.size()-1];
    for(unsigned int i=0;i<poly.size();i++)
    {
        Point p1 = poly[i];
        if (shorterThen(p0 - p1, 10))
        {
            poly.erase(poly.begin() + i);
            i --;
        }else{
            Point p2;
            if (i < poly.size() - 1)
                p2 = poly[i+1];
            else
                p2 = poly[0];
            
            Point diff0 = normal(p1 - p0, 1000000);
            Point diff2 = normal(p1 - p2, 1000000);
            
            int64_t d = dot(diff0, diff2);
            if (d < -999999000000LL)
            {
                poly.erase(poly.begin() + i);
                i --;
            }else{
                p0 = p1;
            }
        }
    }
}
Пример #14
0
void MakeRandomPoly(ClipperLib::Polygon &p, int width, int height, int edgeCount)
{
	p.resize(edgeCount);
	for (int i = 0; i < edgeCount; i++)
	{
		p[i].X = (rand()%(width -20) +10)*scale;
		p[i].Y = (rand()%(height -20) +10)*scale;
	}
}
Пример #15
0
void SlicerLayer::makePolygons(OptimizedVolume* ov, bool keepNoneClosed, bool extensiveStitching)
{
    for(unsigned int startSegment=0; startSegment < segmentList.size(); startSegment++)
    {
        if (segmentList[startSegment].addedToPolygon)
            continue;
        
        ClipperLib::Polygon poly;
        poly.push_back(segmentList[startSegment].start);
        
        unsigned int segmentIndex = startSegment;
        bool canClose;
        while(true)
        {
            canClose = false;
            segmentList[segmentIndex].addedToPolygon = true;
            Point p0 = segmentList[segmentIndex].end;
            poly.push_back(p0);
            int nextIndex = -1;
            OptimizedFace* face = &ov->faces[segmentList[segmentIndex].faceIndex];
            for(unsigned int i=0;i<3;i++)
            {
                if (face->touching[i] > -1 && faceToSegmentIndex.find(face->touching[i]) != faceToSegmentIndex.end())
                {
                    Point p1 = segmentList[faceToSegmentIndex[face->touching[i]]].start;
                    Point diff = p0 - p1;
                    if (shorterThen(diff, 10))
                    {
                        if (faceToSegmentIndex[face->touching[i]] == (int)startSegment)
                            canClose = true;
                        if (segmentList[faceToSegmentIndex[face->touching[i]]].addedToPolygon)
                            continue;
                        nextIndex = faceToSegmentIndex[face->touching[i]];
                    }
                }
            }
            if (nextIndex == -1)
                break;
            segmentIndex = nextIndex;
        }
        if (canClose)
            polygonList.add(poly);
        else
            openPolygonList.add(poly);
    }
    //Clear the segmentList to save memory, it is no longer needed after this point.
    segmentList.clear();

    //Connecting polygons that are not closed yet, as models are not always perfect manifold we need to join some stuff up to get proper polygons
    //First link up polygon ends that are within 2 microns.
    for(unsigned int i=0;i<openPolygonList.size();i++)
    {
        if (openPolygonList[i].size() < 1) continue;
        for(unsigned int j=0;j<openPolygonList.size();j++)
        {
            if (openPolygonList[j].size() < 1) continue;
            
            Point diff = openPolygonList[i][openPolygonList[i].size()-1] - openPolygonList[j][0];
            int64_t distSquared = vSize2(diff);

            if (distSquared < 2 * 2)
            {
                if (i == j)
                {
                    polygonList.add(openPolygonList[i]);
                    openPolygonList[i].clear();
                    break;
                }else{
                    for(unsigned int n=0; n<openPolygonList[j].size(); n++)
                        openPolygonList[i].push_back(openPolygonList[j][n]);

                    openPolygonList[j].clear();
                }
            }
        }
    }
    
    //Next link up all the missing ends, closing up the smallest gaps first. This is an inefficient implementation which can run in O(n*n*n) time.
    while(1)
    {
        int64_t bestScore = 10000 * 10000;
        unsigned int bestA = -1;
        unsigned int bestB = -1;
        bool reversed = false;
        for(unsigned int i=0;i<openPolygonList.size();i++)
        {
            if (openPolygonList[i].size() < 1) continue;
            for(unsigned int j=0;j<openPolygonList.size();j++)
            {
                if (openPolygonList[j].size() < 1) continue;
                
                Point diff = openPolygonList[i][openPolygonList[i].size()-1] - openPolygonList[j][0];
                int64_t distSquared = vSize2(diff);
                if (distSquared < bestScore)
                {
                    bestScore = distSquared;
                    bestA = i;
                    bestB = j;
                    reversed = false;
                }

                if (i != j)
                {
                    Point diff = openPolygonList[i][openPolygonList[i].size()-1] - openPolygonList[j][openPolygonList[j].size()-1];
                    int64_t distSquared = vSize2(diff);
                    if (distSquared < bestScore)
                    {
                        bestScore = distSquared;
                        bestA = i;
                        bestB = j;
                        reversed = true;
                    }
                }
            }
        }
        
        if (bestScore >= 10000 * 10000)
            break;
        
        if (bestA == bestB)
        {
            polygonList.add(openPolygonList[bestA]);
            openPolygonList[bestA].clear();
        }else{
            if (reversed)
            {
                for(unsigned int n=openPolygonList[bestB].size()-1; int(n)>=0; n--)
                    openPolygonList[bestA].push_back(openPolygonList[bestB][n]);
            }else{
                for(unsigned int n=0; n<openPolygonList[bestB].size(); n++)
                    openPolygonList[bestA].push_back(openPolygonList[bestB][n]);
            }

            openPolygonList[bestB].clear();
        }
    }

    if (extensiveStitching)
    {
        //For extensive stitching find 2 open polygons that are touching 2 closed polygons.
        // Then find the sortest path over this polygon that can be used to connect the open polygons,
        // And generate a path over this shortest bit to link up the 2 open polygons.
        // (If these 2 open polygons are the same polygon, then the final result is a closed polyon)
        
        while(1)
        {
            unsigned int bestA = -1;
            unsigned int bestB = -1;
            gapCloserResult bestResult;
            bestResult.len = LLONG_MAX;
            bestResult.polygonIdx = -1;
            bestResult.pointIdxA = -1;
            bestResult.pointIdxB = -1;
            
            for(unsigned int i=0; i<openPolygonList.size(); i++)
            {
                if (openPolygonList[i].size() < 1) continue;
                
                {
                    gapCloserResult res = findPolygonGapCloser(openPolygonList[i][0], openPolygonList[i][openPolygonList[i].size()-1]);
                    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)
                    {
                        unsigned int n = polygonList.size();
                        polygonList.add(ClipperLib::Polygon());
                        for(unsigned int j = bestResult.pointIdxA; j != bestResult.pointIdxB; j = (j + 1) % polygonList[bestResult.polygonIdx].size())
                            polygonList[n].push_back(polygonList[bestResult.polygonIdx][j]);
                        for(unsigned int j = openPolygonList[bestA].size() - 1; int(j) >= 0; j--)
                            polygonList[n].push_back(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].push_back(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].push_back(openPolygonList[bestA][n]);
                        openPolygonList[bestA].clear();
                    }
                    else if (bestResult.AtoB)
                    {
                        ClipperLib::Polygon poly;
                        for(unsigned int n = bestResult.pointIdxA; n != bestResult.pointIdxB; n = (n + 1) % polygonList[bestResult.polygonIdx].size())
                            poly.push_back(polygonList[bestResult.polygonIdx][n]);
                        for(unsigned int n=poly.size()-1;int(n) >= 0; n--)
                            openPolygonList[bestB].push_back(poly[n]);
                        for(unsigned int n=0; n<openPolygonList[bestA].size(); n++)
                            openPolygonList[bestB].push_back(openPolygonList[bestA][n]);
                        openPolygonList[bestA].clear();
                    }
                    else
                    {
                        for(unsigned int n = bestResult.pointIdxB; n != bestResult.pointIdxA; n = (n + 1) % polygonList[bestResult.polygonIdx].size())
                            openPolygonList[bestB].push_back(polygonList[bestResult.polygonIdx][n]);
                        for(unsigned int n = openPolygonList[bestA].size() - 1; int(n) >= 0; n--)
                            openPolygonList[bestB].push_back(openPolygonList[bestA][n]);
                        openPolygonList[bestA].clear();
                    }
                }
            }
            else
            {
                break;
            }
        }
    }

    /*
    int q=0;
    for(unsigned int i=0;i<openPolygonList.size();i++)
    {
        if (openPolygonList[i].size() < 2) continue;
        if (!q) printf("***\n");
        printf("S: %f %f\n", float(openPolygonList[i][0].X), float(openPolygonList[i][0].Y));
        printf("E: %f %f\n", float(openPolygonList[i][openPolygonList[i].size()-1].X), float(openPolygonList[i][openPolygonList[i].size()-1].Y));
        q = 1;
    }
    */
    //if (q) exit(1);

    if (keepNoneClosed)
    {
        for(unsigned int n=0; n<openPolygonList.size(); n++)
        {
            if (openPolygonList[n].size() > 0)
                polygonList.add(openPolygonList[n]);
        }
    }
    //Clear the openPolygonList to save memory, the only reason to keep it after this is for debugging.
    //openPolygonList.clear();

    //Remove all the tiny polygons, or polygons that are not closed. As they do not contribute to the actual print.
    int snapDistance = 1000;
    for(unsigned int i=0;i<polygonList.size();i++)
    {
        int length = 0;
        
        for(unsigned int n=1; n<polygonList[i].size(); n++)
        {
            length += vSize(polygonList[i][n] - polygonList[i][n-1]);
            if (length > snapDistance)
                break;
        }
        if (length < snapDistance)
        {
            polygonList.remove(i);
            i--;
        }
    }

    //Finally optimize all the polygons. Every point removed saves time in the long run.
    optimizePolygons(polygonList);
}
Пример #16
0
void PathOrderOptimizer::optimize()
{
    std::vector<bool> picked;
    for(unsigned int i=0;i<polygons.size(); i++)
    {
        int best = -1;
        float bestDist = 0xFFFFFFFFFFFFFFFFLL;
        ClipperLib::Polygon* 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];
        }
    }
}