Пример #1
0
void RS_ActionDrawArc3P::trigger() {
    RS_PreviewActionInterface::trigger();

    preparePreview();
    if (data.isValid()) {
        RS_Arc* arc = new RS_Arc(container,
                                 data);
        arc->setLayerToActive();
        arc->setPenToActive();
        container->addEntity(arc);

        // upd. undo list:
        if (document!=NULL) {
            document->startUndoCycle();
            document->addUndoable(arc);
            document->endUndoCycle();
        }

        deleteSnapper();
        graphicView->moveRelativeZero(RS_Vector(0.0,0.0));
        graphicView->drawEntity(arc);
        graphicView->moveRelativeZero(arc->getEndpoint());
        drawSnapper();

        setStatus(SetPoint1);
        reset();
    } else {
        //RS_DIALOGFACTORY->requestWarningDialog(tr("Invalid arc data."));
        RS_DIALOGFACTORY->commandMessage(tr("Invalid arc data."));
    }
}
void RS_ActionDrawArcTangential::trigger() {
    RS_PreviewActionInterface::trigger();

    if (point.valid==false || baseEntity==NULL) {
        RS_DEBUG->print("RS_ActionDrawArcTangential::trigger: "
                        "conditions not met");
        return;
    }

    preparePreview();
	RS_Arc* arc = new RS_Arc(container, *data);
    arc->setLayerToActive();
    arc->setPenToActive();
    container->addEntity(arc);

    // upd. undo list:
    if (document!=NULL) {
        document->startUndoCycle();
        document->addUndoable(arc);
        document->endUndoCycle();
    }

    graphicView->redraw(RS2::RedrawDrawing);
    graphicView->moveRelativeZero(arc->getCenter());

    setStatus(SetBaseEntity);
    reset();
}
/**
 * Helper function for makeContour
 * Modify newEntity to parellel of orgEntity at distance dist
 * If dist is positive the offset is in left else in right
 * Bot newEntity and orgEntity are the same type of entity
 * if not return NULL pointer
 *
 * @retval RS_Entity* of parellel entity
 *
 * @author Rallaz
 */
RS_Entity* RS_ActionPolylineEquidistant::calculateOffset(RS_Entity* newEntity,RS_Entity* orgEntity, double dist) {
    if (orgEntity->rtti()==RS2::EntityArc && newEntity->rtti()==RS2::EntityArc) {
        RS_Arc* arc = (RS_Arc*)newEntity;
        double r0 = ((RS_Arc*)orgEntity)->getRadius();
        double r;
        if ( ((RS_Arc*)orgEntity)->isReversed())
            r = r0 + dist;
        else
            r = r0 - dist;
        if(r < 0)
            return NULL;
        arc->setData(((RS_Arc*)orgEntity)->getData());
        arc->setRadius(r);
        arc->calculateEndpoints();
        return newEntity;
    } else if (orgEntity->rtti()==RS2::EntityLine && newEntity->rtti()==RS2::EntityLine) {
        RS_Line* line0 = (RS_Line*)orgEntity;
        RS_Line* line1 = (RS_Line*)newEntity;
        RS_Vector v0 = line0->getStartpoint();
        RS_Vector v1(v0.x,v0.y+dist);
        RS_Vector v2(v0.x+line0->getLength(),v0.y+dist);
        line1->setStartpoint(v1);
        line1->setEndpoint(v2);
        line1->rotate(v0, line0->getAngle1());
        return newEntity;
    }
    return NULL;
}
Пример #4
0
void RS_ActionDrawArc::trigger() {
    RS_PreviewActionInterface::trigger();

    RS_Arc* arc = new RS_Arc(container,
                             data);
    arc->setLayerToActive();
    arc->setPenToActive();
    container->addEntity(arc);

    // upd. undo list:
    if (document!=NULL) {
        document->startUndoCycle();
        document->addUndoable(arc);
        document->endUndoCycle();
    }

        graphicView->redraw(RS2::RedrawDrawing);
    graphicView->moveRelativeZero(arc->getCenter());

    setStatus(SetCenter);
    reset();

    RS_DEBUG->print("RS_ActionDrawArc::trigger(): arc added: %d",
                    arc->getId());
}
Пример #5
0
void RS_ActionDimDiametric::preparePreview() {
    if (entity) {
		double radius{0.};
		RS_Vector center{false};
        if (entity->rtti()==RS2::EntityArc) {
			RS_Arc* p = static_cast<RS_Arc*>(entity);
			radius = p->getRadius();
			center = p->getCenter();
        } else if (entity->rtti()==RS2::EntityCircle) {
			RS_Circle* p = static_cast<RS_Circle*>(entity);
			radius = p->getRadius();
			center = p->getCenter();
        }
		double angle = center.angleTo(*pos);

		data->definitionPoint.setPolar(radius, angle + M_PI);
		data->definitionPoint += center;

		edata->definitionPoint.setPolar(radius, angle);
		edata->definitionPoint += center;
    }
}
Пример #6
0
void DL_Jww::CreateEnko(DL_CreationInterface* creationInterface, CDataEnko& DEnko)
{
	string lName = HEX[DEnko.m_nGLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DEnko.m_nGLayer] + "-" +
													HEX[DEnko.m_nLayer > ArraySize(HEX)-1 ? ArraySize(HEX)-1: DEnko.m_nLayer];

	// add layer
	creationInterface->addLayer(DL_LayerData(lName,0));

	int width;
	if(DEnko.m_nPenWidth > 26)
		width = 0;
	else
		width = DEnko.m_nPenWidth;
	int color = colTable[DEnko.m_nPenColor > ArraySize(colTable)-1 ? ArraySize(colTable)-1 : DEnko.m_nPenColor];
	attrib = DL_Attributes(values[8],	  // layer
			       color,	      // color
			       width,	      // width
			       lTable[DEnko.m_nPenStyle > ArraySize(lTable)-1 ? ArraySize(lTable)-1 : DEnko.m_nPenStyle]);	  // linetype
	creationInterface->setAttributes(attrib);

	creationInterface->setExtrusion(0.0, 0.0, 1.0, 0.0 );

	double angle1, angle2;
	//正円
	if(DEnko.m_bZenEnFlg){
		if(DEnko.m_dHenpeiRitsu == 1.0){
			DL_CircleData d(DEnko.m_start.x, DEnko.m_start.y, 0.0, DEnko.m_dHankei);
			creationInterface->addCircle(d);
		}else{
			double angle1, angle2;
			if(DEnko.m_radEnkoKaku > 0.0){
				angle1 = DEnko.m_radKaishiKaku;
				angle2 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku;
			}else{
				angle1 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku;
				angle2 = DEnko.m_radKaishiKaku;
			}
			angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0;
			angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0;
			if( angle2 <= angle1 )
				angle1 = angle1 - M_PI * 2.0;
			//楕円
			DL_EllipseData d(DEnko.m_start.x, DEnko.m_start.y, 0.0,
							DEnko.m_dHankei * cos(DEnko.m_radKatamukiKaku), DEnko.m_dHankei * sin(DEnko.m_radKatamukiKaku), 0.0,
							DEnko.m_dHenpeiRitsu,
							angle1, angle2);

			creationInterface->addEllipse(d);
		}
	}else{
		if(DEnko.m_dHenpeiRitsu == 1.0){
			//円弧
			if(DEnko.m_radEnkoKaku > 0.0){
				angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku;
				angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku;
			}else{
				angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku;
				angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku;
			}
			angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0;
			angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0;
			if( angle2 <= angle1 )
				angle1 = angle1 - M_PI * 2.0;
			DL_ArcData d(DEnko.m_start.x, DEnko.m_start.y, 0.0,
					DEnko.m_dHankei,
					Deg(angle1),
					Deg(angle2));

			creationInterface->addArc(d);
		}else{
			double angle1, angle2;
			if(DEnko.m_radEnkoKaku > 0.0){
				angle1 = DEnko.m_radKaishiKaku;
				angle2 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku;
			}else{
				angle1 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku;
				angle2 = DEnko.m_radKaishiKaku;
			}
			angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0;
			angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0;
			if( angle2 <= angle1 )
				angle1 = angle1 - M_PI * 2.0;
			//楕円
			DL_EllipseData d(DEnko.m_start.x, DEnko.m_start.y, 0.0,
							DEnko.m_dHankei * cos(DEnko.m_radKatamukiKaku), DEnko.m_dHankei * sin(DEnko.m_radKatamukiKaku), 0.0,
							DEnko.m_dHenpeiRitsu,
							angle1, angle2);

			creationInterface->addEllipse(d);
		}
	}
#ifdef FINISHED
	RS_CircleData data1(RS_Vector(0.0, 0.0), 0.0);
	RS_Circle* circle;
	RS_ArcData arc_data(RS_Vector(0.0, 0.0), 0.0, 0.0, 0.0, false);
	RS_Arc* arc;
	RS_Ellipse* elps;
	//正円
	if(DEnko.m_bZenEnFlg){
		if(DEnko.m_dHenpeiRitsu == 1.0){
			data1.center = RS_Vector(DEnko.m_start.x, DEnko.m_start.y);
			data1.radius = DEnko.m_dHankei;
			circle = new RS_Circle(graphic, data1);
			RS2::LineType ltype = lTable[DEnko.m_nPenStyle];
			RS_Color col = colTable[DEnko.m_nPenColor];
			RS2::LineWidth lw = lWidth[DEnko.m_nPenWidth > 26 ? 0 : DEnko.m_nPenWidth];//RS2::Width12
			circle->setPen(RS_Pen(col, lw, ltype));

			RS_String lName = HEX[DEnko.m_nGLayer > 0x0f ? 0:DEnko.m_nGLayer] + "-" +
				HEX[DEnko.m_nLayer > 0x0f ? 0: DEnko.m_nLayer];
			if( graphic->findLayer(lName) == (RS_Layer*)NULL ){
#ifdef DEBUG
std::cout << lName.ascii() << std::endl;
#endif
				RS_Layer* layer = new RS_Layer(lName);
				graphic->addLayer(layer);
			}
			circle->setLayer(lName);
			// add the line to the graphic
			graphic->addEntity(circle);
#ifdef DEBUG
std::cout << *circle;
#endif
		}else{
			//楕円
			double angle1, angle2;
			if(DEnko.m_radEnkoKaku > 0.0){
				angle1 = DEnko.m_radKaishiKaku;
				angle2 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku;
			}else{
				angle1 = DEnko.m_radKaishiKaku + DEnko.m_radEnkoKaku;
				angle2 = DEnko.m_radKaishiKaku;
			}
			angle1 = angle1 - floor(angle1 / (M_PI * 2.0)) * M_PI * 2.0;
			angle2 = angle2 - floor(angle2 / (M_PI * 2.0)) * M_PI * 2.0;
			if( angle2 <= angle1 )
				angle1 = angle1 - M_PI * 2.0;
			RS_EllipseData elps_data(RS_Vector(DEnko.m_start.x, DEnko.m_start.y),
									RS_Vector(DEnko.m_dHankei * cos(DEnko.m_radKatamukiKaku), DEnko.m_dHankei * sin(DEnko.m_radKatamukiKaku)),
									DEnko.m_dHenpeiRitsu,
									angle1, angle2, false);
			elps = new RS_Ellipse(graphic, elps_data);
			RS2::LineType ltype = lTable[DEnko.m_nPenStyle];
			RS_Color col = colTable[DEnko.m_nPenColor];
			RS2::LineWidth lw = lWidth[DEnko.m_nPenWidth > 26 ? 0 : DEnko.m_nPenWidth];//RS2::Width12
			elps->setPen(RS_Pen(col, lw, ltype));

			RS_String lName = HEX[DEnko.m_nGLayer > 0x0f ? 0:DEnko.m_nGLayer] + "-" +
				HEX[DEnko.m_nLayer > 0x0f ? 0: DEnko.m_nLayer];
			if( graphic->findLayer(lName) == (RS_Layer*)NULL ){
				RS_Layer* layer = new RS_Layer(lName);
				graphic->addLayer(layer);
			}
			elps->setLayer(lName);
			// add the line to the graphic
			graphic->addEntity(elps);
		}
	}else{
		//円弧
		arc_data.center = RS_Vector(DEnko.m_start.x, DEnko.m_start.y);
		arc_data.radius = DEnko.m_dHankei;
		if(DEnko.m_radEnkoKaku > 0.0){
			arc_data.angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku;
			arc_data.angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku;
		}else{
			arc_data.angle1 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku + DEnko.m_radEnkoKaku;
			arc_data.angle2 = DEnko.m_radKaishiKaku + DEnko.m_radKatamukiKaku;
		}
		if( arc_data.angle2 <= arc_data.angle1 )
			arc_data.angle1 = arc_data.angle1 - M_PI * 2.0;
		arc_data.angle1 = Deg(arc_data.angle1);
		arc_data.angle2 = Deg(arc_data.angle2);
		arc_data.reversed = false;
		arc = new RS_Arc(graphic, arc_data);
		RS2::LineType ltype = lTable[DEnko.m_nPenStyle];
		RS_Color col = colTable[DEnko.m_nPenColor];
		RS2::LineWidth lw = lWidth[DEnko.m_nPenWidth > 26 ? 0 : DEnko.m_nPenWidth];//RS2::Width12
		arc->setPen(RS_Pen(col, lw, ltype));

		RS_String lName = HEX[DEnko.m_nGLayer > 0x0f ? 0:DEnko.m_nGLayer] + "-" +
			HEX[DEnko.m_nLayer > 0x0f ? 0: DEnko.m_nLayer];
		if( graphic->findLayer(lName) == (RS_Layer*)NULL ){
#ifdef DEBUG
std::cout << lName.ascii() << std::endl;
#endif
			RS_Layer* layer = new RS_Layer(lName);
			graphic->addLayer(layer);
		}
		arc->setLayer(lName);
		// add the line to the graphic
		graphic->addEntity(arc);
	}
#endif
}
Пример #7
0
/**
 * Checks if the given coordinate is inside the given contour.
 *
 * @param point Coordinate to check.
 * @param contour One or more entities which shape a contour.
 *         If the given contour is not closed, the result is undefined.
 *         The entities don't need to be in a specific order.
 * @param onContour Will be set to true if the given point it exactly
 *         on the contour.
 */
