Ejemplo n.º 1
0
/**
 * Selects all entities within the given area.
 *
 * @param select True to select, False to deselect the entities.
 */
void RS_EntityContainer::selectWindow(RS_Vector v1, RS_Vector v2,
                                      bool select, bool cross) {

    bool included;

    for (RS_Entity* e=firstEntity(RS2::ResolveNone);
            e!=NULL;
            e=nextEntity(RS2::ResolveNone)) {

        included = false;

        if (e->isVisible()) {
            if (e->isInWindow(v1, v2)) {
                //e->setSelected(select);
                included = true;
            } else 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 (e->isContainer()) {
                    RS_EntityContainer* ec = (RS_EntityContainer*)e;
                    for (RS_Entity* se=ec->firstEntity(RS2::ResolveAll);
                            se!=NULL && included==false;
                            se=ec->nextEntity(RS2::ResolveAll)) {

                        for (int i=0; i<4; ++i) {
                            sol = RS_Information::getIntersection(
                                      se, &l[i], true);
                            if (sol.hasValid()) {
                                included = true;
                                break;
                            }
                        }
                    }
                } else {
                    for (int i=0; i<4; ++i) {
                        sol = RS_Information::getIntersection(e, &l[i], true);
                        if (sol.hasValid()) {
                            included = true;
                            break;
                        }
                    }
                }
            }
        }

        if (included) {
            e->setSelected(select);
        }
    }
}
/**
 * Selects all entities within the given area.
 *
 * @param select True to select, False to deselect the entities.
 */
void RS_EntityContainer::selectWindow(RS_Vector v1, RS_Vector v2,
                                      bool select, bool cross) {

    bool included;

	for(auto e: entities){

        included = false;

        if (e->isVisible()) {
            if (e->isInWindow(v1, v2)) {
                //e->setSelected(select);
                included = true;
			} else if (cross) {
				RS_EntityContainer l;
				l.addRectangle(v1, v2);
                RS_VectorSolutions sol;

                if (e->isContainer()) {
                    RS_EntityContainer* ec = (RS_EntityContainer*)e;
                    for (RS_Entity* se=ec->firstEntity(RS2::ResolveAll);
						 se && included==false;
                         se=ec->nextEntity(RS2::ResolveAll)) {

                        if (se->rtti() == RS2::EntitySolid){
							included = static_cast<RS_Solid*>(se)->isInCrossWindow(v1,v2);
                        } else {
							for (auto line: l) {
                                sol = RS_Information::getIntersection(
											se, line, true);
                                if (sol.hasValid()) {
                                    included = true;
                                    break;
                                }
                            }
                        }
                    }
                } else if (e->rtti() == RS2::EntitySolid){
					included = static_cast<RS_Solid*>(e)->isInCrossWindow(v1,v2);
                } else {
					for (auto line: l) {
						sol = RS_Information::getIntersection(e, line, true);
                        if (sol.hasValid()) {
                            included = true;
                            break;
                        }
                    }
                }
            }
        }

        if (included) {
            e->setSelected(select);
        }
    }
}
Ejemplo n.º 3
0
/**
 * Selects all entities that are intersected by the given line.
 *
 * @param v1 Startpoint of line.
 * @param v2 Endpoint of line.
 * @param select true: select, false: deselect
 */
