Ejemplo n.º 1
0
// merge all regions' slices to get islands
void Layer::make_slices()
{
    ExPolygons slices;
    if (m_regions.size() == 1) {
        // optimization: if we only have one region, take its slices
        slices = m_regions.front()->slices;
    } else {
        Polygons slices_p;
        for (LayerRegion *layerm : m_regions)
            polygons_append(slices_p, to_polygons(layerm->slices));
        slices = union_ex(slices_p);
    }
    
    this->slices.expolygons.clear();
    this->slices.expolygons.reserve(slices.size());
    
    // prepare ordering points
    Points ordering_points;
    ordering_points.reserve(slices.size());
    for (const ExPolygon &ex : slices)
        ordering_points.push_back(ex.contour.first_point());
    
    // sort slices
    std::vector<Points::size_type> order;
    Slic3r::Geometry::chained_path(ordering_points, order);
    
    // populate slices vector
    for (size_t i : order)
        this->slices.expolygons.push_back(std::move(slices[i]));
}
Ejemplo n.º 2
0
vector<ExPoly> Clipping::getExPolys(const CL::PolyTree &ctree, double z,
				    double extrusionfactor)
{
  ExPolygons cexpolys;
  PolyTreeToExPolygons(&ctree, cexpolys);
  vector<ExPoly> expolys(cexpolys.size());
  for (uint j = 0 ; j < cexpolys.size(); j++) {
    expolys[j].outer = getPoly(cexpolys[0].outer, z, extrusionfactor);
    for (uint i = 0 ; i < cexpolys[j].holes.size(); i++)
      expolys[j].holes.push_back(getPoly(cexpolys[j].holes[i], z, extrusionfactor));
  }
  return expolys;
}
Ejemplo n.º 3
0
void
LayerRegion::merge_slices()
{
    // without safety offset, artifacts are generated (GH #2494)
    ExPolygons expp = union_ex((Polygons)this->slices, true);
    this->slices.surfaces.clear();
    this->slices.surfaces.reserve(expp.size());
    
    for (ExPolygons::const_iterator expoly = expp.begin(); expoly != expp.end(); ++expoly)
        this->slices.surfaces.push_back(Surface(stInternal, *expoly));
}
Ejemplo n.º 4
0
ExtrusionEntityCollection
PerimeterGenerator::_fill_gaps(double min, double max, double w,
    const Polygons &gaps) const
{
    ExtrusionEntityCollection coll;
    
    min *= (1 - INSET_OVERLAP_TOLERANCE);
    
    ExPolygons curr = diff_ex(
        offset2(gaps, -min/2, +min/2),
        offset2(gaps, -max/2, +max/2),
        true
    );
    
    Polylines polylines;
    for (ExPolygons::const_iterator ex = curr.begin(); ex != curr.end(); ++ex)
        ex->medial_axis(max, min/2, &polylines);
    if (polylines.empty())
        return coll;
    
    #ifdef SLIC3R_DEBUG
    if (!curr.empty())
        printf("  %zu gaps filled with extrusion width = %f\n", curr.size(), w);
    #endif
    
    //my $flow = $layerm->flow(FLOW_ROLE_SOLID_INFILL, 0, $w);
    Flow flow(
        w, this->layer_height, this->solid_infill_flow.nozzle_diameter
    );
    
    double mm3_per_mm = flow.mm3_per_mm();
    
    for (Polylines::const_iterator p = polylines.begin(); p != polylines.end(); ++p) {
        ExtrusionPath path(erGapFill);
        path.polyline   = *p;
        path.mm3_per_mm = mm3_per_mm;
        path.width      = flow.width;
        path.height     = this->layer_height;
        
        if (p->is_valid() && p->first_point().coincides_with(p->last_point())) {
            // since medial_axis() now returns only Polyline objects, detect loops here
            ExtrusionLoop loop;
            loop.paths.push_back(path);
            coll.append(loop);
        } else {
            coll.append(path);
        }
    }
    
    return coll;
}
Ejemplo n.º 5
0
void Clipping::AddOuterPolyNodeToExPolygons(const CL::PolyNode * polynode,
					    ExPolygons& expolygons)
{
  size_t cnt = expolygons.size();
  expolygons.resize(cnt + 1);
  expolygons[cnt].outer = polynode->Contour;
  expolygons[cnt].holes.resize(polynode->ChildCount());
  for (int i = 0; i < polynode->ChildCount(); ++i)
  {
    expolygons[cnt].holes[i] = polynode->Childs[i]->Contour;
    //Add outer polygons contained by (nested within) holes ...
    for (int j = 0; j < polynode->Childs[i]->ChildCount(); ++j)
      AddOuterPolyNodeToExPolygons(polynode->Childs[i]->Childs[j], expolygons);
  }
}
Ejemplo n.º 6
0
void
MotionPlanner::initialize()
{
    if (this->initialized) return;
    if (this->islands.empty()) return;  // prevent initialization of empty BoundingBox
    
    ExPolygons expp;
    for (ExPolygons::const_iterator island = this->islands.begin(); island != this->islands.end(); ++island) {
        island->simplify(SCALED_EPSILON, expp);
    }
    this->islands = expp;
    
    // loop through islands in order to create inner expolygons and collect their contours
    this->inner.reserve(this->islands.size());
    Polygons outer_holes;
    for (ExPolygons::const_iterator island = this->islands.begin(); island != this->islands.end(); ++island) {
        this->inner.push_back(ExPolygonCollection());
        offset(*island, &this->inner.back().expolygons, -MP_INNER_MARGIN);
        
        outer_holes.push_back(island->contour);
    }
    
    // grow island contours in order to prepare holes of the outer environment
    // This is actually wrong because it might merge contours that are close,
    // thus confusing the island check in shortest_path() below
    //offset(outer_holes, &outer_holes, +MP_OUTER_MARGIN);
    
    // generate outer contour as bounding box of everything
    Points points;
    for (Polygons::const_iterator contour = outer_holes.begin(); contour != outer_holes.end(); ++contour)
        points.insert(points.end(), contour->points.begin(), contour->points.end());
    BoundingBox bb(points);
    
    // grow outer contour
    Polygons contour;
    offset(bb.polygon(), &contour, +MP_OUTER_MARGIN);
    assert(contour.size() == 1);
    
    // make expolygon for outer environment
    ExPolygons outer;
    diff(contour, outer_holes, &outer);
    assert(outer.size() == 1);
    this->outer = outer.front();
    
    this->graphs.resize(this->islands.size() + 1, NULL);
    this->initialized = true;
}
Ejemplo n.º 7
0
Surfaces
offset(const Surface &surface, const float delta,
    double scale, ClipperLib::JoinType joinType, double miterLimit)
{
    // perform offset
    ExPolygons expp = offset_ex(surface.expolygon, delta, scale, joinType, miterLimit);
    
    // clone the input surface for each expolygon we got
    Surfaces retval;
    retval.reserve(expp.size());
    for (ExPolygons::iterator it = expp.begin(); it != expp.end(); ++it) {
        Surface s = surface;  // clone
        s.expolygon = *it;
        retval.push_back(s);
    }
    return retval;
}
Ejemplo n.º 8
0
void
MotionPlanner::initialize()
{
    if (this->initialized) return;
    if (this->islands.empty()) return;  // prevent initialization of empty BoundingBox
    
    // loop through islands in order to create inner expolygons and collect their contours
    Polygons outer_holes;
    for (std::vector<MotionPlannerEnv>::iterator island = this->islands.begin(); island != this->islands.end(); ++island) {
        // generate the internal env boundaries by shrinking the island
        // we'll use these inner rings for motion planning (endpoints of the Voronoi-based
        // graph, visibility check) in order to avoid moving too close to the boundaries
        island->env = offset_ex(island->island, -MP_INNER_MARGIN);
        
        // island contours are holes of our external environment
        outer_holes.push_back(island->island.contour);
    }
    
    // generate outer contour as bounding box of everything
    BoundingBox bb;
    for (Polygons::const_iterator contour = outer_holes.begin(); contour != outer_holes.end(); ++contour)
        bb.merge(contour->bounding_box());
    
    // grow outer contour
    Polygons contour = offset(bb.polygon(), +MP_OUTER_MARGIN*2);
    assert(contour.size() == 1);
    
    // make expolygon for outer environment
    ExPolygons outer = diff_ex(contour, outer_holes);
    assert(outer.size() == 1);
    this->outer.island = outer.front();
    
    this->outer.env = ExPolygonCollection(diff_ex(contour, offset(outer_holes, +MP_OUTER_MARGIN)));
    
    this->graphs.resize(this->islands.size() + 1, NULL);
    this->initialized = true;
}