//---------------------------------------------------------------------------- // EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 // Contenuto : Implementazione della classe Volume Zmap (singola griglia) // // // // Modifiche : 22.01.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CurveLine.h" #include "CurveArc.h" #include "VolZmap.h" #include "GeoConst.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 = CylindricalMill ; 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 = GenericTool ; 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 = BallEndMill ; 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 ; 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) return SetStdTool( sToolName, dH, dR, dCornR) ; // caso avanzato if ( abs( dTipR - dR) < EPS_SMALL) { m_nToolType = CylindricalMill ; m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = 0 ; m_dTipRadius = m_dRadius ; m_dRCorner = 0 ; } else { m_nToolType = ConusMill ; m_dHeight = dH ; m_dRadius = dR ; m_dTipHeight = dTipH ; m_dTipRadius = max( dTipR, 0.) ; m_dRCorner = dCornR ; } // assegno il nome m_sToolName = sToolName ; return true ; } //---------------------------------------------------------------------------- bool VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline) { // Aggiorno il nome dell'utensile m_sToolName = sToolName ; // Aggiorno il tipo di utensile m_nToolType = GenericTool ; // Copio il profilo m_ToolOutline.CopyFrom( pToolOutline) ; // Se ci fosse una Bézier la convertiamo in archi e rette m_ToolOutline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg) ; // Puntatore a curva costante const ICurve* pCurve = m_ToolOutline.GetFirstCurve() ; // Ciclo sulle curve componenti while ( pCurve != nullptr) { // Se la curva è un arco valuto approssimarlo if ( pCurve->GetType() == CRV_ARC) { // Centro e punti iniziale e finale dell'arco Point3d ptStart, ptEnd, ptO ; pCurve->GetStartPoint( ptStart) ; pCurve->GetEndPoint( ptEnd) ; pCurve->GetCenterPoint( ptO) ; // Vettore congiungente il centro con i punti iniziale e finale Vector3d vtStRad = ptStart - ptO ; Vector3d vtEnRad = ptEnd - ptO ; // Calcolo del raggio dell'arco double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ; // Recupero la curva precedente e quella successiva const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ; const ICurve* pNext = m_ToolOutline.GetNextCurve() ; pNext = m_ToolOutline.GetNextCurve() ; // Valuto la necessità di approssimare l'arco o meno // Punto Iniziale della curva precedente e finale della successiva Point3d ptStartPrev, ptEndNext ; // Vettori tangenti alle curve precedente corrente e successiva // rispettivamente nei punti finale, iniziale e finale e iniziale // e prodotti vettore fra i suddetti Vector3d vtPrevEndDir, vtCurrentStartDir, vtCurrentEndDir, vtNextStartDir ; Vector3d vtIProd, vtFProd ; Point3d ptTopCurrent = ptO + Y_AX * dRadius ; Point3d ptBottomCurrent = ptO - Y_AX * dRadius ; // Valuto le relazioni geometriche fra la // curva corrente e quella precedente. pPrev->GetStartPoint( ptStartPrev) ; pPrev->GetEndDir( vtPrevEndDir) ; pCurve->GetStartDir( vtCurrentStartDir) ; vtIProd = vtPrevEndDir ^ vtCurrentStartDir ; // Se la curva successiva esiste valuto le // medesime relazioni con la quest'ultima if ( pNext != nullptr) { pNext->GetEndPoint( ptEndNext) ; pCurve->GetEndDir( vtCurrentEndDir) ; pNext->GetStartDir( vtNextStartDir) ; vtFProd = vtCurrentEndDir ^ vtNextStartDir ; } // Se devo approssimare if ( ! ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptStartPrev.y > ptTopCurrent.y) && ( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) || ( pNext != nullptr && vtFProd.z > 0 && ptBottomCurrent.y > ptEndNext.y)))) { // Copio la parte precedente const ICurve* pAux = m_ToolOutline.GetFirstCurve() ; while ( pAux != pCurve) { m_ToolArcLineApprox.AddCurve( * pAux, true) ; pAux = m_ToolOutline.GetNextCurve() ; } // Creo la polyline approssimante PolyLine Polygonal ; pCurve->ApproxWithLines( m_dLinTol, m_dAngTolDeg, 10, Polygonal) ; // Definisco una curva composita a partire dalla polyline CurveComposite cvTemp ; cvTemp.FromPolyLine( Polygonal) ; // Aggiungo la parte approssimata pAux = cvTemp.GetFirstCurve() ; while ( pAux != nullptr) { m_ToolArcLineApprox.AddCurve( * pAux, true) ; pAux = cvTemp.GetNextCurve() ; } } // Se non deve essere approssimato else { // Se è già stato definito m_ToolArcLineApprox deve // essere completo, aggiungo quindi l'arco corrente if ( m_ToolArcLineApprox.GetCurveCount() != 0) m_ToolArcLineApprox.AddCurve( * pCurve, true) ; } } // Se è segmento else { // Se è già stato definito m_ToolArcLineApprox deve // essere completo, aggiungo quindi il segmento corrente if ( m_ToolArcLineApprox.GetCurveCount() != 0) m_ToolArcLineApprox.AddCurve( * pCurve, true) ; } pCurve = m_ToolOutline.GetNextCurve() ; } // 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 ; }