void cairo_to_clipper(cairo_t* cr,
                          Polygons &pg,
                          int scaling_factor,
                          Transform transform)
    {
      if (scaling_factor > 8 || scaling_factor < 0)
        throw clipperCairoException("cairo_to_clipper: invalid scaling factor");
      double scaling = std::pow((double)10, scaling_factor);

      pg.clear();
      cairo_path_t *path = cairo_copy_path_flat(cr);

      int poly_count = 0;
      for (int i = 0; i < path->num_data; i += path->data[i].header.length) {
        if( path->data[i].header.type == CAIRO_PATH_CLOSE_PATH) poly_count++;
      }

      pg.resize(poly_count);
      int i = 0, pc = 0;
      while (pc < poly_count)
      {
        int vert_count = 1;
        int j = i;
        while(j < path->num_data &&
          path->data[j].header.type != CAIRO_PATH_CLOSE_PATH)
        {
          if (path->data[j].header.type == CAIRO_PATH_LINE_TO)
            vert_count++;
          j += path->data[j].header.length;
        }
        pg[pc].resize(vert_count);
        if (path->data[i].header.type != CAIRO_PATH_MOVE_TO) {
          pg.resize(pc);
          break;
        }
        pg[pc][0].X = Round(path->data[i+1].point.x *scaling);
        pg[pc][0].Y = Round(path->data[i+1].point.y *scaling);
        if (transform != tNone)
          transform_point(cr, transform, &pg[pc][0].X, &pg[pc][0].Y);

        i += path->data[i].header.length;

        j = 1;
        while (j < vert_count && i < path->num_data &&
          path->data[i].header.type == CAIRO_PATH_LINE_TO) {
          pg[pc][j].X = Round(path->data[i+1].point.x *scaling);
          pg[pc][j].Y = Round(path->data[i+1].point.y *scaling);
          if (transform != tNone)
            transform_point(cr, transform, &pg[pc][j].X, &pg[pc][j].Y);
          j++;
          i += path->data[i].header.length;
        }
        pc++;
        i += path->data[i].header.length;
      }
      cairo_path_destroy(path);
    }
Exemple #2
0
void
SLAPrint::_infill_layer(size_t i, const Fill* _fill)
{
    Layer &layer = this->layers[i];
    
    const float shell_thickness = this->config.get_abs_value("perimeter_extrusion_width", this->config.layer_height.value);
    
    // In order to detect what regions of this layer need to be solid,
    // perform an intersection with layers within the requested shell thickness.
    Polygons internal = layer.slices;
    for (size_t j = 0; j < this->layers.size(); ++j) {
        const Layer &other = this->layers[j];
        if (abs(other.print_z - layer.print_z) > shell_thickness) continue;
    
        if (j == 0 || j == this->layers.size()-1) {
            internal.clear();
            break;
        } else if (i != j) {
            internal = intersection(internal, other.slices);
            if (internal.empty()) break;
        }
    }
    
    // If we have no internal infill, just print the whole layer as a solid slice.
    if (internal.empty()) return;
    layer.solid = false;
    
    const Polygons infill = offset(layer.slices, -scale_(shell_thickness));
    
    // Generate solid infill
    layer.solid_infill << diff_ex(infill, internal, true);
    
    // Generate internal infill
    {
        std::auto_ptr<Fill> fill(_fill->clone());
        fill->layer_id = i;
        fill->z        = layer.print_z;
        
        ExtrusionPath templ(erInternalInfill);
        templ.width = fill->spacing;
        const ExPolygons internal_ex = intersection_ex(infill, internal);
        for (ExPolygons::const_iterator it = internal_ex.begin(); it != internal_ex.end(); ++it) {
            Polylines polylines = fill->fill_surface(Surface(stInternal, *it));
            layer.infill.append(polylines, templ);
        }
    }
    
    // Generate perimeter(s).
    layer.perimeters << diff_ex(
        layer.slices,
        offset(layer.slices, -scale_(shell_thickness))
    );
}
Exemple #3
0
 void clear() { contour.points.clear(); holes.clear(); }