void Plugin_Entity::getPolylineData(QList<Plug_VertexData> *data){ if (entity == NULL) return; RS2::EntityType et = entity->rtti(); if (et != RS2::EntityPolyline) return; RS_Polyline *l = static_cast<RS_Polyline*>(entity); RS_Entity* nextEntity = 0; RS_AtomicEntity* ae = NULL; RS_Entity* v = l->firstEntity(RS2::ResolveNone); double bulge=0.0; //bad polyline without vertex if (v == NULL) return; //First polyline vertex if (v->rtti() == RS2::EntityArc) { bulge = ((RS_Arc*)v)->getBulge(); } ae = (RS_AtomicEntity*)v; data->append(Plug_VertexData(QPointF(ae->getStartpoint().x, ae->getStartpoint().y),bulge)); for (v=l->firstEntity(RS2::ResolveNone); v!=NULL; v=nextEntity) { nextEntity = l->nextEntity(RS2::ResolveNone); bulge = 0.0; if (!v->isAtomic()) { continue; } ae = (RS_AtomicEntity*)v; if (nextEntity!=NULL) { if (nextEntity->rtti()==RS2::EntityArc) { bulge = ((RS_Arc*)nextEntity)->getBulge(); } } if (l->isClosed()==false || nextEntity!=NULL) { data->append(Plug_VertexData(QPointF(ae->getEndpoint().x, ae->getEndpoint().y),bulge)); } } }
void RS_ActionDrawCircleTan2_1P::mouseReleaseEvent(QMouseEvent* e) { // Proceed to next status if (e->button()==Qt::LeftButton) { switch (getStatus()) { case SetCircle1: case SetCircle2: { circles.resize(getStatus()); RS_AtomicEntity* en = static_cast<RS_AtomicEntity*>(catchCircle(e)); if (en==NULL) return; // circle = static_cast<RS_AtomicEntity*>(en); en->setHighlighted(true); circles.push_back(en); graphicView->redraw(RS2::RedrawDrawing); setStatus(getStatus()+1); } break; case SetPoint: { RS_Vector snapped = snapPoint(e); RS_CoordinateEvent ce(snapped); coordinateEvent(&ce); } break; case SetCenter: coord=graphicView->toGraph(e->x(),e->y()); if(preparePreview()) trigger(); break; default: break; } } else if (e->button()==Qt::RightButton) { // Return to last status: if(getStatus()>0){ deletePreview(); } init(getStatus()-1); } }
/** * Selects all entities that are connected to the given entity. * * @param e The entity where the algorithm starts. Must be an atomic entity. */ void RS_Selection::selectContour(RS_Entity* e) { if (e==NULL) { return; } if (!e->isAtomic()) { return; } bool select = !e->isSelected(); RS_AtomicEntity* ae = (RS_AtomicEntity*)e; RS_Vector p1 = ae->getStartpoint(); RS_Vector p2 = ae->getEndpoint(); bool found = false; // (de)select 1st entity: if (graphicView!=NULL) { graphicView->deleteEntity(e); } e->setSelected(select); if (graphicView!=NULL) { graphicView->drawEntity(e); } do { found = false; for (RS_Entity* en=container->firstEntity(); en!=NULL; en=container->nextEntity()) { //for (uint i=0; i<container->count(); ++i) { //RS_Entity* en = container->entityAt(i); if (en!=NULL && en->isVisible() && en->isAtomic() && en->isSelected()!=select && (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) { ae = (RS_AtomicEntity*)en; bool doit = false; // startpoint connects to 1st point if (ae->getStartpoint().distanceTo(p1)<1.0e-4) { doit = true; p1 = ae->getEndpoint(); } // endpoint connects to 1st point else if (ae->getEndpoint().distanceTo(p1)<1.0e-4) { doit = true; p1 = ae->getStartpoint(); } // startpoint connects to 2nd point else if (ae->getStartpoint().distanceTo(p2)<1.0e-4) { doit = true; p2 = ae->getEndpoint(); } // endpoint connects to 1st point else if (ae->getEndpoint().distanceTo(p2)<1.0e-4) { doit = true; p2 = ae->getStartpoint(); } if (doit) { if (graphicView!=NULL) { graphicView->deleteEntity(ae); } ae->setSelected(select); if (graphicView!=NULL) { graphicView->drawEntity(ae); } found = true; } } } } while(found); }
double RS_ActionDrawPolyline::solveBulge(RS_Vector mouse) { double b(0.); bool suc; RS_Arc arc(NULL, RS_ArcData()); RS_Line line(NULL,RS_LineData()); double direction,direction2,delta; RS_AtomicEntity* lastentity; calculatedSegment=false; switch (Mode){ // case Line: // b=0.0; // break; case Tangential: if (polyline){ lastentity = (RS_AtomicEntity*)polyline->lastEntity(); direction = RS_Math::correctAngle( lastentity->getDirection2()+M_PI); line.setStartpoint(point); line.setEndpoint(mouse); direction2=RS_Math::correctAngle(line.getDirection2()+M_PI); delta=direction2-direction; if( fabs(remainder(delta,M_PI))>RS_TOLERANCE_ANGLE ) { b=tan(delta/2); suc = arc.createFrom2PBulge(point,mouse,b); if (suc) arc_data.reset(new RS_ArcData(arc.getData())); else b=0; } break; // if(delta<RS_TOLERANCE_ANGLE || // (delta<M_PI+RS_TOLERANCE_ANGLE && // delta>M_PI-RS_TOLERANCE_ANGLE)) // b=0; // else{ // b=tan((direction2-direction)/2); // suc = arc.createFrom2PBulge(point,mouse,b); // if (suc) // arc_data = arc.getData(); // else // b=0; // } } // else // b=0; // break; case TanRad: if (polyline){ lastentity = (RS_AtomicEntity*)polyline->lastEntity(); direction = RS_Math::correctAngle( lastentity->getDirection2()+M_PI); suc = arc.createFrom2PDirectionRadius(point, mouse, direction,Radius); if (suc){ arc_data.reset(new RS_ArcData(arc.getData())); b=arc.getBulge(); calculatedEndpoint = arc.getEndpoint(); calculatedSegment=true; } // else // b=0; } // else // b=0; break; /* case TanAng: b=tan(Reversed*Angle*M_PI/720.0); break; case TanRadAng: b=tan(Reversed*Angle*M_PI/720.0); break;*/ case Ang: b=tan(m_Reversed*Angle*M_PI/720.0); suc = arc.createFrom2PBulge(point,mouse,b); if (suc) arc_data.reset(new RS_ArcData(arc.getData())); else b=0; break; default: break; /* case RadAngEndp: b=tan(Reversed*Angle*M_PI/720.0); break; case RadAngCenp: b=tan(Reversed*Angle*M_PI/720.0);*/ } return b; }
/** * Rearranges the atomic entities in this container in a way that connected * entities are stored in the right order and direction. * Non-recoursive. Only affects atomic entities in this container. * * @retval true all contours were closed * @retval false at least one contour is not closed */ bool RS_ActionPolylineSegment::convertPolyline(RS_Entity* selectedEntity) { RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline"); RS_Vector current(false); RS_Vector start(false); RS_Vector end(false); RS_EntityContainer tmp; bool closed = true; int pos = container->findEntity(selectedEntity); RS_Entity* e1=container->entityAt(pos); if (!e1) return false; if (document!=NULL) { document->startUndoCycle(); } if (document!=NULL) { if (e1!=NULL && e1->isEdge() && !e1->isContainer() && !e1->isProcessed()) { RS_AtomicEntity* ce = (RS_AtomicEntity*)e1; /////////////////////////////////////////////////// ce->setUndoState(true); document->addUndoable(ce); /////////////////////////////////////////////////// // next contour start: ce->setProcessed(true); tmp.addEntity(ce->clone()); current = ce->getStartpoint(); end = ce->getEndpoint(); // find first connected entities: for (int ei=pos-1; ei>=0; --ei) { RS_Entity* e2=container->entityAt(ei); if (e2!=NULL && e2->isEdge() && !e2->isContainer() && !e2->isProcessed()) { RS_AtomicEntity* e = (RS_AtomicEntity*)e2; /////////////////////////////////////////////////// e->setUndoState(true); document->addUndoable(e); /////////////////////////////////////////////////// if (e->getEndpoint().distanceTo(current) < 1.0e-4) { e->setProcessed(true); tmp.insertEntity(0,e->clone()); current = e->getStartpoint(); } else if (e->getStartpoint().distanceTo(current) < 1.0e-4) { e->setProcessed(true); RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone(); cl->reverse(); tmp.insertEntity(0,cl); current = cl->getStartpoint(); }else break; } } if (current.distanceTo(end)>1.0e-4) { closed = false; } current = ce->getEndpoint(); start = ce->getStartpoint(); // find last connected entities: for (uint ei=pos+1; ei<container->count(); ++ei) { RS_Entity* e2=container->entityAt(ei); /////////////////////////////////////////////////// e2->setUndoState(true); document->addUndoable(e2); /////////////////////////////////////////////////// if (e2!=NULL && e2->isEdge() && !e2->isContainer() && !e2->isProcessed()) { RS_AtomicEntity* e = (RS_AtomicEntity*)e2; if (e->getStartpoint().distanceTo(current) < 1.0e-4) { e->setProcessed(true); tmp.addEntity(e->clone()); current = e->getEndpoint(); } else if (e->getEndpoint().distanceTo(current) < 1.0e-4) { e->setProcessed(true); RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone(); cl->reverse(); tmp.addEntity(cl); current = cl->getEndpoint(); }else break; } } if (current.distanceTo(start)>1.0e-4) { closed = false; } } } if (document!=NULL) { document->endUndoCycle(); } RS_Polyline* newPolyline = new RS_Polyline(container, RS_PolylineData(RS_Vector(false), RS_Vector(false), closed)); newPolyline->setLayerToActive(); newPolyline->setPenToActive(); // add new polyline: bool first = true; RS_Entity* lastEntity = tmp.lastEntity(); for (RS_Entity* en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) { en->setProcessed(false); double bulge = 0.0; if (en->rtti()==RS2::EntityArc) { bulge = ((RS_Arc*)en)->getBulge(); } else { bulge = 0.0; } if (first) { newPolyline->setNextBulge(bulge); newPolyline->addVertex(((RS_AtomicEntity*)en)->getStartpoint()); first = false; } if (en!=lastEntity || closed==false){ newPolyline->setNextBulge(bulge); newPolyline->addVertex(((RS_AtomicEntity*)en)->getEndpoint()); } } double bulge = lastEntity->rtti() == RS2::EntityArc? ((RS_Arc*)lastEntity)->getBulge():0.0; newPolyline->setNextBulge(bulge); newPolyline->endPolyline(); container->addEntity(newPolyline); if (graphicView!=NULL) { graphicView->drawEntity(newPolyline); } if (document!=NULL) { document->startUndoCycle(); document->addUndoable(newPolyline); document->endUndoCycle(); } RS_DEBUG->print("RS_ActionPolylineSegment::convertPolyline: OK"); return closed; }
/** * Rearranges the atomic entities in this container in a way that connected * entities are stored in the right order and direction. * Non-recoursive. Only affects atomic entities in this container. * * @retval true all contours were closed * @retval false at least one contour is not closed */ bool RS_EntityContainer::optimizeContours() { RS_DEBUG->print("RS_EntityContainer::optimizeContours"); RS_Vector current(false); RS_Vector start(false); RS_EntityContainer tmp; bool changed = false; bool closed = true; for (uint ci=0; ci<count(); ++ci) { RS_Entity* e1=entityAt(ci); if (e1!=NULL && e1->isEdge() && !e1->isContainer() && !e1->isProcessed()) { RS_AtomicEntity* ce = (RS_AtomicEntity*)e1; // next contour start: ce->setProcessed(true); tmp.addEntity(ce->clone()); current = ce->getEndpoint(); start = ce->getStartpoint(); // find all connected entities: bool done; do { done = true; for (uint ei=0; ei<count(); ++ei) { RS_Entity* e2=entityAt(ei); if (e2!=NULL && e2->isEdge() && !e2->isContainer() && !e2->isProcessed()) { RS_AtomicEntity* e = (RS_AtomicEntity*)e2; if (e->getStartpoint().distanceTo(current) < 1.0e-4) { e->setProcessed(true); tmp.addEntity(e->clone()); current = e->getEndpoint(); done=false; } else if (e->getEndpoint().distanceTo(current) < 1.0e-4) { e->setProcessed(true); RS_AtomicEntity* cl = (RS_AtomicEntity*)e->clone(); cl->reverse(); tmp.addEntity(cl); current = cl->getEndpoint(); changed = true; done=false; } } } if (!done) { changed = true; } } while (!done); if (current.distanceTo(start)>1.0e-4) { closed = false; } } } // remove all atomic entities: bool done; do { done = true; for (RS_Entity* en=firstEntity(); en!=NULL; en=nextEntity()) { if (!en->isContainer()) { removeEntity(en); done = false; break; } } } while (!done); // add new sorted entities: for (RS_Entity* en=tmp.firstEntity(); en!=NULL; en=tmp.nextEntity()) { en->setProcessed(false); addEntity(en->clone()); } RS_DEBUG->print("RS_EntityContainer::optimizeContours: OK"); return closed; }
/** * Selects all circles (and arcs min. 3/4 circle) with same diameter and same layer, * in a window (v1, v2) * mosty used with CAM bores * * @param e Must be an circle or arc (min. 3/4 circle) */ void RS_Selection::selectCircles(RS_Entity* e, RS_Vector v1, RS_Vector v2 /*, bool inside=true */ ) { if (e==NULL) return; if (!e->isAtomic()) return; e->toggleSelected(); // bool cross = v2.y > v1.y; bool cross = v1.x > v2.x; bool select = !e->isSelected(); RS_AtomicEntity* ae = (RS_AtomicEntity*)e; double r_clicked = 0; RS_Layer* layer_clicked = 0; if (graphicView!=NULL) graphicView->drawEntity(e); if (ae->rtti()==RS2::EntityArc || ae->rtti()==RS2::EntityCircle) { r_clicked = ae->getRadius(); if (ae->rtti()==RS2::EntityArc) if(ae->getAngleLength() < 4.66) /* ca. 267 grad (knapp 3/4 kreis) */ { r_clicked = 0; RS_DIALOGFACTORY->commandMessage("selected arc has AngleLength < 4.66"); } layer_clicked = ae->getLayer(); } for (RS_Entity* en=container->firstEntity(); en!=NULL; en=container->nextEntity()) { int included = 0; if (en!=NULL && en->isVisible() && en->isAtomic() && en->isSelected()!=select && (en->rtti()==RS2::EntityArc || en->rtti()==RS2::EntityCircle) && (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) { ae = (RS_AtomicEntity*)en; if(en->isInWindow(v1, v2)) included++; if (cross == true) { RS_Line l[] = { RS_Line(NULL, RS_LineData(v1, RS_Vector(v2.x, v1.y))), RS_Line(NULL, RS_LineData(RS_Vector(v2.x, v1.y), v2)), RS_Line(NULL, RS_LineData(v2, RS_Vector(v1.x, v2.y))), RS_Line(NULL, RS_LineData(RS_Vector(v1.x, v2.y), v1)) }; RS_VectorSolutions sol; if (ae->isContainer()) continue; else { for (int i=0; i<4; ++i) { sol = RS_Information::getIntersection(ae, &l[i], true); if (sol.hasValid()) { included++; break; } } } } // ----------------------- if(included) { double rc = ae->getRadius(); double rdiff = fabs (rc - r_clicked); if ((r_clicked > 0.000003) && (0.000003 > rdiff) && (ae->getLayer() == layer_clicked)) { if (graphicView!=NULL) { graphicView->deleteEntity(ae); } ae->setSelected(select); if (graphicView!=NULL) { graphicView->drawEntity(ae); } } } } } //std::cerr << "ende in rs_selection.cpp \n"; }
/** * Selects all circles (and arcs min. 3/4 circle) with same diameter and same layer, * on a pitch circle (Teilkreis) * mosty used with CAM bores * * @param e Must be an circle or arc (min. 3/4 circle) */ void RS_Selection::selectCircles(RS_Entity* e, RS_Entity* tk ) { //std::cerr << "in selectCircles(RS_Entity* e, RS_Entity* tk ) \n"; if (e==NULL || tk==NULL) return; if (!e->isAtomic()) return; if (tk->rtti()!=RS2::EntityCircle) return; RS_Vector tkcc = tk->getCenter(); double tkr = tk->getRadius(); // std::cerr << "tkcc.x, r " << tkcc.x << " " << tkr << "\n"; e->toggleSelected(); bool select = !e->isSelected(); RS_AtomicEntity* ae = (RS_AtomicEntity*)e; double r_clicked = 0; RS_Layer* layer_clicked = 0; if (graphicView!=NULL) graphicView->drawEntity(e); if (ae->rtti()==RS2::EntityArc || ae->rtti()==RS2::EntityCircle) { r_clicked = ae->getRadius(); if (ae->rtti()==RS2::EntityArc && ae->getAngleLength() < 4.66) /* ca. 267 grad (knapp 3/4 kreis) */ r_clicked = 0; layer_clicked = ae->getLayer(); } for (RS_Entity* en=container->firstEntity(); en!=NULL; en=container->nextEntity()) { if (en!=NULL && en->isVisible() && en->isAtomic() && en->isSelected()!=select && (en->rtti()==RS2::EntityArc || en->rtti()==RS2::EntityCircle) && fabs (tkr - tkcc.distanceTo(en->getCenter() )) < 0.000003 && (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) { ae = (RS_AtomicEntity*)en; double rc = ae->getRadius(); double rdiff = fabs (rc - r_clicked); // std::cerr << "r_clicked " << r_clicked << " rc " << rc << "\n"; if ((r_clicked > 0.000003) && (0.000003 > rdiff) && (ae->getLayer() == layer_clicked)) { if (graphicView!=NULL) { graphicView->deleteEntity(ae); } ae->setSelected(select); if (graphicView!=NULL) { graphicView->drawEntity(ae); } } } } }
/** * Selects all circles (and arcs min. 3/4 circle) with same diameter and same layer, * mosty used with CAM bores * * @param e Must be an circle or arc (min. 3/4 circle) */ void RS_Selection::selectCircles(RS_Entity* e) { if (e==NULL) return; if (!e->isAtomic()) return; bool select = !e->isSelected(); RS_AtomicEntity* ae = (RS_AtomicEntity*)e; double r_clicked = 0; RS_Layer* layer_clicked = 0; // (de)select 1st entity: if (graphicView!=NULL) graphicView->deleteEntity(e); e->setSelected(select); if (graphicView!=NULL) graphicView->drawEntity(e); std::cout << " RS_Selection::selectCircles \n"; if (ae->rtti()==RS2::EntityArc || ae->rtti()==RS2::EntityCircle) { r_clicked = ae->getRadius(); if (ae->rtti()==RS2::EntityArc && ae->getAngleLength() < 4.66) /* ca. 267 grad (knapp 3/4 kreis) */ r_clicked = 0; layer_clicked = ae->getLayer(); } for (RS_Entity* en=container->firstEntity(); en!=NULL; en=container->nextEntity()) { if (en!=NULL && en->isVisible() && en->isAtomic() && en->isSelected()!=select && (en->rtti()==RS2::EntityArc || en->rtti()==RS2::EntityCircle) && (en->getLayer()==NULL || en->getLayer()->isLocked()==false)) { ae = (RS_AtomicEntity*)en; double rc = ae->getRadius(); double rdiff = fabs (rc - r_clicked); if ((r_clicked > 0.000003) && (0.000003 > rdiff) && (ae->getLayer() == layer_clicked)) { if (graphicView!=NULL) { graphicView->deleteEntity(ae); } ae->setSelected(select); if (graphicView!=NULL) { graphicView->drawEntity(ae); } } } } }