//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 // Contenuto : Implementazione della classe Tool // // // // Modifiche : 22.01.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CurveLine.h" #include "CurveArc.h" #include "Tool.h" #include "GeoConst.h" #include "/EgtDev/Include/EGKLinePntTgCurve.h" #include "/EgtDev/Include/EGKFilletChamfer.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include using namespace std ; //---------------------------------------------------------------------------- Tool::Tool( void) : m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG), m_nType( UNDEF), m_nCurrentNum( 0), m_dHeight( 0), m_dTipHeight( 0), m_dRadius( 0), m_dRCorner( 0), m_dTipRadius( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0) { } //---------------------------------------------------------------------------- Tool::~Tool( void) { } //---------- Tolleranza nell'approssimazione di curve profilo ---------------- //---------------------------------------------------------------------------- bool Tool::SetTolerances( double dLinTol, double dAngTolDeg) { m_dLinTol = max( dLinTol, LIN_TOL_MIN) ; m_dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; return true ; } //---------------------------------------------------------------------------- bool Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, int nToolNum) { // assegno il nome m_sName = sToolName ; // Aggiorno il numero dell'utensile corrente m_nCurrentNum = nToolNum ; // Imposto il tipo di utensile a indefinito m_nType = UNDEF ; // verifica sulle minime dimensioni globali if ( dH < EPS_SMALL || dR < EPS_SMALL) return false ; // utensile cilindrico if ( dCornR < EPS_SMALL) { m_nType = CYLMILL ; m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = 0 ; m_dTipRadius = m_dRadius ; m_dRCorner = 0 ; } // utensile naso di toro else if ( dCornR < dR - EPS_SMALL) { m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = dCornR ; m_dTipRadius = dR - dCornR ; m_dRCorner = dCornR ; // come profilo Point3d pt0( 0, 0, 0) ; Point3d pt1( m_dRadius, 0, 0) ; Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; Point3d pt3( m_dTipRadius, - m_dHeight, 0) ; Point3d pt4( 0, - m_dHeight, 0) ; m_Outline.Clear() ; CurveLine Line ; Line.Set( pt0, pt1) ; m_Outline.AddCurve( Line) ; m_Outline.AddLine( pt2); m_Outline.AddArcTg( pt3) ; m_Outline.AddLine( pt4) ; return SetGenTool( sToolName, & m_Outline, nToolNum) ; } // utensile sferico else if ( dCornR < dR + EPS_SMALL) { m_nType = BALLMILL ; m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = m_dRadius ; m_dTipRadius = 0 ; m_dRCorner = m_dRadius ; } // impossibile else return false ; return true ; } //---------------------------------------------------------------------------- bool Tool::SetAdvTool( const string& sToolName, double dH, double dR, double dTipH, double dTipR, double dCornR, int nToolNum) { // Setto il nome m_sName = sToolName ; m_nCurrentNum = nToolNum ; m_nType = UNDEF ; // Verifica dimensioni globali if ( dH < EPS_SMALL || dR < EPS_SMALL) return false ; // Se altezza punta nulla, ricado nel caso standard if ( dTipH < EPS_SMALL || abs( dTipR - dR) < EPS_SMALL) return SetStdTool( sToolName, dH, dR, dCornR, nToolNum) ; // Caso avanzato m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = dTipH ; m_dTipRadius = max( dTipR, 0.) ; // Se raggio corner nullo, allora utensile conico if ( dCornR < EPS_SMALL) { m_nType = CONUSMILL ; m_dRCorner = 0 ; return true ; } // Altrimenti utensile generico. m_dRCorner = dCornR ; m_Outline.Clear() ; // Definisco il profilo Point3d pt0( 0, 0, 0) ; Point3d pt1( m_dRadius, 0, 0) ; Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; if ( m_dTipRadius < m_dRadius) { CurveLine LineSt ; LineSt.Set( pt0, pt1) ; Point3d ptInt( dTipR, - dH, 0) ; Point3d ptLast( 0, - dH, 0) ; CurveLine cLine1 ; cLine1.Set( pt2, ptInt) ; CurveLine cLine2 ; cLine2.Set( ptInt, ptLast) ; Point3d ptIn1 = ptInt + Y_AX * dCornR ; Point3d ptIn2 = ptInt - X_AX * dCornR ; double dTrim1, dTrim2 ; PtrOwner< ICurveArc> pArc( CreateFillet( cLine1, ptIn1, cLine2, ptIn2, Z_AX, dCornR, dTrim1, dTrim2)) ; if ( IsNull( pArc)) return false ; cLine1.TrimEndAtParam( abs( dTrim1)) ; cLine2.TrimStartAtParam( abs( dTrim2)) ; Point3d pt3, pt4 ; cLine1.GetEndPoint( pt3) ; cLine2.GetStartPoint( pt4) ; Point3d ptC = pArc->GetCenter() ; CurveArc cvArc ; cvArc.SetC2P( ptC, pt3, pt4) ; m_Outline.AddCurve( LineSt) ; m_Outline.AddLine( pt2); m_Outline.AddLine( pt3); m_Outline.AddCurve( cvArc) ; m_Outline.AddLine( ptLast) ; } else { if ( m_dTipRadius < m_dRCorner) return false ; CurveLine LineSt ; LineSt.Set( pt0, pt1) ; Point3d ptC( dTipR - dCornR, - dH + dCornR, 0) ; CurveArc cvCirc ; cvCirc.SetXY( ptC, dCornR) ; Point3d ptNear( ptC.x + dCornR, ptC.y + dCornR, 0) ; PtrOwner pLine( GetLinePointTgCurve( pt2, cvCirc, ptNear)) ; if ( IsNull( pLine)) return false ; Point3d pt3 ; pLine->GetEndPoint( pt3) ; Point3d pt4( ptC.x, - dH, 0) ; CurveArc cvArc ; cvArc.SetC2P( ptC, pt3, pt4) ; Point3d pt5( 0, - dH, 0) ; m_Outline.AddCurve( LineSt) ; m_Outline.AddLine( pt2); m_Outline.AddLine( pt3); m_Outline.AddCurve( cvArc) ; m_Outline.AddLine( pt5) ; } return SetGenTool( sToolName, &m_Outline, nToolNum) ; } //---------------------------------------------------------------------------- bool Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, int nToolNum) { // Assegno nome, tipo e id dell'utensile m_sName = sToolName ; m_nType = UNDEF ; m_nCurrentNum = nToolNum ; // Copio il profilo e garantisco sia di soli archi e rette (converto eventuali curve di Bezier) if ( ! m_Outline.CopyFrom( pToolOutline) || ! m_Outline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg)) return false ; // Flag di avvenuta approssimazione bool bApprox = false ; // Ciclo sulle curve componenti const ICurve* pCurve = m_Outline.GetFirstCurve() ; while ( pCurve != nullptr) { // Se la curva è un arco verifico se approssimarlo if ( pCurve->GetType() == CRV_ARC) { // Centro e raggio dell'arco Point3d ptO = GetBasicCurveArc( pCurve)->GetCenter() ; double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ; // Se il centro è fuori dall'asse devo approssimare bool bCurrApprox = ( abs( ptO.x) > EPS_SMALL) ; // Se una delle altre curve dista dal centro meno del raggio, devo approssimare for ( int nI = 0 ; ! bCurrApprox && nI < m_Outline.GetCurveCount() ; ++ nI) { const ICurve* pOtherCrv = m_Outline.GetCurve( nI) ; if ( pOtherCrv != pCurve) { DistPointCurve CalcDist( ptO, *pOtherCrv) ; double dCurrDist ; if ( CalcDist.GetDist( dCurrDist) && dCurrDist < dRadius - EPS_SMALL) bCurrApprox = true ; } } // Se devo approssimare if ( bCurrApprox) { // Creo la polyline approssimante PolyLine plyApprox ; if ( ! pCurve->ApproxWithLines( m_dLinTol, m_dAngTolDeg, ICurve::APL_SPECIAL, plyApprox)) return false ; // Aggiungo i segmenti di retta alla approssimazione Point3d ptEnd ; plyApprox.GetFirstPoint( ptEnd) ; while ( plyApprox.GetNextPoint( ptEnd)) { m_ArcLineApprox.AddLine( ptEnd) ; } bApprox = true ; } // altrimenti lo aggiungo semplicemente else m_ArcLineApprox.AddCurve( *pCurve, true) ; } // altrimenti è segmento e lo aggiungo semplicemente else m_ArcLineApprox.AddCurve( *pCurve, true) ; pCurve = m_Outline.GetNextCurve() ; } // Se non ci sono state approssimazioni, cancello la curva approssimante if ( ! bApprox) m_ArcLineApprox.Clear() ; m_nType = GEN ; // Il profilo dell'utensile deve stare nel 4° quadrante del piano XY BBox3d Bounding ; m_Outline.GetLocalBBox( Bounding) ; if ( Bounding.GetMin().x < - 10 * EPS_SMALL || Bounding.GetMax().y > 10 * EPS_SMALL) return false ; // Assegno le dimensioni dell'utensile m_dHeight = - Bounding.GetMin().y ; m_dRadius = Bounding.GetMax().x ; return true ; } //---------------------------------------------------------------------------- bool Tool::SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum) { // Setto il nome e il numero dell'utensile m_sName = sToolName ; m_nCurrentNum = nToolNum ; // Imposto a indefinito il tipo m_nType = UNDEF ; if ( dH < EPS_SMALL || dW < EPS_SMALL || dTh < EPS_SMALL || dRc < 0 || dW - 2 * dRc < 0) return false ; m_dHeight = dH ; m_dRCorner = dRc ; m_dMrtChsWidth = dW ; m_dMrtChsThickness = dTh ; // Imposto il tipo m_nType = MORTISER ; return true ; } //---------------------------------------------------------------------------- bool Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh, int nToolNum) { // Setto il nome e il numero dell'utensile m_sName = sToolName ; m_nCurrentNum = nToolNum ; // Imposto a indefinito il tipo m_nType = UNDEF ; if ( dH < EPS_SMALL || dW < EPS_SMALL || dTh < 0) return false ; m_dHeight = dH ; m_dMrtChsWidth = dW ; m_dMrtChsThickness = dTh ; // Imposto il tipo m_nType = CHISEL ; return true ; }