📄 rs_graphicview.cpp
字号:
*/void RS_GraphicView::setPenForEntity(RS_Entity* e) { if (drawingMode==RS2::ModePreview /*|| draftMode==true*/) { return; } // set color of entity if (painter!=NULL && !painter->isPreviewMode()) { // Getting pen from entity (or layer) RS_Pen pen = e->getPen(true); int w = pen.getWidth(); if (w<0) { w = 0; } // scale pen width: if (!draftMode) { double uf = 1.0; // unit factor double wf = 1.0; // width factor RS_Graphic* graphic = container->getGraphic(); if (graphic!=NULL) { uf = RS_Units::convert(1.0, RS2::Millimeter, graphic->getUnit()); if ((isPrinting() || isPrintPreview()) && graphic->getPaperScale()>1.0e-6) { wf = 1.0/graphic->getPaperScale(); } } pen.setScreenWidth(toGuiDX(w/100.0*uf*wf)); } else { //pen.setWidth(RS2::Width00); pen.setScreenWidth(0); } // prevent drawing with 1-width which is slow: if (RS_Math::round(pen.getScreenWidth())==1) { pen.setScreenWidth(0.0); } // prevent background color on background drawing: if (pen.getColor().stripFlags()==background.stripFlags()) { pen.setColor(foreground); } // this entity is selected: if (e->isSelected()) { pen.setLineType(RS2::DotLine); //pen.setColor(RS_Color(0xa5,0x47,0x47)); pen.setColor(selectedColor); } // this entity is highlighted: if (e->isHighlighted()) { //pen.setColor(RS_Color(0x73, 0x93, 0x73)); pen.setColor(highlightedColor); } // deleting not drawing: if (getDeleteMode()) { pen.setColor(background); } painter->setPen(pen); }}/** * Draws an entity. Might be recusively called e.g. for polylines. * If the class wide painter is NULL a new painter will be created * and destroyed afterwards. * * @param patternOffset Offset of line pattern (used for connected * lines e.g. in splines). * @param db Double buffering on (recommended) / off */void RS_GraphicView::drawEntity(RS_Entity* e, double patternOffset, bool db) { //RS_DEBUG->print("RS_GraphicView::drawEntity() begin"); // update is diabled: if (!isUpdateEnabled()) { return; } // given entity is NULL: if (e==NULL) { return; } // entity is not visible: if (!e->isVisible()) { return; } // test if the entity is in the viewport if (!e->isContainer() && !isPrinting() && (painter==NULL || !painter->isPreviewMode()) && (toGuiX(e->getMax().x)<0 || toGuiX(e->getMin().x)>getWidth() || toGuiY(e->getMin().y)<0 || toGuiY(e->getMax().y)>getHeight())) { return; } //drawRecursion++; //RS_DEBUG->print("recursion 1: %d", drawRecursion); // was the painter instance created by this call? bool painterCreated = false; // create a temporary painter device if (painter==NULL) { if (db) { createPainter(); } else { createDirectPainter(); } painterCreated = true; } // set pen (color): setPenForEntity(e); //RS_DEBUG->print("draw plain"); if (draftMode) { // large texts as rectangles: if (e->rtti()==RS2::EntityText) { if (toGuiDX(((RS_Text*)e)->getHeight())<4 || e->countDeep()>100) { painter->drawRect(toGui(e->getMin()), toGui(e->getMax())); } else { drawEntityPlain(e, patternOffset); } } // all images as rectangles: else if (e->rtti()==RS2::EntityImage) { painter->drawRect(toGui(e->getMin()), toGui(e->getMax())); } // hide hatches: else if (e->rtti()==RS2::EntityHatch) { // nothing } else { drawEntityPlain(e, patternOffset); } } else { drawEntityPlain(e, patternOffset); } // draw reference points: if (e->isSelected()) { if (!e->isParentSelected()) { RS_VectorSolutions s = e->getRefPoints(); for (int i=0; i<s.getNumber(); ++i) { int sz = -1; RS_Color col = RS_Color(0,0,255); if (e->rtti()==RS2::EntityPolyline) { if (i==0 || i==s.getNumber()-1) { if (i==0) { sz = 4; col = QColor(0,64,255); } else { sz = 3; col = QColor(0,0,128); } } } if (getDeleteMode()) { painter->drawHandle(toGui(s.get(i)), background, sz); } else { painter->drawHandle(toGui(s.get(i)), col, sz); } } } } //RS_DEBUG->print("draw plain OK"); if (painterCreated==true) { destroyPainter(); } //RS_DEBUG->print("RS_GraphicView::drawEntity() end");}/** * Deletes an entity with the background color. * Might be recusively called e.g. for polylines. */void RS_GraphicView::deleteEntity(RS_Entity* e) { setDeleteMode(true); drawEntity(e); setDeleteMode(false);}/** * Draws an entity. * The painter must be initialized and all the attributes (pen) must be set. */void RS_GraphicView::drawEntityPlain(RS_Entity* e, double patternOffset) { if (e==NULL) { return; } e->draw(painter, this, patternOffset);}/** * Simulates this drawing in slow motion. */void RS_GraphicView::simulateIt() { if (simulationRunning) { return; } simulationRunning = true; simulationLast = RS_Vector(0.0,0.0); destroyPainter(); createDirectPainter(); painter->erase(); // drawing paper border: if (isPrintPreview()) { drawPaper(); } // drawing meta grid: if (!isPrintPreview()) { drawMetaGrid(); } // drawing grid: if (!isPrintPreview()) { drawGrid(); } //if (draftMode) { //painter->setPen(RS_Pen(foreground, // RS2::Width00, RS2::SolidLine)); //} // drawing entities: RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine); simulateEntity(container, pen); //RS_DEBUG->timestamp(); //RS_DEBUG->print(" draw zero.."); // drawing zero points: if (!isPrintPreview()) { drawAbsoluteZero(); drawRelativeZero(); } //RS_DEBUG->timestamp(); //RS_DEBUG->print(" draw grid.."); //RS_DEBUG->timestamp(); //RS_DEBUG->print("RS_GraphicView::drawIt() end"); //if (painterCreated==true) { destroyPainter(); //} simulationRunning = false;}/** * Simulates the given entity. * * @param smooth If true, the entity will be drawn slowly (pixel by pixel). */void RS_GraphicView::simulateEntity(RS_Entity* e, const RS_Pen& pen) { if (painter==NULL || e==NULL) { return; } if (e->isContainer()) { RS_EntityContainer* ec = (RS_EntityContainer*)e; for (RS_Entity* en=ec->firstEntity(RS2::ResolveNone); en!=NULL; en = ec->nextEntity(RS2::ResolveNone)) { if (en->isVisible() && en->isUndone()==false) { // draw rapid move: if (en->isAtomic() && simulationRapid) { RS_Vector sp = ((RS_AtomicEntity*)en)->getStartpoint(); if (sp.distanceTo(simulationLast)>1.0e-4) { createDirectPainter(); RS_Pen rpen(RS_Color(0,0,255), RS2::Width00, RS2::SolidLine); //painter->setPen(pen); RS_Line rapidLine(NULL, RS_LineData(simulationLast, sp)); simulateEntity(&rapidLine, rpen); } } if (en->isHighlighted()) { RS_Pen hpen(highlightedColor, RS2::Width00, RS2::SolidLine); simulateEntity(en, hpen); } else { simulateEntity(en, pen); } if (en->isAtomic()) { simulationLast = ((RS_AtomicEntity*)en)->getEndpoint(); } if (!simulationSmooth) { simulationDelay(true); } } } } else { if (simulationSmooth) { switch (e->rtti()) { case RS2::EntityLine: { RS_Line* line = (RS_Line*)e; drawLineSmooth(toGui(line->getStartpoint()), toGui(line->getEndpoint()), pen); //simulationSpeed); } break; case RS2::EntityArc: { RS_Arc* arc = (RS_Arc*)e; drawArcSmooth(toGui(arc->getCenter()), toGuiDX(arc->getRadius()), arc->getAngle1(), arc->getAngle2(), arc->isReversed(), pen); } break; case RS2::EntityCircle: { RS_Circle* circle = (RS_Circle*)e; drawArcSmooth(toGui(circle->getCenter()), toGuiDX(circle->getRadius()), 0.0, 2.0*M_PI, false, pen); } break; default: break; } } else { createDirectPainter(); //RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine); painter->setPen(pen); drawEntityPlain(e); } }}/** * Delay for slow motion simulation. * * @param step true: stepping mode (entity by entity simulation). adds a delay. */void RS_GraphicView::simulationDelay(bool step) { int delay; RS_SETTINGS->beginGroup("/CAM"); double fact = (double)RS_SETTINGS->readNumEntry("/SimulationFactor", 12000); RS_SETTINGS->endGroup(); // simulationSpeed: 0..100#ifdef __APPLE__ delay = (int)(((1.0/(simulationSpeed+1.0)) * fact) - (fact/100.0)); if (step) { delay*=16; } //usleep(delay); static int call=0; if (call>=(fact-delay)/1000) { call=0; for (int i=0; i<delay; ++i) { RS_APP->processEvents(10); } } else { call++; }#else delay = (int)(((1.0/(simulationSpeed+1.0)) * fact) - (fact/100.0)); if (step) { delay*=16; } for (int i=0; i<delay; ++i) { RS_APP->processEvents(10); }#endif}/** * Draws a line slowly from (x1, y1) to (x2, y2). This is used for simulation only. */void RS_GraphicView::drawLineSmooth(const RS_Vector& p1, const RS_Vector& p2, const RS_Pen& pen) { double alpha = p1.angleTo(p2); double xStep, yStep; bool xIsOne; if (RS_Math::cmpDouble(alpha, 0.0) || RS_Math::cmpDouble(alpha, 2*M_PI)) { xStep = 1.0; yStep = 0.0; xIsOne=true; } else if (RS_Math::cmpDouble(alpha, M_PI/2.0)) { xStep = 0.0; yStep =1.0; xIsOne=false; } else if (RS_Math::cmpDouble(alpha, M_PI)) { xStep =-1.0; yStep = 0.0; xIsOne=true; } else if (RS_Math::cmpDouble(alpha, M_PI/2.0*3.0)) { xStep = 0.0; yStep =-1.0; xIsOne=false; } else if (fabs(p2.x-p1.x)>fabs(p2.y-p1.y)) { if (p2.x>p1.x) { xStep=1.0; } else { xStep=-1.0; } yStep = tan(alpha)*xStep; xIsOne=true; } else { if (p2.y>p1.y) { yStep=1.0; } else { yStep=-1.0; } xStep = yStep/tan(alpha); xIsOne=false; } double lx = p1.x; double ly = p1.y; //RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine); do { if (lx>=0.0 && lx<=(double)getWidth() && ly>=0.0 && ly<=(double)getHeight()) { //if (painter==NULL) { createDirectPainter(); //} painter->setPen(pen); painter->drawGridPoint(RS_Vector(lx, ly)); simulationDelay(); } lx+=xStep; ly+=yStep; } while( ( xIsOne && ((lx>=p1.x && lx<=p2.x) || (lx>=p2.x && lx<=p1.x))) || (!xIsOne && ((ly>=p1.y && ly<=p2.y) || (ly>=p2.y && ly<=p1.y))));}void RS_GraphicView::drawArcSmooth(const RS_Vector& center, double radius, double a1, double a2, bool rev, const RS_Pen& pen) { //int icx = graphic->realToScreenX(cx); //int icy = graphic->realToScreenY(cy); //RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine); if (radius<=1.4) { createDirectPainter(); painter->setPen(pen); painter->drawGridPoint(center); } else { int ix1 = RS_Math::round(center.x + cos(a1)*radius); int iy1 = RS_Math::round(center.y - sin(a1)*radius); int ix2 = RS_Math::round(center.x + cos(a2)*radius); int iy2 = RS_Math::round(center.y - sin(a2)*radius); int k2x=0; // Next point on circle int k2y=0; // int k1x=ix1; // Prev point on circle int k1y=iy1; // double aStep; // Angle Step (rad) double a; // Actual Angle (rad) double a2cp = a2; // Copy of a2 if (1.0/(radius*factor.x)<=1.0) { aStep=asin(1.0/(radius*factor.x)); } else { aStep = 0.01; } if (aStep<0.01) { aStep = 0.01; } if (!rev) { // Arc Counterclockwise: // if (a1>a2cp-0.01) { a2cp+=2*M_PI; } //if (painter==NULL) { //painter->setPen(pen); //createDirectPainter(); //} //painter->moveTo(ix1, iy1); for (a=a1+aStep; a<=a2cp; a+=aStep) { k2x = RS_Math::round(center.x+cos(a)*radius); k2y = RS_Math::round(center.y-sin(a)*radius); //if(graphic->isPointOnScreen(k2x, k2y) || // graphic->isPointOnScreen(k1x, k1y) ) { createDirectPainter(); painter->setPen(pen); if ((k2x>=0 && k2x<=painter->getWidth() && k2y>=0 && k2y<=painter->getHeight()) || (k1x>=0 && k1x<=painter->getWidth() && k1y>=0 && k1y<=painter->getHeight())) { //painter->lineTo(k2x, k2y); painter->drawLine(RS_Vector(k1x, k1y), RS_Vector(k2x, k2y)); simulationDelay(); //graphic->simulationDelay(); } //createDirectPainter(); //painter->setPen(pen); //painter->moveTo(k2x, k2y); k1x=k2x; k1y=k2y; } createDirectPainter(); painter->setPen(pen); painter->drawLine(RS_Vector(k2x, k2y), RS_Vector(ix2, iy2)); //painter->lineTo(ix2, iy2); } else { // Arc Clockwise: // if (a1<a2cp+0.01) { a2cp-=2*M_PI; } //createDirectPainter(); //painter->setPen(pen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -