// add full fill and subtract them from normal fill polys void Layer::addFullPolygons(const vector<Poly> &newpolys, bool decor) { if (newpolys.size()==0) return; Clipping clipp; clipp.clear(); // full fill only where already normal fill clipp.addPolys(fillPolygons,subject); if (decor) clipp.addPolys(fullFillPolygons,subject); clipp.addPolys(newpolys,clip); clipp.setZ(Z); vector<Poly> inter = clipp.intersect(); vector<Poly> normals = clipp.subtractMerged(thickness/2.); if (decor) {// && LayerNo != 0) // no decor on base layers decorPolygons.insert(decorPolygons.end(), inter.begin(), inter.end()); Clipping clipp; clipp.addPolys(fullFillPolygons,subject); clipp.addPolys(inter,clip); clipp.setZ(Z); setFullFillPolygons(clipp.subtract()); } else { fullFillPolygons.insert(fullFillPolygons.end(),inter.begin(),inter.end()); } setNormalFillPolygons(normals); // mergeFullPolygons(false); // done separately }
// add bridge polys and substract them from normal and full fill polys void Layer::addBridgePolygons(const vector<Poly> newpolys) { if (newpolys.size()==0) return; bridgePolygons.clear(); Clipping clipp; clipp.clear(); clipp.addPolys(fillPolygons,subject); clipp.addPolys(newpolys,clip); vector<Poly> inter = clipp.intersect(); bridgePolygons= inter;//.insert(bridgePolygons.end(),inter.begin(),inter.end()); clipp.clear(); clipp.addPolys(fillPolygons,subject); clipp.addPolys(inter,clip); setNormalFillPolygons(clipp.substract()); mergeFullPolygons(true); }
void Layer::calcBridgeAngles(const Layer *layerbelow) { bridge_angles.resize(bridgePolygons.size()); Clipping clipp; vector<Poly> polysbelow = *(layerbelow->GetInnerShell());//clipp.getOffset(polygons,3*thickness); bridgePillars.resize(bridgePolygons.size()); for (uint i=0; i<bridgePolygons.size(); i++) { // intersect bridge poly with polygons below (=pillars of bridge) clipp.clear(); clipp.addPolys(polysbelow,subject); clipp.addPolys(clipp.getOffset(bridgePolygons[i].outer,thickness),clip); bridgePillars[i] = clipp.intersect(); // TODO detect circular bridges -> rotating infill? // get average direction of the mutual connections of all the intersections Vector2d dir(0,0); for (uint p=0; p<bridgePillars[i].size(); p++){ for (uint q=p+1; q<bridgePillars[i].size(); q++){ // Vector2d p1,p2; // bridgePillars[i][q].shortestConnectionSq(bridgePillars[i][p], p1,p2); // dir += (p2-p1); dir += bridgePillars[i][q].center - bridgePillars[i][p].center; } } //cerr << pillars.size() << " - " << dir << endl; bridge_angles[i] = atan2(dir.y(),dir.x()); if (bridge_angles[i]<0) bridge_angles[i]+=M_PI; } }
void Model::MakeSkirt() { if (!settings.get_boolean("Slicing","Skirt")) return; double skirtdistance = settings.get_double("Slicing","SkirtDistance"); Clipping clipp; guint count = layers.size(); guint endindex = 0; // find maximum of all calculated skirts clipp.clear(); double skirtheight = settings.get_double("Slicing","SkirtHeight"); bool singleskirt = settings.get_boolean("Slicing","SingleSkirt"); bool support = settings.get_boolean("Slicing","Support"); for (guint i=0; i < count; i++) { if (layers[i]->getZ() > skirtheight) break; layers[i]->MakeSkirt(skirtdistance, singleskirt && !support); vector<Poly> sp = layers[i]->GetSkirtPolygons(); clipp.addPolys(sp,subject); endindex = i; } vector<Poly> skirts = clipp.unite(CL::pftPositive,CL::pftPositive); // set this skirt for all skirted layers if (skirts.size()>0) for (guint i=0; i<=endindex; i++) { layers[i]->setSkirtPolygons(skirts); } }
// add full fill and substract them from normal fill polys void Layer::addFullPolygons(const vector<Poly> newpolys, bool decor) { if (newpolys.size()==0) return; Clipping clipp; clipp.clear(); // full fill only where already normal fill clipp.addPolys(fillPolygons,subject); clipp.addPolys(newpolys,clip); vector<Poly> inter = clipp.intersect(); if (decor) decorPolygons.insert(decorPolygons.end(),inter.begin(),inter.end()); else fullFillPolygons.insert(fullFillPolygons.end(),inter.begin(),inter.end()); //substract from normal fills clipp.clear(); clipp.addPolys(fillPolygons,subject); clipp.addPolys(inter,clip); setNormalFillPolygons(clipp.substract()); mergeFullPolygons(false); }
// add bridge polys and subtract them from normal and full fill polys // each given ExPoly is a single bridge with its holes void Layer::addBridgePolygons(const vector<ExPoly> &newexpolys) { // clip against normal fill and make these areas into bridges: Clipping clipp; uint num_bridges = newexpolys.size(); if (num_bridges==0) return; clipp.clear(); bridgePolygons.clear(); for (uint i=0; i < num_bridges; i++){ vector<Poly> newpolys = Clipping::getPolys(newexpolys[i]); clipp.clear(); clipp.addPolys(fillPolygons,subject); clipp.addPolys(newpolys, clip); vector<ExPoly> exbridges = clipp.ext_intersect(); bridgePolygons.insert(bridgePolygons.end(),exbridges.begin(),exbridges.end()); } // subtract from normal fill clipp.clear(); clipp.addPolys(fillPolygons,subject); clipp.addPolys(newexpolys, clip); setNormalFillPolygons(clipp.subtract()); }
// find polys in subjlayer that are not covered by shell of cliplayer vector<Poly> Model::GetUncoveredPolygons(const Layer * subjlayer, const Layer * cliplayer) { Clipping clipp; clipp.clear(); clipp.addPolys(subjlayer->GetFillPolygons(), subject); clipp.addPolys(subjlayer->GetFullFillPolygons(), subject); clipp.addPolys(subjlayer->GetBridgePolygons(), subject); clipp.addPolys(subjlayer->GetDecorPolygons(), subject); //clipp.addPolys(cliplayer->GetOuterShell(), clip); // have some overlap clipp.addPolys(cliplayer->GetInnerShell(), clip); // have some more overlap vector<Poly> uncovered = clipp.subtractMerged(); return uncovered; }
void Layer::calcBridgeAngles(const Layer *layerbelow) { bridge_angles.resize(bridgePolygons.size()); Clipping clipp; vector<Poly> polysbelow = layerbelow->polygons;//clipp.getOffset(polygons,3*thickness); for (uint i=0; i<bridgePolygons.size(); i++) { // intersect bridge poly with polygons below (=pillars of bridge) clipp.clear(); clipp.addPolys(polysbelow,subject); clipp.addPolys(clipp.getOffset(bridgePolygons[i],2*thickness),clip); vector<Poly> pillars = clipp.intersect(); // get average direction of the connection lines of all the intersections Vector2d dir(0,0); for (uint p=0; p<pillars.size(); p++){ for (uint q=p+1; q<pillars.size(); q++){ dir+=pillars[q].center-pillars[p].center; } } //cerr << pillars.size() << " - " << dir << endl; bridge_angles[i] = atan2(dir.y,dir.x); } }
// these are used for the bridge polys of the layer above vector <double> Layer::getBridgeRotations(const vector<Poly> polys) const{ vector<double> angles; angles.resize(polys.size()); Clipping clipp; vector<Poly> offset = polygons;//clipp.getOffset(polygons,3*thickness); for (uint i=0; i<polys.size(); i++) { // intersect bridge poly with polygons below (=pillars of bridge) clipp.clear(); clipp.addPolys(offset,subject); clipp.addPolys(clipp.getOffset(polys[i],2*thickness),clip); vector<Poly> pillars = clipp.intersect(); // get average direction of the connection lines of all the intersections Vector2d dir(0,0); for (uint p=0; p<pillars.size(); p++){ for (uint q=p+1; q<pillars.size(); q++){ dir+=pillars[q].center-pillars[p].center; } } //cerr << pillars.size() << " - " << dir << endl; angles[i] = atan2(dir.y,dir.x); } return angles; }
void Layer::mergeFullPolygons(bool bridge) { // if (bridge) { // // setBridgePolygons(Clipping::getMerged(bridgePolygons, thickness)); // // clipp.addPolys(bridgePolygons,clip); // } else { //subtract decor from full Clipping clipp; // clipp.addPolys(fullFillPolygons,subject); // clipp.addPolys(decorPolygons,clip); // setFullFillPolygons(clipp.subtract()); setFullFillPolygons(Clipping::getMerged(fullFillPolygons, thickness)); cleanup(fullFillPolygons, thickness/CLEANFACTOR); //subtract from normal fills clipp.clear(); cleanup(fillPolygons, thickness/CLEANFACTOR); clipp.addPolys(fillPolygons,subject); clipp.addPolys(fullFillPolygons,clip); clipp.addPolys(decorPolygons,clip); vector<Poly> normals = clipp.subtractMerged(); setNormalFillPolygons(normals); // } }