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); }
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)) ); }
void clear() { contour.points.clear(); holes.clear(); }