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; }
/** * Rearranges the lines, arcs or opened polylines entities * in this container, non-recoursive. * document can not be null * * @retval true contour are closed * @retval false if the contour is not closed * * @author Rallaz */ bool RS_ActionPolylineSegment::convertPolyline(RS_Entity* selectedEntity) { RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline"); QList<RS_Entity*> remaining; QList<RS_Entity*> completed; RS_Vector start = selectedEntity->getStartpoint(); RS_Vector end = selectedEntity->getEndpoint(); completed.append(selectedEntity); //get list with useful entities for (uint i=0; i<container->count(); ++i) { RS_Entity* e1 = container->entityAt(i); if (e1->isLocked() || !e1->isVisible() || e1 == selectedEntity) continue; if (e1->rtti()==RS2::EntityLine || e1->rtti()==RS2::EntityArc || e1->rtti()==RS2::EntityPolyline) { if (targetEntity->rtti()==RS2::EntityPolyline && ((RS_Polyline*)targetEntity)->isClosed()) continue; if (e1 == selectedEntity) continue; remaining.append(e1); } } // find all connected entities: bool done = true; do { done = true; for (int i=(remaining.size() -1) ; i>=0; --i) { RS_Entity* e=remaining.at(i); if (e->getEndpoint().distanceTo(start) < 1.0e-4) { completed.prepend( e); start = e->getStartpoint(); remaining.removeAt(i); done = false; } else if (e->getStartpoint().distanceTo(start) < 1.0e-4) { completed.prepend( e); start = e->getEndpoint(); remaining.removeAt(i); done = false; } else if (e->getEndpoint().distanceTo(end) < 1.0e-4) { completed.append( e); end = e->getStartpoint(); remaining.removeAt(i); done = false; } else if (e->getStartpoint().distanceTo(end) < 1.0e-4) { completed.append( e); end = e->getEndpoint(); remaining.removeAt(i); done = false; } } } while (!done); //cleanup for no more needed list remaining.clear(); bool closed = false; if (document!=NULL) { document->startUndoCycle(); bool revert = false; double bulge = 0.0; if (end.distanceTo(start) < 1.0e-4) closed = true; RS_Polyline* newPolyline = new RS_Polyline(container, RS_PolylineData(RS_Vector(false), RS_Vector(false), closed)); newPolyline->setLayerToActive(); newPolyline->setPenToActive(); //complete polyline end =start; while (!completed.isEmpty()) { RS_Entity* e2= completed.takeFirst(); e2->setUndoState(true); document->addUndoable(e2); if (e2->getStartpoint().distanceTo(end) < 1.0e-4) { revert = false; start = e2->getStartpoint(); end = e2->getEndpoint(); } else { revert = true; start = e2->getEndpoint(); end = e2->getStartpoint(); } if (e2->rtti()==RS2::EntityArc) { if (revert) bulge = ((RS_Arc*)e2)->getBulge()*-1; else bulge = ((RS_Arc*)e2)->getBulge(); } else bulge = 0.0; if (e2->rtti()==RS2::EntityPolyline) { newPolyline->addVertex(start, bulge); end = appendPol(newPolyline, (RS_Polyline*)e2, revert); } else newPolyline->addVertex(start, bulge); } if (closed) newPolyline->setClosed(true); else newPolyline->addVertex(end, bulge); newPolyline->endPolyline(); container->addEntity(newPolyline); if (graphicView!=NULL) { graphicView->drawEntity(newPolyline); } document->addUndoable(newPolyline); document->endUndoCycle(); } RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline: OK"); return closed; }
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(); }