⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_graphicview.cpp

📁 Linux下一个开源的CAD软件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 */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 + -