bool RS_Information::isPointInsideContour(const RS_Vector& point,
        RS_EntityContainer* contour, bool* onContour) {

    if (contour==NULL) {
        RS_DEBUG->print(RS_Debug::D_WARNING,
                        "RS_Information::isPointInsideContour: contour is NULL");
        return false;
    }

    if (point.x < contour->getMin().x || point.x > contour->getMax().x ||
            point.y < contour->getMin().y || point.y > contour->getMax().y) {
        return false;
    }

    double width = contour->getSize().x+1.0;

    bool sure;
    int counter;
    int tries = 0;
    double rayAngle = 0.0;
    do {
        sure = true;

        // create ray:
        RS_Vector v;
        v.setPolar(width*10.0, rayAngle);
        RS_Line ray(NULL, RS_LineData(point, point+v));
        counter = 0;
        RS_VectorSolutions sol;

        if (onContour!=NULL) {
            *onContour = false;
        }

        for (RS_Entity* e = contour->firstEntity(RS2::ResolveAll);
                e!=NULL;
                e = contour->nextEntity(RS2::ResolveAll)) {

            // intersection(s) from ray with contour entity:
            sol = RS_Information::getIntersection(&ray, e, true);

            for (int i=0; i<=1; ++i) {
                RS_Vector p = sol.get(i);

                if (p.valid) {
                    // point is on the contour itself
                    if (p.distanceTo(point)<1.0e-5) {
                        if (onContour!=NULL) {
                            *onContour = true;
                        }
                    } else {
                        if (e->rtti()==RS2::EntityLine) {
                            RS_Line* line = (RS_Line*)e;

                            // ray goes through startpoint of line:
                            if (p.distanceTo(line->getStartpoint())<1.0e-4) {
                                if (RS_Math::correctAngle(line->getAngle1())<M_PI) {
                                    counter++;
                                    sure = false;
                                }
                            }

                            // ray goes through endpoint of line:
                            else if (p.distanceTo(line->getEndpoint())<1.0e-4) {
                                if (RS_Math::correctAngle(line->getAngle2())<M_PI) {
                                    counter++;
                                    sure = false;
                                }
                            }
                            // ray goes through the line:


                            else {
                                counter++;
                            }
                        } else if (e->rtti()==RS2::EntityArc) {
                            RS_Arc* arc = (RS_Arc*)e;

                            if (p.distanceTo(arc->getStartpoint())<1.0e-4) {
                                double dir = arc->getDirection1();
                                if ((dir<M_PI && dir>=1.0e-5) ||
                                        ((dir>2*M_PI-1.0e-5 || dir<1.0e-5) &&
                                         arc->getCenter().y>p.y)) {
                                    counter++;
                                    sure = false;
                                }
                            }
                            else if (p.distanceTo(arc->getEndpoint())<1.0e-4) {
                                double dir = arc->getDirection2();
                                if ((dir<M_PI && dir>=1.0e-5) ||
                                        ((dir>2*M_PI-1.0e-5 || dir<1.0e-5) &&
                                         arc->getCenter().y>p.y)) {
                                    counter++;
                                    sure = false;
                                }
                            } else {
                                counter++;
                            }
                        } else if (e->rtti()==RS2::EntityCircle) {
                            // tangent:
                            if (i==0 && sol.get(1).valid==false) {
                                if (!sol.isTangent()) {
                                    counter++;
                                } else {
                                    sure = false;
                                }
                            } else if (i==1 || sol.get(1).valid==true) {
                                counter++;
                            }
                        }
                    }
                }
            }
        }

        rayAngle+=0.02;
        tries++;
    }
    while (!sure && rayAngle<2*M_PI && tries<6);

    // remove double intersections:
    /*
       QList<RS_Vector> is2;
       bool done;
    RS_Vector* av;
       do {
           done = true;
           double minDist = RS_MAXDOUBLE;
           double dist;
    	av = NULL;
           for (RS_Vector* v = is.first(); v!=NULL; v = is.next()) {
               dist = point.distanceTo(*v);
               if (dist<minDist) {
                   minDist = dist;
                   done = false;
    			av = v;
               }
           }

    	if (!done && av!=NULL) {
    		is2.append(*av);
    	}
       } while (!done);
    */

    return ((counter%2)==1);
}
Пример #8
0
/**
 * Updates the Hatch. Called when the
 * hatch or it's data, position, alignment, .. changes.
 */