void RS_Selection::selectIntersected(const RS_Vector& v1, const RS_Vector& v2,
                                     bool select) {

    RS_Line line(NULL, RS_LineData(v1, v2));
    bool inters;

    for (RS_Entity* e=container->firstEntity(); e!=NULL;
            e=container->nextEntity()) {
    //for (uint i=0; i<container->count(); ++i) {
        //RS_Entity* e = container->entityAt(i);

        if (e!=NULL && e->isVisible()) {

            inters = false;

            // select containers / groups:
            if (e->isContainer()) {
                RS_EntityContainer* ec = (RS_EntityContainer*)e;

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

                    RS_VectorSolutions sol =
                        RS_Information::getIntersection(&line, e2, true);

                    if (sol.hasValid()) {
                        inters = true;
                    }
                }
            } else {

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

                if (sol.hasValid()) {
                    inters = true;
                }
            }

            if (inters) {
                if (graphicView!=NULL) {
                    graphicView->deleteEntity(e);
                }

                e->setSelected(select);

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

}
Ejemplo n.º 4
0
RS_Vector RS_Line::prepareTrim(const RS_Vector& trimCoord,
                               const RS_VectorSolutions& trimSol) {
//prepare trimming for multiple intersections
    if ( ! trimSol.hasValid()) return(RS_Vector(false));
    if ( trimSol.getNumber() == 1 ) return(trimSol.get(0));
    auto&& vp0=trimSol.getClosest(trimCoord,NULL,0);

    double dr2=trimCoord.squaredTo(vp0);
    //the trim point found is closer to mouse location (trimCoord) than both end points, return this trim point
    if(dr2 < trimCoord.squaredTo(getStartpoint()) && dr2 < trimCoord.squaredTo(getEndpoint())) return vp0;
    //the closer endpoint to trimCoord
    RS_Vector vp1=(trimCoord.squaredTo(getStartpoint()) <= trimCoord.squaredTo(getEndpoint()))?getStartpoint():getEndpoint();

    //searching for intersection in the direction of the closer end point
    auto&& dvp1=vp1 - trimCoord;
    RS_VectorSolutions sol1;
    for(size_t i=0; i<trimSol.size(); i++){
        auto&& dvp2=trimSol.at(i) - trimCoord;
        if( RS_Vector::dotP(dvp1, dvp2) > RS_TOLERANCE) sol1.push_back(trimSol.at(i));
    }
    //if found intersection in direction, return the closest to trimCoord from it
    if(sol1.size()) return sol1.getClosest(trimCoord,NULL,0);

    //no intersection by direction, return previously found closest intersection
    return vp0;
}
void RS_ActionInfoAngle::trigger() {

    RS_DEBUG->print("RS_ActionInfoAngle::trigger()");

    if (entity1!=NULL && entity2!=NULL) {
        RS_VectorSolutions sol =
            RS_Information::getIntersection(entity1, entity2, false);

        if (sol.hasValid()) {
            intersection = sol.get(0);

            if (intersection.valid && point1.valid && point2.valid) {
                double angle1 = intersection.angleTo(point1);
                double angle2 = intersection.angleTo(point2);
                double angle = RS_Math::rad2deg(remainder(angle2-angle1,2.*M_PI));

                QString str;
                str.setNum(angle);
                str += QChar(0xB0);
                if(angle<0.) {
                    QString str2;
                    str2.setNum(angle+360.); //positive value
                    str += QString(" or %1%2").arg(str2).arg(QChar(0xB0));
                }
                RS_DIALOGFACTORY->commandMessage(tr("Angle: %1").arg(str));
            }
        } else {
            RS_DIALOGFACTORY->commandMessage(tr("Lines are parallel"));
        }
    }
}
Ejemplo n.º 6
0
RS_Vector RS_Line::prepareTrim(const RS_Vector& trimCoord,
                               const RS_VectorSolutions& trimSol) {
//prepare trimming for multiple intersections
    if ( ! trimSol.hasValid()) return(RS_Vector(false));
    if ( trimSol.getNumber() == 1 ) return(trimSol.get(0));
    return trimSol.getClosest(trimCoord,NULL,0);
}
Ejemplo n.º 7
0
void RS_ActionInfoAngle::trigger() {

    RS_DEBUG->print("RS_ActionInfoAngle::trigger()");

    if (entity1 && entity2) {
        RS_VectorSolutions sol =
            RS_Information::getIntersection(entity1, entity2, false);

        if (sol.hasValid()) {
            intersection = sol.get(0);

            if (intersection.valid && point1.valid && point2.valid) {
                double angle1 = intersection.angleTo(point1);
                double angle2 = intersection.angleTo(point2);
				double angle = remainder(angle2-angle1,2.*M_PI);

				QString str = RS_Units::formatAngle(angle,
													graphic->getAngleFormat(), graphic->getAnglePrecision());

                if(angle<0.){
					str += " or ";
					str += RS_Units::formatAngle(angle + 2.*M_PI,
												 graphic->getAngleFormat(), graphic->getAnglePrecision());
                }
                RS_DIALOGFACTORY->commandMessage(tr("Angle: %1").arg(str));
            }
        } else {
            RS_DIALOGFACTORY->commandMessage(tr("Lines are parallel"));
        }
    }
}
Ejemplo n.º 8
0
void RS_ActionInfoAngle::trigger() {

    RS_DEBUG->print("RS_ActionInfoAngle::trigger()");

    if (entity1!=NULL && entity2!=NULL) {
        RS_VectorSolutions sol =
            RS_Information::getIntersection(entity1, entity2, false);

        if (sol.hasValid()) {
            intersection = sol.get(0);

            if (intersection.valid && point1.valid && point2.valid) {
                double angle1 = intersection.angleTo(point1);
                double angle2 = intersection.angleTo(point2);
                double angle = fabs(angle2-angle1);

                QString str;
                str.sprintf("%.6f", RS_Math::rad2deg(angle));
                RS_DIALOGFACTORY->commandMessage(tr("Angle: %1%2")
                                                 .arg(str).arg(QChar(0xB0)));
            }
        } else {
            RS_DIALOGFACTORY->commandMessage(tr("Lines are parallel"));
        }
    }
}
Ejemplo n.º 9
0
RS_Vector RS_Ellipse::prepareTrim(const RS_Vector& trimCoord,
                                  const RS_VectorSolutions& trimSol) {
//special trimming for ellipse arc
        RS_DEBUG->print("RS_Ellipse::prepareTrim()");
    if( ! trimSol.hasValid() ) return (RS_Vector(false));
    if( trimSol.getNumber() == 1 ) return (trimSol.get(0));
    double am=getEllipseAngle(trimCoord);
    QList<double> ias;
    double ia(0.),ia2(0.);
    RS_Vector is,is2;
    for(int ii=0; ii<trimSol.getNumber(); ii++) { //find closest according ellipse angle
        ias.append(getEllipseAngle(trimSol.get(ii)));
        if( !ii ||  fabs( remainder( ias[ii] - am, 2*M_PI)) < fabs( remainder( ia -am, 2*M_PI)) ) {
            ia = ias[ii];
            is = trimSol.get(ii);
        }
    }
    qSort(ias.begin(),ias.end());
    for(int ii=0; ii<trimSol.getNumber(); ii++) { //find segment to enclude trimCoord
        if ( ! RS_Math::isSameDirection(ia,ias[ii],RS_TOLERANCE)) continue;
        if( RS_Math::isAngleBetween(am,ias[(ii+trimSol.getNumber()-1)% trimSol.getNumber()],ia,false))  {
            ia2=ias[(ii+trimSol.getNumber()-1)% trimSol.getNumber()];
        } else {
            ia2=ias[(ii+1)% trimSol.getNumber()];
        }
        break;
    }
    for(int ii=0; ii<trimSol.getNumber(); ii++) { //find segment to enclude trimCoord
        if ( ! RS_Math::isSameDirection(ia2,getEllipseAngle(trimSol.get(ii)),RS_TOLERANCE)) continue;
        is2=trimSol.get(ii);
        break;
    }
    if(RS_Math::isSameDirection(getAngle1(),getAngle2(),RS_TOLERANCE_ANGLE)
            ||  RS_Math::isSameDirection(ia2,ia,RS_TOLERANCE) ) {
        //whole ellipse
        if( !RS_Math::isAngleBetween(am,ia,ia2,isReversed())) {
            std::swap(ia,ia2);
            std::swap(is,is2);
        }
        setAngle1(ia);
        setAngle2(ia2);
        double da1=fabs(remainder(getAngle1()-am,2*M_PI));
        double da2=fabs(remainder(getAngle2()-am,2*M_PI));
        if(da2<da1) {
            std::swap(is,is2);
        }

    } else {
        double dia=fabs(remainder(ia-am,2*M_PI));
        double dia2=fabs(remainder(ia2-am,2*M_PI));
        double ai_min=std::min(dia,dia2);
        double da1=fabs(remainder(getAngle1()-am,2*M_PI));
        double da2=fabs(remainder(getAngle2()-am,2*M_PI));
        double da_min=std::min(da1,da2);
        if( da_min < ai_min ) {
            //trimming one end of arc
            bool irev= RS_Math::isAngleBetween(am,ia2,ia, isReversed()) ;
            if ( RS_Math::isAngleBetween(ia,getAngle1(),getAngle2(), isReversed()) &&
                    RS_Math::isAngleBetween(ia2,getAngle1(),getAngle2(), isReversed()) ) { //
                if(irev) {
                    setAngle2(ia);
                    setAngle1(ia2);
                } else {
                    setAngle1(ia);
                    setAngle2(ia2);
                }
                da1=fabs(remainder(getAngle1()-am,2*M_PI));
                da2=fabs(remainder(getAngle2()-am,2*M_PI));
            }
            if( ((da1 < da2) && (RS_Math::isAngleBetween(ia2,ia,getAngle1(),isReversed()))) ||
                    ((da1 > da2) && (RS_Math::isAngleBetween(ia2,getAngle2(),ia,isReversed())))
              ) {
                std::swap(is,is2);
                //std::cout<<"reset: angle1="<<getAngle1()<<" angle2="<<getAngle2()<<" am="<< am<<" is="<<getEllipseAngle(is)<<" ia2="<<ia2<<std::endl;
            }
        } else {
            //choose intersection as new end
            if( dia > dia2) {
                std::swap(is,is2);
                std::swap(ia,ia2);
            }
            if(RS_Math::isAngleBetween(ia,getAngle1(),getAngle2(),isReversed())) {
                if(RS_Math::isAngleBetween(am,getAngle1(),ia,isReversed())) {
                    setAngle2(ia);
                } else {
                    setAngle1(ia);
                }
            }
        }
    }
    return is;
}
Ejemplo n.º 10
0
bool RS_Solid::isInCrossWindow(const RS_Vector& v1,const RS_Vector& v2)const {
//    bool sol = false;
    RS_Vector vBL, vTR;
    RS_VectorSolutions sol;
//sort imput vectors to BottomLeft & TopRight
    if (v1.x<v2.x) {
        vBL.x = v1.x;
        vTR.x = v2.x;
    } else {
        vBL.x = v2.x;
        vTR.x = v1.x;
    }
    if (v1.y<v2.y) {
        vBL.y = v1.y;
        vTR.y = v2.y;
    } else {
        vBL.y = v2.y;
        vTR.y = v1.y;
    }
    //Check if is out of window
    if ( getMin().x > vTR.x || getMax().x < vBL.x
           || getMin().y > vTR.y || getMax().y < vBL.y) {
        return false;
    }
	std::vector<RS_Line> l;
	l.push_back(RS_Line(nullptr, RS_LineData(data.corner[0], data.corner[1])));
	l.push_back(RS_Line(nullptr, RS_LineData(data.corner[1], data.corner[2])));
    if (data.corner[3].valid) {
		l.push_back(RS_Line(nullptr, RS_LineData(data.corner[2], data.corner[3])));
		l.push_back(RS_Line(nullptr, RS_LineData(data.corner[3], data.corner[0])));
    } else {
		l.push_back(RS_Line(nullptr, RS_LineData(data.corner[2], data.corner[0])));
    }
    //Find crossing edge
    if (getMax().x > vBL.x && getMin().x < vBL.x) {//left
		RS_Line edge = RS_Line(nullptr, RS_LineData(vBL, RS_Vector(vBL.x, vTR.y)));
		for(auto const& l0: l) {
			sol = RS_Information::getIntersection(&edge, &l0, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }
    if (getMax().x > vTR.x && getMin().x < vTR.x) {//right
		RS_Line edge = RS_Line(nullptr, RS_LineData(RS_Vector(vTR.x, vBL.y), vTR));
		for(auto const& l0: l) {
			sol = RS_Information::getIntersection(&edge, &l0, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }
    if (getMax().y > vBL.y && getMin().y < vBL.y) {//bottom
		RS_Line edge = RS_Line(nullptr, RS_LineData(vBL, RS_Vector(vTR.x, vBL.y)));
		for(auto const& l0: l) {
			sol = RS_Information::getIntersection(&edge, &l0, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }
    if(getMax().y > vTR.y && getMin().y < vTR.y) {//top
		RS_Line edge = RS_Line(nullptr, RS_LineData(RS_Vector(vBL.x, vTR.y), vTR));
		for(auto const& l0: l) {
			sol = RS_Information::getIntersection(&edge, &l0, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }
    return false;
}
Ejemplo n.º 11
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";
}
Ejemplo n.º 12
0
bool RS_Solid::isInCrossWindow(const RS_Vector& v1, const RS_Vector& v2) const
{
    RS_Vector vBL;
    RS_Vector vTR;
    RS_VectorSolutions sol;

    //sort input vectors to BottomLeft & TopRight
    if (v1.x < v2.x) {
        vBL.x = v1.x;
        vTR.x = v2.x;
    }
    else {
        vBL.x = v2.x;
        vTR.x = v1.x;
    }
    if (v1.y < v2.y) {
        vBL.y = v1.y;
        vTR.y = v2.y;
    }
    else {
        vBL.y = v2.y;
        vTR.y = v1.y;
    }

    //Check if entity is out of window
    if (getMin().x > vTR.x
        || getMax().x < vBL.x
        || getMin().y > vTR.y
        || getMax().y < vBL.y) {
        return false;
    }

    std::vector<RS_Line> border;
    border.emplace_back( data.corner[0], data.corner[1]);
    border.emplace_back( data.corner[1], data.corner[2]);
    if (isTriangle()) {
        border.emplace_back( data.corner[2], data.corner[0]);
    }
    else {
        border.emplace_back( data.corner[2], data.corner[3]);
        border.emplace_back( data.corner[3], data.corner[0]);
    }

    //Find crossing edge
    if (getMax().x > vBL.x
        && getMin().x < vBL.x) {    //left
        RS_Line edge {vBL, {vBL.x, vTR.y}};
        for (auto const& line: border) {
            sol = RS_Information::getIntersection(&edge, &line, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }
    if (getMax().x > vTR.x
        && getMin().x < vTR.x) {    //right
        RS_Line edge {{vTR.x, vBL.y}, vTR};
        for (auto const& line: border) {
            sol = RS_Information::getIntersection(&edge, &line, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }
    if (getMax().y > vBL.y
        && getMin().y < vBL.y) {    //bottom
        RS_Line edge {vBL, {vTR.x, vBL.y}};
        for(auto const& line: border) {
            sol = RS_Information::getIntersection(&edge, &line, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }
    if(getMax().y > vTR.y
       && getMin().y < vTR.y) { //top
        RS_Line edge {{vBL.x, vTR.y}, vTR};
        for(auto const& line: border) {
            sol = RS_Information::getIntersection(&edge, &line, true);
            if (sol.hasValid()) {
                return true;
            }
        }
    }

    return false;
}