//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 // Contenuto : Implementazione della classe Volume Zmap (utensili) // // // // Modifiche : 22.01.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CurveLine.h" #include "CurveArc.h" #include "VolZmap.h" #include "GeoConst.h" #include "/EgtDev/Include/EGKLinePntTgCurve.h" #include "/EgtDev/Include/EGKFilletChamfer.h" #include "/EgtDev/Include/EGkDistPointCurve.h" using namespace std ; //---------- Tolleranza nell'approssimazione di curve profilo ---------------- //---------------------------------------------------------------------------- bool VolZmap::SetTolerances( double dLinTol, double dAngTolDeg) { m_dLinTol = max( dLinTol, LIN_TOL_MIN) ; m_dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::SetStdTool( const string& sToolName, double dH, double dR, double dCornR) { // reset nome m_sToolName.clear() ; // verifica minime dimensioni globali if ( dH < EPS_SMALL || dR < EPS_SMALL) return false ; // utensile cilindrico if ( dCornR < EPS_SMALL) { m_nToolType = 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_nToolType = BULLNOSEMILL ; m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = dCornR ; m_dTipRadius = dR - dCornR ; m_dRCorner = dCornR ; // come profilo m_nToolType = GENTOOL ; 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_ToolOutline.Clear() ; CurveLine Line ; Line.Set( pt0, pt1) ; m_ToolOutline.AddCurve( Line) ; m_ToolOutline.AddLine( pt2); m_ToolOutline.AddArcTg( pt3) ; m_ToolOutline.AddLine( pt4) ; return SetGenTool( sToolName, &m_ToolOutline) ; } // utensile sferico else if ( dCornR < dR + EPS_SMALL) { m_nToolType = BALLMILL ; m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = m_dRadius ; m_dTipRadius = 0 ; m_dRCorner = m_dRadius ; } // impossibile else return false ; // assegno il nome m_sToolName = sToolName ; // Aggiorno il numero dell'utensile corrente m_nCurrentToolNum = 0 ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::SetAdvTool( const string& sToolName, double dH, double dR, double dTipH, double dTipR, double dCornR) { // Reset nome m_sToolName.clear() ; // 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) ; // 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_nToolType = CONUSMILL ; m_dRCorner = 0 ; // assegno nome e identificativo m_sToolName = sToolName ; m_nCurrentToolNum = 0 ; return true ; } // Altrimenti utensile generico. m_nToolType = GENTOOL ; m_dRCorner = dCornR ; m_ToolOutline.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_ToolOutline.AddCurve( LineSt) ; m_ToolOutline.AddLine( pt2); m_ToolOutline.AddLine( pt3); m_ToolOutline.AddCurve( cvArc) ; m_ToolOutline.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_ToolOutline.AddCurve( LineSt) ; m_ToolOutline.AddLine( pt2); m_ToolOutline.AddLine( pt3); m_ToolOutline.AddCurve( cvArc) ; m_ToolOutline.AddLine( pt5) ; } return SetGenTool( sToolName, &m_ToolOutline) ; } //---------------------------------------------------------------------------- bool VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline) { // Assegno nome, tipo e id dell'utensile m_sToolName = sToolName ; m_nToolType = GENTOOL ; m_nCurrentToolNum = 0 ; // Copio il profilo e garantisco sia di soli archi e rette (converto eventuali curve di Bezier) if ( ! m_ToolOutline.CopyFrom( pToolOutline) || ! m_ToolOutline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg)) return false ; // Flag di avvenuta approssimazione bool bApprox = false ; // Ciclo sulle curve componenti const ICurve* pCurve = m_ToolOutline.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_ToolOutline.GetCurveCount() ; ++ nI) { const ICurve* pOtherCrv = m_ToolOutline.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 ; pCurve->ApproxWithLines( m_dLinTol, m_dAngTolDeg, ICurve::APL_SPECIAL, plyApprox) ; // Aggiungo i segmenti di retta alla approssimazione Point3d ptEnd ; plyApprox.GetFirstPoint( ptEnd) ; while ( plyApprox.GetNextPoint( ptEnd)) { m_ToolArcLineApprox.AddLine( ptEnd) ; } bApprox = true ; } // altrimenti lo aggiungo semplicemente else m_ToolArcLineApprox.AddCurve( *pCurve, true) ; } // altrimenti è segmento e lo aggiungo semplicemente else m_ToolArcLineApprox.AddCurve( *pCurve, true) ; pCurve = m_ToolOutline.GetNextCurve() ; } // Se non ci sono state approssimazioni, cancello la curva approssimante if ( ! bApprox) m_ToolArcLineApprox.Clear() ; // Dimensioni dell'utensile BBox3d Bounding ; m_ToolOutline.GetLocalBBox( Bounding) ; double m_dHeight = Bounding.GetMax().y - Bounding.GetMin().y ; double m_dRadius = Bounding.GetMax().x - Bounding.GetMin().x ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc) { // Reset nome m_sToolName.clear() ; 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 ; m_sToolName = sToolName ; m_nToolType = MORTISER ; m_nCurrentToolNum = 0 ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::SetChiselTool( const string& sToolName, double dH, double dW, double dTh) { // Reset nome m_sToolName.clear() ; if ( dH < EPS_SMALL || dW < EPS_SMALL || dTh < 0) return false ; m_dHeight = dH ; m_dMrtChsWidth = dW ; m_dMrtChsThickness = dTh ; m_sToolName = sToolName ; m_nToolType = CHISEL ; m_nCurrentToolNum = 0 ; return true ; }