void RS_Hatch::update() {
        RS_DEBUG->print("RS_Hatch::update");
        RS_DEBUG->print("RS_Hatch::update: contour has %d loops", count());

    updateError = HATCH_OK;
    if (updateRunning) {
        return;
    }

    if (updateEnabled==false) {
        return;
    }

    if (data.solid==true) {
        calculateBorders();
        return;
    }

    RS_DEBUG->print("RS_Hatch::update");
    updateRunning = true;

    // delete old hatch:
    if (hatch) {
        removeEntity(hatch);
		hatch = nullptr;
    }

    if (isUndone()) {
        updateRunning = false;
        return;
    }

    if (!validate()) {
        RS_DEBUG->print(RS_Debug::D_WARNING,
                        "RS_Hatch::update: invalid contour in hatch found");
        updateRunning = false;
        updateError = HATCH_INVALID_CONTOUR;
        return;
    }

    // search pattern:
    RS_DEBUG->print("RS_Hatch::update: requesting pattern");
    RS_Pattern* pat = RS_PATTERNLIST->requestPattern(data.pattern);
	if (!pat) {
        updateRunning = false;
        RS_DEBUG->print("RS_Hatch::update: requesting pattern: not found");
        updateError = HATCH_PATTERN_NOT_FOUND;
        return;
    }
    RS_DEBUG->print("RS_Hatch::update: requesting pattern: OK");

    RS_DEBUG->print("RS_Hatch::update: cloning pattern");
    pat = (RS_Pattern*)pat->clone();
    RS_DEBUG->print("RS_Hatch::update: cloning pattern: OK");

    // scale pattern
    RS_DEBUG->print("RS_Hatch::update: scaling pattern");
    pat->scale(RS_Vector(0.0,0.0), RS_Vector(data.scale, data.scale));
    pat->calculateBorders();
    forcedCalculateBorders();
    RS_DEBUG->print("RS_Hatch::update: scaling pattern: OK");

    // find out how many pattern-instances we need in x/y:
    int px1, py1, px2, py2;
    double f;
    RS_Hatch* copy = (RS_Hatch*)this->clone();
    copy->rotate(RS_Vector(0.0,0.0), -data.angle);
    copy->forcedCalculateBorders();

    // create a pattern over the whole contour.
    RS_Vector pSize = pat->getSize();
    RS_Vector rot_center=pat->getMin();
//    RS_Vector cPos = getMin();
    RS_Vector cSize = getSize();


    RS_DEBUG->print("RS_Hatch::update: pattern size: %f/%f", pSize.x, pSize.y);
    RS_DEBUG->print("RS_Hatch::update: contour size: %f/%f", cSize.x, cSize.y);

    if (cSize.x<1.0e-6 || cSize.y<1.0e-6 ||
            pSize.x<1.0e-6 || pSize.y<1.0e-6 ||
            cSize.x>RS_MAXDOUBLE-1 || cSize.y>RS_MAXDOUBLE-1 ||
            pSize.x>RS_MAXDOUBLE-1 || pSize.y>RS_MAXDOUBLE-1) {
        delete pat;
        delete copy;
        updateRunning = false;
        RS_DEBUG->print("RS_Hatch::update: contour size or pattern size too small");
        updateError = HATCH_TOO_SMALL;
        return;
    }

    // avoid huge memory consumption:
    else if ( cSize.x* cSize.y/(pSize.x*pSize.y)>1e4) {
        RS_DEBUG->print("RS_Hatch::update: contour size too large or pattern size too small");
        delete pat;
        delete copy;
        updateError = HATCH_AREA_TOO_BIG;
        return;
    }

    f = copy->getMin().x/pSize.x;
    px1 = (int)floor(f);
    f = copy->getMin().y/pSize.y;
    py1 = (int)floor(f);
    f = copy->getMax().x/pSize.x;
    px2 = (int)ceil(f);
    f = copy->getMax().y/pSize.y;
    py2 = (int)ceil(f);
    RS_Vector dvx=RS_Vector(data.angle)*pSize.x;
    RS_Vector dvy=RS_Vector(data.angle+M_PI*0.5)*pSize.y;
    pat->rotate(rot_center, data.angle);
    pat->move(-rot_center);


    RS_EntityContainer tmp;   // container for untrimmed lines

    // adding array of patterns to tmp:
    RS_DEBUG->print("RS_Hatch::update: creating pattern carpet");

    for (int px=px1; px<px2; px++) {
		for (int py=py1; py<py2; py++) {
			for(auto e: *pat){
                RS_Entity* te=e->clone();
                te->move(dvx*px + dvy*py);
                tmp.addEntity(te);
            }
        }
    }

    delete pat;
    pat = nullptr;
    delete copy;
    copy = nullptr;
    RS_DEBUG->print("RS_Hatch::update: creating pattern carpet: OK");


    RS_DEBUG->print("RS_Hatch::update: cutting pattern carpet");
    // cut pattern to contour shape:
    RS_EntityContainer tmp2;   // container for small cut lines
	RS_Line* line = nullptr;
	RS_Arc* arc = nullptr;
	RS_Circle* circle = nullptr;
	RS_Ellipse* ellipse = nullptr;
	for(auto e: tmp){

		line = nullptr;
		arc = nullptr;
		circle = nullptr;
		ellipse = nullptr;

        RS_Vector startPoint;
        RS_Vector endPoint;
        RS_Vector center = RS_Vector(false);
        bool reversed=false;

        switch(e->rtti()){
        case RS2::EntityLine:
            line=static_cast<RS_Line*>(e);
            startPoint = line->getStartpoint();
            endPoint = line->getEndpoint();
            break;
        case RS2::EntityArc:
            arc=static_cast<RS_Arc*>(e);
            startPoint = arc->getStartpoint();
            endPoint = arc->getEndpoint();
            center = arc->getCenter();
            reversed = arc->isReversed();
            break;
        case RS2::EntityCircle:
            circle=static_cast<RS_Circle*>(e);
            startPoint = circle->getCenter()
                    + RS_Vector(circle->getRadius(), 0.0);
            endPoint = startPoint;
            center = circle->getCenter();
            break;
        case RS2::EntityEllipse:
            ellipse = static_cast<RS_Ellipse*>(e);
            startPoint = ellipse->getStartpoint();
            endPoint = ellipse->getEndpoint();
            center = ellipse->getCenter();
            reversed = ellipse->isReversed();
            break;
        default:
            continue;
        }

        // getting all intersections of this pattern line with the contour:
        QList<std::shared_ptr<RS_Vector> > is;

		for(auto loop: entities){

            if (loop->isContainer()) {
				for(auto p: * static_cast<RS_EntityContainer*>(loop)){

                    RS_VectorSolutions sol =
                        RS_Information::getIntersection(e, p, true);

					for (const RS_Vector& vp: sol){
						if (vp.valid) {
							is.append(std::shared_ptr<RS_Vector>(
										  new RS_Vector(vp)
										  ));
							RS_DEBUG->print("  pattern line intersection: %f/%f",
											vp.x, vp.y);
						}
					}
				}
			}
		}


        QList<std::shared_ptr<RS_Vector> > is2;//to be filled with sorted intersections
        is2.append(std::shared_ptr<RS_Vector>(new RS_Vector(startPoint)));

        // sort the intersection points into is2 (only if there are intersections):
        if(is.size() == 1)
        {//only one intersection
            is2.append(is.first());
        }
        else if(is.size() > 1)
        {
            RS_Vector sp = startPoint;
            double sa = center.angleTo(sp);
			if(ellipse ) sa=ellipse->getEllipseAngle(sp);
            bool done;
            double minDist;
            double dist = 0.0;
            std::shared_ptr<RS_Vector> av;
            std::shared_ptr<RS_Vector> v;
            RS_Vector last = RS_Vector(false);
            do {
                done = true;
                minDist = RS_MAXDOUBLE;
                av.reset();
                for (int i = 0; i < is.size(); ++i) {
                    v = is.at(i);
                    double a;
                    switch(e->rtti()){
                    case RS2::EntityLine:
                        dist = sp.distanceTo(*v);
                        break;
                    case RS2::EntityArc:
                    case RS2::EntityCircle:
                        a = center.angleTo(*v);
                        dist = reversed?
                                    fmod(sa - a + 2.*M_PI,2.*M_PI):
                                    fmod(a - sa + 2.*M_PI,2.*M_PI);
                        break;
                    case RS2::EntityEllipse:
                        a = ellipse->getEllipseAngle(*v);
                        dist = reversed?
                                    fmod(sa - a + 2.*M_PI,2.*M_PI):
                                    fmod(a - sa + 2.*M_PI,2.*M_PI);
                        break;
                    default:
                        break;

                    }

                    if (dist<minDist) {
                        minDist = dist;
                        done = false;
                        av = v;
                    }
                }

                // copy to sorted list, removing double points
                if (!done && av.get()) {
                    if (last.valid==false || last.distanceTo(*av)>RS_TOLERANCE) {
                        is2.append(std::shared_ptr<RS_Vector>(new RS_Vector(*av)));
                        last = *av;
                    }
#if QT_VERSION < 0x040400
                    emu_qt44_removeOne(is, av);
#else
                    is.removeOne(av);
#endif

                    av.reset();
                }
            } while(!done);
        }

is2.append(std::shared_ptr<RS_Vector>(new RS_Vector(endPoint)));

        // add small cut lines / arcs to tmp2:
            for (int i = 1; i < is2.size(); ++i) {
                auto v1 = is2.at(i-1);
                auto v2 = is2.at(i);


                if (line) {

					tmp2.addEntity(new RS_Line{&tmp2, *v1, *v2});
                } else if (arc || circle) {
                    if(fabs(center.angleTo(*v2)-center.angleTo(*v1)) > RS_TOLERANCE_ANGLE)
                    {//don't create an arc with a too small angle
                        tmp2.addEntity(new RS_Arc(&tmp2,
                                                  RS_ArcData(center,
                                                             center.distanceTo(*v1),
                                                             center.angleTo(*v1),
                                                             center.angleTo(*v2),
                                                             reversed)));
                    }

                }
            }

    }

    // updating hatch / adding entities that are inside
    RS_DEBUG->print("RS_Hatch::update: cutting pattern carpet: OK");

    //RS_EntityContainer* rubbish = new RS_EntityContainer(getGraphic());

    // the hatch pattern entities:
    hatch = new RS_EntityContainer(this);
    hatch->setPen(RS_Pen(RS2::FlagInvalid));
	hatch->setLayer(nullptr);
    hatch->setFlag(RS2::FlagTemp);

    //calculateBorders();

	for(auto e: tmp2){

        RS_Vector middlePoint;
        RS_Vector middlePoint2;
        if (e->rtti()==RS2::EntityLine) {
			RS_Line* line = static_cast<RS_Line*>(e);
            middlePoint = line->getMiddlePoint();
            middlePoint2 = line->getNearestDist(line->getLength()/2.1,
                                                line->getStartpoint());
        } else if (e->rtti()==RS2::EntityArc) {
			RS_Arc* arc = static_cast<RS_Arc*>(e);
            middlePoint = arc->getMiddlePoint();
            middlePoint2 = arc->getNearestDist(arc->getLength()/2.1,
                                               arc->getStartpoint());
        } else {
			middlePoint = RS_Vector{false};
			middlePoint2 = RS_Vector{false};
        }

        if (middlePoint.valid) {
            bool onContour=false;

            if (RS_Information::isPointInsideContour(
                        middlePoint,
                        this, &onContour) ||
                    RS_Information::isPointInsideContour(middlePoint2, this)) {

                RS_Entity* te = e->clone();
				te->setPen(RS2::FlagInvalid);
				te->setLayer(nullptr);
                te->reparent(hatch);
                hatch->addEntity(te);
            }
        }
    }

    addEntity(hatch);
    //getGraphic()->addEntity(rubbish);

    forcedCalculateBorders();

    // deactivate contour:
    activateContour(false);

    updateRunning = false;

    RS_DEBUG->print("RS_Hatch::update: OK");
}
Пример #9
0
/**
 * Updates the sub entities of this dimension. Called when the
 * dimension or the position, alignment, .. changes.
 *
 * @param autoText Automatically reposition the text label
 */
