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); } }
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--; } } }
void SubDivCube::addLineAndCombine(Polygons& group, Point from, Point to) { int epsilon = 10; // the smallest distance of two points which are viewed as coincident (dist > 0 due to rounding errors) for (unsigned int idx = 0; idx < group.size(); idx++) { if (std::abs(from.X - group[idx][1].X) < epsilon && std::abs(from.Y - group[idx][1].Y) < epsilon) { from = group[idx][0]; group.remove(idx); idx--; continue; } if (std::abs(to.X - group[idx][0].X) < epsilon && std::abs(to.Y - group[idx][0].Y) < epsilon) { to = group[idx][1]; group.remove(idx); idx--; continue; } } group.addLine(from, to); }
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 generateSparse(int layerNr, SliceVolumeStorage& storage, int extrusionWidth, int downSkinCount, int upSkinCount) { SliceLayer* layer = &storage.layers[layerNr]; for(unsigned int partNr=0; partNr<layer->parts.size(); partNr++) { SliceLayerPart* part = &layer->parts[partNr]; Polygons sparse = part->insets[part->insets.size() - 1].offset(-extrusionWidth/2); Polygons downskin = sparse; Polygons upskin = sparse; if (int(layerNr - downSkinCount) >= 0) { SliceLayer* layer2 = &storage.layers[layerNr - downSkinCount]; for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++) { if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox)) { if (layer2->parts[partNr2].insets.size() > 1) { downskin = downskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 2]); }else{ downskin = downskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1]); } } } } if (int(layerNr + upSkinCount) < (int)storage.layers.size()) { SliceLayer* layer2 = &storage.layers[layerNr + upSkinCount]; for(unsigned int partNr2=0; partNr2<layer2->parts.size(); partNr2++) { if (part->boundaryBox.hit(layer2->parts[partNr2].boundaryBox)) { if (layer2->parts[partNr2].insets.size() > 1) { upskin = upskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 2]); }else{ upskin = upskin.difference(layer2->parts[partNr2].insets[layer2->parts[partNr2].insets.size() - 1]); } } } } Polygons result = upskin.unionPolygons(downskin); double minAreaSize = 3.0;//(2 * M_PI * (double(config.extrusionWidth) / 1000.0) * (double(config.extrusionWidth) / 1000.0)) * 3; for(unsigned int i=0; i<result.size(); i++) { double area = fabs(ClipperLib::Area(result[i])) / 1000.0 / 1000.0; if (area < minAreaSize) /* Only create an up/down skin if the area is large enough. So you do not create tiny blobs of "trying to fill" */ { result.remove(i); i -= 1; } } part->sparseOutline = sparse.difference(result); } }