Exemplo n.º 1
0
void Plugin_Entity::updatePolylineData(QList<Plug_VertexData> *data){
    if (entity == NULL) return;
    RS2::EntityType et = entity->rtti();
    if (et != RS2::EntityPolyline) return;
    if (data->size()<2) return; //At least two vertex
    RS_Vector vec(false);
    RS_Polyline *pl = static_cast<RS_Polyline*>(entity);
//    vec.x = data->at(0).point.x();
//    vec.y = data->at(0).point.y();
    pl->clear();
    pl->setEndpoint(vec);
    pl->setStartpoint(vec);
    vec.valid = true;
    for (int i = 0; i < data->size(); ++i) {
        vec.x = data->at(i).point.x();
        vec.y = data->at(i).point.y();
        pl->addVertex(vec, data->at(i).bulge );
    }


}
bool RS_ActionPolylineEquidistant::makeContour() {
	if (container==NULL) {
		RS_DEBUG->print("RS_ActionPolylineEquidistant::makeContour: no valid container",
						RS_Debug::D_WARNING);
		return false;
	}

	RS_Vector offset(false);
        QList<RS_Entity*> addList;

	if (document!=NULL) {
		document->startUndoCycle();
	}
	double neg = 1.0;
	if(bRightSide)
		neg = -1.0;
	// Create new entites
	RS_Line line1(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));
	RS_Line line2(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));
	for (int num=1;
			num<=number || (number==0 && num<=1);
			num++) {
		RS_Polyline* newPolyline = new RS_Polyline(container);
		newPolyline->setClosed(((RS_Polyline*)originalEntity)->isClosed());
//		newPolyline->setSelected((RS_Polyline*)originalEntity)->isSelected());
		newPolyline->setLayer(((RS_Polyline*)originalEntity)->getLayer());
		newPolyline->setPen(((RS_Polyline*)originalEntity)->getPen());

		bool first = true;
		RS_Entity* lastEntity = ((RS_Polyline*)originalEntity)->lastEntity();
		for (RS_Entity* en=((RS_Polyline*)originalEntity)->firstEntity(); en!=NULL; en=((RS_Polyline*)originalEntity)->nextEntity()) {
			double bulge = 0.0;
			if (en->rtti()==RS2::EntityArc) {
				double r0 = ((RS_Arc*)en)->getRadius();
				double r = r0 - dist*neg;
				if(r < 0)
					break;
				((RS_Arc*)en)->setRadius(r);
				bulge = ((RS_Arc*)en)->getBulge();
				((RS_Arc*)en)->setRadius(r0);
			} else {
				bulge = 0.0;
			}
			RS_Vector v1 = ((RS_AtomicEntity*)en)->getStartpoint();
			RS_Vector v2 = ((RS_AtomicEntity*)en)->getEndpoint();
			offset.set(dist * cos(v1.angleTo(v2)+M_PI*0.5*neg), dist * sin(v1.angleTo(v2)+M_PI*0.5*neg));
			v1.move(offset*num);
			v2.move(offset*num);
			if (first) {
				line1.setStartpoint(v1);
				line1.setEndpoint(v2);
				if(newPolyline->isClosed()){
					RS_Vector v01 = ((RS_AtomicEntity*)lastEntity)->getStartpoint();
					RS_Vector v02 = ((RS_AtomicEntity*)en)->getStartpoint();
					offset.set(dist * cos(v01.angleTo(v02)+M_PI*0.5*neg), dist * sin(v01.angleTo(v02)+M_PI*0.5*neg));
					v01.move(offset*num);
					v02.move(offset*num);
					line2.setStartpoint(v01);
					line2.setEndpoint(v02);
					RS_VectorSolutions vsol = RS_Information::getIntersection(&line1, &line2, false);
					v1 = vsol.get(0);
				}
				newPolyline->setStartpoint(v1);
				newPolyline->addVertex(v1, bulge);
				first = false;
			}else{
				line2.setStartpoint(v1);
				line2.setEndpoint(v2);
				RS_VectorSolutions vsol = RS_Information::getIntersection(&line1, &line2, false);
				RS_Vector v = vsol.get(0);
				newPolyline->addVertex(v, bulge);
				newPolyline->setEndpoint(v);
				line1.setStartpoint(v1);
				line1.setEndpoint(v2);
				if (en==lastEntity/* && newPolyline->isClosed()==false*/){
					newPolyline->addVertex(v2, bulge);
				}
			}
		}
		double bulge = lastEntity->rtti() == RS2::EntityArc? ((RS_Arc*)lastEntity)->getBulge():0.0;
//		newPolyline->setNextBulge(bulge);
		newPolyline->endPolyline();
		container->addEntity(newPolyline);
		document->addUndoable(newPolyline);
	}
	if (document!=NULL) {
		document->endUndoCycle();
	}

	if (graphicView!=NULL) {
		graphicView->redraw();
	}

	return true;
}
bool RS_ActionPolylineEquidistant::makeContour() {
    if (container==NULL) {
        RS_DEBUG->print("RS_ActionPolylineEquidistant::makeContour: no valid container",
                        RS_Debug::D_WARNING);
        return false;
    }

    RS_Polyline* originalPolyline = (RS_Polyline*)originalEntity;
//create a list of entities to offset without length = 0
    QList<RS_Entity*> entities;
    for (RS_Entity* en=originalPolyline->firstEntity(); en!=NULL; en=originalPolyline->nextEntity()) {
        if (en->getLength() > 1.0e-12)
            entities.append(en);
    }
    if (entities.isEmpty()) {
        return false;
    }
    if (document!=NULL) {
        document->startUndoCycle();
    }
    double neg = 1.0;
    if(bRightSide)
        neg = -1.0;

    // Create new helper entities
    RS_Line line1(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));//current line
    RS_Line lineFirst(NULL, RS_LineData(RS_Vector(true), RS_Vector(true)));//previous line
    RS_Arc arc1(NULL, RS_ArcData(RS_Vector(true), 0,0,0,false));//current arc
    RS_Arc arcFirst(NULL, RS_ArcData(RS_Vector(true), 0,0,0,false));//previous arc

    for (int num=1; num<=number || (number==0 && num<=1); num++) {
        RS_Polyline* newPolyline = new RS_Polyline(container);
        newPolyline->setLayer(((RS_Polyline*)originalEntity)->getLayer());
        newPolyline->setPen(((RS_Polyline*)originalEntity)->getPen());

        bool first = true;
        bool closed = originalPolyline->isClosed();
        double bulge = 0.0;
        RS_Entity* en;
        RS_Entity* prevEntity = entities.last();
        RS_Entity* currEntity;
        for (int i = 0; i < entities.size(); ++i) {
            en = entities.at(i);
            RS_Vector v(false);
            if (en->rtti()==RS2::EntityArc) {
                currEntity = &arc1;
                calculateOffset(currEntity, en, dist*num*neg);
                bulge = arc1.getBulge();
            } else {
                currEntity = &line1;
                bulge = 0.0;
                calculateOffset(currEntity, en, dist*num*neg);
            }
            if (first) {
                if (closed) {
                    if (prevEntity->rtti()==RS2::EntityArc) {
                        prevEntity = calculateOffset(&arcFirst, prevEntity, dist*num*neg);
                    } else {
                        prevEntity = calculateOffset(&lineFirst, prevEntity, dist*num*neg);
                    }
                    v = calculateIntersection(prevEntity, currEntity);
                }
                if (!v.valid) {
                    v = currEntity->getStartpoint();
                    closed = false;
                } else if (currEntity->rtti()==RS2::EntityArc) {
                    //update bulge
                    arc1.setAngle1(arc1.getCenter().angleTo(v));
                    arc1.calculateEndpoints();
                    bulge = arc1.getBulge();
                }
                first = false;
                if (!prevEntity) break; //prevent crash if not exist offset for prevEntity
            } else {
                v = calculateIntersection(prevEntity, currEntity);
                if (!v.valid) {
                    v= prevEntity->getEndpoint();
                    double dess = currEntity->getStartpoint().distanceTo(prevEntity->getEndpoint());
                    if (dess > 1.0e-12) {
                        newPolyline->addVertex(v, bulge);
                        prevEntity = NULL;
                        break;
                    }
                }
                double startAngle = prevEntity->getStartpoint().angleTo(prevEntity->getEndpoint());
                if (prevEntity->rtti()==RS2::EntityArc) {
                    arcFirst.setAngle2(arcFirst.getCenter().angleTo(v));
                    arcFirst.calculateEndpoints();
                    newPolyline->setNextBulge(arcFirst.getBulge());
                }
                //check if the entity are reverted
                if (abs (prevEntity->getStartpoint().angleTo(prevEntity->getEndpoint())- startAngle) > 0.785) {
                    prevEntity = newPolyline->lastEntity();
                    RS_Vector v0 = calculateIntersection(prevEntity, currEntity);
                    if (prevEntity->rtti()==RS2::EntityArc) {
                        ((RS_Arc*)prevEntity)->setAngle2(arcFirst.getCenter().angleTo(v0));
                        ((RS_Arc*)prevEntity)->calculateEndpoints();
                        newPolyline->setNextBulge( ((RS_Arc*)prevEntity)->getBulge() );
                    } else {
                        ((RS_Line*)prevEntity)->setEndpoint(v0);
                        newPolyline->setNextBulge( 0.0 );
                    }
                    newPolyline->setEndpoint(v0);
                }
                if (currEntity->rtti()==RS2::EntityArc) {
                    arc1.setAngle1(arc1.getCenter().angleTo(v));
                    arc1.calculateEndpoints();
                    bulge = arc1.getBulge();
                } else
                    bulge = 0.0;
            }
            if (prevEntity) {
                newPolyline->addVertex(v, bulge, false);
                if (currEntity->rtti()==RS2::EntityArc) {
                    arcFirst.setData(arc1.getData());
                    arcFirst.calculateEndpoints();
                    prevEntity = &arcFirst;
                } else {
                    lineFirst.setStartpoint(line1.getStartpoint());
                    lineFirst.setEndpoint(line1.getEndpoint());
                    prevEntity = &lineFirst;
                }
            }
        }
        //properly terminated, check closed
        if (prevEntity) {
            if (closed) {
                if (currEntity->rtti()==RS2::EntityArc) {
                    arc1.setAngle2(arc1.getCenter().angleTo(newPolyline->getStartpoint()));
                    arc1.calculateEndpoints();
                    newPolyline->setNextBulge(arc1.getBulge());
                    bulge = arc1.getBulge();
                }
                newPolyline->setClosed(true, bulge);
            } else {
                newPolyline->addVertex(currEntity->getEndpoint(), bulge);
            }
        }
        if (!newPolyline->isEmpty()) {
            container->addEntity(newPolyline);
            document->addUndoable(newPolyline);
        }
    }
    if (document!=NULL) {
        document->endUndoCycle();
    }

    if (graphicView!=NULL) {
        graphicView->redraw();
    }

    return true;
}