Exemple #1
0
void
Polygon::simplify(double tolerance, Polygons &polygons) const
{
    Polygons pp = this->simplify(tolerance);
    polygons.reserve(polygons.size() + pp.size());
    polygons.insert(polygons.end(), pp.begin(), pp.end());
}
ClosestPolygonPoint findClosest(Point from, Polygons& polygons)
{

    Polygon emptyPoly;
    ClosestPolygonPoint none(from, -1, emptyPoly);
    
    if (polygons.size() == 0) return none;
    PolygonRef aPolygon = polygons[0];
    if (aPolygon.size() == 0) return none;
    Point aPoint = aPolygon[0];

    ClosestPolygonPoint best(aPoint, 0, aPolygon);

    int64_t closestDist = vSize2(from - best.location);
    
    for (unsigned int ply = 0; ply < polygons.size(); ply++)
    {
        PolygonRef poly = polygons[ply];
        if (poly.size() == 0) continue;
        ClosestPolygonPoint closestHere = findClosest(from, poly);
        int64_t dist = vSize2(from - closestHere.location);
        if (dist < closestDist)
        {
            best = closestHere;
            closestDist = dist;
        }

    }

    return best;
}
Exemple #3
0
void Weaver::chainify_polygons(Polygons& parts1, Point start_close_to, Polygons& result, bool include_last)
{
    for (unsigned int prt = 0 ; prt < parts1.size(); prt++)
    {
        const PolygonRef upperPart = parts1[prt];
        
        ClosestPolygonPoint closestInPoly = PolygonUtils::findClosest(start_close_to, upperPart);

        
        PolygonRef part_top = result.newPoly();
        
        GivenDistPoint next_upper;
        bool found = true;
        int idx = 0;
        
        for (Point upper_point = upperPart[closestInPoly.point_idx]; found; upper_point = next_upper.location)
        {
            found = PolygonUtils::getNextPointWithDistance(upper_point, nozzle_top_diameter, upperPart, idx, closestInPoly.point_idx, next_upper);

            
            if (!found) 
            {
                break;
            }
            
            part_top.add(upper_point);
            
            idx = next_upper.pos;
        }
        if (part_top.size() > 0)
            start_close_to = part_top.back();
        else
            result.remove(result.size()-1);
    }
}
Exemple #4
0
void Weaver::connect(Polygons& parts0, int z0, Polygons& parts1, int z1, WeaveConnection& result, bool include_last)
{
    // TODO: convert polygons (with outset + difference) such that after printing the first polygon, we can't be in the way of the printed stuff
    // something like:
    // for (m > n)
    //     parts[m] = parts[m].difference(parts[n].offset(nozzle_top_diameter))
    // according to the printing order!
    //
    // OR! : 
    //
    // unify different parts if gap is too small
    
    Polygons& supported = result.supported;
    
    if (parts1.size() == 0) return;
    
    Point& start_close_to = (parts0.size() > 0)? parts0.back().back() : parts1.back().back();
    
    chainify_polygons(parts1, start_close_to, supported, include_last);
    
    if (parts0.size() == 0) return;
    
    connect_polygons(parts0, z0, supported, z1, result);

}
Exemple #5
0
void Slice::drawPolygon(Polygons &pgs, int layer){

    glColor4f(0.0f, 1.0f, 0.0f, 0.25f);
    GLUtesselator* tess = gluNewTess();
    gluTessCallback(tess, GLU_TESS_BEGIN, (GLvoid (__stdcall *) ())&BeginCallback);
    gluTessCallback(tess, GLU_TESS_VERTEX, (GLvoid (__stdcall *) ())&VertexCallback);
    gluTessCallback(tess, GLU_TESS_END, (GLvoid (__stdcall *) ())&EndCallback);
    gluTessCallback(tess, GLU_TESS_COMBINE, (GLvoid (__stdcall *) ())&CombineCallback);
    gluTessCallback(tess, GLU_TESS_ERROR, (GLvoid (__stdcall *) ())&ErrorCallback);
    gluTessNormal(tess, 0.0, 0.0, 1.0);
    gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
    gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); //GL_FALSE
    gluTessBeginPolygon(tess, NULL);
    glPushMatrix();
    glTranslated(0.0,0.0,this->layerHeight*layer);
    for (Polygons::size_type i = 0; i < pgs.size(); ++i)
    {
        gluTessBeginContour(tess);
        for (ClipperLib::Polygon::size_type j = 0; j < pgs[i].size(); ++j)
        {
            GLdouble *vert =
                    NewVector((GLdouble)pgs[i][j].X/1000, (GLdouble)pgs[i][j].Y/1000);
            gluTessVertex(tess, vert, vert);
        }
        gluTessEndContour(tess);
    }
    gluTessEndPolygon(tess);
    ClearVectors();

    glColor4f(0.0f, 0.6f, 1.0f, 0.5f);
    glLineWidth(1.8f);

    gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
    gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE);
    for (Polygons::size_type i = 0; i < pgs.size(); ++i)
    {
        gluTessBeginPolygon(tess, NULL);
        gluTessBeginContour(tess);
        for (ClipperLib::Polygon::size_type j = 0; j < pgs[i].size(); ++j)
        {
            GLdouble *vert =
                    NewVector((GLdouble)pgs[i][j].X/1000, (GLdouble)pgs[i][j].Y/1000);
            gluTessVertex(tess, vert, vert);
        }

        glColor4f(0.0f, 0.0f, 0.8f, 0.5f);

        gluTessEndContour(tess);
        gluTessEndPolygon(tess);
    }

    //final cleanup ...
    gluDeleteTess(tess);
    ClearVectors();
    glPopMatrix();
}
Exemple #6
0
/*!
 * generate lines within the area of \p in_outline, at regular intervals of \p lineSpacing
 * 
 * idea:
 * intersect a regular grid of 'scanlines' with the area inside \p in_outline
 * 
 * we call the areas between two consecutive scanlines a 'scansegment'.
 * Scansegment x is the area between scanline x and scanline x+1
 * 
 * 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
 * 
 */
