Пример #1
0
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);
    }
}
Пример #3
0
/**
 * 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);
}
Пример #4
0
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;
}
Пример #6
0
/**
 * 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;
}
Пример #7
0
/**
 * 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";
}
Пример #8
0
/**
 * 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);
		    }
		  
	       }
	  }
     }
}
Пример #9
0
/**
 * 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);
		    }
		  
	       }
	  }
     }
}