PrintingPathContur::PrintingPathContur(Path *sourcePath, double boardXSize, double boardYSize, double nozzleDiameter) :PathContur(boardXSize, boardYSize, nozzleDiameter), mLast(0) { mWarnings = 0; if(sourcePath==0) return; Path *nextPath = sourcePath; while(nextPath) { GShape *next = nextPath->firstElement; while(next) { switch(next->type()) { case GSHAPE_LINE: { GLine *line = (GLine*)next; if(fabs(line->width-nozzleDiameter)<0.0001L) { addShape(new GLine(line->p1, line->p2, nozzleDiameter, true)); } else if(line->width>nozzleDiameter) { GPoint a = line->p2 - line->p1; a.vectorNormalize(); GPoint o = GPoint(a.y, -a.x); o *= nozzleDiameter; int c = line->width/2.0L/nozzleDiameter+1.0L; const double edge = (line->width-nozzleDiameter)/2.0L; for(int i=0; i<=c; i++) { GPoint s = a*edgeDelta(nozzleDiameter, line->width, o*i); if((o*i).vectorLength()<=edge) { addShape(new GLine(line->p1+o*i-s, line->p2+o*i+s, nozzleDiameter, true)); if(i!=0) addShape(new GLine(line->p1-o*i-s, line->p2-o*i+s, nozzleDiameter, true)); } else { o.vectorNormalize(); GPoint s = a*edgeDelta(nozzleDiameter, line->width, o*edge); addShape(new GLine(line->p1+o*edge-s, line->p2+o*edge+s, nozzleDiameter, true)); addShape(new GLine(line->p1-o*edge-s, line->p2-o*edge+s, nozzleDiameter, true)); break; } } } else { mWarnings = ERROR_DIAMETER; } break; } case GSHAPE_CIRCLE: { GCircle *circle = (GCircle*)next; if(circle->radius >= nozzleDiameter) { int c = circle->radius/nozzleDiameter; for(int i=0; i<=c; i++) { double r = circle->radius - nozzleDiameter/2.0L - i*nozzleDiameter; if(r >= nozzleDiameter/2.0L) { GCircle *result = new GCircle(circle->center, r, nozzleDiameter); result->outer = i==0; addShape(result); } else { GCircle *result = new GCircle(circle->center, nozzleDiameter/2.0L, nozzleDiameter); result->outer = i==0; addShape(result); break; } } } else { mWarnings = ERROR_DIAMETER; } break; } case GSHAPE_RECT: { GRect *rect = (GRect*)next; if(rect->width()>=nozzleDiameter && rect->height()>=nozzleDiameter) { int c = rect->height()/nozzleDiameter; GPoint pl(rect->topLeft.x+nozzleDiameter/2.0L, rect->bottomRight.y); GPoint pr(rect->bottomRight.x-nozzleDiameter/2.0L,rect->bottomRight.y); double y =pl.y; for(int i=0; i<=c; i++) { pr.y = pl.y = y + nozzleDiameter*i+nozzleDiameter/2.0L; if(pr.y<rect->topLeft.y-nozzleDiameter/2.0L) { addShape(new GLine(pl, pr, nozzleDiameter, true)); } else { pr.y = pl.y = rect->topLeft.y-nozzleDiameter/2.0L; addShape(new GLine(pl, pr, nozzleDiameter, true)); break; } } addShape(new GLine(GPoint(rect->topLeft.x+nozzleDiameter/2.0L, rect->topLeft.y-nozzleDiameter/2.0L), \ GPoint(rect->topLeft.x+nozzleDiameter/2.0L, rect->bottomRight.y+nozzleDiameter/2.0L), nozzleDiameter, true)); addShape(new GLine(GPoint(rect->bottomRight.x-nozzleDiameter/2.0L, rect->topLeft.y-nozzleDiameter/2.0L), \ GPoint(rect->bottomRight.x-nozzleDiameter/2.0L, rect->bottomRight.y+nozzleDiameter/2.0L), nozzleDiameter, true)); } else { mWarnings = ERROR_DIAMETER; } break; } } next = next->next; } nextPath = nextPath->next; } }