Esempio n. 1
0
ExPolygonCollection::operator Polygons() const
{
    Polygons polygons;
    for (ExPolygons::const_iterator it = this->expolygons.begin(); it != this->expolygons.end(); ++it) {
        polygons.push_back(it->contour);
        for (Polygons::const_iterator ith = it->holes.begin(); ith != it->holes.end(); ++ith) {
            polygons.push_back(*ith);
        }
    }
    return polygons;
}
Esempio n. 2
0
// Append a vector of Surfaces at the end of another vector of polygons.
inline void polygons_append(Polygons &dst, const SurfacesPtr &src)
{
    dst.reserve(dst.size() + number_polygons(src));
    for (SurfacesPtr::const_iterator it = src.begin(); it != src.end(); ++ it) {
        dst.push_back((*it)->expolygon.contour);
        dst.insert(dst.end(), (*it)->expolygon.holes.begin(), (*it)->expolygon.holes.end());
    }
}
Esempio n. 3
0
inline void polygons_append(Polygons &dst, ExPolygons &&src)
{ 
    dst.reserve(dst.size() + number_polygons(src));
    for (ExPolygons::const_iterator it = src.begin(); it != src.end(); ++ it) {
        dst.push_back(std::move(it->contour));
        std::move(std::begin(it->holes), std::end(it->holes), std::back_inserter(dst));
    }
}
Esempio n. 4
0
inline void polygons_append(Polygons &dst, const ExPolygons &src) 
{ 
    dst.reserve(dst.size() + number_polygons(src));
    for (ExPolygons::const_iterator it = src.begin(); it != src.end(); ++ it) {
        dst.push_back(it->contour);
        dst.insert(dst.end(), it->holes.begin(), it->holes.end());
    }
}
Esempio n. 5
0
inline Polygons to_polygons(ExPolygon &&src)
{
    Polygons polygons;
    polygons.reserve(src.holes.size() + 1);
    polygons.push_back(std::move(src.contour));
    std::move(std::begin(src.holes), std::end(src.holes), std::back_inserter(polygons));
    return polygons;
}
Esempio n. 6
0
inline Polygons to_polygons(const ExPolygon &src)
{
    Polygons polygons;
    polygons.reserve(src.holes.size() + 1);
    polygons.push_back(src.contour);
    polygons.insert(polygons.end(), src.holes.begin(), src.holes.end());
    return polygons;
}
Esempio n. 7
0
Polygons
ExPolygonCollection::contours() const
{
    Polygons contours;
    for (ExPolygons::const_iterator it = this->expolygons.begin(); it != this->expolygons.end(); ++it) {
        contours.push_back(it->contour);
    }
    return contours;
}
Esempio n. 8
0
inline void polygons_append(Polygons &dst, SurfacesPtr &&src)
{
    dst.reserve(dst.size() + number_polygons(src));
    for (SurfacesPtr::const_iterator it = src.begin(); it != src.end(); ++ it) {
        dst.push_back(std::move((*it)->expolygon.contour));
        std::move(std::begin((*it)->expolygon.holes), std::end((*it)->expolygon.holes), std::back_inserter(dst));
        (*it)->expolygon.holes.clear();
    }
}
Esempio n. 9
0
inline Polygons to_polygons(ExPolygons &&src)
{
    Polygons polygons;
    polygons.reserve(number_polygons(src));
    for (ExPolygons::const_iterator it = src.begin(); it != src.end(); ++it) {
        polygons.push_back(std::move(it->contour));
        std::move(std::begin(it->holes), std::end(it->holes), std::back_inserter(polygons));
    }
    return polygons;
}
Esempio n. 10
0
inline Polygons to_polygons(const ExPolygons &src)
{
    Polygons polygons;
    polygons.reserve(number_polygons(src));
    for (ExPolygons::const_iterator it = src.begin(); it != src.end(); ++it) {
        polygons.push_back(it->contour);
        polygons.insert(polygons.end(), it->holes.begin(), it->holes.end());
    }
    return polygons;
}
Esempio n. 11
0
Polygons
Polygon::simplify(double tolerance) const
{
    Polygon p = *this;
    p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
    
    Polygons pp;
    pp.push_back(p);
    simplify_polygons(pp, pp);
    return pp;
}
Esempio n. 12
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);
    }
}
Esempio n. 13
0
// this only works on CCW polygons as CW will be ripped out by Clipper's simplify_polygons()
Polygons
Polygon::simplify(double tolerance) const
{
    // repeat first point at the end in order to apply Douglas-Peucker
    // on the whole polygon
    Points points = this->points;
    points.push_back(points.front());
    Polygon p(MultiPoint::_douglas_peucker(points, tolerance));
    p.points.pop_back();
    
    Polygons pp;
    pp.push_back(p);
    simplify_polygons(pp, &pp);
    return pp;
}
Esempio n. 14
0
Polygons top_level_islands(const Slic3r::Polygons &polygons)
{
    ClipperLib::Paths input;
    Slic3rMultiPoints_to_ClipperPaths(polygons, &input);   
    // init Clipper
    ClipperLib::Clipper clipper;
    clipper.Clear();
    // perform union
    clipper.AddPaths(input, ClipperLib::ptSubject, true);
    ClipperLib::PolyTree polytree;
    clipper.Execute(ClipperLib::ctUnion, polytree, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); 
    // Convert only the top level islands to the output.
    Polygons out;
    out.reserve(polytree.ChildCount());
    for (int i = 0; i < polytree.ChildCount(); ++i) {
        out.push_back(Polygon());
        ClipperPath_to_Slic3rMultiPoint(polytree.Childs[i]->Contour, &out.back());
    }
    return out;
}
Esempio n. 15
0
void processFile(const char* input_filename, ConfigSettings& config, GCodeExport& gcode, bool firstFile)
{
    for(unsigned int n=1; n<16;n++)
        gcode.setExtruderOffset(n, config.extruderOffset[n].p());
    gcode.setFlavor(config.gcodeFlavor);
    
    double t = getTime();
    log("Loading %s from disk...\n", input_filename);
    SimpleModel* m = loadModel(input_filename, config.matrix);
    if (!m)
    {
        log("Failed to load model: %s\n", input_filename);
        return;
    }
    log("Loaded from disk in %5.3fs\n", timeElapsed(t));
    log("Analyzing and optimizing model...\n");
    OptimizedModel* om = new OptimizedModel(m, Point3(config.objectPosition.X, config.objectPosition.Y, -config.objectSink));
    for(unsigned int v = 0; v < m->volumes.size(); v++)
    {
        log("  Face counts: %i -> %i %0.1f%%\n", (int)m->volumes[v].faces.size(), (int)om->volumes[v].faces.size(), float(om->volumes[v].faces.size()) / float(m->volumes[v].faces.size()) * 100);
        log("  Vertex counts: %i -> %i %0.1f%%\n", (int)m->volumes[v].faces.size() * 3, (int)om->volumes[v].points.size(), float(om->volumes[v].points.size()) / float(m->volumes[v].faces.size() * 3) * 100);
    }
    delete m;
    log("Optimize model %5.3fs \n", timeElapsed(t));
    //om->saveDebugSTL("c:\\models\\output.stl");
    
    log("Slicing model...\n");
    vector<Slicer*> slicerList;
    for(unsigned int volumeIdx=0; volumeIdx < om->volumes.size(); volumeIdx++)
    {
        slicerList.push_back(new Slicer(&om->volumes[volumeIdx], config.initialLayerThickness / 2, config.layerThickness, config.fixHorrible & FIX_HORRIBLE_KEEP_NONE_CLOSED, config.fixHorrible & FIX_HORRIBLE_EXTENSIVE_STITCHING));
        //slicerList[volumeIdx]->dumpSegments("C:\\models\\output.html");
    }
    log("Sliced model in %5.3fs\n", timeElapsed(t));

    SliceDataStorage storage;
    if (config.supportAngle > -1)
    {
        fprintf(stdout,"Generating support map...\n");
        generateSupportGrid(storage.support, om);
    }
    storage.modelSize = om->modelSize;
    storage.modelMin = om->vMin;
    storage.modelMax = om->vMax;
    delete om;
    
    log("Generating layer parts...\n");
    for(unsigned int volumeIdx=0; volumeIdx < slicerList.size(); volumeIdx++)
    {
        storage.volumes.push_back(SliceVolumeStorage());
        createLayerParts(storage.volumes[volumeIdx], slicerList[volumeIdx], config.fixHorrible & (FIX_HORRIBLE_UNION_ALL_TYPE_A | FIX_HORRIBLE_UNION_ALL_TYPE_B));
        delete slicerList[volumeIdx];
    }
    //carveMultipleVolumes(storage.volumes);
    generateMultipleVolumesOverlap(storage.volumes, config.multiVolumeOverlap);
    log("Generated layer parts in %5.3fs\n", timeElapsed(t));
    //dumpLayerparts(storage, "c:/models/output.html");
    
    const unsigned int totalLayers = storage.volumes[0].layers.size();
    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
        {
            generateInsets(&storage.volumes[volumeIdx].layers[layerNr], config.extrusionWidth, config.insetCount);
        }
        logProgress("inset",layerNr+1,totalLayers);
    }
    log("Generated inset in %5.3fs\n", timeElapsed(t));
    //dumpLayerparts(storage, "c:/models/output.html");

    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
        {
            generateSkins(layerNr, storage.volumes[volumeIdx], config.extrusionWidth, config.downSkinCount, config.upSkinCount, config.infillOverlap);
            generateSparse(layerNr, storage.volumes[volumeIdx], config.extrusionWidth, config.downSkinCount, config.upSkinCount);
        }
        logProgress("skin",layerNr+1,totalLayers);
    }
    log("Generated up/down skin in %5.3fs\n", timeElapsed(t));
    generateSkirt(storage, config.skirtDistance, config.extrusionWidth, config.skirtLineCount, config.skirtMinLength);
    generateRaft(storage, config.raftMargin, config.supportAngle, config.supportEverywhere > 0, config.supportXYDistance);
    
    for(unsigned int volumeIdx=0; volumeIdx<storage.volumes.size(); volumeIdx++)
    {
        for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
        {
            for(unsigned int partNr=0; partNr<storage.volumes[volumeIdx].layers[layerNr].parts.size(); partNr++)
            {
                if (layerNr > 0)
                    storage.volumes[volumeIdx].layers[layerNr].parts[partNr].bridgeAngle = bridgeAngle(&storage.volumes[volumeIdx].layers[layerNr].parts[partNr], &storage.volumes[volumeIdx].layers[layerNr-1]);
                else
                    storage.volumes[volumeIdx].layers[layerNr].parts[partNr].bridgeAngle = -1;
            }
        }
    }

    gcode.setRetractionSettings(config.retractionAmount, config.retractionSpeed, config.retractionAmountExtruderSwitch, config.minimalExtrusionBeforeRetraction);
    if (firstFile)
    {
        if (gcode.getFlavor() == GCODE_FLAVOR_ULTIGCODE)
        {
            gcode.addCode(";FLAVOR:UltiGCode");
            gcode.addCode(";TIME:<__TIME__>");
            gcode.addCode(";MATERIAL:<FILAMENT>");
        }
        gcode.addCode(config.startCode);
    }else{
        gcode.addFanCommand(0);
        gcode.resetExtrusionValue();
        gcode.addRetraction();
        gcode.setZ(maxObjectHeight + 5000);
        gcode.addMove(Point(storage.modelMin.x, storage.modelMin.y), config.moveSpeed, 0);
    }
    gcode.addComment("total_layers=%d",totalLayers);

    GCodePathConfig skirtConfig(config.printSpeed, config.extrusionWidth, "SKIRT");
    GCodePathConfig inset0Config(config.printSpeed, config.extrusionWidth, "WALL-OUTER");
    GCodePathConfig inset1Config(config.printSpeed, config.extrusionWidth, "WALL-INNER");
    GCodePathConfig fillConfig(config.infillSpeed, config.extrusionWidth, "FILL");
    GCodePathConfig supportConfig(config.printSpeed, config.extrusionWidth, "SUPPORT");
    
    if (config.raftBaseThickness > 0 && config.raftInterfaceThickness > 0)
    {
        GCodePathConfig raftBaseConfig(config.initialLayerSpeed, config.raftBaseLinewidth, "SUPPORT");
        GCodePathConfig raftInterfaceConfig(config.initialLayerSpeed, config.raftInterfaceLinewidth, "SUPPORT");
        {
            gcode.addComment("LAYER:-2");
            gcode.addComment("RAFT");
            GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
            gcode.setZ(config.raftBaseThickness);
            gcode.setExtrusion(config.raftBaseThickness, config.filamentDiameter, config.filamentFlow);
            gcodeLayer.addPolygonsByOptimizer(storage.raftOutline, &raftBaseConfig);
            
            Polygons raftLines;
            generateLineInfill(storage.raftOutline, raftLines, config.raftBaseLinewidth, config.raftLineSpacing, config.infillOverlap, 0);
            gcodeLayer.addPolygonsByOptimizer(raftLines, &raftBaseConfig);
            
            gcodeLayer.writeGCode(false);
        }

        {
            gcode.addComment("LAYER:-1");
            gcode.addComment("RAFT");
            GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
            gcode.setZ(config.raftBaseThickness + config.raftInterfaceThickness);
            gcode.setExtrusion(config.raftInterfaceThickness, config.filamentDiameter, config.filamentFlow);
            
            Polygons raftLines;
            generateLineInfill(storage.raftOutline, raftLines, config.raftInterfaceLinewidth, config.raftLineSpacing, config.infillOverlap, 90);
            gcodeLayer.addPolygonsByOptimizer(raftLines, &raftInterfaceConfig);
            
            gcodeLayer.writeGCode(false);
        }
    }

    int volumeIdx = 0;
    for(unsigned int layerNr=0; layerNr<totalLayers; layerNr++)
    {
        logProgress("export", layerNr+1, totalLayers);
        
        GCodePlanner gcodeLayer(gcode, config.moveSpeed, config.retractionMinimalDistance);
        gcode.addComment("LAYER:%d", layerNr);
        int32_t z = config.initialLayerThickness + layerNr * config.layerThickness;
        z += config.raftBaseThickness + config.raftInterfaceThickness;
        gcode.setZ(z);
        if (layerNr == 0)
            gcodeLayer.addPolygonsByOptimizer(storage.skirt, &skirtConfig);
        
        for(unsigned int volumeCnt = 0; volumeCnt < storage.volumes.size(); volumeCnt++)
        {
            if (volumeCnt > 0)
                volumeIdx = (volumeIdx + 1) % storage.volumes.size();
            SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
            gcodeLayer.setExtruder(volumeIdx);
            
            PathOptimizer partOrderOptimizer(gcode.getPositionXY());
            for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++)
            {
                partOrderOptimizer.addPolygon(layer->parts[partNr].insets[0][0]);
            }
            partOrderOptimizer.optimize();
            
            for(unsigned int partCounter=0; partCounter<partOrderOptimizer.polyOrder.size(); partCounter++)
            {
                SliceLayerPart* part = &layer->parts[partOrderOptimizer.polyOrder[partCounter]];
                
                if (config.enableCombing)
                    gcodeLayer.setCombBoundary(&part->combBoundery);
                else
                    gcodeLayer.setAlwaysRetract(true);
                gcodeLayer.forceRetract();
                if (config.insetCount > 0)
                {
                    for(int insetNr=part->insets.size()-1; insetNr>-1; insetNr--)
                    {
                        if (insetNr == 0)
                            gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &inset0Config);
                        else
                            gcodeLayer.addPolygonsByOptimizer(part->insets[insetNr], &inset1Config);
                    }
                }
                
                Polygons fillPolygons;
                int fillAngle = 45;
                if (layerNr & 1) fillAngle += 90;
                //int sparseSteps[1] = {config.extrusionWidth};
                //generateConcentricInfill(part->skinOutline, fillPolygons, sparseSteps, 1);
                generateLineInfill(part->skinOutline, fillPolygons, config.extrusionWidth, config.extrusionWidth, config.infillOverlap, (part->bridgeAngle > -1) ? part->bridgeAngle : fillAngle);
                //int sparseSteps[2] = {config.extrusionWidth*5, config.extrusionWidth * 0.8};
                //generateConcentricInfill(part->sparseOutline, fillPolygons, sparseSteps, 2);
                if (config.sparseInfillLineDistance > 0)
                {
                    if (config.sparseInfillLineDistance > config.extrusionWidth * 4)
                    {
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance * 2, config.infillOverlap, 45);
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance * 2, config.infillOverlap, 45 + 90);
                    }
                    else
                    {
                        generateLineInfill(part->sparseOutline, fillPolygons, config.extrusionWidth, config.sparseInfillLineDistance, config.infillOverlap, fillAngle);
                    }
                }

                gcodeLayer.addPolygonsByOptimizer(fillPolygons, &fillConfig);
                
                //After a layer part, make sure the nozzle is inside the comb boundary, so we do not retract on the perimeter.
                gcodeLayer.moveInsideCombBoundary();
            }
            gcodeLayer.setCombBoundary(NULL);
        }
        if (config.supportAngle > -1)
        {
            if (config.supportExtruder > -1)
                gcodeLayer.setExtruder(config.supportExtruder);
            SupportPolyGenerator supportGenerator(storage.support, z, config.supportAngle, config.supportEverywhere > 0, config.supportXYDistance, config.supportZDistance);
            ClipperLib::Clipper supportClipper;
            supportClipper.AddPolygons(supportGenerator.polygons, ClipperLib::ptSubject);
            for(unsigned int volumeCnt = 0; volumeCnt < storage.volumes.size(); volumeCnt++)
            {
                SliceLayer* layer = &storage.volumes[volumeIdx].layers[layerNr];
                Polygons polys;
                for(unsigned int n=0; n<layer->parts.size(); n++)
                    for(unsigned int m=0; m<layer->parts[n].outline.size(); m++)
                        polys.push_back(layer->parts[n].outline[m]);
                ClipperLib::OffsetPolygons(polys, polys, config.supportXYDistance, ClipperLib::jtSquare, 2, false);
                supportClipper.AddPolygons(polys, ClipperLib::ptClip);
            }
            supportClipper.Execute(ClipperLib::ctDifference, supportGenerator.polygons);
            
            Polygons supportLines;
            if (config.supportLineDistance > 0)
            {
                if (config.supportLineDistance > config.extrusionWidth * 4)
                {
                    generateLineInfill(supportGenerator.polygons, supportLines, config.extrusionWidth, config.supportLineDistance*2, config.infillOverlap, 0);
                    generateLineInfill(supportGenerator.polygons, supportLines, config.extrusionWidth, config.supportLineDistance*2, config.infillOverlap, 90);
                }else{
                    generateLineInfill(supportGenerator.polygons, supportLines, config.extrusionWidth, config.supportLineDistance, config.infillOverlap, (layerNr & 1) ? 0 : 90);
                }
            }
            
            gcodeLayer.addPolygonsByOptimizer(supportGenerator.polygons, &supportConfig);
            gcodeLayer.addPolygonsByOptimizer(supportLines, &supportConfig);
        }

        //Finish the layer by applying speed corrections for minimal layer times and slowdown for the initial layer.
        if (int(layerNr) < config.initialSpeedupLayers)
        {
            int n = config.initialSpeedupLayers;
            int layer0Factor = config.initialLayerSpeed * 100 / config.printSpeed;
            gcodeLayer.setExtrudeSpeedFactor((layer0Factor * (n - layerNr) + 100 * (layerNr)) / n);
        }
        gcodeLayer.forceMinimalLayerTime(config.minimalLayerTime, config.minimalFeedrate);
        if (layerNr == 0)
            gcode.setExtrusion(config.initialLayerThickness, config.filamentDiameter, config.filamentFlow);
        else
            gcode.setExtrusion(config.layerThickness, config.filamentDiameter, config.filamentFlow);
        if (int(layerNr) >= config.fanOnLayerNr)
        {
            int speed = config.fanSpeedMin;
            if (gcodeLayer.getExtrudeSpeedFactor() <= 50)
            {
                speed = config.fanSpeedMax;
            }else{
                int n = gcodeLayer.getExtrudeSpeedFactor() - 50;
                speed = config.fanSpeedMin * n / 50 + config.fanSpeedMax * (50 - n) / 50;
            }
            gcode.addFanCommand(speed);
        }else{
            gcode.addFanCommand(0);
        }
        gcodeLayer.writeGCode(config.coolHeadLift > 0);
    }

    /* support debug
    for(int32_t y=0; y<storage.support.gridHeight; y++)
    {
        for(int32_t x=0; x<storage.support.gridWidth; x++)
        {
            unsigned int n = x+y*storage.support.gridWidth;
            if (storage.support.grid[n].size() < 1) continue;
            int32_t z = storage.support.grid[n][0].z;
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, 0), 0);
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, z), z);
            gcode.addMove(Point3(x * storage.support.gridScale + storage.support.gridOffset.X, y * storage.support.gridScale + storage.support.gridOffset.Y, 0), 0);
        }
    }
    //*/
    
    log("Wrote layers in %5.2fs.\n", timeElapsed(t));
    gcode.tellFileSize();
    gcode.addFanCommand(0);

    logProgress("process", 1, 1);
    log("Total time elapsed %5.2fs.\n", timeElapsed(t,true));
    
    //Store the object height for when we are printing multiple objects, as we need to clear every one of them when moving to the next position.
    maxObjectHeight = std::max(maxObjectHeight, storage.modelSize.z);
}
Esempio n. 16
0
Polygon::operator Polygons() const
{
    Polygons pp;
    pp.push_back(*this);
    return pp;
}
Esempio n. 17
0
inline void polygons_append(Polygons &dst, const ExPolygon &src) 
{ 
    dst.reserve(dst.size() + src.holes.size() + 1);
    dst.push_back(src.contour);
    dst.insert(dst.end(), src.holes.begin(), src.holes.end());
}
Esempio n. 18
0
void
BridgeDetector::coverage(double angle, Polygons* coverage) const
{
    // Clone our expolygon and rotate it so that we work with vertical lines.
    ExPolygon expolygon = this->expolygon;
    expolygon.rotate(PI/2.0 - angle, Point(0,0));

    /*  Outset the bridge expolygon by half the amount we used for detecting anchors;
        we'll use this one to generate our trapezoids and be sure that their vertices
        are inside the anchors and not on their contours leading to false negatives. */
    ExPolygons grown;
    offset(expolygon, &grown, this->extrusion_width/2.0);

    // Compute trapezoids according to a vertical orientation
    Polygons trapezoids;
    for (ExPolygons::const_iterator it = grown.begin(); it != grown.end(); ++it)
        it->get_trapezoids2(&trapezoids, PI/2.0);

    // get anchors, convert them to Polygons and rotate them too
    Polygons anchors;
    for (ExPolygons::const_iterator anchor = this->_anchors.begin(); anchor != this->_anchors.end(); ++anchor) {
        Polygons pp = *anchor;
        for (Polygons::iterator p = pp.begin(); p != pp.end(); ++p)
            p->rotate(PI/2.0 - angle, Point(0,0));
        anchors.insert(anchors.end(), pp.begin(), pp.end());
    }

    Polygons covered;
    for (Polygons::const_iterator trapezoid = trapezoids.begin(); trapezoid != trapezoids.end(); ++trapezoid) {
        Lines lines = trapezoid->lines();
        Lines supported;
        intersection(lines, anchors, &supported);

        // not nice, we need a more robust non-numeric check
        for (size_t i = 0; i < supported.size(); ++i) {
            if (supported[i].length() < this->extrusion_width) {
                supported.erase(supported.begin() + i);
                i--;
            }
        }

        if (supported.size() >= 2) covered.push_back(*trapezoid);
    }

    // merge trapezoids and rotate them back
    Polygons _coverage;
    union_(covered, &_coverage);
    for (Polygons::iterator p = _coverage.begin(); p != _coverage.end(); ++p)
        p->rotate(-(PI/2.0 - angle), Point(0,0));

    // intersect trapezoids with actual bridge area to remove extra margins
    // and append it to result
    intersection(_coverage, this->expolygon, coverage);

    /*
    if (0) {
        my @lines = map @{$_->lines}, @$trapezoids;
        $_->rotate(-(PI/2 - $angle), [0,0]) for @lines;

        require "Slic3r/SVG.pm";
        Slic3r::SVG::output(
            "coverage_" . rad2deg($angle) . ".svg",
            expolygons          => [$self->expolygon],
            green_expolygons    => $self->_anchors,
            red_expolygons      => $coverage,
            lines               => \@lines,
        );
    }
    */
}
Esempio n. 19
0
inline void polygons_append(Polygons &dst, ExPolygon &&src)
{ 
    dst.reserve(dst.size() + src.holes.size() + 1);
    dst.push_back(std::move(src.contour));
    std::move(std::begin(src.holes), std::end(src.holes), std::back_inserter(dst));
}
Esempio n. 20
0
File: coco.cpp Progetto: CUAir/edges
list loadCOCO( const std::string & name, int fold ) {
	using namespace rapidjson;
	
	// Load the annotations
	char buf[1024];
	sprintf( buf, COCO_ANNOT.c_str(), name.c_str() );
	
	// Read the json file
	Document doc;
	std::ifstream t(buf);
	std::string json_str = std::string(std::istreambuf_iterator<char>(t),std::istreambuf_iterator<char>());
	doc.Parse( (char*)json_str.c_str() );
	
	// Go through all instance labels
	std::unordered_map< uint64_t, std::vector<int> > categories;
	std::unordered_map< uint64_t, std::vector<float> > areas;
	std::unordered_map< uint64_t, std::vector<Polygons> > segments;
	const Value & instances = doc["instances"];
	for ( Value::ConstValueIterator i = instances.Begin(); i != instances.End(); i++ ) {
		// Get the image id
		Value::ConstMemberIterator cmi_image_id = i->FindMember("image_id");
		eassert( cmi_image_id != i->MemberEnd() );
		const int image_id = cmi_image_id->value.GetInt();
		
		// Get the category id
		Value::ConstMemberIterator cmi_category_id = i->FindMember("category_id");
		eassert( cmi_category_id != i->MemberEnd() );
		const int category_id = cmi_category_id->value.GetInt();
		
		// Get the category id
		Value::ConstMemberIterator cmi_area = i->FindMember("area");
		eassert( cmi_area != i->MemberEnd() );
		const float area = cmi_area->value.GetDouble();
		
		// Read the polygon
		Value::ConstMemberIterator cmi_segmentation = i->FindMember("segmentation");
		eassert( cmi_segmentation != i->MemberEnd() );
		const Value & segmentations = cmi_segmentation->value;
		
		// For now just use the first segmentation for each object
		Polygons polygons;
		for( Value::ConstValueIterator segmentation = segmentations.Begin(); segmentation!=segmentations.End(); segmentation++ ){
			Polygon polygon = RMatrixXf( segmentation->Size() / 2, 2 );
			float * ppolygon = polygon.data();
			for ( Value::ConstValueIterator j = segmentation->Begin(); j != segmentation->End(); j++ )
				*(ppolygon++) = j->GetDouble();
			polygons.push_back( polygon );
		}
		if( !ONLY_CONNECTED || polygons.size() == 1 ) {
			categories[ image_id ].push_back( category_id );
			segments[ image_id ].push_back( polygons );
			areas[ image_id ].push_back( area );
		}
	}
	
	// Load all images
	Value::ConstValueIterator B = doc["images"].Begin(), E = doc["images"].End();
	const int N = E-B;
	Value::ConstValueIterator i0 = B+(fold*N/N_FOLDS), i1 = B+((fold+1)*N/N_FOLDS);
	
	std::vector< std::shared_ptr<Image8u> > images( i1 - i0 );
#pragma omp parallel for
	for ( int k=0; k<i1-i0; k++ ) {
		Value::ConstValueIterator i = i0+k;
		// Get the file name and path
		Value::ConstMemberIterator cmi_file_name = i->FindMember("file_name");
		eassert( cmi_file_name != i->MemberEnd() );
		const std::string file_name = cmi_file_name->value.GetString();
		Value::ConstMemberIterator cmi_file_path = i->FindMember("file_path");
		eassert( cmi_file_path != i->MemberEnd() );
		const std::string file_path = cmi_file_path->value.GetString();
		
		// Add the image entry
		images[i-i0] = imreadShared( coco_dir+"/"+file_path+"/"+file_name );
	}
	// Create the python struct with the result
	list r;
	for ( Value::ConstValueIterator i = i0; i != i1; i++ ) {
		// Get the image id
		Value::ConstMemberIterator cmi_image_id = i->FindMember("id");
		eassert( cmi_image_id != i->MemberEnd() );
		const int image_id = cmi_image_id->value.GetInt();
		
		// Add the image entry
		const int N = categories[ image_id ].size();
		if( N > 0 ){
			dict entry;
			entry["id"] = image_id;
			entry["image"] = images[i - i0];
			entry["categories"] = categories[ image_id ];
			entry["areas"] = areas[ image_id ];
			entry["segmentation"] = segments[ image_id ];
			r.append( entry );
		}
// 		else 
// 			printf("Image '%d' doesn't have any annotations!\n", image_id );
	}

	return r;
}