// 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; }
// 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; }