Esempio n. 1
0
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;
    }
}
Esempio n. 2
0
// 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
}
Esempio n. 3
0
void Model::MakeSupportPolygons(Layer * layer, // lower -> will change
				const Layer * layerabove,  // upper
				double widen)
{
  const double distance =
    settings.GetExtrudedMaterialWidth(layer->thickness);
  // vector<Poly> tosupport = Clipping::getOffset(layerabove->GetToSupportPolygons(),
  //  					       distance/2.);
  //vector<Poly> tosupport = Clipping::getMerged(layerabove->GetToSupportPolygons(),
  // 					       distance);
  vector<Poly> tosupport = layerabove->GetToSupportPolygons();

  Clipping clipp;
  clipp.addPolys(layerabove->GetSupportPolygons(),  subject);
  clipp.addPolys(tosupport,                         subject);
  clipp.addPolys(layer->GetPolygons(),              clip);
  clipp.setZ(layer->getZ());

  vector<Poly> spolys = clipp.subtract(CL::pftNonZero,CL::pftEvenOdd);

  if (widen != 0) // widen from layer to layer
    spolys = clipp.getOffset(spolys, widen * layer->thickness);

  spolys = clipp.getMerged(spolys,distance);

  layer->setSupportPolygons(spolys);
}
Esempio n. 4
0
vector<Poly> Layer::getOverhangs() const
{
  vector<Poly> overhangs;
  if (previous!=NULL) {
    Clipping clipp;
    clipp.addPolys(polygons, subject);
    vector<Poly> prevoffset = Clipping::getOffset(previous->polygons, thickness/2);
    clipp.addPolys(prevoffset, clip);
    clipp.setZ(Z);
    overhangs = clipp.subtract();//CL::pftNonZero,CL::pftNonZero);
  }
  return overhangs;
}
Esempio n. 5
0
// 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;
}
Esempio n. 6
0
// 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);
}
Esempio n. 7
0
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);
  }
}
Esempio n. 8
0
vector<Poly> Clipping::getPolys(const ExPoly &expoly)
{
  Clipping clipp;
  clipp.addPoly(expoly.outer,  subject);
  clipp.addPolys(expoly.holes, clip);
  vector<Poly> polys = clipp.subtract();
  return polys;
}
Esempio n. 9
0
// 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);
}
Esempio n. 10
0
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);
    }
}
Esempio n. 11
0
// 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());
}
Esempio n. 12
0
// 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;
}
Esempio n. 13
0
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);
  // }
}
Esempio n. 14
0
void Layer::FindThinpolys(const vector<Poly> &polys, double extrwidth,
			  vector<Poly> &thickpolys, vector<Poly> &thinpolys)
{
#define THINPOLYS 1
#if THINPOLYS
  // go in
  thickpolys = Clipping::getOffset(polys, -0.5*extrwidth);
  // go out again, now thin polys are gone
  thickpolys = Clipping::getOffset(thickpolys, 0.55*extrwidth);
  // (need overlap to really clip)

  // use bigger (longer) polys for clip to avoid overlap of thin and thick extrusion lines
  vector <Poly> bigthick = Clipping::getOffset(thickpolys, extrwidth);
  // difference to original are thin polys
  Clipping clipp;
  clipp.addPolys(polys, subject);
  clipp.addPolys(bigthick, clip);
  thinpolys = clipp.subtract();
  // remove overlap
  thickpolys = Clipping::getOffset(thickpolys, -0.05*extrwidth);
#else
  thickpolys = polys;
#endif
}
Esempio n. 15
0
void Layer::CalcInfill (const Settings &settings)
{
  // inFill distances in real mm:
  // for full polys/layers:
  double fullInfillDistance=0;
  double infillDistance=0; // normal fill
  double altInfillDistance=0;
  double altInfillPercent=settings.get_double("Slicing","InfillPercent");
  double normalInfilldist=0;
  bool shellOnly = !settings.get_boolean("Slicing","DoInfill");
  fullInfillDistance = settings.GetInfillDistance(thickness, 100);

  if (settings.get_double("Slicing","InfillPercent") == 0)
    shellOnly = true;
  else
    infillDistance = settings.GetInfillDistance(thickness,altInfillPercent);
  int altinfill = settings.get_integer("Slicing","AltInfillLayers");
  normalInfilldist = infillDistance;
  if ( altinfill != 0  && LayerNo % altinfill == 0 && altInfillPercent != 0) {
    altInfillDistance = settings.GetInfillDistance(thickness,
						   settings.get_double("Slicing","AltInfillPercent"));
    normalInfilldist = altInfillDistance;
  }
  // first layers:
  if (LayerNo < (int)settings.get_integer("Slicing","FirstLayersNum")) {
    double first_infdist =
      fullInfillDistance * (1.+settings.get_double("Slicing","FirstLayersInfillDist"));
    normalInfilldist   = max(normalInfilldist,   first_infdist);
    fullInfillDistance = max(fullInfillDistance, first_infdist);
  }
  // relative extrusion for skins:
  double skinfillextrf = settings.get_double("Slicing","FullFillExtrusion")/skins/skins;
  normalInfill = new Infill(this,settings.get_double("Slicing","NormalFillExtrusion"));
  normalInfill->setName("normal");
  fullInfill = new Infill(this,settings.get_double("Slicing","FullFillExtrusion"));
  fullInfill->setName("full");
  skirtInfill = new Infill(this,settings.get_double("Slicing","FullFillExtrusion"));
  skirtInfill->setName("skirt");
  skinFullInfills.clear();
  supportInfill = new Infill(this,settings.get_double("Slicing","SupportExtrusion"));
  supportInfill->setName("support");
  decorInfill = new Infill(this,1.);
  decorInfill->setName("decor");
  thinInfill = new Infill(this, 1.);
  thinInfill->setName("thin");

  double rot = (settings.get_double("Slicing","InfillRotation"),
		+ (double)LayerNo*settings.get_double("Slicing","InfillRotationPrLayer"))/180.0*M_PI;
  if (!shellOnly)
    normalInfill->addPolys(Z, fillPolygons, (InfillType)settings.get_integer("Slicing","NormalFilltype"),
			   normalInfilldist, fullInfillDistance, rot);

  if (settings.get_boolean("Slicing","FillSkirt")) {
    vector<Poly> skirtFill;
    Clipping clipp;
    clipp.addPolys(skirtPolygons, subject);
    clipp.addPolys(*GetOuterShell(), clip);
    clipp.addPolys(supportPolygons, clip);
    skirtFill = clipp.subtract();
    skirtFill = Clipping::getOffset(skirtFill, -fullInfillDistance);
    skirtInfill->addPolys(Z, skirtFill, (InfillType)settings.get_integer("Slicing","FullFilltype"),
			  fullInfillDistance, fullInfillDistance, rot);
  }

  fullInfill->addPolys(Z, fullFillPolygons, (InfillType)settings.get_integer("Slicing","FullFilltype"),
		       fullInfillDistance, fullInfillDistance, rot);

  decorInfill->addPolys(Z, decorPolygons, (InfillType)settings.get_integer("Slicing","DecorFilltype"),
			settings.get_double("Slicing","DecorInfillDistance"),
			settings.get_double("Slicing","DecorInfillDistance"),
			settings.get_double("Slicing","DecorInfillRotation")/180.0*M_PI);

  assert(bridge_angles.size() >= bridgePolygons.size());
  bridgeInfills.resize(bridgePolygons.size());
  for (uint b=0; b < bridgePolygons.size(); b++){
    bridgeInfills[b] = new Infill(this, settings.get_double("Slicing","BridgeExtrusion"));
    bridgeInfills[b]->addPoly(Z, bridgePolygons[b], BridgeInfill,
			      fullInfillDistance, fullInfillDistance,
			      bridge_angles[b]+M_PI/2);
  }

  if (skins>1) {
    double skindistance = fullInfillDistance/skins;
    for (uint s = 0; s<skins; s++){
      double drot = rot + settings.get_double("Slicing","InfillRotationPrLayer")/180.0*M_PI*s;
      double sz = Z-thickness + (s+1)*thickness/skins;
      Infill *inf = new Infill(this, skinfillextrf);
      inf->setName("skin");
      inf->addPolys(sz, skinFullFillPolygons, (InfillType)settings.get_integer("Slicing","FullFilltype"),
		    skindistance, skindistance, drot);
      skinFullInfills.push_back(inf);
    }
  }
  supportInfill->addPolys(Z, supportPolygons,
			  (InfillType)settings.get_integer("Slicing","SupportFilltype"),
			  settings.get_double("Slicing","SupportInfillDistance"),
			  settings.get_double("Slicing","SupportInfillDistance"), 0);

  thinInfill->addPolys(Z, thinPolygons, ThinInfill,
		       fullInfillDistance, fullInfillDistance, 0);
}