void RS_DimAngular::update(bool /*autoText*/) {

    RS_DEBUG->print("RS_DimAngular::update");

    clear();

        if (isUndone()) {
                return;
        }

    // distance from entities (DIMEXO)
    double dimexo = getExtensionLineOffset();
    // extension line extension (DIMEXE)
    double dimexe = getExtensionLineExtension();
    // text height (DIMTXT)
    double dimtxt = getTextHeight();
    // text distance to line (DIMGAP)
    double dimgap = getDimensionLineGap();

    // find out center:
    RS_Vector center = getCenter();

    if (!center.valid) {
        return;
    }

    double ang1 = 0.0;
    double ang2 = 0.0;
    bool reversed = false;
    RS_Vector p1;
    RS_Vector p2;

    getAngles(ang1, ang2, reversed, p1, p2);

    double rad = edata.definitionPoint4.distanceTo(center);

    RS_Line* line;
    RS_Vector dir;
    double len;
    double dist;

    // 1st extension line:
    dist = center.distanceTo(p1);
    len = rad - dist + dimexe;
    dir.setPolar(1.0, ang1);
    line = new RS_Line(this,
                       RS_LineData(center + dir*dist + dir*dimexo,
                                   center + dir*dist + dir*len));
    line->setPen(RS_Pen(RS2::FlagInvalid));
    line->setLayer(NULL);
    addEntity(line);

    // 2nd extension line:
    dist = center.distanceTo(p2);
    len = rad - dist + dimexe;
    dir.setPolar(1.0, ang2);
    line = new RS_Line(this,
                       RS_LineData(center + dir*dist + dir*dimexo,
                                   center + dir*dist + dir*len));
    line->setPen(RS_Pen(RS2::FlagInvalid));
    line->setLayer(NULL);
    addEntity(line);

    // Create dimension line (arc):
    RS_Arc* arc = new RS_Arc(this,
                             RS_ArcData(center,
                                        rad, ang1, ang2, reversed));
    arc->setPen(RS_Pen(RS2::FlagInvalid));
    arc->setLayer(NULL);
    addEntity(arc);

    // length of dimension arc:
    double distance = arc->getLength();

    // do we have to put the arrows outside of the arc?
    bool outsideArrows = (distance<getArrowSize()*2);

    // arrow angles:
    double arrowAngle1, arrowAngle2;
    double arrowAng;
        if (rad>1.0e-6) {
                arrowAng = getArrowSize() / rad;
        }
        else {
                arrowAng = 0.0;
        }
    RS_Vector v1, v2;
    if (!arc->isReversed()) {
        v1.setPolar(rad, arc->getAngle1()+arrowAng);
    } else {
        v1.setPolar(rad, arc->getAngle1()-arrowAng);
    }
    v1+=arc->getCenter();
    arrowAngle1 = arc->getStartpoint().angleTo(v1);


    if (!arc->isReversed()) {
        v2.setPolar(rad, arc->getAngle2()-arrowAng);
    } else {
        v2.setPolar(rad, arc->getAngle2()+arrowAng);
    }
    v2+=arc->getCenter();
    arrowAngle2 = arc->getEndpoint().angleTo(v2);

    if (!outsideArrows) {
        arrowAngle1 = arrowAngle1+M_PI;
        arrowAngle2 = arrowAngle2+M_PI;
    }

    // Arrows:
    RS_SolidData sd;
    RS_Solid* arrow;

    // arrow 1
    arrow = new RS_Solid(this, sd);
    arrow->shapeArrow(arc->getStartpoint(),
                      arrowAngle1,
                      getArrowSize());
    arrow->setPen(RS_Pen(RS2::FlagInvalid));
    arrow->setLayer(NULL);
    addEntity(arrow);

    // arrow 2:
    arrow = new RS_Solid(this, sd);
    arrow->shapeArrow(arc->getEndpoint(),
                      arrowAngle2,
                      getArrowSize());
    arrow->setPen(RS_Pen(RS2::FlagInvalid));
    arrow->setLayer(NULL);
    addEntity(arrow);


    // text label:
    RS_TextData textData;
    RS_Vector textPos = arc->getMiddlePoint();

    RS_Vector distV;
    double textAngle;
    double dimAngle1 = textPos.angleTo(arc->getCenter())-M_PI/2.0;

    // rotate text so it's readable from the bottom or right (ISO)
    // quadrant 1 & 4
    if (dimAngle1>M_PI/2.0*3.0+0.001 ||
            dimAngle1<M_PI/2.0+0.001) {

        distV.setPolar(dimgap, dimAngle1+M_PI/2.0);
        textAngle = dimAngle1;
    }
    // quadrant 2 & 3
    else {
        distV.setPolar(dimgap, dimAngle1-M_PI/2.0);
        textAngle = dimAngle1+M_PI;
    }

    // move text away from dimension line:
    textPos+=distV;

    textData = RS_TextData(textPos,
                           dimtxt, 30.0,
                           RS2::VAlignBottom,
                           RS2::HAlignCenter,
                           RS2::LeftToRight,
                           RS2::Exact,
                           1.0,
                           getLabel(),
                           "standard",
                           textAngle);

    RS_Text* text = new RS_Text(this, textData);

    // move text to the side:
    text->setPen(RS_Pen(RS2::FlagInvalid));
    text->setLayer(NULL);
    addEntity(text);

    calculateBorders();
}
Пример #10
0
void RS_Font::readCXF(QString path) {
    QString line;
    QFile f(path);
    f.open(QIODevice::ReadOnly);
    QTextStream ts(&f);

    // Read line by line until we find a new letter:
    while (!ts.atEnd()) {
        line = ts.readLine();

        if (line.isEmpty())
            continue;

        // Read font settings:
        if (line.at(0)=='#') {
            QStringList lst =
                    ( line.right(line.length()-1) ).split(':', QString::SkipEmptyParts);
            QStringList::Iterator it3 = lst.begin();

            // RVT_PORT sometimes it happens that the size is < 2
            if (lst.size()<2)
                continue;

            QString identifier = (*it3).trimmed();
            it3++;
            QString value = (*it3).trimmed();

            if (identifier.toLower()=="letterspacing") {
                letterSpacing = value.toDouble();
            } else if (identifier.toLower()=="wordspacing") {
                wordSpacing = value.toDouble();
            } else if (identifier.toLower()=="linespacingfactor") {
                lineSpacingFactor = value.toDouble();
            } else if (identifier.toLower()=="author") {
                authors.append(value);
            } else if (identifier.toLower()=="name") {
                names.append(value);
            } else if (identifier.toLower()=="encoding") {
                ts.setCodec(QTextCodec::codecForName(value.toLatin1()));
                encoding = value;
            }
        }

        // Add another letter to this font:
        else if (line.at(0)=='[') {

            // uniode character:
            QChar ch;

            // read unicode:
            QRegExp regexp("[0-9A-Fa-f]{4,4}");
            regexp.indexIn(line);
            QString cap = regexp.cap();
            if (!cap.isNull()) {
				int uCode = cap.toInt(nullptr, 16);
                ch = QChar(uCode);
            }

            // read UTF8 (LibreCAD 1 compatibility)
            else if (line.indexOf(']')>=3) {
                int i = line.indexOf(']');
                QString mid = line.mid(1, i-1);
                ch = QString::fromUtf8(mid.toLatin1()).at(0);
            }

            // read normal ascii character:
            else {
                ch = line.at(1);
            }

            // create new letter:
            RS_FontChar* letter =
					new RS_FontChar(nullptr, ch, RS_Vector(0.0, 0.0));

            // Read entities of this letter:
            QString coordsStr;
            QStringList coords;
            QStringList::Iterator it2;
            do {
                line = ts.readLine();

                if (line.isEmpty()) {
                    continue;
                }

                coordsStr = line.right(line.length()-2);
                //                coords = QStringList::split(',', coordsStr);
                coords = coordsStr.split(',', QString::SkipEmptyParts);
                it2 = coords.begin();

                // Line:
                if (line.at(0)=='L') {
                    double x1 = (*it2++).toDouble();
                    double y1 = (*it2++).toDouble();
                    double x2 = (*it2++).toDouble();
                    double y2 = (*it2).toDouble();

					RS_Line* line = new RS_Line{letter, {{x1, y1}, {x2, y2}}};
                    line->setPen(RS_Pen(RS2::FlagInvalid));
					line->setLayer(nullptr);
                    letter->addEntity(line);
                }

                // Arc:
                else if (line.at(0)=='A') {
                    double cx = (*it2++).toDouble();
                    double cy = (*it2++).toDouble();
                    double r = (*it2++).toDouble();
					double a1 = RS_Math::deg2rad((*it2++).toDouble());
					double a2 = RS_Math::deg2rad((*it2).toDouble());
                    bool reversed = (line.at(1)=='R');

                    RS_ArcData ad(RS_Vector(cx,cy),
                                  r, a1, a2, reversed);
                    RS_Arc* arc = new RS_Arc(letter, ad);
                    arc->setPen(RS_Pen(RS2::FlagInvalid));
					arc->setLayer(nullptr);
                    letter->addEntity(arc);
                }
            } while (!line.isEmpty());

            if (letter->isEmpty()) {
                delete letter;
            } else {
                letter->calculateBorders();
                letterList.add(letter);
            }
        }
    }
    f.close();
}
Пример #11
0
/**
 * Implementation of the method used for RS_Export to communicate
 * with this filter.
 *
 * @param file Full path to the LFF file that will be written.
 */
