Beispiel #1
0
// split at length 0 < t < 1
uint Printlines::divideline(uint lineindex, const double t) 
{
  PLine *l = &lines[lineindex];
  Vector2d d = l->to - l->from;
  vector<Vector2d> points(1);
  points[0] = l->from + d * t * d.length();
  uint nlines = divideline(lineindex, points);
  delete l;
  return nlines;
}
Beispiel #2
0
// walk around holes
void Printlines::clipMovements(const vector<Poly> *polys, double maxerr) 
{
  if (polys==NULL) return;
  if (lines.size()==0) return;
  vector<PLine> newlines;
  for (guint i=0; i < lines.size(); i++) {
    if (lines[i].feedrate == 0) {
      int frompoly=-1, topoly=-1;
      for (uint p = 0; p < polys->size(); p++) {
	if (frompoly==-1 && (*polys)[p].vertexInside(lines[i].from))
	  frompoly=(int)p;
	if (topoly==-1 && (*polys)[p].vertexInside(lines[i].to))
	  topoly=(int)p;
	vector<Intersection> pinter = 
	  (*polys)[p].lineIntersections(lines[i].from,lines[i].to, maxerr);
	if (pinter.size() > 0) {
	  if (pinter.size()%2 == 0) { // holes
	    std::sort(pinter.begin(), pinter.end());
	    vector<Vector2d> path = 
	      (*polys)[p].getPathAround(pinter.front().p, pinter.back().p);
	    i += (divideline(i,path)); //if (i>0) i--; // test new lines again?
	  }
	}
      }
      if (0 && frompoly != -1 && topoly != -1 && frompoly != topoly) {
	cerr <<i << " : "<<frompoly << " p>> " << topoly << endl;	
	// vector<Intersection> frominter = 
	//   polys[frompoly].lineIntersections(lines[i].from,lines[i].to, maxerr);
	// vector<Intersection> tointer = 
	//   polys[topoly].lineIntersections(lines[i].from,lines[i].to, maxerr);
	// cerr << frominter.size() << " -- " << tointer.size() << endl;
	// vector<Vector2d> frompath = 
	//   polys[frompoly].getPathAround(lines[i].from, lines[i].to);
	// vector<Vector2d> topath = 
	//   polys[topoly].getPathAround(lines[i].from, lines[i].to);
	// cerr << frompath.size() << " -- " << topath.size() << endl;
	int fromind, toind;
	(*polys)[frompoly].nearestIndices((*polys)[topoly], fromind, toind);
	vector<Vector2d> path;
	//path.push_back(lines[i].from);
	path.push_back((*polys)[frompoly].vertices[fromind]);
	path.push_back((*polys)[topoly].vertices[toind]);
	//path.push_back(lines[i].to);
	//i+= (divideline(i,path)); // test new lines again?
      }
    }
  }
}
int Printlines::distribute_AntioozeAmount(double AOamount, double AOspeed,
					  uint fromline, uint &toline,
					  vector< PLine3 > &lines,
					  double &havedistributed)
{
  if (AOamount == 0) return 0;
  bool negative = (AOamount < 0);
  bool reverse  = (toline < fromline); // begin distribution at end of range

  // CASE 1: no lines to distribute the amount could be found
  // negative means retract which normally means reverse distribution
  // if this is not the case, no lines were found
  if (negative != reverse) {
    uint added = 0;
    uint at_line = fromline;
#if AODEBUG
    distCase = 1;
#endif
    if (!reverse) {  // retract case // add retracting halt _after_ fromline
#if AODEBUG
      distCase = -1;
#endif
      at_line++;
    }
    toline = at_line;
    //cerr << "halt at " << at_line <<" - " <<toline<< endl;
    added = insertAntioozeHaltBefore(at_line, AOamount, AOspeed, lines);
    if (added == 1) havedistributed += AOamount;
#if AODEBUG
    else cerr << "no AO on halt possible!" << endl;
#endif
    return added;
  }

#if AODEBUG
  assert(AOspeed > 0);
#endif
  double AOtime = abs(AOamount) / AOspeed; // time needed for AO on move
  // time all lines normally need:
  double linestime = Printlines::time(lines, fromline, toline);


  // CASE 2: simple case, fit AOamount exactly into whole range while slowing down:
  if (linestime > 0 && linestime <= AOtime) {
#if AODEBUG
    distCase = 2;
#endif
    for (uint i=fromline; i<=toline; i++) {
      const double time = lines[i].time();
      const double ratio = time / linestime;
      lines[i].addAbsoluteExtrusionAmount(AOamount * ratio, AOspeed, time);// will slow line down
#if AODEBUG
      havedistributed += AOamount * ratio;
#endif
    }
    return 0;
  }

#if AODEBUG
  distCase = 3;
#endif

  // CASE 3: distribute on the needed part of possible range
  // distribute in range fromline--toline
  int di = ( reverse ? -1 : 1);
  double restamount = AOamount;
  const double sign = (negative?-1.:1.);
  const double signedSpeed = AOspeed * sign;
  int i;
  int end = (int)toline+di;
  for (i = (int)fromline; i != end; i+=di) {
    if (i<0) break;
    double lineamount = lines[i].addMaxAbsoluteExtrusionAmount(signedSpeed); // +-
    havedistributed += lineamount;
    restamount -= lineamount;
    if (restamount * sign < 0)
      break;
  }
  // restamount is negative -> done too much
  lines[i].absolute_extrusion += restamount;
  havedistributed += restamount;
  uint added = 0;
  // now split last line (i)
#if 1
  const double line_ex = lines[i].absolute_extrusion;
  const double neededtime = abs(line_ex / AOspeed);
  double fraction = neededtime/lines[i].time();
  if (fraction < 0.9) { // allow 10% slower AO to avoid split
    if (reverse) fraction = 1-fraction;
    added = divideline(i, fraction * lines[i].length(), lines);
    if (added == 1) {
      if (reverse) {
	lines[i].absolute_extrusion   = 0;
	lines[i+1].absolute_extrusion = line_ex;
      } else {
	lines[i].absolute_extrusion   = line_ex;
	lines[i+1].absolute_extrusion = 0;
      }
    }
  }
#endif
  toline = i + added;
  //  cerr << "rest " << AOamount - havedistributed << endl;
  return added;
}