void generateLineInfill(const Polygons& in_outline, int outlineOffset, Polygons& result, int extrusionWidth, int lineSpacing, double infillOverlap, double rotation)
{
    if (lineSpacing == 0) return;
    if (in_outline.size() == 0) return;
    Polygons outline = ((outlineOffset)? in_outline.offset(outlineOffset) : in_outline).offset(extrusionWidth * infillOverlap / 100);
    if (outline.size() == 0) return;
    
    PointMatrix matrix(rotation);
    
    outline.applyMatrix(matrix);

    
    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 poly_idx=0; poly_idx < outline.size(); poly_idx++)
    {
        Point p0 = outline[poly_idx][outline[poly_idx].size()-1];
        for(unsigned int i=0; i < outline[poly_idx].size(); i++)
        {
            Point p1 = outline[poly_idx][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
            
            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);
            }
            p0 = p1;
        }
    }
    
    addLineInfill(result, matrix, scanline_min_idx, lineSpacing, boundary, cutList, extrusionWidth);
}
Exemple #7
0
void Weaver::fillFloors(Polygons& supporting, Polygons& to_be_supported, int direction, int z, WeaveRoof& horizontals)
{
    std::vector<WeaveRoofPart>& outsets = horizontals.roof_insets;
    
    if (to_be_supported.size() == 0) return; // no parts to start the floor from!
    if (supporting.size() == 0) return; // no parts to start the floor from!
    
    Polygons floors = to_be_supported.difference(supporting);

    const coord_t roof_inset = Application::getInstance().current_slice->scene.current_mesh_group->settings.get<coord_t>("wireframe_roof_inset");
    floors = floors.offset(-roof_inset).offset(roof_inset);
    
    if (floors.size() == 0) return;
    
    
    std::vector<PolygonsPart> floor_parts = floors.splitIntoParts();
    
    Polygons floor_outlines;
    Polygons floor_holes;
    for (PolygonsPart& floor_part : floor_parts)
    {
        floor_outlines.add(floor_part[0]);
        for (unsigned int hole_idx = 1; hole_idx < floor_part.size(); hole_idx++)
        {
            floor_holes.add(floor_part[hole_idx]);
            //floor_holes.back().reverse();
        }
    }
    
    
    Polygons outset1;
    
    Polygons last_supported = supporting;
    
    for (Polygons outset0 = supporting; outset0.size() > 0; outset0 = outset1)
    {
        outset1 = outset0.offset(roof_inset * direction, ClipperLib::jtRound).intersection(floors);
        outset1 = outset1.remove(floor_holes); // throw away holes which appear in every intersection
        outset1 = outset1.remove(floor_outlines); // throw away holes which appear in every intersection
        
        
        outsets.emplace_back();
        
        connect(last_supported, z, outset1, z, outsets.back());
        
        outset1 = outset1.remove(floor_outlines);// throw away fully filled regions
        
        last_supported = outsets.back().supported; // chainified

    }
    
    
    horizontals.roof_outlines.add(floors);
}
Exemple #8
0
void generateConcentricInfill(Polygons outline, Polygons& result, int inset_value)
{
    while(outline.size() > 0)
    {
        for (unsigned int polyNr = 0; polyNr < outline.size(); polyNr++)
        {
            PolygonRef r = outline[polyNr];
            result.add(r);
        }
        outline = outline.offset(-inset_value);
    } 
}
Exemple #9
0
int bridgeAngle(Polygons outline, const SliceLayer* prevLayer, Polygons& supportedRegions)
{
    AABB boundaryBox(outline);
    //To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
    // This gives us the islands that the layer rests on.
    Polygons islands;
    for(auto prevLayerPart : prevLayer->parts)
    {
        if (!boundaryBox.hit(prevLayerPart.boundaryBox))
            continue;
        
        islands.add(outline.intersection(prevLayerPart.outline));
    }
    supportedRegions = islands;
    if (islands.size() > 5 || islands.size() < 1)
        return -1;
    
    //Next find the 2 largest islands that we rest on.
    double area1 = 0;
    double area2 = 0;
    int idx1 = -1;
    int idx2 = -1;
    for(unsigned int n=0; n<islands.size(); n++)
    {
        //Skip internal holes
        if (!islands[n].orientation())
            continue;
        double area = fabs(islands[n].area());
        if (area > area1)
        {
            if (area1 > area2)
            {
                area2 = area1;
                idx2 = idx1;
            }
            area1 = area;
            idx1 = n;
        }else if (area > area2)
        {
            area2 = area;
            idx2 = n;
        }
    }
    
    if (idx1 < 0 || idx2 < 0)
        return -1;
    
    Point center1 = islands[idx1].centerOfMass();
    Point center2 = islands[idx2].centerOfMass();

    return angle(center2 - center1);
}
Exemple #10
0
void generateConcentricInfill(Polygons outline, Polygons& result, int offsets[], int offsetsSize)
{
    int step = 0;
    while(1)
    {
        for(unsigned int polygonNr=0; polygonNr<outline.size(); polygonNr++)
            result.add(outline[polygonNr]);
        outline = outline.offset(-offsets[step]);
        if (outline.size() < 1)
            break;
        step = (step + 1) % offsetsSize;
    }
}
Exemple #11
0
int bridgeAngle(SliceLayerPart* part, SliceLayer* prevLayer)
{
    //To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
    // This gives us the islands that the layer rests on.
    Polygons islands;
    for(unsigned int n=0; n<prevLayer->parts.size(); n++)
    {
        if (!part->boundaryBox.hit(prevLayer->parts[n].boundaryBox)) continue;
        
        islands.add(part->outline.intersection(prevLayer->parts[n].outline));
    }
    if (islands.size() > 5)
        return -1;
    
    //Next find the 2 largest islands that we rest on.
    double area1 = 0;
    double area2 = 0;
    int idx1 = -1;
    int idx2 = -1;
    for(unsigned int n=0; n<islands.size(); n++)
    {
        //Skip internal holes
        if (!ClipperLib::Orientation(islands[n]))
            continue;
        double area = fabs(ClipperLib::Area(islands[n]));
        if (area > area1)
        {
            if (area1 > area2)
            {
                area2 = area1;
                idx2 = idx1;
            }
            area1 = area;
            idx1 = n;
        }else if (area > area2)
        {
            area2 = area;
            idx2 = n;
        }
    }
    
    if (idx1 < 0 || idx2 < 0)
        return -1;
    
    Point center1 = centerOfMass(islands[idx1]);
    Point center2 = centerOfMass(islands[idx2]);
    
    double angle = atan2(center2.X - center1.X, center2.Y - center1.Y) / M_PI * 180;
    if (angle < 0) angle += 360;
    return angle;
}
Exemple #12
0
void Weaver::connect_polygons(Polygons& supporting, int z0, Polygons& supported, int z1, WeaveConnection& result)
{
 
    if (supporting.size() < 1)
    {
        DEBUG_PRINTLN("lower layer has zero parts!");
        return;
    }
    
    result.z0 = z0;
    result.z1 = z1;
    
    std::vector<WeaveConnectionPart>& parts = result.connections;
        
    for (unsigned int prt = 0 ; prt < supported.size(); prt++)
    {
        
        const PolygonRef upperPart = supported[prt];
        
        
        parts.emplace_back(prt);
        WeaveConnectionPart& part = parts.back();
        PolyLine3& connection = part.connection;
        
        Point3 last_upper;
        bool firstIter = true;
        
        for (const Point& upper_point : upperPart)
        {
            
            ClosestPolygonPoint lowerPolyPoint = findClosest(upper_point, supporting);
            Point& lower = lowerPolyPoint.location;
            
            Point3 lower3 = Point3(lower.X, lower.Y, z0);
            Point3 upper3 = Point3(upper_point.X, upper_point.Y, z1);
            
            
            if (firstIter)
                connection.from = lower3;
            else
                connection.segments.emplace_back<>(lower3, WeaveSegmentType::DOWN);
            
            connection.segments.emplace_back<>(upper3, WeaveSegmentType::UP);
            last_upper = upper3;
            
            firstIter = false;
        }
    }
}
Exemple #13
0
inline Lines to_lines(const Polygons &polys) 
{
    size_t n_lines = 0;
    for (size_t i = 0; i < polys.size(); ++ i)
        n_lines += polys[i].points.size();
    Lines lines;
    lines.reserve(n_lines);
    for (size_t i = 0; i < polys.size(); ++ i) {
        const Polygon &poly = polys[i];
        for (Points::const_iterator it = poly.points.begin(); it != poly.points.end()-1; ++it)
            lines.push_back(Line(*it, *(it + 1)));
        lines.push_back(Line(poly.points.back(), poly.points.front()));
    }
    return lines;
}
Exemple #14
0
void generateConcentricInfillDense(Polygons outline, Polygons& result, Polygons* in_between, int extrusionWidth, bool avoidOverlappingPerimeters)
{
    while(outline.size() > 0)
    {
        for (unsigned int polyNr = 0; polyNr < outline.size(); polyNr++)
        {
            PolygonRef r = outline[polyNr];
            result.add(r);
        }
        Polygons next_outline;
        PolygonUtils::offsetExtrusionWidth(outline, true, extrusionWidth, next_outline, in_between, avoidOverlappingPerimeters);
        outline = next_outline;
    } 

}
void GCodePlanner::addLinesByOptimizer(Polygons& polygons, GCodePathConfig* config, int wipe_dist)
{
    LineOrderOptimizer orderOptimizer(lastPosition);
    for(unsigned int i=0;i<polygons.size();i++)
        orderOptimizer.addPolygon(polygons[i]);
    orderOptimizer.optimize();
    for(unsigned int i=0;i<orderOptimizer.polyOrder.size();i++)
    {
        int nr = orderOptimizer.polyOrder[i];
//         addPolygon(polygons[nr], orderOptimizer.polyStart[nr], config);
        PolygonRef polygon = polygons[nr];
        int start = orderOptimizer.polyStart[nr];
        int end = 1 - start;
        Point& p0 = polygon[start];
        addTravel(p0);
        Point& p1 = polygon[end];
        addExtrusionMove(p1, config);
        if (wipe_dist != 0)
        {
            int line_width = config->getLineWidth();
            if (vSize2(p1-p0) > line_width * line_width * 4)
            { // otherwise line will get optimized by combining multiple into a single extrusion move
                addExtrusionMove(p1 + normal(p1-p0, wipe_dist), config, 0.0);
            }
        }
    }
}
Exemple #16
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());
    }
}
Exemple #17
0
void Polygons::splitIntoPartsView_processPolyTreeNode(PartsView& partsView, Polygons& reordered, ClipperLib::PolyNode* node)
{
    for(int n=0; n<node->ChildCount(); n++)
    {
        ClipperLib::PolyNode* child = node->Childs[n];
        partsView.emplace_back();
        unsigned int pos = partsView.size() - 1;
        partsView[pos].push_back(reordered.size());
        reordered.add(child->Contour);
        for(int i = 0; i < child->ChildCount(); i++)
        {
            partsView[pos].push_back(reordered.size());
            reordered.add(child->Childs[i]->Contour);
            splitIntoPartsView_processPolyTreeNode(partsView, reordered, child->Childs[i]);
        }
    }
}
Exemple #18
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());
    }
}
Exemple #19
0
void ListPolyIt::convertListPolygonsToPolygons(ListPolygons& list_polygons, Polygons& polygons)
{
    for (unsigned int poly_idx = 0; poly_idx < polygons.size(); poly_idx++)
    {
        polygons[poly_idx].clear();
        convertListPolygonToPolygon(list_polygons[poly_idx], polygons[poly_idx]);
    }
}
Exemple #20
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));
    }
}
Exemple #21
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();
    }
}
void CommandSocket::sendPolygons(PrintFeatureType type, int layer_nr, Polygons& polygons, int line_width)
{
#ifdef ARCUS
    if (polygons.size() == 0)
        return;

    std::shared_ptr<cura::proto::Layer> proto_layer = private_data->getLayerById(layer_nr);

    for (unsigned int i = 0; i < polygons.size(); ++i)
    {
        cura::proto::Polygon* p = proto_layer->add_polygons();
        p->set_type(static_cast<cura::proto::Polygon_Type>(type));
        std::string polydata;
        polydata.append(reinterpret_cast<const char*>(polygons[i].data()), polygons[i].size() * sizeof(Point));
        p->set_points(polydata);
        p->set_line_width(line_width);
    }
#endif
}
Exemple #23
0
void Weaver::chainify_polygons(Polygons& parts1, Point start_close_to, Polygons& result)
{
    const Settings& mesh_group_settings = Application::getInstance().current_slice->scene.current_mesh_group->settings;
    const coord_t connection_height = mesh_group_settings.get<coord_t>("wireframe_height");
    const coord_t nozzle_outer_diameter = mesh_group_settings.get<coord_t>("machine_nozzle_tip_outer_diameter");         //  ___     ___
    const AngleRadians nozzle_expansion_angle = mesh_group_settings.get<AngleRadians>("machine_nozzle_expansion_angle"); //     \_U_/
    const coord_t nozzle_clearance = mesh_group_settings.get<coord_t>("wireframe_nozzle_clearance");                     // at least line width
    const coord_t nozzle_top_diameter = tan(nozzle_expansion_angle) * connection_height + nozzle_outer_diameter + nozzle_clearance;

    for (unsigned int prt = 0 ; prt < parts1.size(); prt++)
    {
        ConstPolygonRef upperPart = parts1[prt];
        
        ClosestPolygonPoint closestInPoly = PolygonUtils::findClosest(start_close_to, upperPart);

        
        PolygonRef part_top = result.newPoly();
        
        GivenDistPoint next_upper;
        bool found = true;
        int idx = 0;
        
        for (Point upper_point = upperPart[closestInPoly.point_idx]; found; upper_point = next_upper.location)
        {
            found = PolygonUtils::getNextPointWithDistance(upper_point, nozzle_top_diameter, upperPart, idx, closestInPoly.point_idx, next_upper);

            
            if (!found) 
            {
                break;
            }
            
            part_top.add(upper_point);
            
            idx = next_upper.pos;
        }
        if (part_top.size() > 0)
            start_close_to = part_top.back();
        else
            result.remove(result.size()-1);
    }
}
void CommandSocket::sendPolygons(PolygonType type, int layer_nr, Polygons& polygons, int line_width)
{
    if(!d->current_sliced_object)
        return;
    
    if (polygons.size() == 0)
        return;

    cura::proto::Layer* layer = d->getLayerById(layer_nr);

    for(unsigned int i = 0; i < polygons.size(); ++i)
    {
        cura::proto::Polygon* p = layer->add_polygons();
        p->set_type(static_cast<cura::proto::Polygon_Type>(type));
        std::string polydata;
        polydata.append(reinterpret_cast<const char*>(polygons[i].data()), polygons[i].size() * sizeof(Point));
        p->set_points(polydata);
        p->set_line_width(line_width);
    }
}
void optimizePolygons(Polygons& polys)
{
    for(unsigned int n=0;n<polys.size();n++)
    {
        optimizePolygon(polys[n]);
        if (polys[n].size() < 3)
        {
            polys.remove(n);
            n--;
        }
    }
}
Exemple #26
0
void AABB::calculate(const Polygons& polys)
{
    min = Point(POINT_MAX, POINT_MAX);
    max = Point(POINT_MIN, POINT_MIN);
    for(unsigned int i=0; i<polys.size(); i++)
    {
        for(unsigned int j=0; j<polys[i].size(); j++)
        {
            include(polys[i][j]);
        }
    }
}
Exemple #27
0
void generateLineInfill(const Polygons& in_outline, Polygons& result, int extrusionWidth, int lineSpacing, int infillOverlap, double rotation)
{
    Polygons outline = in_outline.offset(extrusionWidth * infillOverlap / 100);
    PointMatrix matrix(rotation);
    
    outline.applyMatrix(matrix);
    
    AABB boundary(outline);
    
    boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing;
    int lineCount = (boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing;
    vector<vector<int64_t> > cutList;
    for(int n=0; n<lineCount; n++)
        cutList.push_back(vector<int64_t>());

    for(unsigned int polyNr=0; polyNr < outline.size(); polyNr++)
    {
        Point p1 = outline[polyNr][outline[polyNr].size()-1];
        for(unsigned int i=0; i < outline[polyNr].size(); i++)
        {
            Point p0 = outline[polyNr][i];
            int idx0 = (p0.X - boundary.min.X) / lineSpacing;
            int idx1 = (p1.X - boundary.min.X) / lineSpacing;
            int64_t xMin = p0.X, xMax = p1.X;
            if (p0.X > p1.X) { xMin = p1.X; xMax = p0.X; }
            if (idx0 > idx1) { int tmp = idx0; idx0 = idx1; idx1 = tmp; }
            for(int idx = idx0; idx<=idx1; idx++)
            {
                int x = (idx * lineSpacing) + boundary.min.X + lineSpacing / 2;
                if (x < xMin) continue;
                if (x >= xMax) continue;
                int y = p0.Y + (p1.Y - p0.Y) * (x - p0.X) / (p1.X - p0.X);
                cutList[idx].push_back(y);
            }
            p1 = p0;
        }
    }
    
    int idx = 0;
    for(int64_t x = boundary.min.X + lineSpacing / 2; x < boundary.max.X; x += lineSpacing)
    {
        std::sort(cutList[idx].begin(), cutList[idx].end());
        for(unsigned int i = 0; i + 1 < cutList[idx].size(); i+=2)
        {
            if (cutList[idx][i+1] - cutList[idx][i] < extrusionWidth / 5)
                continue;
            PolygonRef p = result.newPoly();
            p.add(matrix.unapply(Point(x, cutList[idx][i])));
            p.add(matrix.unapply(Point(x, cutList[idx][i+1])));
        }
        idx += 1;
    }
}
Exemple #28
0
void GCodePlanner::addPolygonsByOptimizer(Polygons& polygons, GCodePathConfig* config)
{
    PathOrderOptimizer orderOptimizer(lastPosition);
    for(unsigned int i=0;i<polygons.size();i++)
        orderOptimizer.addPolygon(polygons[i]);
    orderOptimizer.optimize();
    for(unsigned int i=0;i<orderOptimizer.polyOrder.size();i++)
    {
        int nr = orderOptimizer.polyOrder[i];
        addPolygon(polygons[nr], orderOptimizer.polyStart[nr], config);
    }
}
void GCodePlanner::addPolygonsByOptimizer(Polygons& polygons, GCodePathConfig* config, WallOverlapComputation* wall_overlap_computation, EZSeamType z_seam_type)
{
    PathOrderOptimizer orderOptimizer(lastPosition, z_seam_type);
    for(unsigned int i=0;i<polygons.size();i++)
        orderOptimizer.addPolygon(polygons[i]);
    orderOptimizer.optimize();
    for(unsigned int i=0;i<orderOptimizer.polyOrder.size();i++)
    {
        int nr = orderOptimizer.polyOrder[i];
        addPolygon(polygons[nr], orderOptimizer.polyStart[nr], config, wall_overlap_computation);
    }
}
Exemple #30
0
inline Polylines to_polylines(const Polygons &polys)
{
    Polylines polylines;
    polylines.assign(polys.size(), Polyline());
    size_t idx = 0;
    for (Polygons::const_iterator it = polys.begin(); it != polys.end(); ++ it) {
        Polyline &pl = polylines[idx ++];
        pl.points = it->points;
        pl.points.push_back(it->points.front());
    }
    assert(idx == polylines.size());
    return polylines;
}