bool RS_FilterLFF::fileExport(RS_Graphic& g, const QString& file, RS2::FormatType /*type*/) {

    RS_DEBUG->print("LFF Filter: exporting file '%s'...", file.toLatin1().data());
    RS_DEBUG->print("RS_FilterLFF::fileExport: open");

    QFile f(file);
    QTextStream ts(&f);
    ts.setCodec("UTF-8");
    if (f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {


        RS_DEBUG->print("RS_FilterLFF::fileExport: open: OK");

        RS_DEBUG->print("RS_FilterLFF::fileExport: header");

        // header:
        ts << "# Format:            LibreCAD Font 1\n";
        ts << QString("# Creator:           %1\n").arg(RS_SYSTEM->getAppName());
        ts << QString("# Version:           %1\n").arg(RS_SYSTEM->getAppVersion());

        QString ns = g.getVariableString("Names", "");
        if (!ns.isEmpty()) {
            QStringList names = ns.split(',');
            RS_DEBUG->print("002");
            for (int i = 0; i < names.size(); ++i) {
                ts << QString("# Name:              %1\n").arg(names.at(i));
            }
        }

        QString es = g.getVariableString("Encoding", "");
        ts << QString("# Encoding:          UTF-8\n");
        ts << QString("# LetterSpacing:     %1\n").arg(
                  g.getVariableDouble("LetterSpacing", 3.0));
        ts << QString("# WordSpacing:       %1\n").arg(
                  g.getVariableDouble("WordSpacing", 6.75));
        ts << QString("# LineSpacingFactor: %1\n").arg(
                  g.getVariableDouble("LineSpacingFactor", 1.0));
        QString dateline = QDate::currentDate().toString ("yyyy-MM-dd");
        ts << QString("# Created:           %1\n").arg(
                  g.getVariableString("Created", dateline));
        ts << QString("# Last modified:     %1\n").arg(dateline);

        QString sa = g.getVariableString("Authors", "");
        RS_DEBUG->print("authors: %s", sa.toLocal8Bit().data());
        if (!sa.isEmpty()) {
            QStringList authors = sa.split(',');
            RS_DEBUG->print("count: %d", authors.count());

            QString a;
            for (int i = 0; i < authors.size(); ++i) {
                ts << QString("# Author:            %1\n").arg(authors.at(i));
            }
        }
        es = g.getVariableString("License", "");
        if (!es.isEmpty()) {
            ts << QString("# License:           %1\n").arg(es);
        } else
            ts << "# License:           unknown\n";

        RS_DEBUG->print("RS_FilterLFF::fileExport: header: OK");

        // iterate through blocks (=letters of font)
        for (uint i=0; i<g.countBlocks(); ++i) {
            RS_Block* blk = g.blockAt(i);

            RS_DEBUG->print("block: %d", i);

            if (blk!=NULL) {
                RS_DEBUG->print("002a: %s",
                                (blk->getName().toLocal8Bit().data()));

                ts << QString("\n%1\n").arg(blk->getName());

                // iterate through entities of this letter:
                for (RS_Entity* e=blk->firstEntity(RS2::ResolveNone);
                     e!=NULL;
                     e=blk->nextEntity(RS2::ResolveNone)) {

                    if (!e->isUndone()) {

                        // lines:
                        if (e->rtti()==RS2::EntityLine) {
                            RS_Line* l = (RS_Line*)e;
                            ts << clearZeros(l->getStartpoint().x, 5) << ',';
                            ts << clearZeros(l->getStartpoint().y, 5) << ';';
                            ts << clearZeros(l->getEndpoint().x, 5) << ',';
                            ts << clearZeros(l->getEndpoint().y, 5) << '\n';
                        }
                        // arcs:
                        else if (e->rtti()==RS2::EntityArc) {
                            RS_Arc* a = (RS_Arc*)e;
                            ts << clearZeros(a->getStartpoint().x, 5) << ',';
                            ts << clearZeros(a->getStartpoint().y, 5) << ';';
                            ts << clearZeros(a->getEndpoint().x, 5) << ',';
                            ts << clearZeros(a->getEndpoint().y, 5) << ",A";
                            ts << clearZeros(a->getBulge(), 5) << '\n';
                        }
                        else if (e->rtti()==RS2::EntityBlock) {
                            RS_Block* b = (RS_Block*)e;
                            QString uCode;
                            uCode.setNum(b->getName().at(0).unicode(), 16);
                            if (uCode.length()<4) {
                                uCode = uCode.rightJustified(4, '0');
                            }
                            ts << QString("C%1\n").arg(uCode);
                        }
                        else if (e->rtti()==RS2::EntityPolyline) {
                            RS_Polyline* p = (RS_Polyline*)e;
                            ts << clearZeros(p->getStartpoint().x, 5) << ',';
                            ts << clearZeros(p->getStartpoint().y, 5);
                            for (RS_Entity* e2=p->firstEntity(RS2::ResolveNone);
                                 e2!=NULL;
                                 e2=p->nextEntity(RS2::ResolveNone)) {
                                if (e2->rtti()==RS2::EntityLine){
                                    RS_Line* l = (RS_Line*)e2;
                                    ts << ';' << clearZeros(l->getEndpoint().x, 5) << ',';
                                    ts << clearZeros(l->getEndpoint().y, 5);
                                } else if (e2->rtti()==RS2::EntityArc){
                                    RS_Arc* a = (RS_Arc*)e2;
                                    ts << ';' << clearZeros(a->getEndpoint().x, 5) << ',';
                                    ts << clearZeros(a->getEndpoint().y, 5) <<",A";
                                    ts << clearZeros(a->getBulge(), 5);
                                }
                            }
                            ts<<'\n';
                        }
                        // Ignore entities other than arcs / lines
                        else {}
                    }

                }
            }
        }
        f.close();
        RS_DEBUG->print("LFF Filter: exporting file: OK");
        return true;
    }
    else {
        RS_DEBUG->print("LFF Filter: exporting file failed");
    }

    return false;
}
Пример #12
0
/**
 * Testing function.
 */
void LC_SimpleTests::slotTestDumpEntities(RS_EntityContainer* d){

	int level = 0;
	std::ofstream dumpFile;
	if (d) {
		dumpFile.open("debug_entities.html", std::ios::app);
		++level;
	} else {
		d = QC_ApplicationWindow::getAppWindow()->getDocument();
		dumpFile.open("debug_entities.html");
		level = 0;
	}

	if (d) {
		if (level==0) {
			dumpFile << "<html>\n";
			dumpFile << "<body>\n";
		}

		for(auto e: *d){

			dumpFile << "<table border=\"1\">\n";
			dumpFile << "<tr><td>Entity: " << e->getId()
					 << "</td></tr>\n";

			dumpFile
					<< "<tr><td><table><tr>"
					<< "<td>VIS:" << e->isVisible() << "</td>"
					<< "<td>UND:" << e->isUndone() << "</td>"
					<< "<td>SEL:" << e->isSelected() << "</td>"
					<< "<td>TMP:" << e->getFlag(RS2::FlagTemp) << "</td>";
			QString lay = "NULL";
			if (e->getLayer()) {
				lay = e->getLayer()->getName();
			}
			dumpFile
					<< "<td>Layer: " << lay.toLatin1().data() << "</td>"
					<< "<td>Width: " << (int)e->getPen(false).getWidth() << "</td>"
					<< "<td>Parent: " << e->getParent()->getId() << "</td>"
					<< "</tr></table>";

			dumpFile
					<< "<tr><td>\n";

			switch (e->rtti()) {
			case RS2::EntityPoint: {
				RS_Point* p = (RS_Point*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Point:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>"
						<< p->getPos()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityLine: {
				RS_Line* l = (RS_Line*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Line:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>"
						<< l->getStartpoint()
						<< "</td>"
						<< "<td>"
						<< l->getEndpoint()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityArc: {
				RS_Arc* a = (RS_Arc*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Arc:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>Center: "
						<< a->getCenter()
						<< "</td>"
						<< "<td>Radius: "
						<< a->getRadius()
						<< "</td>"
						<< "<td>Angle 1: "
						<< a->getAngle1()
						<< "</td>"
						<< "<td>Angle 2: "
						<< a->getAngle2()
						<< "</td>"
						<< "<td>Startpoint: "
						<< a->getStartpoint()
						<< "</td>"
						<< "<td>Endpoint: "
						<< a->getEndpoint()
						<< "</td>"
						<< "<td>reversed: "
						<< (int)a->isReversed()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityCircle: {
				RS_Circle* c = (RS_Circle*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Circle:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>Center: "
						<< c->getCenter()
						<< "</td>"
						<< "<td>Radius: "
						<< c->getRadius()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityDimAligned: {
				RS_DimAligned* d = (RS_DimAligned*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Dimension / Aligned:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>"
						<< d->getDefinitionPoint()
						<< "</td>"
						<< "<td>"
						<< d->getExtensionPoint1()
						<< "</td>"
						<< "<td>"
						<< d->getExtensionPoint2()
						<< "</td>"
						<< "<td>Text: "
						<< d->getText().toLatin1().data()
						<< "</td>"
						<< "<td>Label: "
						<< d->getLabel().toLatin1().data()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityDimLinear: {
				RS_DimLinear* d = (RS_DimLinear*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Dimension / Linear:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>"
						<< d->getDefinitionPoint()
						<< "</td>"
						<< "<td>"
						<< d->getExtensionPoint1()
						<< "</td>"
						<< "<td>"
						<< d->getExtensionPoint2()
						<< "</td>"
						<< "<td>Text: "
						<< d->getText().toLatin1().data()
						<< "</td>"
						<< "<td>Label: "
						<< d->getLabel().toLatin1().data()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityInsert: {
				RS_Insert* i = (RS_Insert*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Insert:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>Insertion point:"
						<< i->getInsertionPoint()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityMText: {
				RS_MText* t = (RS_MText*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Text:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>Text:"
						<< t->getText().toLatin1().data()
						<< "</td>"
						<< "<td>Height:"
						<< t->getHeight()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityText: {
				RS_Text* t = (RS_Text*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Text:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>Text:"
						<< t->getText().toLatin1().data()
						<< "</td>"
						<< "<td>Height:"
						<< t->getHeight()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			case RS2::EntityHatch: {
				RS_Hatch* h = (RS_Hatch*)e;
				dumpFile
						<< "<table><tr><td>"
						<< "<b>Hatch:</b>"
						<< "</td></tr>";
				dumpFile
						<< "<tr>"
						<< "<td>Pattern:"
						<< h->getPattern().toLatin1().data()
						<< "</td>"
						<< "<td>Scale:"
						<< h->getScale()
						<< "</td>"
						<< "<td>Solid:"
						<< (int)h->isSolid()
						<< "</td>"
						<< "</tr></table>";
			}
				break;

			default:
				dumpFile
						<< "<tr><td>"
						<< "<b>Unknown Entity: " << e->rtti() << "</b>"
						<< "</td></tr>";
				break;
			}

			if (e->isContainer() || e->rtti()==RS2::EntityHatch) {
				RS_EntityContainer* ec = (RS_EntityContainer*)e;
				dumpFile << "<table><tr><td valign=\"top\">&nbsp;&nbsp;&nbsp;&nbsp;Contents:</td><td>\n";
				dumpFile.close();
				slotTestDumpEntities(ec);
				dumpFile.open("debug_entities.html", std::ios::app);
				dumpFile << "</td></tr></table>\n";
			}

			dumpFile
					<< "</td></tr>"
					<< "</table>\n"
					<< "<br><br>";
		}

		if (level==0) {
			dumpFile << "</body>\n";
			dumpFile << "</html>\n";
		} else {
			level--;
		}
	}
	RS_DEBUG->print("%s\n: end\n", __func__);
}
Пример #13
0
void Plugin_Entity::updateData(QHash<int, QVariant> *data){
    if (entity == NULL) return;
    QHash<int, QVariant> hash = *data;
    QString str;
    RS_Vector vec;
    RS_Pen epen = entity->getPen();
//    double num;
    if (hash.contains(DPI::LAYER)) {
        str = (hash.take(DPI::LAYER)).toString();
        entity->setLayer(str);
    }
    if (hash.contains(DPI::LTYPE)) {
        str = (hash.take(DPI::LTYPE)).toString();
        epen.setLineType( Converter.str2lt(str) );
    }
    if (hash.contains(DPI::LWIDTH)) {
        str = (hash.take(DPI::LWIDTH)).toString();
        epen.setWidth( Converter.str2lw(str) );
    }
    if (hash.contains(DPI::COLOR)) {
        QColor color = hash.take(DPI::COLOR).value<QColor>();
        epen.setColor(color);
    }
    entity->setPen(epen);

    RS2::EntityType et = entity->rtti();
    switch (et) {
    //atomicEntity
    case RS2::EntityLine: {
        vec = static_cast<RS_Line*>(entity)->getStartpoint();
        if (hash.contains(DPI::STARTX)) {
            vec.x = (hash.take(DPI::STARTX)).toDouble();
        }
        if (hash.contains(DPI::STARTY)) {
            vec.y = (hash.take(DPI::STARTY)).toDouble();
        }
        static_cast<RS_Line*>(entity)->setStartpoint(vec);
        vec = static_cast<RS_Line*>(entity)->getEndpoint();
        if (hash.contains(DPI::ENDX)) {
            vec.x = (hash.take(DPI::ENDX)).toDouble();
        }
        if (hash.contains(DPI::ENDY)) {
            vec.y = (hash.take(DPI::ENDY)).toDouble();
        }
        static_cast<RS_Line*>(entity)->setEndpoint(vec);
        break;}
    case RS2::EntityPoint: {
        vec = static_cast<RS_Point*>(entity)->getPos();
        if (hash.contains(DPI::STARTX)) {
            vec.x = (hash.take(DPI::STARTX)).toDouble();
        }
        if (hash.contains(DPI::STARTY)) {
            vec.y = (hash.take(DPI::STARTY)).toDouble();
        }
        static_cast<RS_Point*>(entity)->setPos(vec);
        break; }
    case RS2::EntityArc: {
        RS_Arc *arc = static_cast<RS_Arc*>(entity);
        vec = arc->getCenter();
        if (hash.contains(DPI::STARTX)) {
            vec.x = (hash.take(DPI::STARTX)).toDouble();
        }
        if (hash.contains(DPI::STARTY)) {
            vec.y = (hash.take(DPI::STARTY)).toDouble();
        }
        arc->setCenter(vec);
        if (hash.contains(DPI::RADIUS)) {
            arc->setRadius( (hash.take(DPI::RADIUS)).toDouble() );
        }
        if (hash.contains(DPI::STARTANGLE)) {
             arc->setAngle1( (hash.take(DPI::STARTANGLE)).toDouble() );
           vec.y = (hash.take(DPI::STARTANGLE)).toDouble();
        }
        if (hash.contains(DPI::ENDANGLE)) {
            arc->setAngle2( (hash.take(DPI::ENDANGLE)).toDouble() );
        }
        break;}
    case RS2::EntityCircle: {
        RS_Circle *cir = static_cast<RS_Circle*>(entity);
        vec = cir->getCenter();
        if (hash.contains(DPI::STARTX)) {
            vec.x = (hash.take(DPI::STARTX)).toDouble();
        }
        if (hash.contains(DPI::STARTY)) {
            vec.y = (hash.take(DPI::STARTY)).toDouble();
        }
        cir->setCenter(vec);
        if (hash.contains(DPI::RADIUS)) {
            cir->setRadius( (hash.take(DPI::RADIUS)).toDouble() );
        }
        break;}
    case RS2::EntityEllipse: {
        RS_Ellipse *ellipse = static_cast<RS_Ellipse*>(entity);
        vec = ellipse->getCenter();
        if (hash.contains(DPI::STARTX)) {
            vec.x = (hash.take(DPI::STARTX)).toDouble();
        }
        if (hash.contains(DPI::STARTY)) {
            vec.y = (hash.take(DPI::STARTY)).toDouble();
        }
        ellipse->setCenter(vec);

        vec = ellipse->getMajorP();
        if (hash.contains(DPI::ENDX)) {
            vec.x = (hash.take(DPI::ENDX)).toDouble();
        }
        if (hash.contains(DPI::ENDY)) {
            vec.y = (hash.take(DPI::ENDY)).toDouble();
        }
        ellipse->setMajorP(vec);

        if (hash.contains(DPI::STARTANGLE)) {
            ellipse->setAngle1((hash.take(DPI::STARTANGLE)).toDouble());
        }
        if (hash.contains(DPI::ENDANGLE)) {
            ellipse->setAngle2((hash.take(DPI::ENDANGLE)).toDouble());
        }
        if (hash.contains(DPI::HEIGHT)) {
            ellipse->setRatio((hash.take(DPI::HEIGHT)).toDouble());
        }
        if (hash.contains(DPI::REVERSED)) {
            ellipse->setReversed( (hash.take(DPI::REVERSED)).toBool());
        }
        break;}
    case RS2::EntitySolid: //TODO
        //Only used in dimensions ?
        break;
    case RS2::EntityConstructionLine:
        //Unused ?
        break;
    case RS2::EntityImage: {
        break;}
    case RS2::EntityOverlayBox:
        //Unused ?
        break;
//EntityContainer
    case RS2::EntityInsert: {
        break;}
    case RS2::EntityText: {
        RS_Text *txt = static_cast<RS_Text*>(entity);
        bool move = false;
        vec = txt->getInsertionPoint();
        if (hash.contains(DPI::STARTX)) {
            vec.x = (hash.take(DPI::STARTX)).toDouble() - vec.x;
            move = true;
        } else vec.x = 0;
        if (hash.contains(DPI::STARTY)) {
            vec.y = (hash.take(DPI::STARTY)).toDouble() - vec.y;
            move = true;
        } else vec.y = 0;
        if (move)
            txt->move(vec);
        if (hash.contains(DPI::TEXTCONTENT)) {
            txt->setText( (hash.take(DPI::TEXTCONTENT)).toString() );
        }
        if (hash.contains(DPI::STARTANGLE)) {
            txt->setAngle( (hash.take(DPI::STARTANGLE)).toDouble() );
        }
        if (hash.contains(DPI::HEIGHT)) {
            txt->setHeight( (hash.take(DPI::HEIGHT)).toDouble() );
        }
        break;}
    case RS2::EntityHatch:
        break;
    case RS2::EntitySpline:
        break;
    case RS2::EntityPolyline: {
        RS_Polyline *pl = static_cast<RS_Polyline*>(entity);
        if (hash.take(DPI::CLOSEPOLY).toBool()) {
            pl->setClosed(true);
        }else{
            pl->setClosed(false);
        }
        break;}
    case RS2::EntityVertex:
        break;
    case RS2::EntityDimAligned:
        break;
    case RS2::EntityDimLinear:
        break;
    case RS2::EntityDimRadial:
        break;
    case RS2::EntityDimDiametric:
        break;
    case RS2::EntityDimAngular:
        break;
    case RS2::EntityDimLeader:
        break;
    case RS2::EntityUnknown:
    default:
        break;
    }
    entity->update();
}
Пример #14
0
/**
 * Updates the Hatch. Called when the
 * hatch or it's data, position, alignment, .. changes.
 */
void RS_Hatch::update() {
        RS_DEBUG->print("RS_Hatch::update");
        RS_DEBUG->print("RS_Hatch::update: contour has %d loops", count());

    if (updateRunning) {
        return;
    }

    if (updateEnabled==false) {
        return;
    }

    if (data.solid==true) {
        calculateBorders();
        return;
    }

    RS_DEBUG->print("RS_Hatch::update");
    updateRunning = true;

    // delete old hatch:
    if (hatch!=NULL) {
        removeEntity(hatch);
        hatch = NULL;
    }

    if (isUndone()) {
        updateRunning = false;
        return;
    }

        if (!validate()) {
                RS_DEBUG->print(RS_Debug::D_WARNING,
                        "RS_Hatch::update: invalid contour in hatch found");
        updateRunning = false;
                return;
        }

    // search pattern:
    RS_DEBUG->print("RS_Hatch::update: requesting pattern");
    RS_Pattern* pat = RS_PATTERNLIST->requestPattern(data.pattern);
    if (pat==NULL) {
        updateRunning = false;
        RS_DEBUG->print("RS_Hatch::update: requesting pattern: not found");
        return;
    }
    RS_DEBUG->print("RS_Hatch::update: requesting pattern: OK");

    RS_DEBUG->print("RS_Hatch::update: cloning pattern");
    pat = (RS_Pattern*)pat->clone();
    RS_DEBUG->print("RS_Hatch::update: cloning pattern: OK");

    // scale pattern
    RS_DEBUG->print("RS_Hatch::update: scaling pattern");
    pat->scale(RS_Vector(0.0,0.0), RS_Vector(data.scale, data.scale));
    pat->calculateBorders();
    forcedCalculateBorders();
    RS_DEBUG->print("RS_Hatch::update: scaling pattern: OK");

    // find out how many pattern-instances we need in x/y:
    int px1, py1, px2, py2;
    double f;
    RS_Hatch* copy = (RS_Hatch*)this->clone();
    copy->rotate(RS_Vector(0.0,0.0), -data.angle);
    copy->forcedCalculateBorders();

    // create a pattern over the whole contour.
    RS_Vector pSize = pat->getSize();
//    RS_Vector cPos = getMin();
    RS_Vector cSize = getSize();


    RS_DEBUG->print("RS_Hatch::update: pattern size: %f/%f", pSize.x, pSize.y);
    RS_DEBUG->print("RS_Hatch::update: contour size: %f/%f", cSize.x, cSize.y);

    if (cSize.x<1.0e-6 || cSize.y<1.0e-6 ||
            pSize.x<1.0e-6 || pSize.y<1.0e-6 ||
            cSize.x>RS_MAXDOUBLE-1 || cSize.y>RS_MAXDOUBLE-1 ||
            pSize.x>RS_MAXDOUBLE-1 || pSize.y>RS_MAXDOUBLE-1) {
        delete pat;
        delete copy;
        updateRunning = false;
        RS_DEBUG->print("RS_Hatch::update: contour size or pattern size too small");
        return;
    }

    // avoid huge memory consumption:
    else if (cSize.x/pSize.x>100 || cSize.y/pSize.y>100) {
        RS_DEBUG->print("RS_Hatch::update: contour size too large or pattern size too small");
        return;
    }

    f = copy->getMin().x/pat->getSize().x;
    px1 = (int)floor(f);
    f = copy->getMin().y/pat->getSize().y;
    py1 = (int)floor(f);
    f = copy->getMax().x/pat->getSize().x;
    px2 = (int)ceil(f) - 1;
    f = copy->getMax().y/pat->getSize().y;
    py2 = (int)ceil(f) - 1;

    RS_EntityContainer tmp;   // container for untrimmed lines

    // adding array of patterns to tmp:
    RS_DEBUG->print("RS_Hatch::update: creating pattern carpet");

    for (int px=px1; px<=px2; px++) {
        for (int py=py1; py<=py2; py++) {
            for (RS_Entity* e=pat->firstEntity(); e!=NULL;
                    e=pat->nextEntity()) {

                RS_Entity* te = e->clone();
                te->rotate(RS_Vector(0.0,0.0), data.angle);
                RS_Vector v1, v2;
                v1.setPolar(px*pSize.x, data.angle);
                v2.setPolar(py*pSize.y, data.angle+M_PI/2.0);
                te->move(v1+v2);
                tmp.addEntity(te);
            }
        }
    }

    delete pat;
    pat = NULL;
    RS_DEBUG->print("RS_Hatch::update: creating pattern carpet: OK");


    RS_DEBUG->print("RS_Hatch::update: cutting pattern carpet");
    // cut pattern to contour shape:
    RS_EntityContainer tmp2;   // container for small cut lines
    RS_Line* line = NULL;
    RS_Arc* arc = NULL;
    RS_Circle* circle = NULL;
    RS_Ellipse* ellipse = NULL;
    for (RS_Entity* e=tmp.firstEntity(); e!=NULL;
            e=tmp.nextEntity()) {

        RS_Vector startPoint;
        RS_Vector endPoint;
        RS_Vector center = RS_Vector(false);
        bool reversed;

        switch(e->rtti()){
        case RS2::EntityLine:
            line=static_cast<RS_Line*>(e);
            startPoint = line->getStartpoint();
            endPoint = line->getEndpoint();
            break;
        case RS2::EntityArc:
            arc=static_cast<RS_Arc*>(e);
            startPoint = arc->getStartpoint();
            endPoint = arc->getEndpoint();
            center = arc->getCenter();
            reversed = arc->isReversed();
            break;
        case RS2::EntityCircle:
            circle=static_cast<RS_Circle*>(e);
            startPoint = circle->getCenter()
                    + RS_Vector(circle->getRadius(), 0.0);
            endPoint = startPoint;
            center = circle->getCenter();
            break;
        case RS2::EntityEllipse:
            ellipse = static_cast<RS_Ellipse*>(e);
            startPoint = ellipse->getStartpoint();
            endPoint = ellipse->getEndpoint();
            center = ellipse->getCenter();
            reversed = ellipse->isReversed();
            break;
        default:
            continue;
        }

        // getting all intersections of this pattern line with the contour:
        QList<std::shared_ptr<RS_Vector> > is;
        is.append(std::shared_ptr<RS_Vector>(new RS_Vector(startPoint)));

        for (RS_Entity* loop=firstEntity(); loop!=NULL;
                loop=nextEntity()) {

            if (loop->isContainer()) {
                for (RS_Entity* p=((RS_EntityContainer*)loop)->firstEntity();
                        p!=NULL;
                        p=((RS_EntityContainer*)loop)->nextEntity()) {

                    RS_VectorSolutions sol =
                        RS_Information::getIntersection(e, p, true);

                    for (int i=0; i<=1; ++i) {
                        if (sol.get(i).valid) {
                            is.append(std::shared_ptr<RS_Vector>(
                                          new RS_Vector(sol.get(i))
                                                        ));
                            RS_DEBUG->print("  pattern line intersection: %f/%f",
                                            sol.get(i).x, sol.get(i).y);
                        }
                    }
                }
            }
        }

        is.append(std::shared_ptr<RS_Vector>(new RS_Vector(endPoint)));

        // sort the intersection points into is2:
        RS_Vector sp = startPoint;
        double sa = center.angleTo(sp);
        if(ellipse != NULL) sa=ellipse->getEllipseAngle(sp);
        QList<std::shared_ptr<RS_Vector> > is2;
        bool done;
        double minDist;
        double dist = 0.0;
        std::shared_ptr<RS_Vector> av;
        std::shared_ptr<RS_Vector> v;
        RS_Vector last = RS_Vector(false);
        do {
            done = true;
            minDist = RS_MAXDOUBLE;
            av.reset();
            for (int i = 0; i < is.size(); ++i) {
                v = is.at(i);
                double a;
                switch(e->rtti()){
                case RS2::EntityLine:
                    dist = sp.distanceTo(*v);
                    break;
                case RS2::EntityArc:
                case RS2::EntityCircle:
                    a = center.angleTo(*v);
                    dist = reversed?
                                fmod(sa - a + 2.*M_PI,2.*M_PI):
                                fmod(a - sa + 2.*M_PI,2.*M_PI);
                    break;
                case RS2::EntityEllipse:
                    a = ellipse->getEllipseAngle(*v);
                    dist = reversed?
                                fmod(sa - a + 2.*M_PI,2.*M_PI):
                                fmod(a - sa + 2.*M_PI,2.*M_PI);
                    break;
                default:
                    break;

                }

                if (dist<minDist) {
                    minDist = dist;
                    done = false;
                    av = v;
                }
            }

            // copy to sorted list, removing double points
            if (!done && av.get()!=NULL) {
                if (last.valid==false || last.distanceTo(*av)>RS_TOLERANCE) {
                    is2.append(std::shared_ptr<RS_Vector>(new RS_Vector(*av)));
                    last = *av;
                }
#if QT_VERSION < 0x040400
                emu_qt44_removeOne(is, av);
#else
                is.removeOne(av);
#endif

                av.reset();
            }
        } while(!done);

        // add small cut lines / arcs to tmp2:
            for (int i = 1; i < is2.size(); ++i) {
                auto v1 = is2.at(i-1);
                auto v2 = is2.at(i);

                if (line!=NULL) {
                    tmp2.addEntity(new RS_Line(&tmp2,
                                               RS_LineData(*v1, *v2)));
                } else if (arc!=NULL || circle!=NULL) {
                    tmp2.addEntity(new RS_Arc(&tmp2,
                                              RS_ArcData(center,
                                                         center.distanceTo(*v1),
                                                         center.angleTo(*v1),
                                                         center.angleTo(*v2),
                                                         reversed)));
                }
            }

    }

    // updating hatch / adding entities that are inside
    RS_DEBUG->print("RS_Hatch::update: cutting pattern carpet: OK");

    //RS_EntityContainer* rubbish = new RS_EntityContainer(getGraphic());

    // the hatch pattern entities:
    hatch = new RS_EntityContainer(this);
    hatch->setPen(RS_Pen(RS2::FlagInvalid));
    hatch->setLayer(NULL);
    hatch->setFlag(RS2::FlagTemp);

    //calculateBorders();

    for (RS_Entity* e=tmp2.firstEntity(); e!=NULL;
            e=tmp2.nextEntity()) {

        RS_Vector middlePoint;
        RS_Vector middlePoint2;
        if (e->rtti()==RS2::EntityLine) {
            RS_Line* line = (RS_Line*)e;
            middlePoint = line->getMiddlePoint();
            middlePoint2 = line->getNearestDist(line->getLength()/2.1,
                                                line->getStartpoint());
        } else if (e->rtti()==RS2::EntityArc) {
            RS_Arc* arc = (RS_Arc*)e;
            middlePoint = arc->getMiddlePoint();
            middlePoint2 = arc->getNearestDist(arc->getLength()/2.1,
                                               arc->getStartpoint());
        } else {
            middlePoint = RS_Vector(false);
            middlePoint2 = RS_Vector(false);
        }

        if (middlePoint.valid) {
            bool onContour=false;

            if (RS_Information::isPointInsideContour(
                        middlePoint,
                        this, &onContour) ||
                    RS_Information::isPointInsideContour(middlePoint2, this)) {

                RS_Entity* te = e->clone();
                te->setPen(RS_Pen(RS2::FlagInvalid));
                te->setLayer(NULL);
                te->reparent(hatch);
                hatch->addEntity(te);
            }
        }
    }

    addEntity(hatch);
    //getGraphic()->addEntity(rubbish);

    forcedCalculateBorders();

    // deactivate contour:
    activateContour(false);

    updateRunning = false;

    RS_DEBUG->print("RS_Hatch::update: OK");
}
Пример #15
0
/**
 * Creates a arc parallel to the given arc e.
 * Out of the 2 possible parallels, the one closest to
 * the given coordinate is returned.
 *
 * @param coord Coordinate to define which parallel we want (typically a
 *              mouse coordinate).
 * @param distance Distance of the parallel.
 * @param number Number of parallels.
 * @param e Original entity.
 *
 * @return Pointer to the first created parallel or NULL if no
 *    parallel has been created.
 */
RS_Arc* RS_Creation::createParallelArc(const RS_Vector& coord,
                                       double distance, int number,
                                       RS_Arc* e) {

    if (e==NULL) {
        return NULL;
    }

    RS_ArcData parallelData;
    RS_Arc* ret = NULL;

    bool inside = (e->getCenter().distanceTo(coord) < e->getRadius());

    if (inside) {
        distance *= -1;
    }

    for (int num=1; num<=number; ++num) {

        // calculate parallel:
        bool ok = true;
        RS_Arc parallel1(NULL, e->getData());
        parallel1.setRadius(e->getRadius() + distance*num);
        if (parallel1.getRadius()<0.0) {
            parallel1.setRadius(RS_MAXDOUBLE);
            ok = false;
        }

        // calculate 2nd parallel:
        //RS_Arc parallel2(NULL, e->getData());
        //parallel2.setRadius(e->getRadius()+distance*num);

        //double dist1 = parallel1.getDistanceToPoint(coord);
        //double dist2 = parallel2.getDistanceToPoint(coord);
        //double minDist = min(dist1, dist2);

        //if (minDist<RS_MAXDOUBLE) {
        if (ok==true) {
            //if (dist1<dist2) {
            parallelData = parallel1.getData();
            //} else {
            //    parallelData = parallel2.getData();
            //}

            if (document!=NULL && handleUndo) {
                document->startUndoCycle();
            }

            RS_Arc* newArc = new RS_Arc(container, parallelData);
            newArc->setLayerToActive();
            newArc->setPenToActive();
            if (ret==NULL) {
                ret = newArc;
            }
            if (container!=NULL) {
                container->addEntity(newArc);
            }
            if (document!=NULL && handleUndo) {
                document->addUndoable(newArc);
                document->endUndoCycle();
            }
            if (graphicView!=NULL) {
                graphicView->drawEntity(newArc);
            }
        }
    }

    return ret;
}
Пример #16
0
/**
 * Testing function.
 */
void LC_SimpleTests::slotTestInsertBlock() {
	RS_DEBUG->print("%s\n: begin\n", __func__);
	auto appWin=QC_ApplicationWindow::getAppWindow();

	RS_Document* d = appWin->getDocument();
	if (d && d->rtti()==RS2::EntityGraphic) {
		RS_Graphic* graphic = (RS_Graphic*)d;
		if (graphic==NULL) {
			return;
		}

		graphic->addLayer(new RS_Layer("default"));
		RS_Block* block = new RS_Block(graphic, RS_BlockData("debugblock",
															 RS_Vector(0.0,0.0), true));

		RS_Line* line;
		RS_Arc* arc;
		RS_Circle* circle;

		// Add one red line:
		line = new RS_Line{block, {0.,0.}, {50.,0.}};
		line->setLayerToActive();
		line->setPen(RS_Pen(RS_Color(255, 0, 0),
							RS2::Width01,
							RS2::SolidLine));
		block->addEntity(line);

		// Add one line with attributes from block:
		line = new RS_Line{block, {50.,0.}, {50.,50.}};
		line->setPen(RS_Pen(RS_Color(RS2::FlagByBlock),
							RS2::WidthByBlock,
							RS2::LineByBlock));
		block->addEntity(line);

		// Add one arc with attributes from block:
		RS_ArcData d({50.,0.},
					 50.0, M_PI_2, M_PI,
					 false);
		arc = new RS_Arc(block, d);
		arc->setPen(RS_Pen(RS_Color(RS2::FlagByBlock),
						   RS2::WidthByBlock,
						   RS2::LineByBlock));
		block->addEntity(arc);

		// Add one blue circle:
		RS_CircleData circleData(RS_Vector(20.0,15.0),
								 12.5);
		circle = new RS_Circle(block, circleData);
		circle->setLayerToActive();
		circle->setPen(RS_Pen(RS_Color(0, 0, 255),
							  RS2::Width01,
							  RS2::SolidLine));
		block->addEntity(circle);


		graphic->addBlock(block);



		RS_Insert* ins;
		RS_InsertData insData("debugblock",
							  RS_Vector(0.0,0.0),
							  RS_Vector(1.0,1.0), 0.0,
							  1, 1, RS_Vector(0.0, 0.0),
							  NULL, RS2::NoUpdate);

		// insert one magenta instance of the block (original):
		ins = new RS_Insert(graphic, insData);
		ins->setLayerToActive();
		ins->setPen(RS_Pen(RS_Color(255, 0, 255),
						   RS2::Width02,
						   RS2::SolidLine));
		ins->update();
		graphic->addEntity(ins);

		// insert one green instance of the block (rotate):
		insData = RS_InsertData("debugblock",
								RS_Vector(-50.0,20.0),
								RS_Vector(1.0,1.0), M_PI/6.,
								1, 1, RS_Vector(0.0, 0.0),
								NULL, RS2::NoUpdate);
		ins = new RS_Insert(graphic, insData);
		ins->setLayerToActive();
		ins->setPen(RS_Pen(RS_Color(0, 255, 0),
						   RS2::Width02,
						   RS2::SolidLine));
		ins->update();
		graphic->addEntity(ins);

		// insert one cyan instance of the block (move):
		insData = RS_InsertData("debugblock",
								RS_Vector(10.0,20.0),
								RS_Vector(1.0,1.0), 0.0,
								1, 1, RS_Vector(0.0, 0.0),
								NULL, RS2::NoUpdate);
		ins = new RS_Insert(graphic, insData);
		ins->setLayerToActive();
		ins->setPen(RS_Pen(RS_Color(0, 255, 255),
						   RS2::Width02,
						   RS2::SolidLine));
		ins->update();
		graphic->addEntity(ins);

		// insert one blue instance of the block:
		for (double a=0.0; a<360.0; a+=45.0) {
			insData = RS_InsertData("debugblock",
									RS_Vector(60.0,0.0),
									RS_Vector(2.0/5,2.0/5), RS_Math::deg2rad(a),
									1, 1, RS_Vector(0.0, 0.0),
									NULL, RS2::NoUpdate);
			ins = new RS_Insert(graphic, insData);
			ins->setLayerToActive();
			ins->setPen(RS_Pen(RS_Color(0, 0, 255),
							   RS2::Width05,
							   RS2::SolidLine));
			ins->update();
			graphic->addEntity(ins);
		}

		// insert an array of yellow instances of the block:
		insData = RS_InsertData("debugblock",
								RS_Vector(-100.0,-100.0),
								RS_Vector(0.2,0.2), M_PI/6.0,
								6, 4, RS_Vector(100.0, 100.0),
								NULL, RS2::NoUpdate);
		ins = new RS_Insert(graphic, insData);
		ins->setLayerToActive();
		ins->setPen(RS_Pen(RS_Color(255, 255, 0),
						   RS2::Width01,
						   RS2::SolidLine));
		ins->update();
		graphic->addEntity(ins);


		RS_GraphicView* v = appWin->getGraphicView();
		if (v) {
			v->redraw();
		}
	}
	RS_DEBUG->print("%s\n: end\n", __func__);
}
Пример #17
0
RS_Entity* RS_Arc::clone() const {
	RS_Arc* a = new RS_Arc(*this);
	a->initId();
	return a;
}