diff --git a/Tool.cpp b/Tool.cpp index 8993909..81e3d76 100644 --- a/Tool.cpp +++ b/Tool.cpp @@ -29,7 +29,8 @@ using namespace std ; Tool::Tool( bool bApproxWithLines) : m_bApproxWithLines( bApproxWithLines), 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_dRefRadius( 0), m_dCutterHeight( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0) + m_dTipRadius( 0), m_dRefRadius( 0), m_dCutterHeight( 0), m_dMrtChsWidth( 0), m_dMrtChsThickness( 0)/*, + m_bAllPartCut( true)*/ { } @@ -73,7 +74,10 @@ Tool::SetTolerances( double dLinTol, double dAngTolDeg) bool Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, double dCutterH, int nToolNum) { - + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////// Per test additivi ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //return SetAdditiveTool( sToolName, dH, dR, dCornR, nToolNum) ; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Impostazioni generali m_sName = sToolName ; m_nCurrentNum = nToolNum ; @@ -101,9 +105,13 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, Point3d pt3( m_dRadius, - m_dHeight, 0) ; Point3d pt4( 0, - m_dHeight, 0) ; m_Outline.AddPoint( pt0) ; - m_Outline.AddLine( pt1); + m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt3) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddLine( pt4) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } // utensile naso di toro else if ( dCornR < dR - EPS_SMALL) { @@ -121,10 +129,15 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, Point3d pt3( m_dTipRadius, - m_dHeight, 0) ; Point3d pt4( 0, - m_dHeight, 0) ; m_Outline.AddPoint( pt0) ; - m_Outline.AddLine( pt1); - m_Outline.AddLine( pt2); + m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddArcTg( pt3) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; m_Outline.AddLine( pt4) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; // se da approosimare if ( m_bApproxWithLines) return SetGenTool( sToolName, &m_Outline, nToolNum) ; @@ -144,9 +157,13 @@ Tool::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; Point3d pt4( 0, - m_dHeight, 0) ; m_Outline.AddPoint( pt0) ; - m_Outline.AddLine( pt1); - m_Outline.AddLine( pt2); + m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddArcTg( pt4) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } // impossibile else @@ -202,9 +219,14 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, // profilo m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddLine( Point3d( m_dTipRadius, - m_dHeight, 0)) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; // eventuali sistemazioni per altezza tagliente if ( ModifyForCutterHeight()) return SetGenTool( sToolName, &m_Outline, nToolNum) ; @@ -214,7 +236,7 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, // Altrimenti utensile generico - // se Tip a punta ( TipRadius è raggio teorico della parte finale dell'utensile senza raccordo) + // se Tip a punta ( TipRadius � raggio teorico della parte finale dell'utensile senza raccordo) if ( m_dTipRadius < m_dRadius) { // se punta a sfera if ( m_dTipRadius < EPS_SMALL) { @@ -243,10 +265,16 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, // creazione curva composita m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddLine( pt3) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; m_Outline.AddCurve( cvArc) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 4, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } // altrimenti punta a naso di toro else { @@ -272,16 +300,22 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, // creazione curva composita m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddLine( pt3) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; m_Outline.AddCurve( Release( pArc)) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 4, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } } - // altrimenti Tip a coda di rondine ( TipRadius è raggio misurabile della parte finale dell'utensile) + // altrimenti Tip a coda di rondine ( TipRadius � raggio misurabile della parte finale dell'utensile) else { - // il raggio della punta non può essere inferiore al raggio corner + // il raggio della punta non pu� essere inferiore al raggio corner if ( m_dTipRadius < m_dRCorner) return false ; // Assegno il raggio di riferimento @@ -306,10 +340,16 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, // creazione curva composita m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddLine( pt3) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; m_Outline.AddCurve( cvArc) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 4, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } // eventuali sistemazioni per altezza tagliente @@ -322,7 +362,7 @@ Tool::SetAdvTool( const string& sToolName, double dH, double dR, bool Tool::ModifyForCutterHeight( void) { - // Se altezza tagliente non definita o superiore alla altezza utensile non devo fare alcunché + // Se altezza tagliente non definita o superiore alla altezza utensile non devo fare alcunch� if ( m_dCutterHeight < EPS_SMALL || m_dCutterHeight > m_dHeight - EPS_SMALL) return false ; // quota di taglio @@ -341,6 +381,8 @@ Tool::ModifyForCutterHeight( void) m_Outline.TrimStartAtParam( dU) ; m_Outline.AddLine( Point3d( 0, dYtrim, 0), false) ; m_Outline.AddLine( ORIG, false) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; return true ; } return false ; @@ -376,22 +418,36 @@ Tool::SetSawTool( const string& sToolName, double dH, double dR, // creazione profilo m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddLine( pt3) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; m_Outline.AddLine( pt4) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 4, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } // altrimenti con raggio corner else { // creazione profilo m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt1) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt2) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; m_Outline.AddLine( pt3 - X_AX * dCornR) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddArcTg( pt3 - Y_AX * dCornR) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; m_Outline.AddLine( pt4 + Y_AX * dCornR) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; m_Outline.AddArcTg( pt4 - X_AX * dCornR) ; + m_Outline.SetCurveTempProp( 4, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 5, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } } // altrimenti senza gambo @@ -406,18 +462,28 @@ Tool::SetSawTool( const string& sToolName, double dH, double dR, // creazione profilo m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt3) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt4) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } // altrimenti con raggio corner else { // creazione profilo m_Outline.AddPoint( pt0) ; m_Outline.AddLine( pt3 - X_AX * dCornR) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddArcTg( pt3 - Y_AX * dCornR) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt4 + Y_AX * dCornR) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddArcTg( pt4 - X_AX * dCornR) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; m_Outline.AddLine( pt5) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; } } // Assegno il raggio di riferimento @@ -437,17 +503,30 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, if ( pToolOutline != &m_Outline) m_Outline.Clear() ; m_ArcLineApprox.Clear() ; - + // 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 ; - // Ciclo sulle curve componenti + // Valuto se tutte le curve tagliano + m_ArcLineApprox.SetTempProp( 1, 1) ; const ICurve* pCurve = m_Outline.GetFirstCurve() ; + while ( pCurve != nullptr && m_ArcLineApprox.GetTempProp( 1) == 1) { + int nCutTempProp = pCurve->GetTempProp( 1) ; + if ( nCutTempProp == 0) { + m_ArcLineApprox.SetTempProp( 0, 1) ; + } + pCurve = m_Outline.GetNextCurve() ; + } + + // Ciclo sulle curve componenti + pCurve = m_Outline.GetFirstCurve() ; while ( pCurve != nullptr) { - // Se la curva è un arco ed è richiesto la verifica per l'approssimazione, + int nCutTempProp = pCurve->GetTempProp( 1) ; + + // Se la curva � un arco ed � richiesto la verifica per l'approssimazione, // verifico se approssimarlo if ( m_bApproxWithLines && pCurve->GetType() == CRV_ARC) { @@ -455,11 +534,11 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, Point3d ptO = GetBasicCurveArc( pCurve)->GetCenter() ; double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ; - // Se il centro è fuori dall'asse devo approssimare + // 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) { + for ( int nI = 0 ; ! bCurrApprox && nI < m_Outline.GetCurveCount() && m_ArcLineApprox.GetTempProp( 1) == 1 ; ++ nI) { const ICurve* pOtherCrv = m_Outline.GetCurve( nI) ; if ( pOtherCrv != pCurve) { DistPointCurve CalcDist( ptO, *pOtherCrv) ; @@ -494,6 +573,7 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, m_vArcNormals.emplace_back( vtExtN) ; int nCvCount = m_ArcLineApprox.GetCurveCount() ; m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, int( m_vArcNormals.size()) - 1) ; + m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ; } } // altrimenti lo aggiungo semplicemente @@ -501,16 +581,20 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, m_ArcLineApprox.AddCurve( *pCurve, true) ; int nCvCount = m_ArcLineApprox.GetCurveCount() ; m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, - 1) ; + m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ; } } - // altrimenti è segmento e lo aggiungo semplicemente - else + // altrimenti � segmento e lo aggiungo semplicemente + else { m_ArcLineApprox.AddCurve( *pCurve, true) ; + int nCvCount = m_ArcLineApprox.GetCurveCount() ; + m_ArcLineApprox.SetCurveTempProp( nCvCount - 1, nCutTempProp, 1) ; + } pCurve = m_Outline.GetNextCurve() ; } - // Il profilo dell'utensile deve stare nel 1° e 4° quadrante del piano XY + // Il profilo dell'utensile deve stare nel 1� e 4� quadrante del piano XY BBox3d Bounding ; m_Outline.GetLocalBBox( Bounding) ; if ( Bounding.GetMin().x < - 10 * EPS_SMALL) @@ -522,7 +606,7 @@ Tool::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, // Assegno le dimensioni dell'utensile m_dHeight = - Bounding.GetMin().y ; m_dRadius = Bounding.GetMax().x ; - // Assegno il raggio di riferimento se non già assegnato + // Assegno il raggio di riferimento se non gi� assegnato if ( m_dRefRadius < EPS_SMALL) m_dRefRadius = 0.25 * m_dRadius ; @@ -580,3 +664,85 @@ Tool::SetChiselTool( const string& sToolName, double dH, double dW, double dTh, return true ; } + +//---------------------------------------------------------------------------- +bool +Tool::SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum) +{ + // Impostazioni generali + m_sName = sToolName ; + m_nCurrentNum = nToolNum ; + m_nType = UNDEF ; + m_Outline.Clear() ; + m_ArcLineApprox.Clear() ; + + // verifica sulle minime dimensioni globali + if ( dH < EPS_SMALL || dR < EPS_SMALL || dRC < - EPS_SMALL) + return false ; + + m_nType = ADDITIVE ; + m_dHeight = dH ; + m_dRadius = dR ; + m_dRCorner = dRC ; + m_dTipHeight = 0 ; + m_dTipRadius = 0 ; + m_dRefRadius = 0 ; + m_dCutterHeight = dH ; + + double dSquareCornerRadProj = m_dRCorner * m_dRCorner - 0.25 * m_dHeight * m_dHeight ; + // Utensile sfiancato + if ( dSquareCornerRadProj > 0) { + double dCenX = m_dRadius - m_dRCorner ; + double dCylRad = dCenX + sqrt( dSquareCornerRadProj) ; + // Utensile mal definito + if ( dCylRad < 0) + return false ; + // Profilo + m_Outline.AddPoint( Point3d( 0, 0, 0)) ; + m_Outline.AddLine( Point3d( dCylRad, 0, 0)) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + CurveArc cvArc ; + cvArc.SetC2P( Point3d( dCenX, - 0.5 * m_dHeight, 0), Point3d( dCylRad, 0, 0), Point3d( dCylRad, - m_dHeight, 0)) ; + m_Outline.AddCurve( cvArc) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; + m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; + } + // Utensile cilindrico con eventuale raggio corner + else { + // Utensile mal definito + if ( m_dRadius - m_dRCorner < EPS_SMALL) + return false ; + // Raggio corner nullo + if ( m_dRadius < EPS_SMALL) { + // Profilo + m_Outline.AddPoint( Point3d( 0, 0, 0)) ; + m_Outline.AddLine( Point3d( m_dRadius, 0, 0)) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + m_Outline.AddLine( Point3d( m_dRadius, - m_dHeight, 0)) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; + m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; + } + else { + // Profilo + m_Outline.AddPoint( Point3d( 0, 0, 0)) ; + m_Outline.AddLine( Point3d( m_dRadius - m_dRCorner, 0, 0)) ; + m_Outline.SetCurveTempProp( 0, 1, 1) ; + CurveArc cvArc ; + cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, 0, 0), Point3d( m_dRadius, - m_dRCorner, 0)) ; + m_Outline.SetCurveTempProp( 1, 1, 1) ; + m_Outline.AddLine( Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0)) ; + m_Outline.SetCurveTempProp( 2, 1, 1) ; + cvArc.SetC2P( Point3d( m_dRadius - m_dRCorner, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius, - m_dHeight + m_dRCorner, 0), Point3d( m_dRadius - m_dRCorner, - m_dHeight, 0)) ; + m_Outline.AddCurve( cvArc) ; + m_Outline.SetCurveTempProp( 3, 1, 1) ; + m_Outline.AddLine( Point3d( 0, - m_dHeight, 0)) ; + m_Outline.SetCurveTempProp( 4, 1, 1) ; + m_Outline.SetTempProp( 1, 1) ; + } + } + + return SetGenTool( sToolName, &m_Outline, nToolNum) ; +} \ No newline at end of file diff --git a/Tool.h b/Tool.h index acc340f..54e3d92 100644 --- a/Tool.h +++ b/Tool.h @@ -16,7 +16,7 @@ #include "CurveComposite.h" //---------------------------------------------------------------------------- -class Tool +class Tool { public : Tool( bool bApproxWithLines = false) ; @@ -33,6 +33,7 @@ class Tool bool SetGenTool( const std::string& sToolName, const ICurveComposite* pToolOutline, int nToolNum) ; bool SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nToolNum) ; bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nToolNum) ; + bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRC, int nToolNum) ; bool SetToolNum( int nToolNum) { m_nCurrentNum = nToolNum ; return true ; } int GetType() const @@ -61,6 +62,8 @@ class Tool { return ( m_ArcLineApprox.GetCurveCount() == 0 ? m_Outline : m_ArcLineApprox) ; } const VCT3DVECTOR& GetArcNormalVec( void) const { return m_vArcNormals ; } + bool GetCuttingFlag() const + { /*return m_bAllPartCut ;*/ return ( m_nType == GEN ? m_ArcLineApprox.GetTempProp( 1) == 1 : true ) ; } public : enum ToolType { UNDEF = 0, // Utensile indefinito @@ -70,13 +73,15 @@ class Tool BULLNOSEMILL = 4, // Naso di toro CONEMILL = 5, // Con parte terminale conica MORTISER = 6, // Mortasatrice - CHISEL = 7} ; // Scalpello + CHISEL = 7, // Scalpello + ADDITIVE = 8} ; // Additivo private : bool ModifyForCutterHeight( void) ; private : bool m_bApproxWithLines ; + //bool m_bAllPartCut ; double m_dLinTol ; double m_dAngTolDeg ; std::string m_sName ; diff --git a/VolZmap.cpp b/VolZmap.cpp index 32cd3c5..2a0abff 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -35,7 +35,7 @@ GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ; //---------------------------------------------------------------------------- VolZmap::VolZmap(void) : m_nStatus( TO_VERIFY), m_dStep( 10.0), m_nMapNum( 0), m_nShape( GENERIC), m_nVoxNumPerBlock( N_VOXBLOCK), - m_nDexVoxRatio( 1), m_nNumBlock( 0), m_nConnectedCompoCount( 0), m_Tool( true) + m_nDexVoxRatio( 1), m_nNumBlock( 0), m_nConnectedCompoCount( 0), m_nCurrTool( - 1)/*, m_Tool( true)*/ { for ( int i = 0 ; i < N_MAPS ; ++ i) { m_nNx[i] = 0 ; @@ -47,7 +47,7 @@ VolZmap::VolZmap(void) } m_nTempProp[0] = 0 ; m_nTempProp[1] = 0 ; - m_Tool.SetTolerances( LIN_TOL_STD, ANG_TOL_APPROX_DEG) ; + //m_Tool.SetTolerances( LIN_TOL_STD, ANG_TOL_APPROX_DEG) ; } //---------------------------------------------------------------------------- @@ -76,7 +76,7 @@ VolZmap::Clear( void) m_dStep = EPS_SMALL ; m_nTempProp[0] = 0 ; m_nTempProp[1] = 0 ; - m_Tool.Clear() ; + ResetAllTools() ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; @@ -1680,8 +1680,10 @@ VolZmap::Cut( const Plane3d& plPlane) Plane3d plMyPlane = plPlane ; plMyPlane.ToLoc( m_MapFrame) ; // Imposto numero fittizio di utensile per avere il colore di sezione opportuno - int nToolNumOld = m_Tool.GetCurrentToolNum() ; - m_Tool.SetToolNum( 1) ; + if ( m_nCurrTool < 0) + return false ; + int nToolNumOld = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + m_vTool[m_nCurrTool].SetToolNum( 1) ; // Interseco lo Zmap col piano, ciclando sulle griglie bool bModified = false ; for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) { @@ -1735,7 +1737,7 @@ VolZmap::Cut( const Plane3d& plPlane) } // Ripristino numero utensile - m_Tool.SetToolNum( nToolNumOld) ; + m_vTool[m_nCurrTool].SetToolNum( nToolNumOld) ; if ( bModified == true) { // Imposto forma generica @@ -1970,14 +1972,18 @@ VolZmap::CalcBlockNum( void) bool VolZmap::SetToolTolerances( double dLinTol, double dAngTolDeg) { - return m_Tool.SetTolerances( dLinTol, dAngTolDeg) ; + if ( m_nCurrTool < 0) + return false ; + return m_vTool[m_nCurrTool].SetTolerances( dLinTol, dAngTolDeg) ; } //---------------------------------------------------------------------------- bool VolZmap::SetStdTool( const string& sToolName, double dH, double dR, double dCornR, double dCutterH, int nFlag) { - return m_Tool.SetStdTool( sToolName, dH, dR, dCornR, dCutterH, nFlag) ; + if ( m_nCurrTool < 0) + return false ; + return m_vTool[m_nCurrTool].SetStdTool( sToolName, dH, dR, dCornR, dCutterH, nFlag) ; } //---------------------------------------------------------------------------- @@ -1985,7 +1991,9 @@ bool VolZmap::SetAdvTool( const string& sToolName, double dH, double dR, double dTipH, double dTipR, double dCornR, double dCutterH, int nFlag) { - return m_Tool.SetAdvTool( sToolName, dH, dR, dTipH, dTipR, dCornR, dCutterH, nFlag) ; + if ( m_nCurrTool < 0) + return false ; + return m_vTool[m_nCurrTool].SetAdvTool( sToolName, dH, dR, dTipH, dTipR, dCornR, dCutterH, nFlag) ; } //---------------------------------------------------------------------------- @@ -1993,33 +2001,90 @@ bool VolZmap::SetSawTool( const string& sToolName, double dH, double dR, double dThick, double dStemR, double dCornR, int nFlag) { - return m_Tool.SetSawTool( sToolName, dH, dR, dThick, dStemR, dCornR, nFlag) ; + if ( m_nCurrTool < 0) + return false ; + return m_vTool[m_nCurrTool].SetSawTool( sToolName, dH, dR, dThick, dStemR, dCornR, nFlag) ; } //---------------------------------------------------------------------------- bool VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline, int nFlag) { - return m_Tool.SetGenTool( sToolName, pToolOutline, nFlag) ; + if ( m_nCurrTool < 0) + return false ; + return m_vTool[m_nCurrTool].SetGenTool( sToolName, pToolOutline, nFlag) ; } //---------------------------------------------------------------------------- bool VolZmap::SetMortiserTool( const string& sToolName, double dH, double dW, double dTh, double dRc, int nFlag) { - return m_Tool.SetMortiserTool( sToolName, dH, dW, dTh, dRc, nFlag) ; + if ( m_nCurrTool < 0) + return false ; + return m_vTool[m_nCurrTool].SetMortiserTool( sToolName, dH, dW, dTh, dRc, nFlag) ; } //---------------------------------------------------------------------------- bool VolZmap::SetChiselTool( const string& sToolName, double dH, double dW, double dTh, int nFlag) { - return m_Tool.SetChiselTool( sToolName, dH, dW, dTh, nFlag) ; + if ( m_nCurrTool < 0) + return false ; + return m_vTool[m_nCurrTool].SetChiselTool( sToolName, dH, dW, dTh, nFlag) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SetCurrTool( int nCurrTool) +{ + if ( nCurrTool < 0 || nCurrTool >= int( m_vTool.size())) + return false ; + m_nCurrTool = nCurrTool ; + return true ; +} + +//---------------------------------------------------------------------------- +int +VolZmap::GetToolCount( void) const +{ + return int( m_vTool.size()) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddTool( void) +{ + m_vTool.emplace_back( true) ; + m_vTool.back().SetTolerances( LIN_TOL_STD, ANG_TOL_APPROX_DEG) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ResetAllTools( void) +{ + bool bOk = true ; + for ( int n = 0 ; n < int( m_vTool.size()) ; ++ n) { + bOk = bOk || m_vTool[n].Clear() ; + } + m_vTool.clear() ; + return bOk ; } //---------------------------------------------------------------------------- bool VolZmap::ResetTool( void) { - return m_Tool.Clear() ; + bool bOk = m_vTool.back().Clear() ; + m_vTool.erase( m_vTool.begin() + int( m_vTool.size()) - 1) ; + return bOk ; +} + +//---------------------------------------------------------------------------- +const ICurveComposite& +VolZmap::GetToolOutline( bool bApprox) const +{ + if ( m_nCurrTool < 0) + return cvEmptyOutline ; + return ( bApprox ? m_vTool[m_nCurrTool].GetApproxOutline() : m_vTool[m_nCurrTool].GetOutline()) ; } diff --git a/VolZmap.h b/VolZmap.h index 69422b9..d6499bc 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -72,6 +72,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ; bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) override ; bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex) override ; + bool CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) override ; int GetBlockCount( void) const override ; int GetBlockUpdatingCounter( int nBlock) const override ; bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ; @@ -90,9 +91,14 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool SetGenTool( const std::string& sToolName, const ICurveComposite* pToolOutline, int nFlag) override ; bool SetMortiserTool( const std::string& sToolName, double dH, double dW, double dTh, double dRc, int nFlag) override ; bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh, int nFlag) override ; + bool SetCurrTool( int nCurrTool) override ; + int GetToolCount( void) const override ; + int GetCurrTool( void) const override + { return m_nCurrTool ; } + bool AddTool( void) override ; + bool ResetAllTools( void) override ; bool ResetTool( void) override ; - const ICurveComposite& GetToolOutline( bool bApprox = false) const override - { return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;} + const ICurveComposite& GetToolOutline( bool bApprox = false) const override ; bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) override ; bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs, const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) override ; @@ -303,6 +309,38 @@ class VolZmap : public IVolZmap, public IGeoObjRW inline bool TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtD, const Vector3d& vtA, double dLenX, double dLenY, double dLenZ, int& nStI, int& nStJ, int& nEnI, int& nEnJ) ; + + // Asportazioni superfici elementari vuote + bool SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; + bool SurfCircCrown_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; + bool SurfCircCrown_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; + bool SurfCircCrown_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) ; + /*bool SurfCyl_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bTapB, bool bTapT) ; + bool SurfCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bTapB, bool bTapT) ;*/ + bool SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dRad, bool bOuterCutter) ; + bool SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, + const Vector3d& vtToolDir, double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) ; + bool SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, + bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, + double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad, + bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) ; + bool SurfSphericalShellPart_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dRad, double dInfH, double dSupH, bool bOuterCutter) ; + bool SurfSphericalShell_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dRad, double dHei, bool bOuterCutter) ; + // Additivo + bool AddingMotion( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx/*, double dHei, double dRad, double dCornerRad*/) ; + + // Intersezioni bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax) const ; bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax, @@ -332,6 +370,34 @@ class VolZmap : public IVolZmap, public IGeoObjRW const Frame3d& frTruncPyramFrame, double dSegMin, double dSegMax, double dHeight, Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; bool TestIntersPlaneZmapBBox( const Plane3d& plPlane) const ; + + // Intersezioni per asportazioni avanzate + int IntersLineCircCrown( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dMaxRad, double dMinRad, + Point3d& ptInt, Vector3d& vtN) const ; + int IntersLineParallelogram( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptParOrig, const Vector3d& vtSeg1, const Vector3d& vtSeg2, + bool bExtNorm, Point3d& ptInt, Vector3d& vtN) const ; + int IntersLineCylinderCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptBaseCen, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + int IntersLineCircSweptSurfCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dRad, const Vector3d& vtSweptVec, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + int IntersLineConeCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptVert, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + int IntersLineSphereCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineD, + const Point3d& ptCen, double dRad, bool bInOut, + const std::vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ; + int IntersLineCatTongue( const Point3d& ptLineP, const Vector3d& vtLineD, + const Point3d& ptCenSt, const Point3d& ptCenEn, const Vector3d& vtNorm, double dRad, + Point3d& ptInt, Vector3d& vtN) const ; + // Voxel: esistenza e passaggio da N a ijk per i voxel bool IsValidVoxel( int nN) const ; bool IsValidVoxel( int nI, int nJ, int nK) const ; @@ -452,7 +518,10 @@ class VolZmap : public IVolZmap, public IGeoObjRW mutable std::atomic m_bBreak ; std::atomic m_bIsBox ; - Tool m_Tool ; + // Utensili + std::vector m_vTool ; + int m_nCurrTool ; + CurveComposite cvEmptyOutline ; } ; diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp index 681bf34..11f6107 100644 --- a/VolZmapCreation.cpp +++ b/VolZmapCreation.cpp @@ -28,6 +28,10 @@ using namespace std ; bool VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) { + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////// Per test additivi ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //return CreateEmptyMap( ptO, dLengthX, dLengthY, dLengthZ, dStep, bTriDex) ; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) return false ; @@ -220,7 +224,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double // Determino le intersezioni della retta con la regione CRVCVECTOR IntersectionResults ; - Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ; + Surf.GetCurveClassification( GridLine, IntersectionResults) ; // Analizzo le parti in cui la retta è stata divisa int nPart = int( IntersectionResults.size()) ; @@ -327,7 +331,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double // Determino le intersezioni della retta con la regione CRVCVECTOR IntersectionResults ; - Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ; + Surf.GetCurveClassification( GridLine, IntersectionResults) ; // Analizzo le parti int nPart = int( IntersectionResults.size()) ; @@ -665,3 +669,77 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex return bCompleted ; } + +//---------------------------------------------------------------------------- +bool +VolZmap::CreateEmptyMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dStep, bool bTriDex) +{ + // Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo + if ( dStep < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) + return false ; + + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + m_dStep = max( dStep, 100 * EPS_SMALL) ; + + // Aggiorno la dimensione della mappa 1 o 3 + m_nMapNum = ( bTriDex ? 3 : 1) ; + + // Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z + // di uno si ottengono da una permutazione ciclica di quelle del precedente sistema. + // es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1) + + // Definisco il sistema di riferimento intrinseco + m_MapFrame.Set( ptO, X_AX, Y_AX, Z_AX) ; + + // Definisco i vettori dei limiti su indici + m_nNx[0] = max( int( ( dLengthX + EPS_SMALL) / m_dStep + 0.5), 1) ; + m_nNy[0] = max( int( ( dLengthY + EPS_SMALL) / m_dStep + 0.5), 1) ; + + // Numero di componenti connesse + m_nConnectedCompoCount = 1 ; + + // Se tridexel + if ( bTriDex) { + m_nNx[1] = m_nNy[0] ; + m_nNy[1] = max( int( ( dLengthZ + EPS_SMALL) / m_dStep + 0.5), 1) ; + m_nNx[2] = m_nNy[1] ; + m_nNy[2] = m_nNx[0] ; + } + + // altrimenti mono dexel + else { + m_nNx[1] = 0 ; + m_nNy[1] = 0 ; + m_nNx[2] = 0 ; + m_nNy[2] = 0 ; + } + + // Definisco il numero di blocchi lungo x,y e z + if ( ! CalcBlockNum()) + return false ; + + // Creazione delle mappe + // Calcolo del numero di celle per ogni mappa + for ( int i = 0 ; i < m_nMapNum ; ++ i) + m_nDim[i] = m_nNx[i] * m_nNy[i] ; + + // Creazione delle celle per ogni mappa + for ( int i = 0 ; i < m_nMapNum ; ++ i) + m_Values[i].resize( m_nDim[i]) ; + + // Definizione delle limitazioni iniziali in Z per ogni mappa + m_dMinZ[0] = 0 ; + m_dMaxZ[0] = dLengthZ ; + m_dMinZ[1] = 0 ; + m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ; + m_dMinZ[2] = 0 ; + m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ; + + // Tipologia + m_nShape = BOX ; + + // Aggiornamento dello stato + m_nStatus = OK ; + + return true ; +} \ No newline at end of file diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index b07419c..24aedb1 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -844,7 +844,7 @@ VolZmap::UpdateTripleMapGraphics( void) const VecTriHold.resize( m_nNumBlock) ; // Ciclo sui blocchi per eliminare le slice fra blocchi da aggiornare - for ( int t = 0 ; t < m_nNumBlock ; ++ t) { + for ( int t = 0 ; t < m_nNumBlock ; ++ t) { for ( auto it = m_SliceXY[t].begin() ; it != m_SliceXY[t].end() ;) { int nSlIJK[3] ; if ( GetVoxIJKFromN( it->first, nSlIJK[0], nSlIJK[1], nSlIJK[2])) { @@ -1083,7 +1083,7 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const // Flag di regolarità dei campi scalare e vettoriale bool bReg = true ; - + // Ciclo sui segmenti for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) { // Se il segmento non attraversa la superficie passo al successivo diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp index 4f0c008..450143f 100644 --- a/VolZmapVolume.cpp +++ b/VolZmapVolume.cpp @@ -20,6 +20,9 @@ #include "GeoConst.h" #include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EGkStringUtils3d.h" +#include "/EgtDev/Include/EGkIntersLinePlane.h" +#include "/EgtDev/Include/EGkIntersLineSphere.h" +#include "/EgtDev/Include/ENkPolynomialRoots.h" #include "/EgtDev/Include/EgtPerfCounter.h" #include @@ -81,25 +84,25 @@ VolZmap::SubtractIntervals( int nGrid, int nI, int nJ, if ( dMin <= vDexel[i].dMin + EPS_ZERO && dMax < vDexel[i].dMax - EPS_ZERO) { vDexel[i].dMin = dMax ; vDexel[i].vtMinN = vtNma ; - vDexel[i].nToolMin = m_Tool.GetCurrentToolNum() ; + vDexel[i].nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; } // se devo limitarlo superiormente else if ( dMin > vDexel[i].dMin + EPS_ZERO && dMax >= vDexel[i].dMax - EPS_ZERO) { vDexel[i].dMax = dMin ; vDexel[i].vtMaxN = vtNmi ; - vDexel[i].nToolMax = m_Tool.GetCurrentToolNum() ; + vDexel[i].nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; } // se devo dividerlo in due parti else if ( dMin > vDexel[i].dMin + EPS_ZERO && dMax < vDexel[i].dMax - EPS_ZERO) { // inserisco nuovo intervallo (parte superiore) vDexel.insert( vDexel.begin() + i + 1, - { dMax, vtNma, m_Tool.GetCurrentToolNum(), + { dMax, vtNma, m_vTool[m_nCurrTool].GetCurrentToolNum(), vDexel[i].dMax, vDexel[i].vtMaxN, vDexel[i].nToolMax, vDexel[i].nCompo}) ; // aggiorno il vecchio (parte inferiore) vDexel[i].dMax = dMin ; vDexel[i].vtMaxN = vtNmi ; - vDexel[i].nToolMax = m_Tool.GetCurrentToolNum() ; + vDexel[i].nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; ++ i ; } // altrimenti devo eliminarlo @@ -108,10 +111,10 @@ VolZmap::SubtractIntervals( int nGrid, int nI, int nJ, -- i ; } } - // se è tutto minore dell'intervallo corrente, ho finito + // se � tutto minore dell'intervallo corrente, ho finito else if ( dMax <= vDexel[i].dMin + EPS_ZERO) break ; - // altrimenti è tutto maggiore dell'intervallo corrente, passo al successivo + // altrimenti � tutto maggiore dell'intervallo corrente, passo al successivo else // dMin >= vDexel[i].dMax - EPS_ZERO ; } @@ -252,229 +255,360 @@ bool VolZmap::AddIntervals( int nGrid, int nI, int nJ, double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax) { -// // Controllo che dMin e dMax non siano quasi coincidenti -// if ( abs( dMax - dMin) < EPS_SMALL) -// return true ; -// -// // Controllo che il numero di griglia sia entro i limiti -// if ( nGrid < 0 || nGrid > 2) -// return false ; -// -// // Controllo che dMin < dMax -// if ( dMin > dMax) -// swap( dMin, dMax) ; -// -// // Controllo che indici nI, nJ siano entro i limiti -// if ( nI < 0 && nI >= m_nNx[nGrid] && -// nJ < 0 && nJ >= m_nNy[nGrid]) -// return false ; -// -// // Riporto le coordinate cicliche nell'ordine di partenza -// Vector3d vtNmi = vtNMin ; -// Vector3d vtNma = vtNMax ; -// if ( nGrid == 1) { -// swap( vtNmi.x, vtNmi.z) ; -// swap( vtNmi.y, vtNmi.z) ; -// swap( vtNma.x, vtNma.z) ; -// swap( vtNma.y, vtNma.z) ; -// } -// else if ( nGrid == 2) { -// swap( vtNmi.y, vtNmi.z) ; -// swap( vtNmi.x, vtNmi.z) ; -// swap( vtNma.y, vtNma.z) ; -// swap( vtNma.x, vtNma.z) ; -// } -// -// // Calcolo nPos -// unsigned int nPos = nJ * m_nNx[nGrid] + nI ; -// -// -// // Se spillone vuoto -// if ( m_Values[nGrid][nPos].size() == 0) { -// -// m_Values[nGrid][nPos].resize( 1) ; -// -// m_Values[nGrid][nPos][0].dMin = dMin ; -// m_Values[nGrid][nPos][0].dMax = dMax ; -// -// m_Values[nGrid][nPos][0].vtMinN = vtNmi ; -// m_Values[nGrid][nPos][0].vtMaxN = vtNma ; -// -// if ( dMax > m_dMaxZ[nGrid]) -// m_dMinZ[nGrid] = dMax ; -// -// if ( dMin < m_dMinZ[nGrid]) -// m_dMinZ[nGrid] = dMin ; -// -// m_OGrMgr.Reset() ; -// -// return true ; -// } -// -// // Ciclo sugli intervalli dello spillone -// bool bModified = false ; -// unsigned int i = 0 ; -// while ( i < m_Values[nGrid][nPos].size()) { -// -// // Eventuale aggiustamento di intervalli sovrapposti -// if ( i < m_Values[nGrid][nPos].size() - 1) { -// if ( m_Values[nGrid][nPos][i].dMax > m_Values[nGrid][nPos][i + 1].dMin - EPS_SMALL) { -// -// // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva -// if ( m_Values[nGrid][nPos][i].dMin < m_Values[nGrid][nPos][i + 1].dMin + EPS_SMALL) { -// -// m_Values[nGrid][nPos][i].dMax = m_Values[nGrid][nPos][i + 1].dMax ; -// m_Values[nGrid][nPos][i].vtMaxN = m_Values[nGrid][nPos][i + 1].vtMaxN ; -// } -// // altrimenti -// else { -// -// m_Values[nGrid][nPos][i].dMin = m_Values[nGrid][nPos][i].dMin ; -// m_Values[nGrid][nPos][i].vtMinN = m_Values[nGrid][nPos][i].vtMinN ; -// -// m_Values[nGrid][nPos][i].dMax = m_Values[nGrid][nPos][i].dMax ; -// m_Values[nGrid][nPos][i].vtMaxN = m_Values[nGrid][nPos][i].vtMaxN ; -// } -// -// for ( unsigned int j = i + 1 ; j < m_Values[nGrid][nPos].size() - 1 ; ++ j) { -// -// m_Values[nGrid][nPos][j].dMin = m_Values[nGrid][nPos][j + 1].dMin ; -// m_Values[nGrid][nPos][j].vtMinN = m_Values[nGrid][nPos][j + 1].vtMinN ; -// -// m_Values[nGrid][nPos][j].dMax = m_Values[nGrid][nPos][j + 1].dMax ; -// m_Values[nGrid][nPos][j].vtMaxN = m_Values[nGrid][nPos][j + 1].vtMaxN ; -// } -// -// m_Values[nGrid][nPos].resize( m_Values[nGrid][nPos].size() - 1) ; -// -// i = i - 1 ; -// } -// } -// -// -// // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente -// if ( m_Values[nGrid][nPos][i].dZVal > dMax + EPS_SMALL) { -// -// bModified = true ; -// -// m_Values[nGrid][nPos].resize( m_Values[nGrid][nPos].size() + 2) ; -// -// for ( size_t j = m_Values[nGrid][nPos].size() - 1 ; j >= i + 2 ; -- j) { -// -// m_Values[nGrid][nPos][j].dZVal = m_Values[nGrid][nPos][j - 2].dZVal ; -// m_Values[nGrid][nPos][j].vtN = m_Values[nGrid][nPos][j - 2].vtN ; -// } -// -// -// m_Values[nGrid][nPos][i].dZVal = dMin ; -// m_Values[nGrid][nPos][i + 1].dZVal = dMax ; -// -// m_Values[nGrid][nPos][i].vtN = vtNMin ; -// m_Values[nGrid][nPos][i + 1].vtN = vtNMax ; -// -// i = i + 2 ; -// } -// -// // Casi d'intersezione: -// else if ( m_Values[nGrid][nPos][i + 1].dZVal > dMax - EPS_SMALL) { -// -// // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente -// if ( m_Values[nGrid][nPos][i].dZVal > dMin - EPS_SMALL) { -// -// bModified = true ; -// m_Values[nGrid][nPos][i].dZVal = dMin ; -// m_Values[nGrid][nPos][i].vtN = vtNmi ; -// } -// } -// -// else { -// // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi -// if ( m_Values[nGrid][nPos][i].dZVal > dMin + EPS_SMALL) { -// -// bModified = true ; -// m_Values[nGrid][nPos][i].dZVal = dMin ; -// m_Values[nGrid][nPos][i + 1].dZVal = dMax ; -// m_Values[nGrid][nPos][i].vtN = vtNMin ; -// m_Values[nGrid][nPos][i + 1].vtN = vtNma ; -// } -// // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente -// else if ( m_Values[nGrid][nPos][i + 1].dZVal > dMin - EPS_SMALL) { -// -// bModified = true ; -// m_Values[nGrid][nPos][i + 1].dZVal = dMax ; -// m_Values[nGrid][nPos][i + 1].vtN = vtNma ; -// } -// else { -// // Aggiungo intervallo a destra dell'ultimo intervallo -// if ( i == m_Values[nGrid][nPos].size() - 2) { -// -// bModified = true ; -// m_Values[nGrid][nPos].resize( m_Values[nGrid][nPos].size() + 2) ; -// -// m_Values[nGrid][nPos][i + 2].dZVal = dMin ; -// m_Values[nGrid][nPos][i + 3].dZVal = dMax ; -// m_Values[nGrid][nPos][i + 2].vtN = vtNmi ; -// m_Values[nGrid][nPos][i + 3].vtN = vtNma ; -// -// i = i + 2 ; -// } -// } -// } -// -// i = i + 2 ; -// } -// -// // se eseguita modifica, imposto ricalcolo della grafica -// if ( bModified) { -// -// // Determino quali blocchi sono stati modificati -// int nLayerBlock = m_nFracLin[0] * m_nFracLin[1] ; -// -// if ( nGrid == 0) { -// -// int nXBlock = min( nI / m_nDexNumPBlock, m_nFracLin[0] - 1) ; -// int nYBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[1] - 1) ; -// int nMinZBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; -// int nMaxZBlock = min( int( m_nFracLin[2] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; -// -// for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) -// -// m_BlockToUpdate[k * nLayerBlock + nYBlock * m_nFracLin[0] + nXBlock] = true ; -// } -// else if ( nGrid == 1) { -// -// int nYBlock = min( nI / m_nDexNumPBlock, m_nFracLin[1] - 1) ; -// int nZBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[2] - 1) ; -// int nMinXBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; -// int nMaxXBlock = min( int( m_nFracLin[0] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; -// -// for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) -// -// m_BlockToUpdate[nZBlock * nLayerBlock + nYBlock * m_nFracLin[0] + k] = true ; -// } -// else if ( nGrid == 2) { -// -// int nXBlock = min( nJ / m_nDexNumPBlock, m_nFracLin[0] - 1) ; -// int nZBlock = min( nI / m_nDexNumPBlock, m_nFracLin[2] - 1) ; -// int nMinYBlock = max( 0, int( floor( ( dMin / m_dStep))) / int( m_nDexNumPBlock)) ; -// int nMaxYBlock = min( int( m_nFracLin[1] - 1), int( floor( ( dMax / m_dStep))) / int( m_nDexNumPBlock)) ; -// -// for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) -// -// m_BlockToUpdate[nZBlock * nLayerBlock + k * m_nFracLin[0] + nXBlock] = true ; -// } -// -// m_OGrMgr.Reset() ; -// -// // Aggiorno massima e minima Z -// // sullo Zmap -// if ( dMax > m_dMaxZ[nGrid]) -// m_dMinZ[nGrid] = dMax ; -// -// if ( dMin < m_dMinZ[nGrid]) -// m_dMinZ[nGrid] = dMin ; -// } -// + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + return true ; + + // Controllo che il numero di griglia sia entro i limiti + if ( nGrid < 0 || nGrid > 2) + return false ; + + // Controllo che indici nI, nJ siano entro i limiti + if ( nI < 0 && nI >= m_nNx[nGrid] && + nJ < 0 && nJ >= m_nNy[nGrid]) + return false ; + + // Controllo che dMin < dMax + Vector3d vtNmi = vtNMin ; + Vector3d vtNma = vtNMax ; + if ( dMin > dMax) { + swap( dMin, dMax) ; + swap( vtNmi, vtNma) ; + } + + // Riporto le coordinate cicliche nell'ordine di partenza + /*Vector3d vtNmi = vtNMin ; + Vector3d vtNma = vtNMax ;*/ + if ( nGrid == 1) { + swap( vtNmi.x, vtNmi.z) ; + swap( vtNmi.y, vtNmi.z) ; + swap( vtNma.x, vtNma.z) ; + swap( vtNma.y, vtNma.z) ; + } + else if ( nGrid == 2) { + swap( vtNmi.y, vtNmi.z) ; + swap( vtNmi.x, vtNmi.z) ; + swap( vtNma.y, vtNma.z) ; + swap( vtNma.x, vtNma.z) ; + } + + // Calcolo nPos + unsigned int nPos = nJ * m_nNx[nGrid] + nI ; + vector& vDexel = m_Values[nGrid][nPos] ; + + bool bModified = false ; + + // Non esistono segmenti + if ( m_Values[nGrid][nPos].size() == 0) { + + vDexel.emplace_back() ; + vDexel.back().dMin = dMin ; + vDexel.back().vtMinN = vtNmi ; + vDexel.back().nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + vDexel.back().dMax = dMax ; + vDexel.back().vtMaxN = vtNma ; + vDexel.back().nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + + if ( dMax > m_dMaxZ[nGrid]) + m_dMaxZ[nGrid] = dMax ; + + if ( dMin < m_dMinZ[nGrid]) + m_dMinZ[nGrid] = dMin ; + + m_OGrMgr.Reset() ; + + bModified = true ; + } + // Esiste almeno un segmento + else { + // Cerco l'ultimo intervallo a sinistra e l'ultimo intervallo a destra + // di quello da aggiungere, che non interferiscono con quest'ultimo. + auto itLastLeft = vDexel.end() ; + auto itFirstRight = vDexel.end() ; + for ( auto it = vDexel.begin() ; it != vDexel.end() ; ++ it) { + if ( dMin > it->dMax + EPS_SMALL) + itLastLeft = it ; + if ( dMax < it->dMin - EPS_SMALL && itFirstRight == vDexel.end()) + itFirstRight = it ; + } + // Esistono intervalli a sinistra. + if ( itLastLeft != vDexel.end()) { + // Intervallo successivo all'ultimo a sinistra + auto itNextToLastLeft = itLastLeft ; + ++ itNextToLastLeft ; + // Il successivo non esiste. + if ( itNextToLastLeft == vDexel.end()) { + // Aggiungo il nuovo semgento + vDexel.emplace_back() ; + vDexel.back().dMin = dMin ; + vDexel.back().dMax = dMax ; + vDexel.back().vtMinN = vtNmi ; + vDexel.back().vtMaxN = vtNma; + vDexel.back().nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + vDexel.back().nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //m_Values[nGrid][nPos].back().nCompo = ; + bModified = true ; + } + // Il successivo esiste. + else { + // Il successivo è il primo a destra. + if ( itNextToLastLeft == itFirstRight) { + // Inserisco nuovo segmento- + Data NewSegment ; + NewSegment.dMin = dMin ; + NewSegment.dMax = dMax ; + NewSegment.vtMinN = vtNmi ; + NewSegment.vtMaxN = vtNma ; + NewSegment.nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + NewSegment.nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //NewSegment.nCompo = ; + vDexel.insert( itFirstRight, NewSegment) ; + bModified = true ; + } + else { + // Il successivo non esce a sinistra da quello da aggiungere. + if ( itNextToLastLeft->dMin > dMin + EPS_SMALL) { + itNextToLastLeft->dMin = dMin ; + itNextToLastLeft->vtMinN = vtNmi ; + itNextToLastLeft->nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + } + // Cerco l'ultimo segmento che interferisce con quello da aggiungere. + auto itPrevToFirstRight = vDexel.end() ; + for ( auto it = itNextToLastLeft ; it != itFirstRight ; ++ it) { + itPrevToFirstRight = it ; + } + // L'ultimo che interferisce non esce a destra da quello da aggiungere. + if ( itPrevToFirstRight->dMax < dMax - EPS_SMALL) { + itNextToLastLeft->dMax = dMax ; + itNextToLastLeft->vtMaxN = vtNma ; + itNextToLastLeft->nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //itNextToLastLeft->nCompo = ; + bModified = true ; + } + else { + itNextToLastLeft->dMax = itPrevToFirstRight->dMax ; + itNextToLastLeft->vtMaxN = itPrevToFirstRight->vtMaxN ; + itNextToLastLeft->nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //itNextToLastLeft->nCompo = ; + bModified = true ; + } + auto itFirstToCancel = itNextToLastLeft ; + ++ itFirstToCancel ; + vDexel.erase( itFirstToCancel, itFirstRight) ; + } + } + } + // Non esistono neanche a destra. + else if ( itFirstRight == m_Values[nGrid][nPos].end()) { + // Il primo intervallo non sporge a sinistra + if ( vDexel.begin()->dMin > dMin + EPS_SMALL) { + vDexel.begin()->dMin = dMin ; + vDexel.begin()->vtMinN = vtNmi ; + vDexel.begin()->nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //vDexel.begin().nCompo = ; + bModified = true ; + } + // L'ultimo intervallo sporge a destra. + if ( m_Values[nGrid][nPos].back().dMax > dMax + EPS_SMALL) { + // Ci sono più segmenti, inglobo tutti nel primo. + if ( vDexel.back().dMax > vDexel.begin()->dMax + EPS_SMALL) { + vDexel.begin()->dMax = vDexel.back().dMax ; + vDexel.begin()->vtMaxN = vDexel.back().vtMaxN ; + vDexel.begin()->nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //vDexel.begin().nCompo = ; + bModified = true ; + } + } + // L'ultimo intervallo non sporge a destra. + else { + vDexel.begin()->dMax = dMax ; + vDexel.begin()->vtMaxN = vtNma ; + vDexel.begin()->nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //vDexel.begin().nCompo = ; + bModified = true ; + } + vDexel.erase( vDexel.begin() + 1, vDexel.end()) ; + } + // A destra esistono. + else { + // Tutti i segmenti sono a destra di qullo da aggiungere. + if ( itFirstRight == vDexel.begin()) { + // Inserisco nuovo segmento- + Data NewSegment ; + NewSegment.dMin = dMin ; + NewSegment.dMax = dMax ; + NewSegment.vtMinN = vtNmi ; + NewSegment.vtMaxN = vtNma ; + NewSegment.nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + NewSegment.nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //NewSegment.nCompo = ; + vDexel.insert( vDexel.begin(), NewSegment) ; + bModified = true ; + } + else { + // Se il primo segmento non esce a sinistra da quello da aggiungere, cambio l'inizio. + if ( vDexel.begin()->dMin > dMin + EPS_SMALL) { + vDexel.begin()->dMin = dMin ; + vDexel.begin()->vtMinN = vtNmi ; + vDexel.begin()->nToolMin = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //vDexel.begin().nCompo = ; + bModified = true ; + } + // Cerco l'ultimo segmento che interferisce con quello da aggiungere. + auto itPrevToFirstRight = vDexel.begin() ; + for ( auto it = m_Values[nGrid][nPos].begin() ; it != itFirstRight ; ++ it) { + itPrevToFirstRight = it ; + } + // L'ultimo che interferisce non esce a destra da quello da aggiungere. + if ( itPrevToFirstRight->dMax < dMax - EPS_SMALL) { + vDexel.begin()->dMax = dMax ; + vDexel.begin()->vtMaxN = vtNma ; + vDexel.begin()->nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //vDexel.begin().nCompo = ; + bModified = true ; + } + else { + vDexel.begin()->dMax = itPrevToFirstRight->dMax ; + vDexel.begin()->vtMaxN = itPrevToFirstRight->vtMaxN ; + vDexel.begin()->nToolMax = m_vTool[m_nCurrTool].GetCurrentToolNum() ; + //vDexel.begin().nCompo = ; + bModified = true ; + } + auto itFirstToCancel = vDexel.begin() ; + ++ itFirstToCancel ; + vDexel.erase( itFirstToCancel, itFirstRight) ; + } + } + } + + // Se nessuna modifica, esco + if ( ! bModified) + return true ; + + // Elimino residui di intervalli inutili + for ( int i = 0 ; i < int( vDexel.size()) ; ++ i) { + int nMaxN = int( floor( ( vDexel[i].dMax + 2 * EPS_SMALL - 0.5 * m_dStep) / m_dStep)) ; + int nMinN = int( floor( ( vDexel[i].dMin - 2 * EPS_SMALL - 0.5 * m_dStep) / m_dStep)) ; + if ( nMinN == nMaxN) { + vDexel.erase( vDexel.begin() + i) ; + -- i ; + } + } + + // Imposto ricalcolo della grafica + m_OGrMgr.Reset() ; + // Imposto forma generica + m_nShape = GENERIC ; + // Imposto ricalcolo numero di componenti connesse + m_nConnectedCompoCount = - 1 ; + + // Passo da indici di dexel a indici di voxel + nI /= m_nDexVoxRatio ; + nJ /= m_nDexVoxRatio ; + + // Determino quali blocchi sono stati modificati + if ( nGrid == 0) { + // Voxel lungo X + int nXStop = 1 ; + int nXBlock[2] ; + nXBlock[0] = min( nI / m_nVoxNumPerBlock, m_nFracLin[0] - 1) ; + if ( nI % N_VOXBLOCK == 0 && nXBlock[0] > 0) { + nXBlock[1] = nXBlock[0] - 1 ; + ++ nXStop ; + } + // Voxel lungo Y + int nYStop = 1 ; + int nYBlock[2] ; + nYBlock[0] = min( nJ / m_nVoxNumPerBlock, m_nFracLin[1] - 1) ; + if ( nJ % N_VOXBLOCK == 0 && nYBlock[0] > 0) { + nYBlock[1] = nYBlock[0] - 1 ; + ++ nYStop ; + } + // Voxel lungo Z + int nVoxNumZ = int( m_nNy[1] / m_nDexVoxRatio + ( m_nNy[1] % m_nDexVoxRatio == 0 ? 1 : 2)) ; + int nMinK = Clamp( int( floor( ( ( dMin - 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) - EPS_SMALL))), 0, nVoxNumZ - 2) ; + int nMaxK = Clamp( int( floor( ( ( dMax + 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) + EPS_SMALL))), 0, nVoxNumZ - 2) ; + int nMinZBlock = ( m_nMapNum == 1 ? 0 : Clamp( nMinK / int( m_nVoxNumPerBlock), 0, int( m_nFracLin[2] - 1))) ; + int nMaxZBlock = min( int( m_nFracLin[2] - 1), nMaxK / int( m_nVoxNumPerBlock)) ; + // Assegno flag ai voxel + for ( int tI = 0 ; tI < nXStop ; ++ tI) { + for ( int tJ = 0 ; tJ < nYStop ; ++ tJ) { + for ( int k = nMinZBlock ; k <= nMaxZBlock ; ++ k) { + int nBlockNum = k * m_nFracLin[0] * m_nFracLin[1] + nYBlock[tJ] * m_nFracLin[0] + nXBlock[tI] ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + + else if ( nGrid == 1) { + // Voxel lungo Y + int nYStop = 1 ; + int nYBlock[2] ; + nYBlock[0] = min( nI / m_nVoxNumPerBlock, m_nFracLin[1] - 1) ; + if ( nI % N_VOXBLOCK == 0 && nYBlock[0] > 0) { + nYBlock[1] = nYBlock[0] - 1 ; + ++ nYStop ; + } + // Voxel lungo Z + int nZStop = 1 ; + int nZBlock[2] ; + nZBlock[0] = min( nJ / m_nVoxNumPerBlock, m_nFracLin[2] - 1) ; + if ( nJ % N_VOXBLOCK == 0 && nZBlock[0] > 0) { + nZBlock[1] = nZBlock[0] - 1 ; + ++ nZStop ; + } + // Voxel lungo X + int nVoxNumX = int( m_nNx[0] / m_nDexVoxRatio + ( m_nNx[0] % m_nDexVoxRatio == 0 ? 1 : 2)) ; + int nMinI = Clamp( int( floor( ( ( dMin - 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) - EPS_SMALL))), 0, nVoxNumX - 2) ; + int nMaxI = Clamp( int( floor( ( ( dMax + 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) + EPS_SMALL))), 0, nVoxNumX - 2) ; + int nMinXBlock = Clamp( nMinI / int( m_nVoxNumPerBlock), 0, int( m_nFracLin[0] - 1)) ; + int nMaxXBlock = min( int( m_nFracLin[0] - 1), nMaxI / int( m_nVoxNumPerBlock)) ; + // Assegno flag ai voxel + for ( int tI = 0 ; tI < nYStop ; ++ tI) { + for ( int tJ = 0 ; tJ < nZStop ; ++ tJ) { + for ( int k = nMinXBlock ; k <= nMaxXBlock ; ++ k) { + int nBlockNum = nZBlock[tJ] * m_nFracLin[0] * m_nFracLin[1] + nYBlock[tI] * m_nFracLin[0] + k ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + + else if ( nGrid == 2) { + // Voxel lungo X + int nXStop = 1 ; + int nXBlock[2] ; + nXBlock[0] = min( nJ / m_nVoxNumPerBlock, m_nFracLin[0] - 1) ; + if ( nJ % N_VOXBLOCK == 0 && nXBlock[0] > 0) { + nXBlock[1] = nXBlock[0] - 1 ; + ++ nXStop ; + } + // Voxel lungo Z + int nZStop = 1 ; + int nZBlock[2] ; + nZBlock[0] = min( nI / m_nVoxNumPerBlock, m_nFracLin[2] - 1) ; + if ( nI % N_VOXBLOCK == 0 && nZBlock[0] > 0) { + nZBlock[1] = nZBlock[0] - 1 ; + ++ nZStop ; + } + // Voxel lungo Y + int nVoxNumY = int( m_nNy[0] / m_nDexVoxRatio + ( m_nNy[0] % m_nDexVoxRatio == 0 ? 1 : 2)) ; + int nMinJ = Clamp( int( floor( ( ( dMin - 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) - EPS_SMALL))), 0, nVoxNumY - 2) ; + int nMaxJ = Clamp( int( floor( ( ( dMax + 0.5 * m_dStep) / ( m_nDexVoxRatio * m_dStep) + EPS_SMALL))), 0, nVoxNumY - 2) ; + int nMinYBlock = Clamp( nMinJ / int( m_nVoxNumPerBlock), 0, int( m_nFracLin[1] - 1)) ; + int nMaxYBlock = min( int( m_nFracLin[1] - 1), nMaxJ / int( m_nVoxNumPerBlock)) ; + // Assegno flag ai voxel + for ( int tI = 0 ; tI < nZStop ; ++ tI) { + for ( int tJ = 0 ; tJ < nXStop ; ++ tJ) { + for ( int k = nMinYBlock ; k <= nMaxYBlock ; ++ k) { + int nBlockNum = nZBlock[tI] * m_nFracLin[0] * m_nFracLin[1] + k * m_nFracLin[0] + nXBlock[tJ] ; + m_BlockToUpdate[nBlockNum] = true ; + } + } + } + } + return true ; } @@ -493,8 +627,8 @@ bool VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs, const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) { - // Se non è definito l'utensile, non devo fare alcunchè - if ( m_Tool.GetType() == Tool::UNDEF) + // Se non � definito l'utensile, non devo fare alcunch� + if ( m_nCurrTool < 0 || m_vTool[m_nCurrTool].GetType() == Tool::UNDEF) return true ; // Controllo definizione vettori direzione if ( vtDs.IsSmall() || vtDe.IsSmall()) @@ -503,7 +637,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe)) return true ; // Se utensile chisel o mortise, controllo definizione vettori ausiliari - if ( m_Tool.GetType() == Tool::MORTISER || m_Tool.GetType() == Tool::CHISEL) { + if ( m_vTool[m_nCurrTool].GetType() == Tool::MORTISER || m_vTool[m_nCurrTool].GetType() == Tool::CHISEL) { if ( vtAs.IsSmall() || vtAe.IsSmall()) return false ; } @@ -592,7 +726,7 @@ VolZmap::MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d vtLs[N_MAPS] ; Vector3d vtALs[N_MAPS] ; InitializePointsAndVectors( ptPs, ptPe, vtD, vtA, ptLs, ptLe, vtLs, vtALs) ; - // Ciclo sulle mappe + // Ciclo sulle mappe vector< future> vRes ; vRes.resize( m_nMapNum) ; for ( int i = 0 ; i < m_nMapNum ; ++ i) { @@ -654,7 +788,7 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons // Foratura if ( vtMove.SqLenXY() < EPS_SMALL * EPS_SMALL) { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_ZDrilling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -676,7 +810,7 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons // Fresatura con vettore movimento perpendicolare all'utensile else if ( abs( vtMove.z) < EPS_SMALL) { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_ZMilling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -693,12 +827,15 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons case Tool::CHISEL : Chs_Milling( nGrid, ptLs, ptLe, vtL, vtAL) ; break ; + case Tool::ADDITIVE : + // Chiama metodo + break ; } } // Fresatura con vettore movimento generico rispetto all'utensile else { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_ZMilling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -728,7 +865,7 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons // Foratura if ( dSqLOrt < EPS_SMALL * EPS_SMALL) { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_Drilling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -749,7 +886,7 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons } // Fresatura con vettore movimento perpendicolare all'utensile else if ( dSqLLong < EPS_SMALL * EPS_SMALL) { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_Milling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -758,7 +895,7 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons CylBall_XYPerp( nGrid, ptLs, ptLe, vtL) ; break ; case Tool::CONEMILL : - // Usiamo la generica per via dell'intsabilità di Conus_XYPerp + // Usiamo la generica per via dell'intsabilit� di Conus_XYPerp //Conus_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; Conus_Milling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -768,11 +905,14 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons case Tool::CHISEL : Chs_Milling( nGrid, ptLs, ptLe, vtL, vtAL) ; break ; + case Tool::ADDITIVE : + // Chiama metodo + break ; } } // Fresatura con vettore movimento generico rispetto all'utensile else { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_Milling( nGrid, ptLs, ptLe, vtL); break ; @@ -801,7 +941,7 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons // Foratura if ( dSqLOrt < EPS_SMALL * EPS_SMALL) { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_Drilling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -822,7 +962,7 @@ VolZmap::SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, cons } // Fresatura con vettore movimento generico rispetto all'utensile else { - switch ( m_Tool.GetType()) { + switch ( m_vTool[m_nCurrTool].GetType()) { case Tool::GEN : GenTool_Milling( nGrid, ptLs, ptLe, vtL) ; break ; @@ -865,8 +1005,8 @@ VolZmap::CylBall_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, Point3d ptSxy( ptS.x, ptS.y, 0) ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dSqRad = m_Tool.GetRadius() * m_Tool.GetRadius() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dSqRad = m_vTool[m_nCurrTool].GetRadius() * m_vTool[m_nCurrTool].GetRadius() ; // Punte del gambo Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ; @@ -884,12 +1024,12 @@ VolZmap::CylBall_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, double dSqLen = vtC.SqLen() ; // Se il punto si trova dentro il cerchio taglio - if ( dSqLen < dSqRad - 2 * m_Tool.GetRadius() * EPS_SMALL) { + if ( dSqLen < dSqRad - 2 * m_vTool[m_nCurrTool].GetRadius() * EPS_SMALL) { // utensile cilindrico - if ( m_Tool.GetType() == Tool::CYLMILL) + if ( m_vTool[m_nCurrTool].GetType() == Tool::CYLMILL) SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ, Z_AX, - Z_AX) ; // utensile sferico - else if ( m_Tool.GetType() == Tool::BALLMILL) { + else if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) { double dH = sqrt( dSqRad - dSqLen) ; if ( vtToolDir.z > 0) { Vector3d vtNorm = Point3d( ptSxy.x, ptSxy.y, dMinStemZ) - Point3d( dX, dY, dMinStemZ - dH) ; @@ -918,8 +1058,8 @@ VolZmap::CylBall_ZPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const return true ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dSafeRad = m_Tool.GetRadius() - EPS_SMALL ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dSafeRad = m_vTool[m_nCurrTool].GetRadius() - EPS_SMALL ; double dSafeSqRad = dSafeRad * dSafeRad ; // Punte del gambo @@ -937,7 +1077,7 @@ VolZmap::CylBall_ZPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const // Definizione di un sistema di riferimento ad hoc Point3d ptSxy( ptS.x, ptS.y, 0) ; Vector3d vtV1 = vtMove ; - vtV1.Normalize() ; // se |vtMove| < EPS è un buco con dz = 0 + vtV1.Normalize() ; // se |vtMove| < EPS � un buco con dz = 0 Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 0, 1) ; @@ -951,7 +1091,7 @@ VolZmap::CylBall_ZPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; // Utensile cilindrico - if ( m_Tool.GetType() == Tool::CYLMILL) { + if ( m_vTool[m_nCurrTool].GetType() == Tool::CYLMILL) { // Se il punto cade nella zona di interesse taglio if ( ( dP1 * dP1 + dP2 * dP2 < dSafeSqRad) || ( ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2) < dSafeSqRad || @@ -961,7 +1101,7 @@ VolZmap::CylBall_ZPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const } // Utensile sferico - else if ( m_Tool.GetType() == Tool::BALLMILL) { + else if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) { if ( abs( dP2) < dSafeRad) { @@ -1043,10 +1183,10 @@ VolZmap::CylBall_ZMilling( int nGrid, const Point3d & ptS, const Point3d & ptE, return true ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dSafeRadius = m_Tool.GetRadius() - EPS_SMALL ; - double dSqRad = m_Tool.GetRadius() * m_Tool.GetRadius() ; - double dSafeSqRad = dSqRad - 2 * m_Tool.GetRadius() * EPS_SMALL ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dSafeRadius = m_vTool[m_nCurrTool].GetRadius() - EPS_SMALL ; + double dSqRad = m_vTool[m_nCurrTool].GetRadius() * m_vTool[m_nCurrTool].GetRadius() ; + double dSafeSqRad = dSqRad - 2 * m_vTool[m_nCurrTool].GetRadius() * EPS_SMALL ; // Studio delle simmetrie Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; @@ -1074,7 +1214,7 @@ VolZmap::CylBall_ZMilling( int nGrid, const Point3d & ptS, const Point3d & ptE, // Definizione di un sistema di riferimento ad hoc Vector3d vtV1, vtV2 ; - // Se la lunghezza è troppo piccola lo allungo + // Se la lunghezza � troppo piccola lo allungo if ( dLenXY < EPS_SMALL) vtV1 = ( 1 / dLenXY) * vtMoveXY ; else @@ -1148,9 +1288,9 @@ VolZmap::CylBall_ZMilling( int nGrid, const Point3d & ptS, const Point3d & ptE, } } - if ( m_Tool.GetType() == Tool::BALLMILL) + if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) - CompBall_Milling( nGrid, ptIT, ptFT, m_Tool.GetRadius()) ; + CompBall_Milling( nGrid, ptIT, ptFT, m_vTool[m_nCurrTool].GetRadius()) ; return true ; } @@ -1167,9 +1307,9 @@ VolZmap::Conus_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, c return true ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dMinRad = min( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; - double dMaxRad = max( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dMinRad = min( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; + double dMaxRad = max( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; @@ -1178,17 +1318,17 @@ VolZmap::Conus_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, c Point3d ptO( ptS.x, ptS.y, 0) ; // Quote massime e minime dell'utensile durante il moto - double dZMax = max( max( ptS.z, ptS.z - vtToolDir.z * m_Tool.GetHeigth()), - max( ptE.z, ptE.z - vtToolDir.z * m_Tool.GetHeigth())) ; - double dZMin = min( min( ptS.z, ptS.z - vtToolDir.z * m_Tool.GetHeigth()), - min( ptE.z, ptE.z - vtToolDir.z * m_Tool.GetHeigth())) ; + double dZMax = max( max( ptS.z, ptS.z - vtToolDir.z * m_vTool[m_nCurrTool].GetHeigth()), + max( ptE.z, ptE.z - vtToolDir.z * m_vTool[m_nCurrTool].GetHeigth())) ; + double dZMin = min( min( ptS.z, ptS.z - vtToolDir.z * m_vTool[m_nCurrTool].GetHeigth()), + min( ptE.z, ptE.z - vtToolDir.z * m_vTool[m_nCurrTool].GetHeigth())) ; // Parametri geometrici per // determinare il vettore normale - double dL = m_Tool.GetTipHeigth() * dMaxRad / dDeltaRad ; + double dL = m_vTool[m_nCurrTool].GetTipHeigth() * dMaxRad / dDeltaRad ; // Trapano - if ( m_Tool.GetTipRadius() < m_Tool.GetRadius()) { + if ( m_vTool[m_nCurrTool].GetTipRadius() < m_vTool[m_nCurrTool].GetRadius()) { // Ciclo sui punti for ( int i = nStartI ; i <= nEndI ; ++ i) { @@ -1213,7 +1353,7 @@ VolZmap::Conus_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, c if ( vtToolDir.z > 0) { - double dMin = dZMin + m_Tool.GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; + double dMin = dZMin + m_vTool[m_nCurrTool].GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; double dMax = dZMax ; Point3d ptInt( dX, dY, dMin) ; @@ -1227,7 +1367,7 @@ VolZmap::Conus_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, c else { double dMin = dZMin ; - double dMax = dZMax - m_Tool.GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; + double dMax = dZMax - m_vTool[m_nCurrTool].GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; Point3d ptInt( dX, dY, dMax) ; Point3d ptPn( ptO.x, ptO.y, dMax - dl) ; @@ -1268,7 +1408,7 @@ VolZmap::Conus_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, c if ( vtToolDir.z > 0) { double dMin = dZMin ; - double dMax = dZMax - dStemHeigth - m_Tool.GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; + double dMax = dZMax - dStemHeigth - m_vTool[m_nCurrTool].GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; Point3d ptInt( dX, dY, dMax) ; Point3d ptPn( ptO.x, ptO.y, dMax - dl) ; @@ -1280,7 +1420,7 @@ VolZmap::Conus_ZDrilling( int nGrid, const Point3d & ptS, const Point3d & ptE, c } else { - double dMin = dZMin + dStemHeigth + m_Tool.GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; + double dMin = dZMin + dStemHeigth + m_vTool[m_nCurrTool].GetTipHeigth() * ( dr - dMinRad) / dDeltaRad ; double dMax = dZMax ; Point3d ptInt( dX, dY, dMin) ; @@ -1308,9 +1448,9 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const return true ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dMinRad = min( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; - double dMaxRad = max( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dMinRad = min( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; + double dMaxRad = max( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; double dDeltaRad = dMaxRad - dMinRad ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; @@ -1333,13 +1473,13 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const double dBaseZ = ptS.z ; double dStemZ = ptS.z - vtToolDir.z * dStemHeigth ; - double dTipZ = ptS.z - vtToolDir.z * m_Tool.GetHeigth() ; + double dTipZ = ptS.z - vtToolDir.z * m_vTool[m_nCurrTool].GetHeigth() ; // Lunghezza cono - double dL = m_Tool.GetTipHeigth() * dMaxRad / dDeltaRad ; + double dL = m_vTool[m_nCurrTool].GetTipHeigth() * dMaxRad / dDeltaRad ; // Punta a trapano - if ( m_Tool.GetTipRadius() < m_Tool.GetRadius()) { + if ( m_vTool[m_nCurrTool].GetTipRadius() < m_vTool[m_nCurrTool].GetRadius()) { Vector3d vtV = vtToolDir ; @@ -1389,7 +1529,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Point3d ptInt( dX, dY, dMin) ; Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; vtU.Normalize() ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; vtNmax = - Z_AX ; } @@ -1399,7 +1539,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; vtU.Normalize() ; vtNmin = Z_AX ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; @@ -1415,7 +1555,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Point3d ptInt( dX, dY, dMin) ; Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; vtU.Normalize() ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; vtNmax = - Z_AX ; } @@ -1425,7 +1565,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; vtU.Normalize() ; vtNmin = Z_AX ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } @@ -1443,7 +1583,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Point3d ptInt( dX, dY, dMin) ; Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; vtU.Normalize() ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; vtNmax = -Z_AX ; } @@ -1453,7 +1593,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; vtU.Normalize() ; vtNmin = Z_AX ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } @@ -1470,8 +1610,8 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtV = - vtToolDir ; - Point3d ptVS = ptS - vtToolDir * ( m_Tool.GetHeigth() - dL) ; - Point3d ptVE = ptE - vtToolDir * ( m_Tool.GetHeigth() - dL) ; + Point3d ptVS = ptS - vtToolDir * ( m_vTool[m_nCurrTool].GetHeigth() - dL) ; + Point3d ptVE = ptE - vtToolDir * ( m_vTool[m_nCurrTool].GetHeigth() - dL) ; for ( int i = nStartI ; i <= nEndI ; ++ i) { for( int j = nStartJ ; j <= nEndJ ; ++ j) { @@ -1513,7 +1653,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; vtU.Normalize() ; vtNmin = Z_AX ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } @@ -1522,7 +1662,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVS) - ( ptInt - ptVS) * vtV * vtV ; vtU.Normalize() ; vtNmax = -Z_AX ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; } SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; @@ -1539,7 +1679,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; vtU.Normalize() ; vtNmin = Z_AX ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } @@ -1548,7 +1688,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVtemp) - ( ptInt - ptVtemp) * vtV * vtV ; vtU.Normalize() ; vtNmax = -Z_AX ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; } @@ -1565,7 +1705,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; vtU.Normalize() ; vtNmin = Z_AX ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } @@ -1574,7 +1714,7 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d vtU = ( ptInt - ptVE) - ( ptInt - ptVE) * vtV * vtV ; vtU.Normalize() ; vtNmax = -Z_AX ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; } @@ -1592,20 +1732,20 @@ VolZmap::Conus_ZPerp( int nGrid, const Point3d & ptS, const Point3d & ptE, const bool VolZmap::Conus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { - double dStemH = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; + double dStemH = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; - CompCyl_ZMilling( nGrid, ptS, ptE, vtToolDir, dStemH, m_Tool.GetRadius()) ; + CompCyl_ZMilling( nGrid, ptS, ptE, vtToolDir, dStemH, m_vTool[m_nCurrTool].GetRadius()) ; - if ( m_Tool.GetTipRadius() < m_Tool.GetRadius()) { + if ( m_vTool[m_nCurrTool].GetTipRadius() < m_vTool[m_nCurrTool].GetRadius()) { Point3d ptSC = ptS - vtToolDir * dStemH ; Point3d ptEC = ptE - vtToolDir * dStemH ; - CompConus_ZMilling( nGrid, ptSC, ptEC, vtToolDir, m_Tool.GetTipHeigth(), m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; + CompConus_ZMilling( nGrid, ptSC, ptEC, vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; } else { - Point3d ptSC = ptS - vtToolDir * m_Tool.GetHeigth() ; - Point3d ptEC = ptE - vtToolDir * m_Tool.GetHeigth() ; - CompConus_ZMilling( nGrid, ptSC, ptEC, - vtToolDir, m_Tool.GetTipHeigth(), m_Tool.GetTipRadius(), m_Tool.GetRadius()) ; + Point3d ptSC = ptS - vtToolDir * m_vTool[m_nCurrTool].GetHeigth() ; + Point3d ptEC = ptE - vtToolDir * m_vTool[m_nCurrTool].GetHeigth() ; + CompConus_ZMilling( nGrid, ptSC, ptEC, - vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), m_vTool[m_nCurrTool].GetTipRadius(), m_vTool[m_nCurrTool].GetRadius()) ; } return true ; @@ -1624,21 +1764,21 @@ VolZmap::Mrt_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const // Scompongo la mortasatrice in solidi semplici // Parallelepipedo di base - double dLenX = m_Tool.GetMrtChsWidth() ; - double dLenY = m_Tool.GetMrtChsThickness() ; - double dLenZ = m_Tool.GetHeigth() - m_Tool.GetCornRadius() ; + double dLenX = m_vTool[m_nCurrTool].GetMrtChsWidth() ; + double dLenY = m_vTool[m_nCurrTool].GetMrtChsThickness() ; + double dLenZ = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetCornRadius() ; CompPar_ZDrilling( nGrid, dLenX, dLenY, dLenZ, ptS, ptEOnP, vtToolDir, vtAux) ; - // Se la punta è di tipo bull-nose - if ( abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) > EPS_SMALL) { + // Se la punta � di tipo bull-nose + if ( abs( m_vTool[m_nCurrTool].GetMrtChsWidth() - 2 * m_vTool[m_nCurrTool].GetCornRadius()) > EPS_SMALL) { // Parallelepipedo di punta Point3d ptTipS = ptS - dLenZ * vtToolDir ; Point3d ptTipE = ptEOnP - dLenZ * vtToolDir ; - dLenX = abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) ; - dLenZ = m_Tool.GetCornRadius() ; + dLenX = abs( m_vTool[m_nCurrTool].GetMrtChsWidth() - 2 * m_vTool[m_nCurrTool].GetCornRadius()) ; + dLenZ = m_vTool[m_nCurrTool].GetCornRadius() ; CompPar_ZDrilling( nGrid, dLenX, dLenY, dLenZ, ptTipS, ptTipE, vtToolDir, vtAux) ; @@ -1650,17 +1790,17 @@ VolZmap::Mrt_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Point3d ptSplus = ptTipS + ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ; Point3d ptEplus = ptTipE + ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ; - CompCyl_Milling( nGrid, ptSminus, ptEminus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; - CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptSminus, ptEminus, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; } - // se la punta è di tipo sfera + // se la punta � di tipo sfera else { // Cilindro Point3d ptCylS = ptS - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; Point3d ptCylE = ptEOnP - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; - CompCyl_Milling( nGrid, ptCylS, ptCylE, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptCylS, ptCylE, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; } return true ; @@ -1673,7 +1813,7 @@ VolZmap::Mrt_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const bool VolZmap::Chs_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) { - CompPar_ZDrilling( nGrid, m_Tool.GetMrtChsWidth(), m_Tool.GetMrtChsThickness(), m_Tool.GetHeigth(), + CompPar_ZDrilling( nGrid, m_vTool[m_nCurrTool].GetMrtChsWidth(), m_vTool[m_nCurrTool].GetMrtChsThickness(), m_vTool[m_nCurrTool].GetHeigth(), ptS, ptE, vtToolDir, vtAux) ; return true ; } @@ -1687,7 +1827,7 @@ VolZmap::Chs_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d vtMoveOnP = ( ptE - ptS) - ( ptE - ptS) * vtToolDir * vtToolDir ; Point3d ptEp = ptS + vtMoveOnP ; - CompPar_ZMilling( nGrid, m_Tool.GetMrtChsWidth(), m_Tool.GetMrtChsThickness(), m_Tool.GetHeigth(), + CompPar_ZMilling( nGrid, m_vTool[m_nCurrTool].GetMrtChsWidth(), m_vTool[m_nCurrTool].GetMrtChsThickness(), m_vTool[m_nCurrTool].GetHeigth(), ptSp, ptEp, vtToolDir, vtAux) ; return true ; } @@ -1703,18 +1843,19 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Point3d ptF = ptE ; Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi - const VCT3DVECTOR& vArcNorm = m_Tool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + const VCT3DVECTOR& vArcNorm = m_vTool[m_nCurrTool].GetArcNormalVec() ; + // Poinch� l'asse utensile � parallelo all'asse Z, definisco un sistema di // riferimento ad hoc in cui le normali agli archi giacciano nel piano XZ. Frame3d frNormFrame ; frNormFrame.Set( ORIG, X_AX, - Z_AX, Y_AX) ; // Ciclo sulle curve - const CurveComposite& ToolProfile = m_Tool.GetApproxOutline() ; + const CurveComposite& ToolProfile = m_vTool[m_nCurrTool].GetApproxOutline() ; int i = - 1 ; const ICurve* pCurve = ToolProfile.GetCurve( ++ i) ; while ( pCurve != nullptr) { double dHeight = 0 ; + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { @@ -1731,29 +1872,62 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c vtNormEn.ToLoc( frNormFrame) ; } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; + // Cilindro o cono if ( dHeight > EPS_SMALL) { - // Se X costante, è un cilindro + // Se X costante, � un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) + if ( dRadius > 10 * EPS_SMALL && m_vTool[m_nCurrTool].GetCuttingFlag()) CompCyl_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; } - // Se X crescente, è un cono con vettore equiverso a quello dell'utensile + // Se X crescente, � un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormEn, vtNormSt) ; + } + } } - // Se X decrescente, è un cono con vettore opposto a quello dell'utensile + // Se X decrescente, � un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; - Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptIn = ptI - vtToolDir * dSignedHeight ; Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormEn, vtNormSt) ; + else { + vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ; + SurfConus_ZDrilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormSt, vtNormEn) ; + } + } + } + } + // Corona circolare + else if ( ! m_vTool[m_nCurrTool].GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_ZDrilling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_ZDrilling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; } } } @@ -1770,13 +1944,45 @@ VolZmap::GenTool_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, c Point3d ptCenS = ptI - vtToolDir * ( ptStart.y - ptCen.y) ; Point3d ptCenE = ptCenS + vtMove ; // Eseguo l'asportazione del materiale - CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + else if ( pCurve->GetTempProp( 1) == 1) { + double dStH = ptStart.y - ptCen.y ; + double dEnH = ptEnd.y - ptCen.y ; + // Tagliente esterno + if ( dEnH < dStH) { + if ( dEnH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, dEnH, dStH, true) ; + } + else if ( dStH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, dStH, true) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, - dEnH, true) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, - dEnH, - dStH, true) ; + } + } + // Tagliente interno + else { + if ( dEnH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + else if ( dStH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, abs( dStH), false) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, abs( dEnH), false) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + } + dSignedHeight = ptStart.y - ptEnd.y ; + } // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; // Passo alla curva successiva del profilo @@ -1795,18 +2001,19 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Point3d ptF = ptE ; Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi - const VCT3DVECTOR& vArcNorm = m_Tool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + const VCT3DVECTOR& vArcNorm = m_vTool[m_nCurrTool].GetArcNormalVec() ; + // Poinch� l'asse utensile � parallelo all'asse Z, definisco un sistema di // riferimento ad hoc in cui le normali agli archi giacciano nel piano XZ. Frame3d frNormFrame; frNormFrame.Set( ORIG, X_AX, -Z_AX, Y_AX) ; // Ciclo sulle curve del profilo utensile - const CurveComposite& ToolProfile = m_Tool.GetApproxOutline() ; + const CurveComposite& ToolProfile = m_vTool[m_nCurrTool].GetApproxOutline() ; int i = - 1 ; const ICurve* pCurve = ToolProfile.GetCurve( ++ i) ; while ( pCurve != nullptr) { double dHeight = 0 ; + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { @@ -1823,31 +2030,71 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co vtNormEn.ToLoc( frNormFrame) ; } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; if ( dHeight > EPS_SMALL) { - // Se X costante, è un cilindro + // Se X costante, � un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) - CompCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; + if ( dRadius > 10 * EPS_SMALL) { + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, true) ; + else { + SurfCyl_ZMilling( nGrid, ptI, ptF, - vtToolDir, dHeight, dRadius, false) ; + } + } + } } - // Se X crescente, è un cono con vettore equiverso a quello dell'utensile + // Se X crescente, � un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormEn, vtNormSt) ; + } + } } - // Se X decrescente, è un cono con vettore opposto a quello dell'utensile + // Se X decrescente, � un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; - Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptIn = ptI - vtToolDir * dSignedHeight ; Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, vtNormEn, vtNormSt) ; + else { + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, vtNormSt, vtNormEn) ; + } + } } } + else if ( ! m_vTool[m_nCurrTool].GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_ZMilling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_ZMilling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; + } + } } // se altrimenti arco @@ -1862,13 +2109,45 @@ VolZmap::GenTool_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Point3d ptCenS = ptI - vtToolDir * ( ptStart.y - ptCen.y) ; Point3d ptCenE = ptCenS + vtMove ; // Eseguo l'asportazione del materiale - CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + else if ( pCurve->GetTempProp( 1) == 1) { + double dStH = ptStart.y - ptCen.y ; + double dEnH = ptEnd.y - ptCen.y ; + // Tagliente esterno + if ( dEnH < dStH) { + if ( dEnH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, dEnH, dStH, true) ; + } + else if ( dStH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, dStH, true) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, - dEnH, true) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, - dEnH, - dStH, true) ; + } + } + // Tagliente interno + else { + if ( dEnH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + else if ( dStH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, abs( dStH), false) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, abs( dEnH), false) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + } + dSignedHeight = ptStart.y - ptEnd.y ; + } // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; // Passo alla curva successiva del profilo @@ -1891,8 +2170,8 @@ VolZmap::CylBall_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, return true ; // Parametri geometrici dell'utensile e quota Z del movimento - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dSqRad = m_Tool.GetRadius() * m_Tool.GetRadius() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dSqRad = m_vTool[m_nCurrTool].GetRadius() * m_vTool[m_nCurrTool].GetRadius() ; double dZ = ptS.z ; // Vettore movimento e sua lunghezza @@ -1922,7 +2201,7 @@ VolZmap::CylBall_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, // Zona lavorata dalla parte cilindrica if ( dP1 > EPS_SMALL && dP1 < dStemHeigth + dLen - EPS_SMALL && - abs( dP2) < m_Tool.GetRadius()) { + abs( dP2) < m_vTool[m_nCurrTool].GetRadius()) { double dH = sqrt( dSqRad - dP2 * dP2) ; double dMin = dZ - dH ; @@ -1942,9 +2221,9 @@ VolZmap::CylBall_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; } - // Se l'utensile è sferico sottraggo anche la punta - if ( m_Tool.GetType() == Tool::BALLMILL) - if ( dSqLen < dSqRad) { // LA SOLUZIONE MOMENTANEA è CREARE UTENSILE GENERICO SE LO STELO è PIù CORTO DEL RAGGIO + // Se l'utensile � sferico sottraggo anche la punta + if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) + if ( dSqLen < dSqRad) { // LA SOLUZIONE MOMENTANEA � CREARE UTENSILE GENERICO SE LO STELO � PI� CORTO DEL RAGGIO double dH = sqrt( dSqRad - dSqLen) ; double dMin = dZ - dH ; @@ -1973,14 +2252,14 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons return true ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dSqRad = m_Tool.GetRadius() * m_Tool.GetRadius() ; - double dSafeSqRad = dSqRad - 2 * m_Tool.GetRadius() * EPS_SMALL ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dSqRad = m_vTool[m_nCurrTool].GetRadius() * m_vTool[m_nCurrTool].GetRadius() ; + double dSafeSqRad = dSqRad - 2 * m_vTool[m_nCurrTool].GetRadius() * EPS_SMALL ; // Studio simmetrie del problema Point3d ptI = ( ptS.z <= ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z <= ptE.z ? ptE : ptS) ; - // elimino eventuale piccolo errore di perpendicolarità del movimento rispetto all'utensile + // elimino eventuale piccolo errore di perpendicolarit� del movimento rispetto all'utensile Vector3d vtErr = 0.5 * ( ( ptF - ptI) * vtToolDir) * vtToolDir ; ptI += vtErr ; ptF -= vtErr ; @@ -2010,15 +2289,15 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons // Vettori e punti determinanti i piani Vector3d vtP = vtMove ; // Se dLen < EPS_SMALL non si usa vtP.Rotate( vtToolDir, 0, 1) ; - Point3d ptUp = ptI + m_Tool.GetRadius() * ( vtP.z > 0 ? vtP : - vtP) ; - Point3d ptDw = ptI + m_Tool.GetRadius() * ( vtP.z > 0 ? - vtP : vtP) ; + Point3d ptUp = ptI + m_vTool[m_nCurrTool].GetRadius() * ( vtP.z > 0 ? vtP : - vtP) ; + Point3d ptDw = ptI + m_vTool[m_nCurrTool].GetRadius() * ( vtP.z > 0 ? - vtP : vtP) ; Vector3d vtPXY( vtP.x, vtP.y, 0) ; Vector3d vtUp = ptUp - ORIG ; double dDotUp = vtUp * vtP ; Vector3d vtDw = ptDw - ORIG ; double dDotDw = vtDw * vtP ; - double dSmall = m_Tool.GetRadius() * vtPXY.LenXY() ; + double dSmall = m_vTool[m_nCurrTool].GetRadius() * vtPXY.LenXY() ; // Parte sferica double dCos = vtMove.z ; // vtMove.z > 0 : ptF.z >= ptI.z @@ -2043,8 +2322,8 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons Vector3d vtNmin, vtNmax ; if ( dP1 > EPS_SMALL && dP1 < dStemHeigth - EPS_SMALL && - dP2 > - m_Tool.GetRadius() + EPS_SMALL && - dP2 < m_Tool.GetRadius() - EPS_SMALL) { + dP2 > - m_vTool[m_nCurrTool].GetRadius() + EPS_SMALL && + dP2 < m_vTool[m_nCurrTool].GetRadius() - EPS_SMALL) { dInfZ = ptI.z - sqrt( dSqRad - dP2 * dP2) ; dSupZ = ptF.z + sqrt( dSqRad - dP2 * dP2) ; @@ -2061,7 +2340,7 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons SubtractIntervals( nGrid, i, j, dInfZ, dSupZ, vtNmin, vtNmax) ; } - if ( m_Tool.GetType() == Tool::BALLMILL) { + if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) { if ( dP1 > dStemHeigth - 2 * EPS_SMALL && ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSafeSqRad) { @@ -2100,7 +2379,7 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons // Parte cilindrica if ( dP1 > EPS_SMALL && dP1 < dStemHeigth - EPS_SMALL) { - if ( dP2 > - m_Tool.GetRadius() && dP2 < dLenXY + m_Tool.GetRadius()) { + if ( dP2 > - m_vTool[m_nCurrTool].GetRadius() && dP2 < dLenXY + m_vTool[m_nCurrTool].GetRadius()) { Vector3d vtNmin, vtNmax ; @@ -2158,12 +2437,12 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons } } - // Se l'utensile è ball-end sottraggo la punta - if ( m_Tool.GetType() == Tool::BALLMILL) { + // Se l'utensile � ball-end sottraggo la punta + if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) { if ( ( ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSqRad || ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + ( dP2 - dLenXY) * ( dP2 - dLenXY) < dSqRad || - ( dP2 > 0 && dP2 < dLenXY && dP1 < m_Tool.GetHeigth())) && ( dP1 > dStemHeigth - 2 * EPS_SMALL)) { + ( dP2 > 0 && dP2 < dLenXY && dP1 < m_vTool[m_nCurrTool].GetHeigth())) && ( dP1 > dStemHeigth - 2 * EPS_SMALL)) { double dSqRoot = sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth)) ; double dP2_0 = dCos * dSqRoot ; @@ -2230,13 +2509,13 @@ VolZmap::CylBall_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, cons bool VolZmap::CylBall_XYMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { - if ( m_Tool.GetType() == Tool::CYLMILL) - return CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, m_Tool.GetHeigth(), m_Tool.GetRadius(), false, false) ; + if ( m_vTool[m_nCurrTool].GetType() == Tool::CYLMILL) + return CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, m_vTool[m_nCurrTool].GetHeigth(), m_vTool[m_nCurrTool].GetRadius(), false, false) ; - else if ( m_Tool.GetType() == Tool::BALLMILL) { - double dHei = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dHei, m_Tool.GetRadius(), false, false) ; - CompBall_Milling( nGrid, ptS - dHei * vtToolDir, ptE - dHei * vtToolDir, m_Tool.GetRadius()) ; + else if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) { + double dHei = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dHei, m_vTool[m_nCurrTool].GetRadius(), false, false) ; + CompBall_Milling( nGrid, ptS - dHei * vtToolDir, ptE - dHei * vtToolDir, m_vTool[m_nCurrTool].GetRadius()) ; return true ; } @@ -2256,32 +2535,32 @@ VolZmap::Conus_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co return true ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dMinRad = min( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; - double dMaxRad = max( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dMinRad = min( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; + double dMaxRad = max( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; double dDeltaRad = dMaxRad - dMinRad ; // Geometria del moto double dLenXY = ( ptE - ptS).LenXY() ; Point3d ptI = ( vtToolDir * ( ptE - ptS) < 0 ? ptS : ptE) ; - double dMatStemLen = ( m_Tool.GetRadius() > m_Tool.GetTipRadius() ? dStemHeigth + dLenXY : dStemHeigth) ; - double dSqTipRad = m_Tool.GetTipRadius() * m_Tool.GetTipRadius() ; - double dSqRad = m_Tool.GetRadius() * m_Tool.GetRadius() ; + double dMatStemLen = ( m_vTool[m_nCurrTool].GetRadius() > m_vTool[m_nCurrTool].GetTipRadius() ? dStemHeigth + dLenXY : dStemHeigth) ; + double dSqTipRad = m_vTool[m_nCurrTool].GetTipRadius() * m_vTool[m_nCurrTool].GetTipRadius() ; + double dSqRad = m_vTool[m_nCurrTool].GetRadius() * m_vTool[m_nCurrTool].GetRadius() ; // Determinazione del vertice del cono - double dL = m_Tool.GetTipHeigth() * dMaxRad / dDeltaRad ; + double dL = m_vTool[m_nCurrTool].GetTipHeigth() * dMaxRad / dDeltaRad ; Point3d ptV ; // Vertice Vector3d vtV ; // Vettore riferimento con origine nel vertice - if ( m_Tool.GetRadius() > m_Tool.GetTipRadius()) { + if ( m_vTool[m_nCurrTool].GetRadius() > m_vTool[m_nCurrTool].GetTipRadius()) { vtV = vtToolDir ; ptV = ( vtToolDir * ( ptE - ptS) < 0 ? ptE : ptS) - vtToolDir * ( dStemHeigth + dL) ; } else { vtV = - vtToolDir ; - ptV = ( vtToolDir * ( ptE - ptS) < 0 ? ptS : ptE) - vtToolDir * ( m_Tool.GetHeigth() - dL) ; + ptV = ( vtToolDir * ( ptE - ptS) < 0 ? ptS : ptE) - vtToolDir * ( m_vTool[m_nCurrTool].GetHeigth() - dL) ; } // Sistema di riferimento sul piano @@ -2305,9 +2584,9 @@ VolZmap::Conus_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; - double dr = m_Tool.GetRadius() + ( dX1 - dMatStemLen) * ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) / m_Tool.GetTipHeigth() ; + double dr = m_vTool[m_nCurrTool].GetRadius() + ( dX1 - dMatStemLen) * ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) / m_vTool[m_nCurrTool].GetTipHeigth() ; - if ( dX1 > EPS_SMALL && dX1 < dMatStemLen && abs( dX2) < m_Tool.GetRadius()) { + if ( dX1 > EPS_SMALL && dX1 < dMatStemLen && abs( dX2) < m_vTool[m_nCurrTool].GetRadius()) { double dH = sqrt( dSqRad - dX2 * dX2) ; double dMin = ptI.z - dH ; @@ -2325,7 +2604,7 @@ VolZmap::Conus_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co } else if ( dX1 >= dMatStemLen && - dX1 < dMatStemLen + m_Tool.GetTipHeigth() - EPS_SMALL && + dX1 < dMatStemLen + m_vTool[m_nCurrTool].GetTipHeigth() - EPS_SMALL && abs( dX2) < dr) { double dH = sqrt( dr * dr - dX2 * dX2) ; @@ -2335,22 +2614,22 @@ VolZmap::Conus_XYDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Point3d ptIntMin( dX, dY, dMin) ; Vector3d vtUmin = ( ptIntMin - ptV) - ( ptIntMin - ptV) * vtV * vtV ; vtUmin.Normalize() ; - Vector3d vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtUmin ; + Vector3d vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtUmin ; vtNmin.Normalize() ; Point3d ptIntMax( dX, dY, dMax) ; Vector3d vtUmax = ( ptIntMax - ptV) - ( ptIntMax - ptV) * vtV * vtV ; vtUmax.Normalize() ; - Vector3d vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtUmax ; + Vector3d vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtUmax ; vtNmax.Normalize() ; SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; } - if ( m_Tool.GetTipRadius() >= m_Tool.GetRadius()) { + if ( m_vTool[m_nCurrTool].GetTipRadius() >= m_vTool[m_nCurrTool].GetRadius()) { - if ( dX1 > dMatStemLen + m_Tool.GetTipHeigth() - 2 * EPS_SMALL && - dX1 < dMatStemLen + m_Tool.GetTipHeigth() + dLenXY - EPS_SMALL && + if ( dX1 > dMatStemLen + m_vTool[m_nCurrTool].GetTipHeigth() - 2 * EPS_SMALL && + dX1 < dMatStemLen + m_vTool[m_nCurrTool].GetTipHeigth() + dLenXY - EPS_SMALL && abs( dX2) < dSqTipRad) { double dH = sqrt( dSqTipRad - dX2 * dX2) ; @@ -2383,16 +2662,16 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const return true ; // Parametri geometrici dell'utensile - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; - double dMinRad = min( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; - double dMaxRad = max( m_Tool.GetRadius(), m_Tool.GetTipRadius()) ; - double dSqRad = m_Tool.GetRadius() * m_Tool.GetRadius() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; + double dMinRad = min( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; + double dMaxRad = max( m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius()) ; + double dSqRad = m_vTool[m_nCurrTool].GetRadius() * m_vTool[m_nCurrTool].GetRadius() ; double dDeltaRad = dMaxRad - dMinRad ; // Studio delle simmetrie del moto Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; - // elimino eventuale piccolo errore di perpendicolarità del movimento rispetto all'utensile + // elimino eventuale piccolo errore di perpendicolarit� del movimento rispetto all'utensile Vector3d vtErr = 0.5 * ( ( ptF - ptI) * vtToolDir) * vtToolDir ; ptI += vtErr ; ptF -= vtErr ; @@ -2408,10 +2687,10 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const vtMove.Normalize() ; // Riferimento coni - double dL = m_Tool.GetTipHeigth() * dMaxRad / dDeltaRad ; - Vector3d vtV = ( m_Tool.GetRadius() > m_Tool.GetTipRadius() ? vtToolDir : - vtToolDir) ; - Point3d ptVI = ptI - ( m_Tool.GetRadius() > m_Tool.GetTipRadius() ? dStemHeigth + dL : m_Tool.GetHeigth() - dL) * vtToolDir ; - Point3d ptVF = ptF - ( m_Tool.GetRadius() > m_Tool.GetTipRadius() ? dStemHeigth + dL : m_Tool.GetHeigth() - dL) * vtToolDir ; + double dL = m_vTool[m_nCurrTool].GetTipHeigth() * dMaxRad / dDeltaRad ; + Vector3d vtV = ( m_vTool[m_nCurrTool].GetRadius() > m_vTool[m_nCurrTool].GetTipRadius() ? vtToolDir : - vtToolDir) ; + Point3d ptVI = ptI - ( m_vTool[m_nCurrTool].GetRadius() > m_vTool[m_nCurrTool].GetTipRadius() ? dStemHeigth + dL : m_vTool[m_nCurrTool].GetHeigth() - dL) * vtToolDir ; + Point3d ptVF = ptF - ( m_vTool[m_nCurrTool].GetRadius() > m_vTool[m_nCurrTool].GetTipRadius() ? dStemHeigth + dL : m_vTool[m_nCurrTool].GetHeigth() - dL) * vtToolDir ; // Movimento verticale if ( dLengthPathXY < EPS_SMALL) { @@ -2434,7 +2713,7 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const // Parte cilindrica if ( dP1 > EPS_SMALL && dP1 <= dStemHeigth && - dP2 > - m_Tool.GetRadius() + EPS_SMALL && dP2 < m_Tool.GetRadius() - EPS_SMALL) { + dP2 > - m_vTool[m_nCurrTool].GetRadius() + EPS_SMALL && dP2 < m_vTool[m_nCurrTool].GetRadius() - EPS_SMALL) { double dMin = dZI - sqrt( dSqRad - dP2 * dP2) ; double dMax = dZF + sqrt( dSqRad - dP2 * dP2) ; @@ -2451,11 +2730,11 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const } // Parte conica - else if ( dP1 > dStemHeigth && dP1 < m_Tool.GetHeigth() - EPS_SMALL && abs( dP2) < m_Tool.GetRadius() + - ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth() - EPS_SMALL) { + else if ( dP1 > dStemHeigth && dP1 < m_vTool[m_nCurrTool].GetHeigth() - EPS_SMALL && abs( dP2) < m_vTool[m_nCurrTool].GetRadius() + + ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth() - EPS_SMALL) { double dr = dP2 ; - double dMr = m_Tool.GetRadius() + ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth() ; + double dMr = m_vTool[m_nCurrTool].GetRadius() + ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth() ; double dMin = dZI - sqrt( dMr * dMr - dr * dr) ; double dMax = dZF + sqrt( dMr * dMr - dr * dr) ; @@ -2463,13 +2742,13 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const Point3d ptIntMin( dX, dY, dMin) ; Vector3d vtUmin = ( ptIntMin - ptVI) - ( ptIntMin - ptVI) * vtV * vtV ; vtUmin.Normalize() ; - Vector3d vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtUmin ; + Vector3d vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtUmin ; vtNmin.Normalize() ; Point3d ptIntMax( dX, dY, dMax) ; Vector3d vtUmax = ( ptIntMax - ptVF) - ( ptIntMax - ptVF) * vtV * vtV ; vtUmax.Normalize() ; - Vector3d vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtUmax ; + Vector3d vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtUmax ; vtNmax.Normalize() ; SubtractIntervals( nGrid, i, j, dMin, dMax, vtNmin, vtNmax) ; @@ -2488,19 +2767,19 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d vtCross = vtToolDir ^ vtMove ; if ( vtCross.z < 0) vtCross = - vtCross ; // Punti di tangenza - Point3d ptUp = ptI - vtToolDir * dStemHeigth + m_Tool.GetRadius() * vtCross ; - Point3d ptDw = ptI - vtToolDir * dStemHeigth - m_Tool.GetRadius() * vtCross ; - double dSmallLength = m_Tool.GetRadius() * vtCross.LenXY() ; + Point3d ptUp = ptI - vtToolDir * dStemHeigth + m_vTool[m_nCurrTool].GetRadius() * vtCross ; + Point3d ptDw = ptI - vtToolDir * dStemHeigth - m_vTool[m_nCurrTool].GetRadius() * vtCross ; + double dSmallLength = m_vTool[m_nCurrTool].GetRadius() * vtCross.LenXY() ; // Punti di tangenza in corrispondenza della punta - Point3d ptTipUp = ptI - vtToolDir * m_Tool.GetHeigth() + m_Tool.GetTipRadius() * vtCross ; - Point3d ptTipDw = ptI - vtToolDir * m_Tool.GetHeigth() - m_Tool.GetTipRadius() * vtCross ; + Point3d ptTipUp = ptI - vtToolDir * m_vTool[m_nCurrTool].GetHeigth() + m_vTool[m_nCurrTool].GetTipRadius() * vtCross ; + Point3d ptTipDw = ptI - vtToolDir * m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipRadius() * vtCross ; Vector3d vtUpTan = ptTipUp - ptUp ; Vector3d vtDwTan = ptTipDw - ptDw ; Vector3d vtUpTanXY( vtUpTan.x, vtUpTan.y, 0) ; double dDeltaSmallAbs = abs( vtUpTanXY * vtV2) ; - double dDeltaSmall = ( m_Tool.GetRadius() > m_Tool.GetTipRadius() ? dDeltaSmallAbs : - dDeltaSmallAbs) ; + double dDeltaSmall = ( m_vTool[m_nCurrTool].GetRadius() > m_vTool[m_nCurrTool].GetTipRadius() ? dDeltaSmallAbs : - dDeltaSmallAbs) ; vtUpTan.Normalize() ; vtDwTan.Normalize() ; @@ -2540,7 +2819,7 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const // Parte cilindrica if ( dP1 > EPS_SMALL && dP1 <= dStemHeigth && // vedere se conviene dP1 < dStemHeigth + eps oppure dP1 <= dStemHeigth - dP2 > - m_Tool.GetRadius() && dP2 < dLengthPathXY + m_Tool.GetRadius()) { + dP2 > - m_vTool[m_nCurrTool].GetRadius() && dP2 < dLengthPathXY + m_vTool[m_nCurrTool].GetRadius()) { // Massimi if ( dP2 < - dSmallLength) { @@ -2586,16 +2865,16 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const } // Parte conica - else if ( dP1 > dStemHeigth && dP1 < m_Tool.GetHeigth() - EPS_SMALL && - dP2 > - m_Tool.GetRadius() - ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth() && - dP2 < m_Tool.GetRadius() + dLengthPathXY + - ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth()) { + else if ( dP1 > dStemHeigth && dP1 < m_vTool[m_nCurrTool].GetHeigth() - EPS_SMALL && + dP2 > - m_vTool[m_nCurrTool].GetRadius() - ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth() && + dP2 < m_vTool[m_nCurrTool].GetRadius() + dLengthPathXY + + ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth()) { // Massimi - if ( dP2 < - dSmallLength + dDeltaSmall * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth()) { + if ( dP2 < - dSmallLength + dDeltaSmall * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth()) { double dr = dP2 ; - double dMr = m_Tool.GetRadius() + ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth() ; + double dMr = m_vTool[m_nCurrTool].GetRadius() + ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth() ; dMax = dZI + sqrt( dMr * dMr - dr * dr) ; @@ -2603,19 +2882,19 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d vtU = ( ptInt - ptVI) - ( ptInt - ptVI) * vtV * vtV ; vtU.Normalize() ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } else if ( dP2 < dLengthPathXY - dSmallLength + - dDeltaSmall * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth()) { + dDeltaSmall * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth()) { dMax = ( dDotUp - dX * vtUpCross.x - dY * vtUpCross.y) / vtUpCross.z ; vtNmax = vtUpCross ; } else { double dr = dP2 - dLengthPathXY ; - double dMr = m_Tool.GetRadius() + ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth() ; + double dMr = m_vTool[m_nCurrTool].GetRadius() + ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth() ; dMax = dZF + sqrt( dMr * dMr - dr * dr) ; @@ -2623,15 +2902,15 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d vtU = ( ptInt - ptVF) - ( ptInt - ptVF) * vtV * vtV ; vtU.Normalize() ; - vtNmax = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmax = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmax.Normalize() ; } // Minimi - if ( dP2 < dSmallLength - dDeltaSmall * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth()) { + if ( dP2 < dSmallLength - dDeltaSmall * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth()) { double dr = dP2 ; - double dMr = m_Tool.GetRadius() + ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth() ; + double dMr = m_vTool[m_nCurrTool].GetRadius() + ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth() ; dMin = dZI - sqrt( dMr * dMr - dr * dr) ; @@ -2639,11 +2918,11 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d vtU = ( ptInt - ptVI) - ( ptInt - ptVI) * vtV * vtV ; vtU.Normalize() ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; } - else if ( dP2 < dLengthPathXY + dSmallLength - dDeltaSmall * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth()) { + else if ( dP2 < dLengthPathXY + dSmallLength - dDeltaSmall * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth()) { dMin = ( dDotDw - dX * vtDwCross.x - dY * vtDwCross.y) / vtDwCross.z ; vtNmin = vtDwCross ; } @@ -2651,7 +2930,7 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const else { double dr = dP2 - dLengthPathXY ; - double dMr = m_Tool.GetRadius() + ( m_Tool.GetTipRadius() - m_Tool.GetRadius()) * ( dP1 - dStemHeigth) / m_Tool.GetTipHeigth() ; + double dMr = m_vTool[m_nCurrTool].GetRadius() + ( m_vTool[m_nCurrTool].GetTipRadius() - m_vTool[m_nCurrTool].GetRadius()) * ( dP1 - dStemHeigth) / m_vTool[m_nCurrTool].GetTipHeigth() ; dMin = dZF - sqrt( dMr * dMr - dr * dr) ; @@ -2659,7 +2938,7 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d vtU = ( ptInt - ptVF) - ( ptInt - ptVF) * vtV * vtV ; vtU.Normalize() ; - vtNmin = dDeltaRad * vtV - m_Tool.GetTipHeigth() * vtU ; + vtNmin = dDeltaRad * vtV - m_vTool[m_nCurrTool].GetTipHeigth() * vtU ; vtNmin.Normalize() ; } @@ -2675,20 +2954,20 @@ VolZmap::Conus_XYPerp( int nGrid, const Point3d& ptS, const Point3d& ptE, const bool VolZmap::Conus_XYMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_Tool.GetRadius(), false, true) ; + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_vTool[m_nCurrTool].GetRadius(), false, true) ; - if ( m_Tool.GetTipRadius() < m_Tool.GetRadius()) { + if ( m_vTool[m_nCurrTool].GetTipRadius() < m_vTool[m_nCurrTool].GetRadius()) { Point3d ptSTip = ptS - dStemHeigth * vtToolDir ; Point3d ptETip = ptE - dStemHeigth * vtToolDir ; - CompConus_Milling( nGrid, ptSTip, ptETip, vtToolDir, m_Tool.GetTipHeigth(), m_Tool.GetRadius(), m_Tool.GetTipRadius(), true, false) ; + CompConus_Milling( nGrid, ptSTip, ptETip, vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius(), true, false) ; } else { - Point3d ptSTip = ptS - m_Tool.GetHeigth() * vtToolDir ; - Point3d ptETip = ptE - m_Tool.GetHeigth() * vtToolDir ; - CompConus_Milling( nGrid, ptSTip, ptETip, - vtToolDir, m_Tool.GetTipHeigth(), m_Tool.GetTipRadius(), m_Tool.GetRadius(), false, true) ; + Point3d ptSTip = ptS - m_vTool[m_nCurrTool].GetHeigth() * vtToolDir ; + Point3d ptETip = ptE - m_vTool[m_nCurrTool].GetHeigth() * vtToolDir ; + CompConus_Milling( nGrid, ptSTip, ptETip, - vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), m_vTool[m_nCurrTool].GetTipRadius(), m_vTool[m_nCurrTool].GetRadius(), false, true) ; } return true ; @@ -2702,14 +2981,14 @@ bool VolZmap::CylBall_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { // Altezza cilindro - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; // Sottraggo cilindro - CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_Tool.GetRadius(), false, false) ; - // Se è sfera la sottraggo - if ( m_Tool.GetType() == Tool::BALLMILL) { + CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_vTool[m_nCurrTool].GetRadius(), false, false) ; + // Se � sfera la sottraggo + if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; - CompBall_Milling( nGrid, ptSBall, ptEBall, m_Tool.GetRadius()) ; + CompBall_Milling( nGrid, ptSBall, ptEBall, m_vTool[m_nCurrTool].GetRadius()) ; } return true ; } @@ -2719,14 +2998,14 @@ bool VolZmap::CylBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { // Altezza cilindro - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; // Sottraggo cilindro - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_Tool.GetRadius(), false, false) ; - // Se è sfera la sottraggo - if ( m_Tool.GetType() == Tool::BALLMILL) { + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_vTool[m_nCurrTool].GetRadius(), false, false) ; + // Se � sfera la sottraggo + if ( m_vTool[m_nCurrTool].GetType() == Tool::BALLMILL) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; - CompBall_Milling( nGrid, ptSBall, ptEBall, m_Tool.GetRadius()) ; + CompBall_Milling( nGrid, ptSBall, ptEBall, m_vTool[m_nCurrTool].GetRadius()) ; } return true ; } @@ -2736,21 +3015,21 @@ VolZmap::CylBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con bool VolZmap::Conus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; - CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_Tool.GetRadius(), false, true) ; + CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_vTool[m_nCurrTool].GetRadius(), false, true) ; // Trapano - if ( m_Tool.GetTipRadius() < m_Tool.GetRadius()) { + if ( m_vTool[m_nCurrTool].GetTipRadius() < m_vTool[m_nCurrTool].GetRadius()) { Point3d ptSCone = ptS - dStemHeigth * vtToolDir ; Point3d ptECone = ptE - dStemHeigth * vtToolDir ; - CompConus_Drilling( nGrid, ptSCone, ptECone, vtToolDir, m_Tool.GetTipHeigth(), m_Tool.GetRadius(), m_Tool.GetTipRadius(), true, false) ; + CompConus_Drilling( nGrid, ptSCone, ptECone, vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius(), true, false) ; } else { - Point3d ptSCone = ptS - m_Tool.GetHeigth() * vtToolDir ; - Point3d ptECone = ptE - m_Tool.GetHeigth() * vtToolDir ; - CompConus_Drilling( nGrid, ptSCone, ptECone, - vtToolDir, m_Tool.GetTipHeigth(), m_Tool.GetTipRadius(), m_Tool.GetRadius(), false, true) ; + Point3d ptSCone = ptS - m_vTool[m_nCurrTool].GetHeigth() * vtToolDir ; + Point3d ptECone = ptE - m_vTool[m_nCurrTool].GetHeigth() * vtToolDir ; + CompConus_Drilling( nGrid, ptSCone, ptECone, - vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), m_vTool[m_nCurrTool].GetTipRadius(), m_vTool[m_nCurrTool].GetRadius(), false, true) ; } return true ; @@ -2760,23 +3039,23 @@ VolZmap::Conus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, cons bool VolZmap::Conus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { - double dStemHeigth = m_Tool.GetHeigth() - m_Tool.GetTipHeigth() ; + double dStemHeigth = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetTipHeigth() ; - CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_Tool.GetRadius(), false, true) ; + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_vTool[m_nCurrTool].GetRadius(), false, true) ; // Trapano - if ( m_Tool.GetTipRadius() < m_Tool.GetRadius()) { + if ( m_vTool[m_nCurrTool].GetTipRadius() < m_vTool[m_nCurrTool].GetRadius()) { Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; - CompConus_Milling( nGrid, ptSBall, ptEBall, vtToolDir, m_Tool.GetTipHeigth(), - m_Tool.GetRadius(), m_Tool.GetTipRadius(), true, false) ; + CompConus_Milling( nGrid, ptSBall, ptEBall, vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), + m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius(), true, false) ; } else { - Point3d ptSBall = ptS - m_Tool.GetHeigth() * vtToolDir ; - Point3d ptEBall = ptE - m_Tool.GetHeigth() * vtToolDir ; - CompConus_Milling( nGrid, ptSBall, ptEBall, - vtToolDir, m_Tool.GetTipHeigth(), - m_Tool.GetTipRadius(), m_Tool.GetRadius(), false, true) ; + Point3d ptSBall = ptS - m_vTool[m_nCurrTool].GetHeigth() * vtToolDir ; + Point3d ptEBall = ptE - m_vTool[m_nCurrTool].GetHeigth() * vtToolDir ; + CompConus_Milling( nGrid, ptSBall, ptEBall, - vtToolDir, m_vTool[m_nCurrTool].GetTipHeigth(), + m_vTool[m_nCurrTool].GetTipRadius(), m_vTool[m_nCurrTool].GetRadius(), false, true) ; } return true ; @@ -2793,20 +3072,20 @@ VolZmap::Mrt_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const // Scompongo la mortasatrice in solidi semplici // Parallelepipedo di base - double dLenX = m_Tool.GetMrtChsWidth() ; - double dLenY = m_Tool.GetMrtChsThickness() ; - double dLenZ = m_Tool.GetHeigth() - m_Tool.GetCornRadius() ; + double dLenX = m_vTool[m_nCurrTool].GetMrtChsWidth() ; + double dLenY = m_vTool[m_nCurrTool].GetMrtChsThickness() ; + double dLenZ = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetCornRadius() ; CompPar_Drilling( nGrid, dLenX, dLenY, dLenZ, ptS, ptEOnP, vtToolDir, vtAux) ; - // Se la punta è di tipo bull-nose - if ( abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) > EPS_SMALL) { + // Se la punta � di tipo bull-nose + if ( abs( m_vTool[m_nCurrTool].GetMrtChsWidth() - 2 * m_vTool[m_nCurrTool].GetCornRadius()) > EPS_SMALL) { // Parallelepipedo di punta Point3d ptTipS = ptS - dLenZ * vtToolDir ; Point3d ptTipE = ptEOnP - dLenZ * vtToolDir ; - dLenX = abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) ; - dLenZ = m_Tool.GetCornRadius() ; + dLenX = abs( m_vTool[m_nCurrTool].GetMrtChsWidth() - 2 * m_vTool[m_nCurrTool].GetCornRadius()) ; + dLenZ = m_vTool[m_nCurrTool].GetCornRadius() ; CompPar_Drilling( nGrid, dLenX, dLenY, dLenZ, ptTipS, ptTipE, vtToolDir, vtAux) ; @@ -2818,16 +3097,16 @@ VolZmap::Mrt_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Point3d ptSplus = ptTipS + ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ; Point3d ptEplus = ptTipE + ( 0.5 * dLenX) * vtVOnP + 0.5 * dLenY * vtAux ; - CompCyl_Milling( nGrid, ptSminus, ptEminus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; - CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptSminus, ptEminus, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; } - // se la punta è di tipo sfera + // se la punta � di tipo sfera else { // Cilindro Point3d ptCylS = ptS - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; Point3d ptCylE = ptEOnP - dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; - CompCyl_Milling( nGrid, ptCylS, ptCylE, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptCylS, ptCylE, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; } return true ; @@ -2840,23 +3119,23 @@ VolZmap::Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V // Scompongo la mortasatrice in solidi semplici // Parallelepipedo di base - double dLenX = m_Tool.GetMrtChsWidth() ; - double dLenY = m_Tool.GetMrtChsThickness() ; - double dLenZ = m_Tool.GetHeigth() - m_Tool.GetCornRadius() ; + double dLenX = m_vTool[m_nCurrTool].GetMrtChsWidth() ; + double dLenY = m_vTool[m_nCurrTool].GetMrtChsThickness() ; + double dLenZ = m_vTool[m_nCurrTool].GetHeigth() - m_vTool[m_nCurrTool].GetCornRadius() ; Point3d ptBasePS = ptS - 0.5 * dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; Point3d ptBasePE = ptE - 0.5 * dLenZ * vtToolDir + 0.5 * dLenY * vtAux ; CompPar_Milling( nGrid, dLenX, dLenZ, dLenY, ptBasePS, ptBasePE, vtAux, vtToolDir) ; - // Se la punta è di tipo bull-nose - if ( abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) > EPS_SMALL) { + // Se la punta � di tipo bull-nose + if ( abs( m_vTool[m_nCurrTool].GetMrtChsWidth() - 2 * m_vTool[m_nCurrTool].GetCornRadius()) > EPS_SMALL) { // Parallelepipedo di punta Point3d ptTipPS = ptBasePS - 0.5 * dLenZ * vtToolDir ; Point3d ptTipPE = ptBasePE - 0.5 * dLenZ * vtToolDir ; - dLenX = abs( m_Tool.GetMrtChsWidth() - 2 * m_Tool.GetCornRadius()) ; - dLenZ = m_Tool.GetCornRadius() ; + dLenX = abs( m_vTool[m_nCurrTool].GetMrtChsWidth() - 2 * m_vTool[m_nCurrTool].GetCornRadius()) ; + dLenZ = m_vTool[m_nCurrTool].GetCornRadius() ; ptTipPS -= 0.5 * dLenZ * vtToolDir ; ptTipPE -= 0.5 * dLenZ * vtToolDir ; @@ -2869,18 +3148,18 @@ VolZmap::Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V vtVOnP *= -1 ; Point3d ptSminus = ptTipPS + 0.5 * dLenZ * vtToolDir - ( 0.5 * dLenX) * vtVOnP ; Point3d ptEminus = ptTipPE + 0.5 * dLenZ * vtToolDir - ( 0.5 * dLenX) * vtVOnP ; - CompCyl_Milling( nGrid, ptSminus, ptEminus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptSminus, ptEminus, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; Point3d ptSplus = ptTipPS + 0.5 * dLenZ * vtToolDir + ( 0.5 * dLenX) * vtVOnP ; Point3d ptEplus = ptTipPE + 0.5 * dLenZ * vtToolDir + ( 0.5 * dLenX) * vtVOnP ; - CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptSplus, ptEplus, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; } - // se la punta è di tipo sfera + // se la punta � di tipo sfera else { // Cilindro Point3d ptCylS = ptBasePS - 0.5 * dLenZ * vtToolDir ; Point3d ptCylE = ptBasePE - 0.5 * dLenZ * vtToolDir ; - CompCyl_Milling( nGrid, ptCylS, ptCylE, vtAux, dLenY, m_Tool.GetCornRadius(), false, false) ; + CompCyl_Milling( nGrid, ptCylS, ptCylE, vtAux, dLenY, m_vTool[m_nCurrTool].GetCornRadius(), false, false) ; } return true ; @@ -2891,10 +3170,10 @@ VolZmap::Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V bool VolZmap::Chs_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) { - // Proiezione della traiettoria sulla varietà del movimento + // Proiezione della traiettoria sulla variet� del movimento Point3d ptProjE = ptS + ( ptE - ptS) * vtToolDir * vtToolDir ; - CompPar_Drilling( nGrid, m_Tool.GetMrtChsWidth(), m_Tool.GetMrtChsThickness(), m_Tool.GetHeigth(), ptS, ptProjE, vtToolDir, vtAux) ; + CompPar_Drilling( nGrid, m_vTool[m_nCurrTool].GetMrtChsWidth(), m_vTool[m_nCurrTool].GetMrtChsThickness(), m_vTool[m_nCurrTool].GetHeigth(), ptS, ptProjE, vtToolDir, vtAux) ; return true ; } @@ -2907,13 +3186,131 @@ VolZmap::Chs_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const V Vector3d vtMoveOnP = ( ptE - ptS) - ( ptE - ptS) * vtToolDir * vtToolDir ; Point3d ptProjE = ptS + vtMoveOnP ; - CompPar_Milling( nGrid, m_Tool.GetMrtChsWidth(), m_Tool.GetMrtChsThickness(), m_Tool.GetHeigth(), ptS, ptProjE, vtToolDir, vtAux) ; + CompPar_Milling( nGrid, m_vTool[m_nCurrTool].GetMrtChsWidth(), m_vTool[m_nCurrTool].GetMrtChsThickness(), m_vTool[m_nCurrTool].GetHeigth(), ptS, ptProjE, vtToolDir, vtAux) ; return true ; } // ---------- Utensile generico ---------------------------------------------- //---------------------------------------------------------------------------- +//bool +//VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) +//{ +// // Descrizione geometrica del moto +// Point3d ptI = ptS ; +// Point3d ptF = ptE ; +// Vector3d vtMove = ptE - ptS ; +// // Vettore delle normali agli archi +// const VCT3DVECTOR& vArcNorm = m_Tool.GetArcNormalVec() ; +// // Poinch� l'asse utensile � parallelo all'asse Z, definisco un sistema di +// // riferimento ad hoc in cui le normali agli archi giacciano nel piano XZ. +// Frame3d frNormFrame ; +// frNormFrame.Set( ORIG, X_AX, -Z_AX, Y_AX) ; +// // Ciclo sulle curve del profilo +// const CurveComposite& ToolProfile = m_Tool.GetApproxOutline() ; +// int i = - 1 ; +// const ICurve* pPrevCurve = nullptr ; +// const ICurve* pCurve = ToolProfile.GetCurve( ++ i) ; +// while ( pCurve != nullptr) { +// +// double dHeight = 0 ; +// +// // Se segmento +// if ( pCurve->GetType() == CRV_LINE) { +// // Recupero gli estremi +// const ICurveLine* pLine = GetCurveLine( pCurve) ; +// Point3d ptStart = pLine->GetStart() ; +// Point3d ptEnd = pLine->GetEnd() ; +// int nNormNum = pLine->GetTempProp(); +// Vector3d vtNormSt, vtNormEn; +// if ( nNormNum != 0) { +// vtNormSt = vArcNorm[nNormNum - 1] ; +// vtNormEn = vArcNorm[nNormNum] ; +// vtNormSt.ToLoc(frNormFrame); +// vtNormEn.ToLoc(frNormFrame); +// } +// // Ne determino l'altezza +// dHeight = abs( ptStart.y - ptEnd.y) ; +// if ( dHeight > EPS_SMALL) { +// // Verifiche curva precedente per eventuale tappo sopra +// bool bTapT = false ; +// if ( pPrevCurve != nullptr && pPrevCurve->GetType() == CRV_LINE) { +// const ICurveLine* pOthLine = GetCurveLine( pPrevCurve) ; +// Point3d ptOthStart = pOthLine->GetStart() ; +// Point3d ptOthEnd = pOthLine->GetEnd() ; +// if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x < ptOthEnd.x) +// bTapT = true ; +// } +// // Verifiche curva successiva per eventuale tappo sotto +// bool bTapB = false ; +// const ICurve* pNextCurve = ToolProfile.GetCurve( ++ i) ; +// if ( pNextCurve != nullptr && pNextCurve->GetType() == CRV_LINE) { +// const ICurveLine* pOthLine = GetCurveLine( pNextCurve) ; +// Point3d ptOthStart = pOthLine->GetStart() ; +// Point3d ptOthEnd = pOthLine->GetEnd() ; +// if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x > ptOthEnd.x) +// bTapB = true ; +// } +// // Se X costante, � un cilindro +// if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { +// double dRadius = ptStart.x ; +// if ( dRadius > 10 * EPS_SMALL) +// CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; +// } +// // Se X crescente, � un cono con vettore equiverso a quello dell'utensile +// else if ( ptStart.x > ptEnd.x) { +// double dMaxRad = ptStart.x ; +// double dMinRad = ptEnd.x ; +// CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; +// } +// // Se X decrescente, � un cono con vettore opposto a quello dell'utensile +// else if ( ptStart.x < ptEnd.x) { +// double dMaxRad = ptEnd.x ; +// double dMinRad = ptStart.x ; +// Point3d ptIn = ptI - vtToolDir * dHeight ; +// Point3d ptFn = ptIn + vtMove ; +// vtNormEn.z *= -1 ; +// vtNormSt.z *= -1 ; +// CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; +// } +// // Passo alla curva successiva +// pPrevCurve = pCurve ; +// pCurve = pNextCurve ; +// } +// else { +// // Passo alla curva successiva +// pPrevCurve = pCurve ; +// pCurve = ToolProfile.GetCurve( ++ i) ; +// } +// } +// +// // Se arco +// else if ( pCurve->GetType() == CRV_ARC) { +// // Recupero estremi, centro e raggio +// const ICurveArc* pArc = GetCurveArc( pCurve) ; +// Point3d ptStart ; pArc->GetStartPoint( ptStart) ; +// Point3d ptEnd ; pArc->GetEndPoint( ptEnd) ; +// Point3d ptCen = pArc->GetCenter() ; +// double dRadius = pArc->GetRadius() ; +// // Determino le posizioni iniziale e finale del centro della sfera +// Point3d ptCenS = ptI - vtToolDir * ( ptStart.y - ptCen.y) ; +// Point3d ptCenE = ptCenS + vtMove ; +// // Eseguo l'asportazione del materiale +// CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; +// // aggiorno l'altezza +// dHeight = abs( ptStart.y - ptEnd.y) ; +// // Passo alla curva successiva +// pPrevCurve = pCurve ; +// pCurve = ToolProfile.GetCurve( ++ i) ; +// } +// +// // Determino le posizioni iniziale e finale del componente successivo +// ptI = ptI - vtToolDir * dHeight ; +// ptF = ptI + vtMove ; +// } +// +// return true ; +//} bool VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) { @@ -2922,19 +3319,20 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Point3d ptF = ptE ; Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi - const VCT3DVECTOR& vArcNorm = m_Tool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + const VCT3DVECTOR& vArcNorm = m_vTool[m_nCurrTool].GetArcNormalVec() ; + // Poinch� l'asse utensile � parallelo all'asse Z, definisco un sistema di // riferimento ad hoc in cui le normali agli archi giacciano nel piano XZ. Frame3d frNormFrame ; frNormFrame.Set( ORIG, X_AX, -Z_AX, Y_AX) ; // Ciclo sulle curve del profilo - const CurveComposite& ToolProfile = m_Tool.GetApproxOutline() ; + const CurveComposite& ToolProfile = m_vTool[m_nCurrTool].GetApproxOutline() ; int i = - 1 ; const ICurve* pPrevCurve = nullptr ; const ICurve* pCurve = ToolProfile.GetCurve( ++ i) ; while ( pCurve != nullptr) { double dHeight = 0 ; + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { @@ -2951,7 +3349,8 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co vtNormEn.ToLoc(frNormFrame); } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; if ( dHeight > EPS_SMALL) { // Verifiche curva precedente per eventuale tappo sopra bool bTapT = false ; @@ -2964,7 +3363,8 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co } // Verifiche curva successiva per eventuale tappo sotto bool bTapB = false ; - const ICurve* pNextCurve = ToolProfile.GetCurve( ++ i) ; + int j = i ; + const ICurve* pNextCurve = ToolProfile.GetCurve( ++ j) ; if ( pNextCurve != nullptr && pNextCurve->GetType() == CRV_LINE) { const ICurveLine* pOthLine = GetCurveLine( pNextCurve) ; Point3d ptOthStart = pOthLine->GetStart() ; @@ -2972,36 +3372,59 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x > ptOthEnd.x) bTapB = true ; } - // Se X costante, è un cilindro + // Se X costante, � un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) + if ( dRadius > 10 * EPS_SMALL && m_vTool[m_nCurrTool].GetCuttingFlag()) CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; } - // Se X crescente, è un cono con vettore equiverso a quello dell'utensile + // Se X crescente, � un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapB, bTapT, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI /*- vtToolDir * dSignedHeight*/ ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapT, bTapB, vtNormEn, vtNormSt) ; + } + } } - // Se X decrescente, è un cono con vettore opposto a quello dell'utensile + // Se X decrescente, � un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; - Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptIn = ptI - vtToolDir * dSignedHeight ; Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapT, bTapB, vtNormEn, vtNormSt) ; + else { + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapB, bTapT, vtNormSt, vtNormEn) ; + } + } + } - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = pNextCurve ; } - else { - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + else if ( ! m_vTool[m_nCurrTool].GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_Drilling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_Drilling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; + } } } @@ -3017,17 +3440,50 @@ VolZmap::GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co Point3d ptCenS = ptI - vtToolDir * ( ptStart.y - ptCen.y) ; Point3d ptCenE = ptCenS + vtMove ; // Eseguo l'asportazione del materiale - CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + else if ( pCurve->GetTempProp( 1) == 1) { + double dStH = ptStart.y - ptCen.y ; + double dEnH = ptEnd.y - ptCen.y ; + // Tagliente esterno + if ( dEnH < dStH) { + if ( dEnH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, dEnH, dStH, true) ; + } + else if ( dStH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, dStH, true) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, - dEnH, true) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, - dEnH, - dStH, true) ; + } + } + // Tagliente interno + else { + if ( dEnH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + else if ( dStH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, abs( dStH), false) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, abs( dEnH), false) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + } + dSignedHeight = ptStart.y - ptEnd.y ; + } // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; + + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = ToolProfile.GetCurve( ++ i) ; } return true ; @@ -3042,20 +3498,20 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con Point3d ptF = ptE ; Vector3d vtMove = ptE - ptS ; // Vettore delle normali agli archi - const VCT3DVECTOR& vArcNorm = m_Tool.GetArcNormalVec() ; - // Poinché l'asse utensile è parallelo all'asse Z, definisco un sistema di + const VCT3DVECTOR& vArcNorm = m_vTool[m_nCurrTool].GetArcNormalVec() ; + // Poinch� l'asse utensile � parallelo all'asse Z, definisco un sistema di // riferimento ad hoc in cui le normali agli archi giacciano nel piano XZ. Frame3d frNormFrame ; frNormFrame.Set( ORIG, X_AX, -Z_AX, Y_AX) ; // Ciclo sulle curve del profilo - const CurveComposite& ToolProfile = m_Tool.GetApproxOutline() ; + const CurveComposite& ToolProfile = m_vTool[m_nCurrTool].GetApproxOutline() ; int i = - 1 ; const ICurve* pPrevCurve = nullptr ; const ICurve* pCurve = ToolProfile.GetCurve( ++ i) ; while ( pCurve != nullptr) { double dHeight = 0 ; - + double dSignedHeight = 0 ; // Se segmento if ( pCurve->GetType() == CRV_LINE) { // Recupero gli estremi @@ -3071,7 +3527,8 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con vtNormEn.ToLoc(frNormFrame); } // Ne determino l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; + dSignedHeight = ptStart.y - ptEnd.y ; + dHeight = abs( dSignedHeight) ; if ( dHeight > EPS_SMALL) { // verifiche curva precedente per eventuale tappo sopra bool bTapT = true ; @@ -3084,7 +3541,8 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con } // verifiche curva successiva per eventuale tappo sotto bool bTapB = false ; - const ICurve* pNextCurve = ToolProfile.GetCurve( ++ i) ; + int j = i ; + const ICurve* pNextCurve = ToolProfile.GetCurve( ++ j) ; if ( pNextCurve != nullptr && pNextCurve->GetType() == CRV_LINE) { const ICurveLine* pOthLine = GetCurveLine( pNextCurve) ; Point3d ptOthStart = pOthLine->GetStart() ; @@ -3092,36 +3550,66 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con if ( abs( ptOthStart.y - ptOthEnd.y) < EPS_SMALL && ptOthStart.x > ptOthEnd.x) bTapB = false ; } - // Se X costante, è un cilindro + // Se X costante, � un cilindro if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { double dRadius = ptStart.x ; - if ( dRadius > 10 * EPS_SMALL) - CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; + if ( dRadius > 10 * EPS_SMALL) { + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, bTapB, bTapT) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius, true, bTapB, bTapT) ; + else + SurfCyl_Milling( nGrid, ptI, ptF, - vtToolDir, dHeight, dRadius, false, bTapB, bTapT) ; + } + } } - // Se X crescente, è un cono con vettore equiverso a quello dell'utensile + // Se X crescente, � un cono con vettore equiverso a quello dell'utensile else if ( ptStart.x > ptEnd.x) { double dMaxRad = ptStart.x ; double dMinRad = ptEnd.x ; - CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, bTapB, bTapT, vtNormSt, vtNormEn) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapB, bTapT, vtNormSt, vtNormEn) ; + else { + Point3d ptIn = ptI /*- vtToolDir * dSignedHeight*/ ; + Point3d ptFn = ptIn + vtMove ; + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapT, bTapB, vtNormEn, vtNormSt) ; + } + } } - // Se X decrescente, è un cono con vettore opposto a quello dell'utensile + // Se X decrescente, � un cono con vettore opposto a quello dell'utensile else if ( ptStart.x < ptEnd.x) { double dMaxRad = ptEnd.x ; double dMinRad = ptStart.x ; - Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptIn = ptI - vtToolDir * dSignedHeight ; Point3d ptFn = ptIn + vtMove ; vtNormEn.z *= -1 ; vtNormSt.z *= -1 ; - CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, bTapT, bTapB, vtNormEn, vtNormSt) ; + else if ( pCurve->GetTempProp( 1) == 1) { + if ( ptStart.y > ptEnd.y) + SurfConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad, true, bTapT, bTapB, vtNormEn, vtNormSt) ; + else { + /*vtNormEn.z *= -1 ; + vtNormSt.z *= -1 ;*/ + SurfConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad, false, bTapB, bTapT, vtNormSt, vtNormEn) ; + } + } } - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = pNextCurve ; } - else { - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + else if ( ! m_vTool[m_nCurrTool].GetCuttingFlag() && pCurve->GetTempProp( 1) == 1) { + if ( ptStart.x < ptEnd.x) { + SurfCircCrown_Milling( nGrid, ptI, ptF, vtToolDir, ptEnd.x, ptStart.x) ; + } + else { + SurfCircCrown_Milling( nGrid, ptI, ptF, - vtToolDir, ptStart.x, ptEnd.x) ; + } } } @@ -3137,17 +3625,50 @@ VolZmap::GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, con Point3d ptCenS = ptI - vtToolDir * ( ptStart.y - ptCen.y) ; Point3d ptCenE = ptCenS + vtMove ; // Eseguo l'asportazione del materiale - CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + if ( m_vTool[m_nCurrTool].GetCuttingFlag()) + CompBall_Milling( nGrid, ptCenS, ptCenE, dRadius) ; + else if ( pCurve->GetTempProp( 1) == 1) { + double dStH = ptStart.y - ptCen.y ; + double dEnH = ptEnd.y - ptCen.y ; + // Tagliente esterno + if ( dEnH < dStH) { + if ( dEnH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, dEnH, dStH, true) ; + } + else if ( dStH > 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, dStH, true) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, - dEnH, true) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, - dEnH, - dStH, true) ; + } + } + // Tagliente interno + else { + if ( dEnH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + else if ( dStH < 0) { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, vtToolDir, dRadius, 0, abs( dStH), false) ; + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, 0, abs( dEnH), false) ; + } + else { + SurfSphericalShellPart_Milling( nGrid, ptCenS, ptCenE, - vtToolDir, dRadius, abs( dEnH), abs( dStH), false) ; + } + } + dSignedHeight = ptStart.y - ptEnd.y ; + } // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - // Passo alla curva successiva - pPrevCurve = pCurve ; - pCurve = ToolProfile.GetCurve( ++ i) ; + //dHeight = abs( ptStart.y - ptEnd.y) ; } // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; + ptI = ptI - vtToolDir * dSignedHeight ; ptF = ptI + vtMove ; + + // Passo alla curva successiva + pPrevCurve = pCurve ; + pCurve = ToolProfile.GetCurve( ++ i) ; } return true ; @@ -3215,9 +3736,9 @@ VolZmap::CompConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dAngC = dHei / ( dMaxRad - dMinRad) ; double dSqMinRad = dMinRad * dMinRad ; double dSqMaxRad = dMaxRad * dMaxRad ; - double dSafeSqMaxRad = dSqMaxRad - 2 * dMaxRad * EPS_SMALL ; // Questa variabile è sperimentale: serve per evitare il taglio di un dexel dalla parte cilindrica del volume spazzato dalla traslazione del cono. - double dDeltaR = dMaxRad - dMinRad ; // Per tornare alla versione precedente basta sostituire dSafeSqMaxRad con dSqMaxRad. Per risolvere il problema in modo forse più sicuro, ma - // computazionalmente più pesante è sottrarre prima il cilindro con dSafeSqMaxRad e dopo il cono con dSqMaxRad. + double dSafeSqMaxRad = dSqMaxRad - 2 * dMaxRad * EPS_SMALL ; // Questa variabile � sperimentale: serve per evitare il taglio di un dexel dalla parte cilindrica del volume spazzato dalla traslazione del cono. + double dDeltaR = dMaxRad - dMinRad ; // Per tornare alla versione precedente basta sostituire dSafeSqMaxRad con dSqMaxRad. Per risolvere il problema in modo forse pi� sicuro, ma + // computazionalmente pi� pesante � sottrarre prima il cilindro con dSafeSqMaxRad e dopo il cono con dSqMaxRad. // Studio delle simmetrie if ( vtToolDir.z > 0) { dZMin = ( ptS.z < ptE.z ? ptS.z - dHei : ptE.z - dHei) ; @@ -3250,7 +3771,7 @@ VolZmap::CompConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, dZMin, dZMax, Z_AX, -Z_AX) ; } - else if ( dSqDist < dSafeSqMaxRad) { // dSafeSqMaxRad è sperimentale + else if ( dSqDist < dSafeSqMaxRad) { // dSafeSqMaxRad � sperimentale double dr = sqrt( dSqDist) ; @@ -3399,7 +3920,7 @@ VolZmap::CompCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, co // Definizione di un sistema di riferimento ad hoc Vector3d vtV1, vtV2 ; - // Se la lunghezza è troppo piccola lo allungo + // Se la lunghezza � troppo piccola lo allungo if ( dLenXY < EPS_SMALL) vtV1 = ( 1 / dLenXY) * vtMoveXY ; else @@ -3807,7 +4328,7 @@ VolZmap::CompConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, } //---------------------------------------------------------------------------- -bool // E' in realtà MillingPerp +bool // E' in realt� MillingPerp VolZmap::CompPar_ZMilling( int nGrid, double dLenX, double dLenY, double dLenZ, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) @@ -3944,7 +4465,7 @@ VolZmap::CompConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, Frame3d ConusFrame ; ConusFrame.Set( ptVertex, vtToolDir) ; Frame3d CylFrame = ConusFrame ; CylFrame.Translate( vtToolDir * dConeMaxH) ; - // L'altezza del cilindro è il movimento + // L'altezza del cilindro � il movimento double dH = ( ptE - ptS).Len() ; for ( int i = nStartI ; i <= nEndI ; ++ i) { @@ -4086,7 +4607,7 @@ VolZmap::CompCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2) ; } - // Cilindro finale:L'unica differenza rispetto a prima è l'origine + // Cilindro finale:L'unica differenza rispetto a prima � l'origine // del sistema di riferimento, quindi usiamo lo stesso sistema sommando a ptC // il vettore che congiunge le due origini. CylFrame.ChangeOrig( ptITip + vtMove) ; @@ -4109,7 +4630,7 @@ VolZmap::CompCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, SubtractIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, vtN1, vtN2) ; } - // Cilindro ellittico di base: L'unica differenza rispetto a prima è l'origine + // Cilindro ellittico di base: L'unica differenza rispetto a prima � l'origine // del sistema di riferimento, quindi usiamo lo stesso sistema sommando a ptC // il vettore che congiunge le due origini. CylFrame.ChangeOrig( ptITip + dHei * vtV1) ; @@ -4420,7 +4941,7 @@ VolZmap::CompConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, c } } } - // Se il poliedro è attraversato taglio + // Se il poliedro � attraversato taglio if ( nIntNum == 2) { // Riporto le intersezioni nel sistema griglia @@ -4642,6 +5163,2802 @@ VolZmap::CompBall_Milling( int nGrid, const Point3d& ptLs, const Point3d& ptLe, return true ; } + +// Superfici laterali + +// Superfici ausiliarie + +//---------------------------------------------------------------------------- +// Calcola l'intersezione di una retta, descritta da punto iniziale ptLineP e versore della direzione +// vtLineDir, e la superficie definita da una corona circolare nello spazio, descritta dal centro delle +// circonferenze di frontiera, dal versore del loro asse di simmetria rotazionale e dai loro raggi. +// Il versore normale alla superficie coincide con quello dell'asse di simmetria e quello vtN +// dell'intersezione � opposto ad'esso. +int +VolZmap::IntersLineCircCrown( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dMaxRad, double dMinRad, + Point3d& ptInt, Vector3d& vtN) const +{ + // Definisco il versore normale al piano e il piano stesso. + Plane3d plMyPlane ; + Vector3d vtPlaneN = vtAx ; + if ( ! vtPlaneN.Normalize() || ! plMyPlane.Set( ptCen, vtPlaneN)) + return 0 ; + + // Quadrati dei raggi + double dSqMinRad = dMinRad * dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Se la corona circolare defenera in un disco (dMinRad < EPS), forzo dSqSafeMinRad a - 1 + // in modo da tagliare i dexel giacenti sul suo asse di simmetria. + if ( dMinRad < EPS_SMALL) + dSqMinRad = - 1 ; + + // Intersezione retta piano + int nIntType = IntersLinePlane( ptLineP, vtLineDir, 1000, plMyPlane, ptInt, false) ; + if ( nIntType == ILPT_YES /* || nIntType == ILPT_START || nIntType == ILPT_END*/) { + // Se il punto d'intersezione sta nella corona + double dSqIntCenDist = ( ptInt - ptCen) * ( ptInt - ptCen) ; + if ( dSqIntCenDist > dSqMinRad && dSqIntCenDist < dSqMaxRad) { + vtN = - vtAx ; + return 1 ; + } + } + + return 0 ; +} + +//---------------------------------------------------------------------------- +// Calcola l'intersezione di una retta, descritta da punto iniziale ptLineP e versore della +// direzione vtLineDir, e la superficie definita da un parallelogramma nello spazio, descritto da un punto +// ptParOrig e i vettori che da esso spiccano. +// Se bExtNorm � true la normale alla superficie ha lo stesso verso di vtSeg2 ^ vtSeg1, altrimenti +// quello opposto. +int +VolZmap::IntersLineParallelogram( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptParOrig, const Vector3d& vtSeg1, const Vector3d& vtSeg2, + bool bExtNorm, Point3d& ptInt, Vector3d& vtN) const +{ + // Definisco il versore normale al piano e il piano stesso. + Plane3d plMyPlane ; + Vector3d vtPlaneN = vtSeg2 ^ vtSeg1 ; + if ( ! vtPlaneN.Normalize() || ! plMyPlane.Set( ptParOrig, vtPlaneN)) + return 0 ; + + // Intersezione retta piano + int nIntType = IntersLinePlane( ptLineP, vtLineDir, 1000, plMyPlane, ptInt, false) ; + if ( nIntType == ILPT_YES /* || nIntType == ILPT_START || nIntType == ILPT_END*/) { + // Creo un sistema di riferimento per stabilire se l'intersezione avviene in un + // punto del piano interno alla superficie o meno. + Vector3d vtUnit2 = vtSeg2 ; + double dLen2 = vtUnit2.Len() ; + vtUnit2 /= dLen2 ; + Vector3d vtPerpToUnit2 = vtPlaneN ^ vtUnit2 ; + double dSegProjPerpLen1 = vtSeg1 * vtPerpToUnit2 ; + double dSegProjLongLen1 = vtSeg1 * vtUnit2 ; + Vector3d vtIntV = ptInt - ptParOrig ; + double dIntPerp = vtIntV * vtPerpToUnit2 ; + double dIntLong = vtIntV * vtUnit2 ; + if ( dIntPerp > 0 - EPS_SMALL && dIntPerp < dSegProjPerpLen1 + EPS_SMALL && + ( dIntLong + EPS_SMALL) * dSegProjPerpLen1 > dIntPerp * dSegProjLongLen1 && + ( dIntLong - dLen2 - EPS_SMALL) * dSegProjPerpLen1 < dIntPerp * dSegProjLongLen1) { + vtN = bExtNorm ? vtPlaneN : - vtPlaneN ; + return 1 ; + } + /*if ( dIntPerp >= 0 && dIntPerp <= dSegProjPerpLen1 && + ( dIntLong) * dSegProjPerpLen1 >= dIntPerp * dSegProjLongLen1 && + ( dIntLong - dLen2) * dSegProjPerpLen1 <= dIntPerp * dSegProjLongLen1) { + vtN = bExtNorm ? vtPlaneN : - vtPlaneN ; + return 1 ; + }*/ + // Oppure crei polyline e chiami la funzione per testare se + // un punto � interno o meno a una polyline chiusa e piana. + } + + return 0 ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con la superficie ottenuta dal taglio di un cilindro, inteso come la sola superficie +// laterale, con un numero arbitrario di piani. +// Nel taglio del cilindro si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// Il cilindro � descritto dal centro della base ptBaseCen, dal versore vtAx del suo asse di simmetria, dal raggio dRad, +// dall'altezza dH e da un flag bInOut che indica se il campo delle normali al cilindro volge verso l'asse di simmetria o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e cilindro. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineCylinderCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptBaseCen, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Se il raggio non � sufficientemente grande, non devo fare alcunch�. + if ( dRad < EPS_SMALL) + return 0 ; + + // Definisco il sistema di riferimento S; se non � possibile, c'� un errore. + Frame3d frFrameS ; + if ( ! frFrameS.Set( ptBaseCen, vtAx)) + return 0 ; + + // Se l'altezza � negativa, cambio sistema di riferimento. + if ( dH < 0) { + frFrameS.Translate( dH * frFrameS.VersZ()) ; + dH *= - 1 ; + } + + // Porto la linea nel riferimento del cilindro + Point3d ptP = ptLineP ; ptP.ToLoc( frFrameS) ; + Vector3d vtV = vtLineDir ; vtV.ToLoc( frFrameS) ; + + // Se la retta � parallela all'asse, non ci sono intersezioni. + if ( vtV.SqLenXY() < EPS_ZERO * EPS_ZERO) + return 0 ; + + // Determino le intersezioni con la superficie cilindrica + DBLVECTOR vdCoef( 3) ; + double dSqRad = dRad * dRad ; + vdCoef[0] = ptP.x * ptP.x + ptP.y * ptP.y - dSqRad ; + vdCoef[1] = 2 * ( ptP.x * vtV.x + ptP.y * vtV.y) ; + vdCoef[2] = vtV.x * vtV.x + vtV.y * vtV.y ; + DBLVECTOR vdRoots ; + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // Se non ho trovato soluzioni, ho terminato. + if ( nRoot == 0) + return nRoot ; + + // Punti di intersezione e versori alla superficie in corrispondenza di essi + ptInt1 = ptP + vdRoots[0] * vtV ; + vtN1.Set( ptInt1.x, ptInt1.y, 0) ; vtN1.Normalize() ; + if ( nRoot == 2) { + ptInt2 = ptP + vdRoots[1] * vtV ; + vtN2.Set( ptInt2.x, ptInt2.y, 0) ; vtN2.Normalize() ; + } + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + // Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z. + if ( ptInt1.z < 0 || ptInt1.z > dH) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( nRoot > 0 && ( ptInt2.z < 0 || ptInt2.z > dH)) { + -- nRoot ; + } + + // Esprimo punti e vettori nel sistema in cui � immerso S. + if ( nRoot > 0) { + ptInt1.ToGlob( frFrameS) ; + vtN1.ToGlob( frFrameS) ; + if ( nRoot == 2) { + ptInt2.ToGlob( frFrameS) ; + vtN2.ToGlob( frFrameS) ; + } + } + + // Elimino le intersezioni sul cono che non fanno parte della superficie. + bool bSecIntToTest = nRoot > 1 ; + for ( int n = 0 ; n < int( vPlanesVec.size()) && nRoot > 0 ; ++ n) { + if ( /*DistPointPlane( ptInt1, vPlanesVec[n]) > 0*/ DistPointPlane( ptInt1, vPlanesVec[n]) >= 0) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( /*bSecIntToTest && nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0*/bSecIntToTest && nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) >= 0) { + bSecIntToTest = false ; + -- nRoot ; + } + } + + return nRoot ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con una superficie di traslazione di una circonferenza di un vettore vtSweptVec +// tagliata da un numero arbitrario di piani. +// Nel taglio della superficie di traslazione si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// La circonferenza � descritta dal centro ptCen, dal versore vtAx del suo asse di simmetria rotazionale e dal raggio dRad. +// Il flag bInOut indica se la proiezione sul piano della circonferenza del campo delle normail alla superficie volge verso il +// centro di quest'ultima o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e la superficie di traslazione. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineCircSweptSurfCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptCen, const Vector3d& vtAx, double dRad, const Vector3d& vtSweptVec, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Se il raggio non � sufficientemente grande, non devo fare alcunch�. + if ( dRad < EPS_SMALL) + return 0 ; + + // Studio delle simmetrie + Point3d ptMyCen = ptCen ; + Vector3d vtMySweptVec = vtSweptVec ; + if ( vtSweptVec * vtAx < 0) { + ptMyCen += vtSweptVec ; + vtMySweptVec *= - 1 ; + } + + // Calcolo le lunghezze del moto nella direzione dell'asse di simmetria rotazionale e + // in quella ortogonale. + double dLongVecLen = vtMySweptVec * vtAx ; + double dOrtVecLen = sqrt( max( vtMySweptVec.SqLen() - dLongVecLen * dLongVecLen, 0.)) ; + + // Definisco il sistema di riferimento S; se non � possibile, c'� un errore. + Vector3d vtV1 = vtMySweptVec - dLongVecLen * vtAx ; + Frame3d frFrameS ; + if ( ! vtV1.Normalize()) { + if ( ! frFrameS.Set( ptMyCen, vtAx)) + return 0 ; + } + else if ( ! frFrameS.Set( ptMyCen, vtV1, vtAx ^ vtV1, vtAx)) + return 0 ; + + // Se la suerficie degenera in un piano, non bisogna tagliare + if ( abs( dLongVecLen) < /*EPS_SMALL*/EPS_ZERO) + return 0 ; + + // Porto la linea nel riferimento S + Point3d ptP = ptLineP ; ptP.ToLoc( frFrameS) ; + Vector3d vtV = vtLineDir ; vtV.ToLoc( frFrameS) ; + + // Asse cilindro ellittico + Vector3d vtSurfAx( dOrtVecLen, 0, dLongVecLen) ; + vtSurfAx.Normalize() ; + + // Retta parallela a quella del moto + if ( AreSameOrOppositeVectorExact( vtV, vtSurfAx)) + return 0 ; + + // Quadrato del raggio, coefficiente angolare della retta di movimento nel + // piano ZX del sistema di riferimento del movimento e suo quadrato + double dSqRad = dRad * dRad ; + double dSqLongLen = dLongVecLen * dLongVecLen ; + double dSqOrtLen = dOrtVecLen * dOrtVecLen ; + // Setto i coeficienti dell'equazione d'intersezione della + // retta con la superficie di traslazione della circonferenza. + DBLVECTOR vdCoef(3) ; + vdCoef[0] = dSqLongLen * ( ptP.x * ptP.x + ptP.y * ptP.y) + dSqOrtLen * ptP.z * ptP.z + - 2 * dLongVecLen * dOrtVecLen * ptP.x * ptP.z - dSqLongLen * dSqRad ; + vdCoef[1] = 2 * dSqLongLen * ( ptP.x * vtV.x + ptP.y * vtV.y) + 2 * dSqOrtLen * ptP.z * vtV.z + - 2 * dLongVecLen * dOrtVecLen * ( ptP.x * vtV.z + ptP.z * vtV.x) ; + vdCoef[2] = dSqLongLen * ( vtV.x * vtV.x + vtV.y * vtV.y) + dSqOrtLen * vtV.z * vtV.z + - 2 * dLongVecLen * dOrtVecLen * vtV.x * vtV.z ; + // Numero di soluzioni + DBLVECTOR vdRoots ; + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // L'equazione ammette o due soluzioni (eventualmente + // coincidenti) oppure nessuna o infinite se la la retta + // appartiene alla superficie + + // Se numero di soluzioni diverso da due le eventuali intersezioni sono gi� state trovate + if ( nRoot != 2) + return 0 ; + + // Punti di intersezione e versori alla superficie in corrispondenza di essi + ptInt1 = ptP + vdRoots[0] * vtV ; + ptInt2 = ptP + vdRoots[1] * vtV ; + vtN1.Set( dSqLongLen * ptInt1.x - dLongVecLen * dOrtVecLen * ptInt1.z, dSqLongLen * ptInt1.y, dSqOrtLen * ptInt1.z - dLongVecLen * dOrtVecLen * ptInt1.x) ; + vtN1.Normalize( EPS_ZERO) ; + vtN2.Set( dSqLongLen * ptInt2.x - dLongVecLen * dOrtVecLen * ptInt2.z, dSqLongLen * ptInt2.y, dSqOrtLen * ptInt2.z - dLongVecLen * dOrtVecLen * ptInt2.x) ; + vtN2.Normalize( EPS_ZERO) ; + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + // Elimino le soluzioni cha non stanno sulla superficie di traslazione, ovvero le intersezioni fuori dai limiti in Z. + if ( ptInt1.z < 0 || ptInt1.z > dLongVecLen) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( ptInt2.z < 0 || ptInt2.z > dLongVecLen) { + -- nRoot ; + } + + // Esprimo punti e vettori nel sistema in cui � immerso S. + if ( nRoot > 0) { + ptInt1.ToGlob( frFrameS) ; + vtN1.ToGlob( frFrameS) ; + if ( nRoot == 2) { + ptInt2.ToGlob( frFrameS) ; + vtN2.ToGlob( frFrameS) ; + } + } + + // Escludo le soluzioni che non stanno dalla parte ammissibile rispetto al piano. + bool bSecIntToTest = nRoot > 1 ; + for ( int n = 0 ; n < int( vPlanesVec.size()) && nRoot > 0 ; ++ n) { + //double dDist1 = DistPointPlane(ptInt1, vPlanesVec[n]); + if ( DistPointPlane( ptInt1, vPlanesVec[n]) > 0 + EPS_SMALL/*DistPointPlane( ptInt1, vPlanesVec[n]) >= 0*/) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + //double dDist2 = DistPointPlane(ptInt2, vPlanesVec[n]); + if ( bSecIntToTest && nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0 + EPS_SMALL/*bSecIntToTest && nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) >= 0*/) { + bSecIntToTest = false ; + -- nRoot ; + } + } + + return nRoot ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con la superficie ottenuta dal taglio di un cono, inteso come la sola superficie +// laterale, con un numero arbitrario di piani. +// Nel taglio del cono si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// Il cono � descritto dal vertice ptVert, dal versore vtAx del suo asse di simmetria, dal raggio dRad, dall'altezza dH +// e da un flag bInOut che indica se il campo delle normali al cono volge verso l'asse di simmetria o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e cono. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineConeCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineDir, + const Point3d& ptVert, const Vector3d& vtAx, double dRad, double dH, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Definisco il sistema di riferimento S; se non � possibile, c'� un errore. + Frame3d frFrameS ; + if ( ! frFrameS.Set( ptVert, vtAx)) + return 0 ; + + // Porto la linea nel riferimento del cilindro + Point3d ptP = ptLineP ; ptP.ToLoc( frFrameS) ; + Vector3d vtV = vtLineDir ; vtV.ToLoc( frFrameS) ; + + // Tangente dell'angolo di semi-apertura + double dTan = dRad / dH ; + + // Determino le intersezioni con la superficie laterale del cono + DBLVECTOR vdCoef( 3) ; + double dSqTan = dTan * dTan ; + vdCoef[0] = dSqTan * ptP.z * ptP.z - ptP.x * ptP.x - ptP.y * ptP.y ; + vdCoef[1] = 2 * ( dSqTan * ptP.z * vtV.z - ptP.x * vtV.x - ptP.y * vtV.y) ; + vdCoef[2] = dSqTan * vtV.z * vtV.z - vtV.x * vtV.x - vtV.y * vtV.y ; + DBLVECTOR vdRoots ; + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // Se non ho trovato soluzioni, ovvero si � stata trovata una soluzione di tangenza, ho terminato. + if ( nRoot == 0 || ( nRoot == 1 && abs( vtV.z) < EPS_ZERO)) + return 0 ; + + // Intersezioni + ptInt1 = ptP + vdRoots[0] * vtV ; + vtN1 = Vector3d( ptInt1.x, ptInt1.y, - dSqTan * ptInt1.z) ; + vtN1.Normalize() ; + if ( nRoot == 2) { + ptInt2 = ptP + vdRoots[1] * vtV ; + vtN2 = Vector3d( ptInt2.x, ptInt2.y, - dSqTan * ptInt2.z) ; + vtN2.Normalize() ; + } + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + // Elimino le intersezioni che non fanno parte del cono. + if ( ptInt1.z < 0 || ptInt1.z > dH) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( nRoot > 0 && ( ptInt2.z < 0 || ptInt2.z > dH)) + -- nRoot ; + + // Esprimo punti e vettori nel sistema in cui � immerso S. + if ( nRoot > 0) { + ptInt1.ToGlob( frFrameS) ; + vtN1.ToGlob( frFrameS) ; + if ( nRoot == 2) { + ptInt2.ToGlob( frFrameS) ; + vtN2.ToGlob( frFrameS) ; + } + } + + // Elimino le intersezioni sul cono che non fanno parte della superficie. + bool bSecIntToTest = nRoot > 1 ; + for ( int n = 0 ; n < int( vPlanesVec.size()) && nRoot > 0 ; ++ n) { + if ( /*DistPointPlane( ptInt1, vPlanesVec[n]) > 0*/DistPointPlane( ptInt1, vPlanesVec[n]) >= 0) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nRoot ; + } + if ( /*bSecIntToTest && nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0*/bSecIntToTest && nRoot > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) >= 0) { + bSecIntToTest = false ; + -- nRoot ; + } + } + + return nRoot ; +} + +//---------------------------------------------------------------------------- +// Calcola le intersezioni di una retta con una superficie sferica tagliata da un numero arbitrario di piani. +// Nel taglio della sfera si esclude la parte che sta nel semispazio verso cui punta la normale al piano. +// Il cono � descritto dal vertice ptVert, dal versore vtAx del suo asse di simmetria, dal raggio dRad, dall'altezza dH +// e da un flag bInOut che indica se il campo delle normali volge verso l'interno della sfera o meno. +// I piani devono essere espressi nello stesso sistema di riferimento in cui sono espressi i punti e i vettori che descrivono +// retta e cono. +// Le soluzioni verranno espresse nel medesimo sistema di riferimeno. I versori normali vtN1 e vtN2 saranno opposti alla normale +// della superficie nei punti ptInt1 e ptInt2 rispettivamente in cui avviene l'intersezione. +// La funzione restituisce 0 in caso di errore o assenza di soluzioni, altrimenti il numero di soluzioni trovate (al massimo 2). +int +VolZmap::IntersLineSphereCuttedByPlanes( const Point3d& ptLineP, const Vector3d& vtLineD, + const Point3d& ptCen, double dRad, bool bInOut, + const vector& vPlanesVec, + Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const +{ + // Intersezione fra retta e sfera + int nSol = IntersLineSphere( ptLineP, vtLineD, ptCen, dRad, ptInt1, ptInt2) ; + + // Non ci sono soluzioni. + if ( nSol == ILST_NO) + return nSol ; + + // Calcolo le normali + vtN1 = ( ptInt1 - ptCen) ; vtN1.Normalize() ; + vtN2 = ( ptInt2 - ptCen) ; vtN2.Normalize() ; + if ( ! bInOut) { + vtN1 *= - 1 ; + vtN2 *= - 1 ; + } + + + // Escludo le soluzioni fuori dalla parte ammissibile. + bool bSecIntToTest = nSol > 1 ; + for ( int n = 0 ; n < int( vPlanesVec.size()) && nSol != 0 ; ++ n) { + if ( /*DistPointPlane( ptInt1, vPlanesVec[n]) > 0*/DistPointPlane( ptInt1, vPlanesVec[n]) >= 0) { + ptInt1 = ptInt2 ; + vtN1 = vtN2 ; + -- nSol ; + } + if ( /*bSecIntToTest && nSol > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) > 0*/bSecIntToTest && nSol > 0 && DistPointPlane( ptInt2, vPlanesVec[n]) >= 0) { + bSecIntToTest = false ; + -- nSol ; + } + } + + return nSol ; +} + +//---------------------------------------------------------------------------- +// Il vettore normale alla superficie deve essere passato gi� normalizzato. +int +VolZmap::IntersLineCatTongue( const Point3d& ptLineP, const Vector3d& vtLineD, + const Point3d& ptCenSt, const Point3d& ptCenEn, const Vector3d& vtNorm, double dRad, + Point3d& ptInt, Vector3d& vtN) const +{ + // Definisco il piano. + Plane3d plPlane ; + if ( ! plPlane.Set( ptCenSt, vtNorm)) + return 0 ; + + // Intersezione retta piano + int nIntType = IntersLinePlane( ptLineP, vtLineD, 1000, plPlane, ptInt, false) ; + if ( nIntType == ILPT_YES /* || nIntType == ILPT_START || nIntType == ILPT_END*/) { + // Creo un sistema di riferimento per stabilire se l'intersezione avviene in un + // punto del piano interno alla superficie o meno. + Vector3d vtLong = ptCenEn - ptCenSt ; + double dLongLen = vtLong.Len() ; + vtLong /= dLongLen ; + Vector3d vtTrasv = vtNorm ^ vtLong ; + // Determino se l'intersezione � sulla superficie + Vector3d vtIntV = ptInt - ptCenSt ; + double dIntLong = vtIntV * vtLong ; + double dIntTrasv = vtIntV * vtTrasv ; + double dInfLongLim = sqrt( max( dRad * dRad - dIntTrasv * dIntTrasv, 0.)) ; + double dSupLongLim = dLongLen + dInfLongLim ; + if ( abs( dIntTrasv) < dRad && dIntLong > dInfLongLim && dIntLong < dSupLongLim) { + vtN = - vtNorm ; + return 1 ; + } + } + + return 0 ; +} + +// Filtro per le intersezioni + +typedef vector> DexelSurfIntersVector ; + +//---------------------------------------------------------------------------- +bool +IntersectionsFilter( const Vector3d& vtDexDir, const DexelSurfIntersVector& vOrigineIntersVec, DexelSurfIntersVector& vFilteredIntersVec) +{ + // Tolleranze + double dDotEps = EPS_ZERO ; + double dLenEps = EPS_SMALL ; + + // Separo gli ingressi dalle uscite. + DexelSurfIntersVector vEntrancesVec, vExitsVec, vIndefVec ; + for ( int n = 0 ; n < int( vOrigineIntersVec.size()) ; ++ n) { + if ( vOrigineIntersVec[n].second * vtDexDir < - dDotEps) { + vExitsVec.emplace_back( vOrigineIntersVec[n]) ; + } + else if ( vOrigineIntersVec[n].second * vtDexDir > dDotEps) { + vEntrancesVec.emplace_back( vOrigineIntersVec[n]) ; + } + else { + vIndefVec.emplace_back( vOrigineIntersVec[n]) ; + } + } + + // Riordino le entrate e le uscite in funzione del parametro lungo la retta in corrispondenza del quale occorrono. + sort( vEntrancesVec.begin(), vEntrancesVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + sort( vExitsVec.begin(), vExitsVec.end(), [] ( pair Int1, pair Int2) + { return Int1.first < Int2.first ; }) ; + + if ( int( vEntrancesVec.size()) == 2 && + int( vExitsVec.size()) == 2 && + abs( vEntrancesVec[0].first - vExitsVec[0].first) < dLenEps && + abs( vEntrancesVec[1].first - vExitsVec[1].first) < dLenEps) + return true ; + + // Modo 1 + for ( int n = 0 ; n < int( vEntrancesVec.size()) ; ++ n) { + for ( int m = 0 ; m < int( vExitsVec.size()) ; ++ m) { + if ( vExitsVec[m].first > vEntrancesVec[n].first) { + if ( n == 0 || ( int( vFilteredIntersVec.size()) > 0 && vEntrancesVec[n].first > vFilteredIntersVec.back().first)) { + vFilteredIntersVec.emplace_back( vEntrancesVec[n]) ; + vFilteredIntersVec.emplace_back( vExitsVec[m]) ; + break ; + } + } + } + } + + // Modo 2 + + // Media e deviazione standard delle entrate + //double dEntrancesAvarage = 0 ; + //double dEntrancesStdDev = 0 ; + //if ( int( vEntrancesVec.size()) != 0) { + // for ( int n = 0 ; n < int( vEntrancesVec.size()) ; ++ n) { + // dEntrancesAvarage += vEntrancesVec[n].first ; + // } + // dEntrancesAvarage /= int( vEntrancesVec.size()) ; + // for ( int n = 0 ; n < int( vEntrancesVec.size()) ; ++ n) { + // dEntrancesStdDev += ( vEntrancesVec[n].first - dEntrancesAvarage) * ( vEntrancesVec[n].first - dEntrancesAvarage) ; + // } + // dEntrancesStdDev = sqrt( dEntrancesStdDev / int( vEntrancesVec.size())) ; + //} + // + //// Media e deviazione standard delle uscite + //double dExitsAvarage = 0 ; + //double dExitsStdDev = 0 ; + //if ( int( vExitsVec.size()) != 0) { + // for ( int n = 0 ; n < int( vExitsVec.size()) ; ++ n) { + // dExitsAvarage += vExitsVec[n].first ; + // } + // dExitsAvarage /= int( vExitsVec.size()) ; + // for ( int n = 0 ; n < int( vExitsVec.size()) ; ++ n) { + // dExitsStdDev += ( vExitsVec[n].first - dExitsAvarage) * ( vExitsVec[n].first - dExitsAvarage) ; + // } + // dExitsStdDev = sqrt( dExitsStdDev / int( vExitsVec.size())) ; + //} + // + //// Deve esserci almeno un entrata e un uscita + //if ( int( vEntrancesVec.size()) != 0 && int( vExitsVec.size()) != 0) { + // // Caso di un solo gruppo per le entrate + // if ( dEntrancesStdDev < dLenEps) { + // // Caso di un solo gruppo per le uscite + // if ( dExitsStdDev < dLenEps) { + // if ( vExitsVec.back().first > vEntrancesVec[0].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[0]) ; + // vFilteredIntersVec.emplace_back( vExitsVec.back()) ; + // } + // } + // // Caso di due gruppi per le uscite + // else { + // // Cerco ultima uscita del primo gruppo + // int n ; + // for ( n = int( vExitsVec.size()) - 1 ; n >= 0 ; -- n) { + // if ( vExitsVec[n].first < dExitsAvarage) + // break ; + // } + // // Aggiungo ingressi e uscite filtrati. + // if ( vExitsVec[n].first > vEntrancesVec[0].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[0]) ; + // vFilteredIntersVec.emplace_back( vExitsVec[n]) ; + // } + // else if ( vExitsVec.back().first > vEntrancesVec[0].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[0]) ; + // vFilteredIntersVec.emplace_back( vExitsVec.back()) ; + // } + // } + // } + // // Caso di due gruppi per le entrate + // else { + // // Cerco prima entrata del secondo gruppo + // int n ; + // for ( n = 0 ; n < int( vEntrancesVec.size()) ; ++ n) { + // if ( vEntrancesVec[n].first > dEntrancesAvarage) + // break ; + // } + // // Caso di un solo gruppo per le uscite + // if ( dExitsStdDev < dLenEps) { + // // Aggiungo ingressi e uscite filtrati. + // if ( vExitsVec.back().first > vEntrancesVec[n].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[n]) ; + // vFilteredIntersVec.emplace_back( vExitsVec.back()) ; + // } + // else if ( vExitsVec.back().first > vEntrancesVec[0].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[0]) ; + // vFilteredIntersVec.emplace_back( vExitsVec.back()) ; + // } + // } + // // Caso di due gruppi per le uscite + // else { + // // Cerco ultima uscita del primo gruppo + // int m ; + // for ( m = int( vExitsVec.size()) - 1 ; m >= 0 ; -- m) { + // if ( vExitsVec[m].first < dExitsAvarage) + // break ; + // } + // // Aggiungo ingressi e uscite ai filtri. + // if ( vExitsVec[m].first > vEntrancesVec[0].first) { + // if ( vExitsVec[m].first > vEntrancesVec[n].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[0]) ; + // vFilteredIntersVec.emplace_back( vExitsVec.back()) ; + // } + // else if ( vExitsVec.back().first > vEntrancesVec[n].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[0]) ; + // vFilteredIntersVec.emplace_back( vExitsVec[m]) ; + // vFilteredIntersVec.emplace_back( vEntrancesVec[n]) ; + // vFilteredIntersVec.emplace_back( vExitsVec.back()) ; + // } + // else { + // vFilteredIntersVec.emplace_back( vEntrancesVec[0]) ; + // vFilteredIntersVec.emplace_back( vExitsVec[m]) ; + // } + // } + // else { + // if ( vExitsVec.back().first > vEntrancesVec[n].first) { + // vFilteredIntersVec.emplace_back( vEntrancesVec[n]) ; + // vFilteredIntersVec.emplace_back( vExitsVec.back()) ; + // } + // } + // } + // } + //} + + return true ; +} + +// Corona circolare +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCircCrown_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMaxRad, 1, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Se il movimento � in direzione opposta a quella ove la corona pu� tagliare, non devo fare nulla. + if ( vtAx.z * ( ptE - ptS).z < EPS_ZERO) + return true ; + + // Raggi di sicurezza per evitare di tagliare i dexel a filo del bordo dela regione interessata dal taglio. + double dSqSafeMinRad = dMinRad * dMinRad + 2 * dMinRad * EPS_SMALL ; + double dSqSafeMaxRad = dMaxRad * dMaxRad - 2 * dMaxRad * EPS_SMALL ; + + // Se la corona circolare defenera in un disco (dMinRad < EPS), forzo dSqSafeMinRad a - 1 + // in modo da tagliare i dexel giacenti sul suo asse di simmetria. + if ( dMinRad < EPS_SMALL) + dSqSafeMinRad = - 1 ; + + Point3d ptSXY( ptS.x, ptS.y, 0) ; + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + Vector3d vtR = ptC - ptSXY ; + double dSqLenR = vtR * vtR ; + if ( dSqLenR > dSqSafeMinRad && dSqLenR < dSqSafeMaxRad) { + double dMinZ = min( ptS.z, ptE.z) ; + double dMaxZ = max( ptS.z, ptE.z) ; + Vector3d vtMinN, vtMaxN ; + if ( ptE.z < ptS.z) { + vtMinN.z = 1 ; + vtMaxN.z = -1 ; + } + else { + vtMinN.z = 1 ; + vtMaxN.z = - 1 ; + } + SubtractIntervals( nGrid, i, j, dMinZ, dMaxZ, vtMinN, vtMaxN) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCircCrown_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, 1, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Se il movimento � in direzione opposta a quella ove la corona pu� tagliare, non devo fare nulla. + double dMotProjOnAx = vtAx * ( ptE - ptS) ; + if ( dMotProjOnAx < EPS_ZERO) + return true ; + + // Vettore di piani fittizio + vector vEmptyPlaneVec ; + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con cilindro esterno + int nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, dMotProjOnAx, false, vEmptyPlaneVec, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro interno in caso di corona circolare propria (la funzione esegue + // l'intersezione solo se il cilindro ha un raggio sensibilmente maggiore di zero) + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMinRad, dMotProjOnAx, true, vEmptyPlaneVec, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptS, - vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptE, vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCircCrown_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) +{ + return SurfCircCrown_Milling( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCircCrown_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dMaxRad, double dMinRad) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMaxRad, 1, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Se il movimento � in direzione opposta a quella ove la corona pu� tagliare, non devo fare nulla. + Vector3d vtDisp = ( ptE - ptS) ; + double dMotProjOnAx = vtAx * vtDisp ; + if ( dMotProjOnAx < EPS_ZERO) + return true ; + + // Vettore di piani fittizio + vector vEmptyPlaneVec ; + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con cilindro ellittico esterno + int nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, vtDisp, false, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro interno in caso di corona circolare propria (la funzione esegue + // l'intersezione solo se il cilindro ha un raggio sensibilmente maggiore di zero) + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMinRad, vtDisp, true, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptS, - vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Intersezione con corona in posizione inziale + nIntNum = IntersLineCircCrown( ptC, Z_AX, ptE, vtAx, dMaxRad, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + + return true ; +} + +// Cilindro +//---------------------------------------------------------------------------- +//bool +//VolZmap::SurfCyl_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, +// double dHei, double dRad, bool bTapB, bool bTapT) +//{ +// return true ; +//} +// +////---------------------------------------------------------------------------- +//bool +//VolZmap::SurfCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, +// double dHei, double dRad, bool bTapB, bool bTapT) +//{ +// return true ; +//} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCyl_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dHei, double dRad, bool bOuterCutter) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + + // Dimensioni del moto nella direzione utensile e ortogonale e quote iniziali e finali + double dDispZ = vtDisp * vtAx ; + double dDispXY = sqrt( max( vtDisp.SqLen() - dDispZ * dDispZ, 0.)) ; + double dStartTopZ = ptS.z ; + double dStartBotZ = ( ptS - dHei * vtAx).z ; + + // Sistema di riferimento del moto + Vector3d vtV3 = vtAx ; + Vector3d vtV1 = vtDisp - dDispZ * vtV3 ; vtV1.Normalize() ; + Vector3d vtV2 = vtV3 ^ vtV1 ; + Point3d ptSxy( ptS.x, ptS.y, 0) ; + + // Caso moto perpendicolare + if ( abs( dDispZ) < EPS_SMALL) { + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + double dProj1 = ( ptC - ptSxy) * vtV1 ; + double dProj2 = ( ptC - ptSxy) * vtV2 ; + double dCirc1 = ( bOuterCutter ? 1 : - 1) * sqrt( max( dRad * dRad - dProj2 * dProj2, 0.)) ; + if ( abs( dProj2) < dRad && dProj1 > dCirc1 && dProj1 < dDispXY + dCirc1) { + // Quote minima e massima rispetto al sistema griglia e versori normali associati + double dMin = vtAx.z > 0 ? dStartBotZ : dStartTopZ ; + double dMax = vtAx.z > 0 ? dStartTopZ : dStartBotZ ; + Vector3d vtMin = Z_AX ; + Vector3d vtMax = - Z_AX ; + // Taglio dei dexel + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; + } + } + } + + return true ; + } + + // Ciclo sui dexel. + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + double dProj1 = ( ptC - ptSxy) * vtV1 ; + double dProj2 = ( ptC - ptSxy) * vtV2 ; + double dCirc1 = ( bOuterCutter ? 1 : - 1) * sqrt( max( dRad * dRad - dProj2 * dProj2, 0.)) ; + if ( abs( dProj2) < dRad && dProj1 > dCirc1 && dProj1 < dDispXY + dCirc1) { + // Quote inferiore e superiore rispetto alla direzione del versore utensile + double dInfZ = dStartBotZ + ( dProj1 - dCirc1) * dDispZ * vtAx.z / dDispXY ; + double dSupZ = dStartTopZ + ( dProj1 - dCirc1) * dDispZ * vtAx.z / dDispXY ; + // Calcolo dei versori normali associati + Vector3d vtRad = dCirc1 * vtV1 + dProj2 * vtV2 ; + Vector3d vtTan( - vtRad.y, vtRad.x, 0) ; + Vector3d vtCross = vtTan ^ vtDisp ; + vtCross.Normalize() ; + // Quote minima e massima rispetto al sistema griglia e versori normali associati + double dMin = vtAx.z > 0 ? dInfZ : dSupZ ; + double dMax = vtAx.z > 0 ? dSupZ : dInfZ ; + Vector3d vtMin = bOuterCutter ? - vtCross : vtCross ; + Vector3d vtMax = bOuterCutter ? vtCross : - vtCross ; + // Taglio dei dexel + SubtractIntervals( nGrid, i, j, dMin, dMax, vtMin, vtMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfCyl_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, + const Vector3d& vtAx, double dHei, double dRad, bool bOuterCutter, bool bTapB, bool bTapT) +{ + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + + // Versore della componente del moto ortogonale all'asse dell'utensile + double dDispZ = vtDisp * vtAx ; + Vector3d vtOrtDisp = vtDisp - dDispZ * vtAx ; + double dOrtDispLen = vtOrtDisp.Len() ; + vtOrtDisp /= dOrtDispLen ; + // Versore direzione del moto + Vector3d vtDispDir = vtDisp ; + vtDispDir.Normalize() ; + // Versore laterale + Vector3d vtLat = vtAx ^ vtOrtDisp ; + + // Deduzione dei punti per la definizione dei piani laterali + Point3d ptPlanePlus = ptS - dHei * vtAx + dRad * vtLat ; + Point3d ptPlaneMinus = ptS - dHei * vtAx - dRad * vtLat ; + + // Moto ortogonale all'asse del cilindro + double dObCoef = dDispZ / dOrtDispLen ; + double dMyLength = dObCoef * dRad / sqrt( 1 + dObCoef * dObCoef) ; + if ( abs( dDispZ) < 2 * EPS_SMALL && dMyLength < 2 * EPS_SMALL) { + + Point3d ptMyE = ptS + dOrtDispLen * vtOrtDisp ; + + // Definisco i piani utilizzati per tagliare le superfici elementari. + // Piano per cilindro in posizione iniziale + vector vCutCylPlaneVecSt ; + vCutCylPlaneVecSt.emplace_back() ; + vCutCylPlaneVecSt.back().Set( ptS, ( bOuterCutter ? - 1 : 1) * vtOrtDisp) ; + // Piano per cilindro in posizione finale + vector vCutCylPlaneVecEn ; + vCutCylPlaneVecEn.emplace_back() ; + vCutCylPlaneVecEn.back().Set( ptMyE, ( bOuterCutter ? - 1 : 1) * vtOrtDisp) ; + + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0.) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con cilindro in posizione iniziale + int nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dRad, - dHei, bOuterCutter, vCutCylPlaneVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro in posizione finale + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, vtAx, dRad, - dHei, ! bOuterCutter, vCutCylPlaneVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con lingua di gatto superiore + nIntNum = IntersLineCatTongue( ptC, Z_AX, bOuterCutter ? ptS : ptMyE, bOuterCutter ? ptMyE : ptS, + vtAx, dRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Intersezione con lingua di gatto inferiore + nIntNum = IntersLineCatTongue( ptC, Z_AX, ( bOuterCutter ? ptS : ptMyE) - dHei * vtAx, ( bOuterCutter ? ptMyE : ptS) - dHei * vtAx, + - vtAx, dRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano + (con normale + vtLat) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlus, dHei * vtAx, vtDisp, + true, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano - (con normale - vtLat) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinus, dHei * vtAx, vtDisp, + false, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + + return true ; + } + + // Definisco i piani utilizzati per tagliare le superfici elementari. + // Piano per cilindro in posizione iniziale + vector vCutCylPlaneVecSt ; + vCutCylPlaneVecSt.emplace_back() ; + vCutCylPlaneVecSt.back().Set( ptS, ( bOuterCutter ? - 1 : 1) * vtOrtDisp) ; + // Piano per cilindro in posizione finale + vector vCutCylPlaneVecEn ; + vCutCylPlaneVecEn.emplace_back() ; + vCutCylPlaneVecEn.back().Set( ptE, ( bOuterCutter ? - 1 : 1) * vtOrtDisp) ; + // Piano per cilindro ellittico superiore + vector vCutEllipCylPlaneVecUp ; + if ( dDispZ > 0) { + vCutEllipCylPlaneVecUp.emplace_back() ; + vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtLat) ; + } + else { + vCutEllipCylPlaneVecUp.emplace_back() ; + vCutEllipCylPlaneVecUp.back().Set( ptS, ( bOuterCutter ? - 1 : 1) * vtDispDir ^ vtLat) ; + } + // Piani per cilindro ellittico inferiore + vector vCutEllipCylPlaneVecDw ; + if ( dDispZ > 0) { + vCutEllipCylPlaneVecDw.emplace_back() ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtAx, ( bOuterCutter ? 1 : - 1) * vtDispDir ^ vtLat) ; + } + else { + vCutEllipCylPlaneVecDw.emplace_back() ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtAx, ( bOuterCutter ? - 1 : 1) * vtDispDir ^ vtLat) ; + } + + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0.) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con cilindro in posizione iniziale + int nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dRad, - dHei, bOuterCutter, vCutCylPlaneVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro in posizione finale + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, vtAx, dRad, - dHei, ! bOuterCutter, vCutCylPlaneVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dRad, vtDisp, bOuterCutter == dDispZ > 0, vCutEllipCylPlaneVecUp, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + if ( vCutEllipCylPlaneVecUp.size() == 1) { + if ( SqDist( ptInt1, ptInt2) < EPS_SMALL) { + //double dLL1 = (ptInt1 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN(); + //double dLL2 = (ptInt2 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN(); + if ( ( ptInt1 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 2) ; + else if ( ( ptInt2 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 1) ; + } + } + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dRad, vtDisp, bOuterCutter != dDispZ > 0, vCutEllipCylPlaneVecDw, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + if ( vCutEllipCylPlaneVecDw.size() == 1) { + if ( SqDist( ptInt1, ptInt2) < EPS_SMALL) { + //double dLL1 = (ptInt1 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN(); + //double dLL2 = (ptInt2 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN(); + if ( ( ptInt1 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 2) ; + else if ( ( ptInt2 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 1) ; + } + } + } + } + + // Piano + (con normale + vtLat) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlus, dHei * vtAx, vtDisp, + true, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano - (con normale - vtLat) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinus, dHei * vtAx, vtDisp, + false, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + + return true ; +} + +// Cono +//---------------------------------------------------------------------------- +bool +VolZmap::SurfConus_ZDrilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dMaxRad, double dMinRad, + bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + // Verifica sull'interferenza con lo Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Raggi di sicurezza per evitare di tagliare i dexel a filo del bordo dela regione interessata dal taglio. + double dSqSafeMinRad = dMinRad * dMinRad + 2 * dMinRad * EPS_SMALL ; + double dSqSafeMaxRad = dMaxRad * dMaxRad - 2 * dMaxRad * EPS_SMALL ; + + // Se il movimento � nella direzione ove il cono non taglia, ho finito. + if ( vtAx.z * ( ptE.z - ptS.z) > 0 == bOuterCutter) + return true ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + double dSqR = ( dX - ptS.x) * ( dX - ptS.x) + ( dY - ptS.y) * ( dY - ptS.y) ; + + if ( dSqR < dSqSafeMinRad || dSqR > dSqSafeMaxRad) + continue ; + + if ( vtAx.z > 0) { + double dr = sqrt( dSqR) ; + // Quote Z + double dMinZ = min( ptS.z, ptE.z) - dHei + ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + double dMaxZ = max( ptS.z, ptE.z) - dHei + ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + // Normali + Vector3d vtMinN, vtMaxN ; + if ( bOuterCutter) { + double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; + Point3d ptIntMinP( dX, dY, dMinZ) ; + Vector3d vtIntMinV = ptIntMinP - ptVertE ; + double dCompLong = vtIntMinV * vtAx ; + Vector3d vtIntMinLongV = dCompLong * vtAx ; + Vector3d vtIntMinOrtV = vtIntMinV - vtIntMinLongV ; + double dCompOrt = vtIntMinOrtV.Len() ; + vtIntMinOrtV /= dCompOrt ; + vtMinN = - dCompLong * vtIntMinOrtV + dCompOrt * vtAx ; + vtMinN.Normalize() ; + vtMaxN = - vtMinN ; + } + else { + double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; + Point3d ptIntMaxP( dX, dY, dMaxZ) ; + Vector3d vtIntMaxV = ptIntMaxP - ptVertE ; + double dCompLong = vtIntMaxV * vtAx ; + Vector3d vtIntMaxLongV = dCompLong * vtAx ; + Vector3d vtIntMaxOrtV = vtIntMaxV - vtIntMaxLongV ; + double dCompOrt = vtIntMaxOrtV.Len() ; + vtIntMaxOrtV /= dCompOrt ; + vtMaxN = dCompLong * vtIntMaxOrtV - dCompOrt * vtAx ; + vtMaxN.Normalize() ; + vtMinN = - vtMaxN ; + } + // Taglio dei dexel + SubtractIntervals( nGrid, i, j, dMinZ, dMaxZ, vtMinN, vtMaxN) ; + } + else { + double dr = sqrt( dSqR) ; + // Quote Z + double dMinZ = min( ptS.z, ptE.z) + dHei - ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + double dMaxZ = max( ptS.z, ptE.z) + dHei - ( dr - dMinRad) * dHei / ( dMaxRad - dMinRad) ; + // Normali + Vector3d vtMinN, vtMaxN; + if ( bOuterCutter) { + double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; + Point3d ptIntMaxP( dX, dY, dMaxZ) ; + Vector3d vtIntMaxV = ptIntMaxP - ptVertE ; + double dCompLong = vtIntMaxV * vtAx ; + Vector3d vtIntMaxLongV = dCompLong * vtAx ; + Vector3d vtIntMaxOrtV = vtIntMaxV - vtIntMaxLongV ; + double dCompOrt = vtIntMaxOrtV.Len() ; + vtIntMaxOrtV /= dCompOrt ; + vtMaxN = - dCompLong * vtIntMaxOrtV + dCompOrt * vtAx ; + vtMaxN.Normalize() ; + vtMinN = - vtMaxN ; + } + else { + double dDeltaH = dMinRad * dHei / ( dMaxRad - dMinRad) ; + Point3d ptVertE = ptE - ( dHei + dDeltaH) * vtAx ; + Point3d ptIntMinP( dX, dY, dMinZ) ; + Vector3d vtIntMinV = ptIntMinP - ptVertE ; + double dCompLong = vtIntMinV * vtAx ; + Vector3d vtIntMinLongV = dCompLong * vtAx ; + Vector3d vtIntMinOrtV = vtIntMinV - vtIntMinLongV ; + double dCompOrt = vtIntMinOrtV.Len() ; + vtIntMinOrtV /= dCompOrt ; + vtMinN = dCompLong * vtIntMinOrtV - dCompOrt * vtAx ; + vtMinN.Normalize() ; + vtMaxN = - vtMinN ; + } + // Taglio dei dexel + SubtractIntervals( nGrid, i, j, dMinZ, dMaxZ, vtMinN, vtMaxN) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfConus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento e sua componente lungo l'asse del cono + Vector3d vtDisp = ptE - ptS ; + double dDispLong = vtAx * vtDisp ; + + // Se lo spostamento � in direzione opposta a quella ove il cono taglia, ho finito. + bool bToolVecAndDispAreOpposite = dDispLong < 0 ; + if ( bToolVecAndDispAreOpposite != bOuterCutter) + return true ; + + // Vertici cono iniziale e finale + double dDeltaHei = ( dMinRad * dHei) / ( dMaxRad - dMinRad) ; + Point3d ptVs = ptS - ( dHei + dDeltaHei) * vtAx ; + Point3d ptVe = ptE - ( dHei + dDeltaHei) * vtAx ; + + // Piani per tagliare le superfici elementari. + vector vCutConePlaneVecSt ; vCutConePlaneVecSt.emplace_back() ; + vCutConePlaneVecSt.back().Set( ptS - dHei * vtAx, - vtAx) ; + vector vCutConePlaneVecEn ; vCutConePlaneVecEn.emplace_back() ; + vCutConePlaneVecEn.back().Set( ptE - dHei * vtAx, - vtAx) ; + vector vEmptyPlaneVec ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con il cono in posizione iniziale + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVs, vtAx, dMaxRad, dHei + dDeltaHei, /*!*/ bToolVecAndDispAreOpposite, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cono in posizione finale + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVe, vtAx, dMaxRad, dHei + dDeltaHei, ! bToolVecAndDispAreOpposite, + vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cilindro esterno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, dDispLong, false, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cilindro interno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dMinRad, dDispLong, true, + vEmptyPlaneVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfConus_ZMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, double dHei, double dMaxRad, double dMinRad, + bool bOuterCutter, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + return SurfConus_Milling( nGrid, ptS, ptE, vtAx, dHei, dMaxRad, dMinRad, bOuterCutter, true, true, vtArcNormMaxR, vtArcNormMinR) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SurfConus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dHei, double dMaxRad, double dMinRad, bool bOuterCutter, bool bTapB, bool bTapT, + const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR) +{ + // Verifico interferenza + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dMaxRad, dMinRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + + // Spostamento nella direzione utensile e in quella ortogonale + double dDispProjOnAxDir = vtDisp * vtAx ; + Vector3d vtDispLong = dDispProjOnAxDir * vtAx ; + Vector3d vtDispOrt = vtDisp - vtDispLong ; + // Terna di riferimento del movimento + Vector3d vtV1 = vtDispOrt ; vtV1.Normalize() ; + Vector3d vtV2 = vtAx ^ vtV1 ; + Vector3d vtV3 = vtAx ; + // Parametri geometrici descriventi il cono e il moto + double dDeltaHei = dMinRad * dHei / ( dMaxRad - dMinRad) ; + double dTanAlpha = dMaxRad / ( dHei + dDeltaHei) ; + double dCosTheta = Clamp( ( dTanAlpha * vtDisp * vtV3) / ( vtDisp * vtV1), -1., 1.) ; + double dSinTheta = sqrt( max( 1 - dCosTheta * dCosTheta, 0.)) ; + double dLim = abs( dCosTheta) ; + + // Se il movimento non � compatibile con il verso delle normali, ho finito. + if ( dLim > 1 - EPS_ZERO && ( bOuterCutter == dDispProjOnAxDir > 0)) + return true ; + + // Vertici del cono nelle posizioni iniziale e finale + Point3d ptVertSt = ptS - ( dHei + dDeltaHei) * vtAx ; + Point3d ptVertEn = ptE - ( dHei + dDeltaHei) * vtAx ; + + // Vettori radiali per definire i piani + Vector3d vtRadPlus = dCosTheta * vtV1 + dSinTheta * vtV2 ; + Vector3d vtRadMinus = dCosTheta * vtV1 - dSinTheta * vtV2 ; + + // Piani per tagliare le superfici elementari. + // Piani per cono in posizione iniziale + vector vCutConePlaneVecSt ; + vCutConePlaneVecSt.emplace_back() ; + vCutConePlaneVecSt.back().Set( ptS - dHei * vtAx, - vtAx) ; + // Piani per cono in posizione finale + vector vCutConePlaneVecEn ; + vCutConePlaneVecEn.emplace_back() ; + vCutConePlaneVecEn.back().Set( ptE - dHei * vtAx, - vtAx) ; + // Piani per cilindro ellittico superiore + vector vCutEllipCylPlaneVecUp ; + // Piani per cilindro ellittico inferiore + vector vCutEllipCylPlaneVecDw ; + + // Caso di limete oltrepassato + if ( dLim > 1 - EPS_ZERO) { + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con il cono in posizione iniziale + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertSt, vtAx, dMaxRad, dHei + dDeltaHei, bOuterCutter, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cono in posizione finale + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertEn, vtAx, dMaxRad, dHei + dDeltaHei, ! bOuterCutter, + vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico esterno + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, vtDisp, false, vCutEllipCylPlaneVecUp, + ptInt1, vtN1, ptInt2, vtN2); + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico interno + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dMinRad, vtDisp, true, vCutEllipCylPlaneVecDw, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + } + else { + + // Vettore normale ai piani per il nuovo taglio dei coni. + Vector3d vtConePlaneNorm = ( ptS + dMaxRad * vtRadPlus - ptVertSt) ^ ( ptS + dMaxRad * vtRadMinus - ptVertSt) ; vtConePlaneNorm.Normalize() ; + if ( bOuterCutter) + vtConePlaneNorm *= - 1 ; + // Aggiorno vettore di piani per tagliare il cono in posizione iniziale. + vCutConePlaneVecSt.emplace_back() ; + vCutConePlaneVecSt.back().Set( ptVertSt, vtConePlaneNorm) ; + // Aggiorno vettore di piani per tagliare il cono in posizione finale. + vCutConePlaneVecEn.emplace_back() ; + vCutConePlaneVecEn.back().Set( ptVertEn, vtConePlaneNorm) ; + + // Punti e normali dei piani laterali + Point3d ptPlanePlusP = ptS - dHei * vtAx + dMinRad * vtRadPlus ; + Point3d ptPlaneMinusP = ptS - dHei * vtAx + dMinRad * vtRadMinus ; + Vector3d vtPlanePlusN = ptS + dMaxRad * vtRadPlus - ptPlanePlusP ; + Vector3d vtPlaneMinusN = ptS + dMaxRad * vtRadMinus - ptPlaneMinusP ; + + // Moto ortogonale all'asse del cono + double dObCoef = dDispProjOnAxDir / vtDispOrt.Len() ; + double dMyLengthMax = dObCoef * dMaxRad / sqrt( 1 + dObCoef * dObCoef) ; + double dMyLengthMin = dObCoef * dMinRad / sqrt( 1 + dObCoef * dObCoef) ; + if ( abs( dDispProjOnAxDir) < 2 * EPS_SMALL && min( dMyLengthMax, dMyLengthMin) < 2 * EPS_SMALL) { + + Point3d ptMyE = ptS + vtDispOrt ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con il cono in posizione iniziale + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertSt, vtAx, dMaxRad, dHei + dDeltaHei, bOuterCutter, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cono in posizione finale + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertEn, vtAx, dMaxRad, dHei + dDeltaHei, ! bOuterCutter, + vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + + + // Intersezione con lingua di gatto superiore + nIntNum = IntersLineCatTongue( ptC, Z_AX, bOuterCutter ? ptS : ptMyE, bOuterCutter ? ptMyE : ptS, + vtAx, dMaxRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Intersezione con lingua di gatto inferiore + nIntNum = IntersLineCatTongue( ptC, Z_AX, ( bOuterCutter ? ptS : ptMyE) - dHei * vtAx, ( bOuterCutter ? ptMyE : ptS) - dHei * vtAx, + - vtAx, dMinRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano + (con normale + vtAx ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlusP, vtPlanePlusN, vtDisp, + true, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano - (con normale - vtAx ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinusP, vtPlaneMinusN, vtDisp, + false, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + + return true ; + } + + // Aggiorno il vettore dei piani per tagliare il cilindro ellittico superiore. + Vector3d vtEllipCylPlaneNormUp = vtDisp ^ vtV2 ; vtEllipCylPlaneNormUp.Normalize() ; + if ( bOuterCutter != dDispProjOnAxDir > 0) + vtEllipCylPlaneNormUp *= - 1 ; + vCutEllipCylPlaneVecUp.emplace_back() ; + vCutEllipCylPlaneVecUp.back().Set( ptS + dMaxRad * dCosTheta * vtV1, vtEllipCylPlaneNormUp) ; + // Aggiorno il vettore dei piani per tagliare il cilindro ellittico inferiore. + Vector3d vtEllipCylPlaneNormDw = vtEllipCylPlaneNormUp ; + vCutEllipCylPlaneVecDw.emplace_back() ; + vCutEllipCylPlaneVecDw.back().Set( ptS - dHei * vtAx + dMinRad * dCosTheta * vtV1, vtEllipCylPlaneNormDw) ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec; + DexelSurfIntersVector vIntersConusStart, vIntersConusEnd, vIntersEllipSup, vIntersEllipInf, vIntersPlanePlus, vIntersPlaneMinus; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con il cono in posizione iniziale + int nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertSt, vtAx, dMaxRad, dHei + dDeltaHei, bOuterCutter, + vCutConePlaneVecSt, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con il cono in posizione finale + nIntNum = IntersLineConeCuttedByPlanes( ptC, Z_AX, ptVertEn, vtAx, dMaxRad, dHei + dDeltaHei, ! bOuterCutter, + vCutConePlaneVecEn, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS, vtAx, dMaxRad, vtDisp, bOuterCutter == dDispProjOnAxDir > 0, vCutEllipCylPlaneVecUp, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + if ( vCutEllipCylPlaneVecUp.size() == 1) { + if ( SqDist( ptInt1, ptInt2) < EPS_SMALL) { + //double dLL1 = (ptInt1 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN(); + //double dLL2 = (ptInt2 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN(); + if ( ( ptInt1 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 2) ; + else if ( ( ptInt2 - vCutEllipCylPlaneVecUp[0].GetPoint()) * vCutEllipCylPlaneVecUp[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 1) ; + } + } + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dMinRad, vtDisp, bOuterCutter != dDispProjOnAxDir > 0, vCutEllipCylPlaneVecDw, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + if ( vCutEllipCylPlaneVecDw.size() == 1) { + if ( SqDist( ptInt1, ptInt2) < EPS_SMALL) { + //double dLL1 = (ptInt1 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN(); + //double dLL2 = (ptInt2 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN(); + if ( ( ptInt1 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 2) ; + else if ( ( ptInt2 - vCutEllipCylPlaneVecDw[0].GetPoint()) * vCutEllipCylPlaneVecDw[0].GetVersN() > 0.) + vParAndNormIntersVec.erase( vParAndNormIntersVec.begin() + int( vParAndNormIntersVec.size()) - 1) ; + } + } + } + } + + // Piano + (con normale + vtAx ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlanePlusP, vtPlanePlusN, vtDisp, + true, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Piano - (con normale - vtAx ^ vtOrtDisp) + nIntNum = IntersLineParallelogram( ptC, Z_AX, ptPlaneMinusP, vtPlaneMinusN, vtDisp, + false, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + } + + return true ; +} + +// Parte di calotta sferica +//---------------------------------------------------------------------------- +bool +VolZmap::SurfSphericalShellPart_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dRad, double dInfH, double dSupH, bool bOuterCutter) +{ + // Se la superficie � una calotta sferica, chiamo la routine apposita. + if ( dInfH > dRad - EPS_SMALL) + return SurfSphericalShell_Milling( nGrid, ptS, ptE, vtAx, dRad, dSupH, bOuterCutter) ; + + // Verifico interferisca + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, V_NULL, dRad, 0, 0, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + Vector3d vtDispVers = vtDisp ; + double dDispLen = vtDispVers.Len() ; + vtDispVers /= dDispLen ; + + // Prodotto scalare fra versore del movimento e asse della calotta sferica + double dAxDispDot = vtDispVers * vtAx ; + + // Raggi dei cilindri ellittici + double dInfRad = sqrt( max( dRad * dRad - dInfH * dInfH, 0.)) ; + double dSupRad = sqrt( max( dRad * dRad - dSupH * dSupH, 0.)) ; + + // Coseni limite + double dCosInf = dInfRad / dRad ; + double dCosSup = dSupRad / dRad ; + + // Vettore dei piani di taglio della sfera in posizione iniziale + vector vSphereCutPlanesVecSt ; + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS - dSupH * vtAx, vtAx) ; + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS - dInfH * vtAx, - vtAx) ; + // Vettore dei piani di taglio della sfera in posizione finale + vector vSphereCutPlanesVecEn ; + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE - dSupH * vtAx, vtAx) ; + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE - dInfH * vtAx, - vtAx) ; + + if ( abs( dAxDispDot) > dCosSup - EPS_ZERO) { + + if ( bOuterCutter == dAxDispDot > 0) + return true ; + + // Vettori dei piani di taglio del cilindro ellittico superiore e inferiore + vector vEllipCylCutPlanesVecSup ; + vector vEllipCylCutPlanesVecInf ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dSupH * vtAx, vtAx, dSupRad, vtDisp, false, + vEllipCylCutPlanesVecSup, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dInfH * vtAx, vtAx, dInfRad, vtDisp, true, + vEllipCylCutPlanesVecInf, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + } + else if ( abs( dAxDispDot) >= dCosInf) { + + // Aggiorno il vettore dei piani di taglio della sfera in posizione iniziale. + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS, bOuterCutter ? - vtDispVers : vtDispVers) ; + // Aggiorno il vettore dei piani di taglio della sfera in posizione finale. + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE, bOuterCutter ? - vtDispVers : vtDispVers) ; + + // Versore della componente del moto perpendicolare all'asse + Vector3d vtOrtDispVers = vtDisp - dDispLen * dAxDispDot * vtAx ; + double dOrtDispLen = vtOrtDispVers.Len() ; + vtOrtDispVers /= dOrtDispLen ; + + // Vettore dei piani di taglio del cilindro ellittico superiore + Vector3d vtPlaneN = - dDispLen * dAxDispDot * vtOrtDispVers + dOrtDispLen * vtAx ; + vtPlaneN.Normalize() ; + if ( bOuterCutter != dAxDispDot > 0) + vtPlaneN *= - 1 ; + double dC = vtDispVers * vtAx ; + double dS = sqrt( max( 1 - dC * dC, 0.)) ; + Point3d ptPlaneP = ptS - dSupH * vtAx + ( dC * dSupH / dS) * vtOrtDispVers ; + vector vEllipCylCutPlanesVecSup ; + vEllipCylCutPlanesVecSup.emplace_back() ; + vEllipCylCutPlanesVecSup.back().Set( ptPlaneP, vtPlaneN) ; + + // Vettore dei piani di taglio del cilindro ellittico inferiore + vector vEllipCylCutPlanesVecInf ; + + // Vettore dei piani di taglio del cilindro + vector vCylCutPlanesVec ; + vCylCutPlanesVec.emplace_back() ; + vCylCutPlanesVec.back().Set( ptPlaneP, bOuterCutter == dAxDispDot > 0 ? vtPlaneN : - vtPlaneN) ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dSupH * vtAx, vtAx, dSupRad, vtDisp, bOuterCutter == dAxDispDot > 0, + vEllipCylCutPlanesVecSup, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore, se necessario + if ( bOuterCutter != dAxDispDot > 0) { + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dInfH * vtAx, vtAx, dInfRad, vtDisp, true, + vEllipCylCutPlanesVecInf, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + } + + // Intersezione con cilindro esterno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, - vtDispVers, dRad, dDispLen, false, + vCylCutPlanesVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + } + else { + + // Aggiorno il vettore dei piani di taglio della sfera in posizione iniziale. + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS, bOuterCutter ? - vtDispVers : vtDispVers) ; + // Aggiorno il vettore dei piani di taglio della sfera in posizione finale. + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE, bOuterCutter ? - vtDispVers : vtDispVers) ; + + // Versore della componente del moto perpendicolare all'asse + Vector3d vtOrtDispVers = vtDisp - dDispLen * dAxDispDot * vtAx ; + double dOrtDispLen = vtOrtDispVers.Len() ; + vtOrtDispVers /= dOrtDispLen ; + + // Determinazione dei piani di taglio dei cilindri ellittici + Vector3d vtPlaneN = - dDispLen * dAxDispDot * vtOrtDispVers + dOrtDispLen * vtAx ; + vtPlaneN.Normalize() ; + if ( bOuterCutter != dAxDispDot > 0) + vtPlaneN *= - 1 ; + double dC = vtDispVers * vtAx ; + double dS = sqrt( max( 1 - dC * dC, 0.)) ; + Point3d ptPlaneSupP = ptS - dSupH * vtAx + ( dC * dSupH / dS) * vtOrtDispVers ; + Point3d ptPlaneInfP = ptS - dInfH * vtAx + ( dC * dInfH / dS) * vtOrtDispVers ; + // Vettore dei piani di taglio del cilindro ellittico superiore + vector vEllipCylCutPlanesVecSup ; + vEllipCylCutPlanesVecSup.emplace_back() ; + vEllipCylCutPlanesVecSup.back().Set( ptPlaneSupP, vtPlaneN) ; + // Vettore dei piani di taglio del cilindro ellittico inferiore + vector vEllipCylCutPlanesVecInf ; + vEllipCylCutPlanesVecInf.emplace_back() ; + vEllipCylCutPlanesVecInf.back().Set( ptPlaneInfP, vtPlaneN) ; + + // Vettore dei piani di taglio del cilindro + vector vCylCutPlanesVec ; + vCylCutPlanesVec.emplace_back() ; + vCylCutPlanesVec.back().Set( ptPlaneSupP, bOuterCutter == dAxDispDot > 0 ? vtPlaneN : - vtPlaneN) ; + vCylCutPlanesVec.emplace_back() ; + vCylCutPlanesVec.back().Set( ptPlaneInfP, bOuterCutter == dAxDispDot > 0 ? - vtPlaneN : vtPlaneN) ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + //// Se il movimento non � ortogonale all'asse interseco con i cilindri ellittici. + //double dObCoef = dDispLen * dAxDispDot / dOrtDispLen ; + //double dMyLengthSup = dObCoef * dSupRad / sqrt( 1 + dObCoef * dObCoef) ; + //double dMyLengthInf = dObCoef * dInfRad / sqrt( 1 + dObCoef * dObCoef) ; + //if ( abs( dDispLen * dAxDispDot) > EPS_SMALL && min( dMyLengthSup, dMyLengthInf) > 2 * EPS_SMALL) { + // // Intersezione con cilindro ellittico superiore + // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dSupH * vtAx, vtAx, dSupRad, vtDisp, bOuterCutter == dAxDispDot > 0, + // vEllipCylCutPlanesVecSup, ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + // + // // Intersezione con cilindro ellittico inferiore + // nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dInfH * vtAx, vtAx, dInfRad, vtDisp, bOuterCutter != dAxDispDot > 0, + // vEllipCylCutPlanesVecInf, ptInt1, vtN1, ptInt2, vtN2) ; + // if ( nIntNum >= 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // if ( nIntNum == 2) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt2.z ; + // vParAndNormIntersVec.back().second = vtN2 ; + // } + // } + //} + //// Altrimenti interseco con le lingue di gatto. + //else { + // Point3d ptMyE = ptS + dOrtDispLen * vtOrtDispVers ; + // // Intersezione con lingua la gatto superiore + // nIntNum = IntersLineCatTongue( ptC, Z_AX, ( bOuterCutter ? ptS : ptMyE) - dSupH * vtAx, ( bOuterCutter ? ptMyE : ptS) - dSupH * vtAx, + // vtAx, dSupRad, ptInt1, vtN1) ; + + // if ( nIntNum == 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // } + + // // Intersezione con la lingua di gatto inferiore + // nIntNum = IntersLineCatTongue( ptC, Z_AX, ( bOuterCutter ? ptS : ptMyE) - dInfH * vtAx, ( bOuterCutter ? ptMyE : ptS) - dInfH * vtAx, + // - vtAx, dInfRad, ptInt1, vtN1) ; + + // if ( nIntNum == 1) { + // vParAndNormIntersVec.emplace_back() ; + // vParAndNormIntersVec.back().first = ptInt1.z ; + // vParAndNormIntersVec.back().second = vtN1 ; + // } + //} + + // Se il movimento � ortogonale all'asse interseco con le lingue di gatto. + double dObCoef = dDispLen * dAxDispDot / dOrtDispLen ; + double dMyLengthSup = dObCoef * dSupRad / sqrt( 1 + dObCoef * dObCoef) ; + double dMyLengthInf = dObCoef * dInfRad / sqrt( 1 + dObCoef * dObCoef) ; + if ( abs( dDispLen * dAxDispDot) < 2 * EPS_SMALL && min( dMyLengthSup, dMyLengthInf) < 2 * EPS_SMALL) { + Point3d ptMyE = ptS + dOrtDispLen * vtOrtDispVers ; + // Intersezione con lingua la gatto superiore + nIntNum = IntersLineCatTongue( ptC, Z_AX, ( bOuterCutter ? ptS : ptMyE) - dSupH * vtAx, ( bOuterCutter ? ptMyE : ptS) - dSupH * vtAx, + vtAx, dSupRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + + // Intersezione con la lingua di gatto inferiore + nIntNum = IntersLineCatTongue( ptC, Z_AX, ( bOuterCutter ? ptS : ptMyE) - dInfH * vtAx, ( bOuterCutter ? ptMyE : ptS) - dInfH * vtAx, + - vtAx, dInfRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + } + // Altrimenti interseco con i cilindri ellittici. + else { + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dSupH * vtAx, vtAx, dSupRad, vtDisp, bOuterCutter == dAxDispDot > 0, + vEllipCylCutPlanesVecSup, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico inferiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dInfH * vtAx, vtAx, dInfRad, vtDisp, bOuterCutter != dAxDispDot > 0, + vEllipCylCutPlanesVecInf, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + } + + // Intersezione con cilindro esterno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, - vtDispVers, dRad, dDispLen, false, + vCylCutPlanesVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + } + + return true ; +} + +// Calotta sferica +//---------------------------------------------------------------------------- +bool +VolZmap::SurfSphericalShell_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx, + double dRad, double dHei, bool bOuterCutter) +{ + // Verifico interferisca + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, V_NULL, dRad, 0, 0, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + // Vettore spostamento + Vector3d vtDisp = ptE - ptS ; + Vector3d vtDispVers = vtDisp ; + double dDispLen = vtDispVers.Len() ; + vtDispVers /= dDispLen ; + + // Prodotto scalare fra versore del movimento e asse della calotta sferica + double dAxDispDot = vtDispVers * vtAx ; + + // Raggio del cilindro ellittico + double dBaseRad = sqrt( max( dRad * dRad - dHei * dHei, 0.)) ; + + // Coseni limite + double dCosLim = dBaseRad / dRad ; + + // Vettore dei piani di taglio della sfera in posizione iniziale + vector vSphereCutPlanesVecSt ; + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS - dHei * vtAx, vtAx) ; + // Vettore dei piani di taglio della sfera in posizione finale + vector vSphereCutPlanesVecEn ; + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE - dHei * vtAx, vtAx) ; + + if ( abs( dAxDispDot) > dCosLim - EPS_ZERO) { + + if ( bOuterCutter == dAxDispDot > 0) + return true ; + + // Vettore dei piani di taglio del cilindro ellittico + vector vEllipCylCutPlanesVec ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con cilindro ellittico superiore + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dBaseRad, vtDisp, false, + vEllipCylCutPlanesVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + } + else { + + // Aggiorno il vettore dei piani di taglio della sfera in posizione iniziale. + vSphereCutPlanesVecSt.emplace_back() ; + vSphereCutPlanesVecSt.back().Set( ptS, bOuterCutter ? - vtDispVers : vtDispVers) ; + // Aggiorno il vettore dei piani di taglio della sfera in posizione finale. + vSphereCutPlanesVecEn.emplace_back() ; + vSphereCutPlanesVecEn.back().Set( ptE, bOuterCutter ? - vtDispVers : vtDispVers) ; + + // Versore della componente del moto perpendicolare all'asse + Vector3d vtOrtDispVers = vtDisp - dDispLen * dAxDispDot * vtAx ; + double dOrtDispLen = vtOrtDispVers.Len() ; + vtOrtDispVers /= dOrtDispLen ; + + // Vettore dei piani di taglio del cilindro ellittico superiore + Vector3d vtPlaneN = - dDispLen * dAxDispDot * vtOrtDispVers + dOrtDispLen * vtAx ; + vtPlaneN.Normalize() ; + if ( bOuterCutter != dAxDispDot > 0) + vtPlaneN *= - 1 ; + double dC = vtDispVers * vtAx ; + double dS = sqrt( max( 1 - dC * dC, 0.)) ; + Point3d ptPlaneP = ptS - dHei * vtAx + ( dC * dHei / dS) * vtOrtDispVers ; + vector vEllipCylCutPlanesVec ; + vEllipCylCutPlanesVec.emplace_back() ; + vEllipCylCutPlanesVec.back().Set( ptPlaneP, vtPlaneN) ; + + // Vettore dei piani di taglio del cilindro + vector vCylCutPlanesVec ; + vCylCutPlanesVec.emplace_back() ; + vCylCutPlanesVec.back().Set( ptPlaneP, bOuterCutter == dAxDispDot > 0 ? vtPlaneN : - vtPlaneN) ; + + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + DexelSurfIntersVector vParAndNormIntersVec ; + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + // Intersezione con sfera in posizione iniziale + int nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptS, dRad, bOuterCutter, vSphereCutPlanesVecSt, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con sfera in posizione finale + nIntNum = IntersLineSphereCuttedByPlanes( ptC, Z_AX, ptE, dRad, ! bOuterCutter, vSphereCutPlanesVecEn, + ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Intersezione con lingua di gatto se il movimento � perpendicolare all'asse di simmetria + double dObCoef = dDispLen * dAxDispDot / dOrtDispLen ; + double dMyLength = dObCoef * dRad / sqrt( 1 + dObCoef * dObCoef) ; + if ( abs( dDispLen * dAxDispDot) < 2 * EPS_SMALL && dMyLength < 2 * EPS_SMALL) { + Point3d ptMyE = ptS + dOrtDispLen * vtOrtDispVers ; + nIntNum = IntersLineCatTongue( ptC, Z_AX, ( bOuterCutter ? ptS : ptMyE) - dHei * vtAx, ( bOuterCutter ? ptMyE : ptS) - dHei * vtAx, + vtAx, dBaseRad, ptInt1, vtN1) ; + if ( nIntNum == 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + } + } + // Intersezione con cilindro ellittico se il movimento � generico + else { + nIntNum = IntersLineCircSweptSurfCuttedByPlanes( ptC, Z_AX, ptS - dHei * vtAx, vtAx, dBaseRad, vtDisp, bOuterCutter == dAxDispDot > 0, + vEllipCylCutPlanesVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + } + + // Intersezione con cilindro esterno + nIntNum = IntersLineCylinderCuttedByPlanes( ptC, Z_AX, ptE, - vtDispVers, dRad, dDispLen, false, + vCylCutPlanesVec, ptInt1, vtN1, ptInt2, vtN2) ; + if ( nIntNum >= 1) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt1.z ; + vParAndNormIntersVec.back().second = vtN1 ; + if ( nIntNum == 2) { + vParAndNormIntersVec.emplace_back() ; + vParAndNormIntersVec.back().first = ptInt2.z ; + vParAndNormIntersVec.back().second = vtN2 ; + } + } + + // Filtro le intersezioni trovate. + DexelSurfIntersVector vFilteredIntersVec ; + IntersectionsFilter( Z_AX, vParAndNormIntersVec, vFilteredIntersVec) ; + + // Sottraggo gli intervalli. + for ( int n = 0 ; n < int( vFilteredIntersVec.size()) ; n += 2) { + SubtractIntervals( nGrid, i, j, vFilteredIntersVec[n].first, vFilteredIntersVec[n+1].first, + vFilteredIntersVec[n].second, vFilteredIntersVec[n+1].second) ; + } + } + } + } + + return true ; +} + +// ------------------------- Utensili additivi --------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::AddingMotion( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtAx/*, double dHei, double dRad, double dCornerRad*/) +{ + // Dimensioni lineari dell'utensile + double dHei = m_vTool[m_nCurrTool].GetHeigth() ; + double dRad = m_vTool[m_nCurrTool].GetRadius() ; + double dCornerRad = m_vTool[m_nCurrTool].GetCornRadius() ; + + // Verifica sull'interferenza utensile Zmap + int nStartI, nStartJ, nEndI, nEndJ ; + if ( ! TestCompoBBox( nGrid, ptS, ptE, vtAx, dRad, dRad, dHei, nStartI, nStartJ, nEndI, nEndJ)) + return true ; + + Vector3d vtV1 = ptE - ptS ; + double dLen1 = vtV1.Len() ; + vtV1 / dLen1 ; + Vector3d vtV2 = Z_AX ^ vtV1 ; + + if ( dCornerRad < EPS_SMALL) { + + if ( nGrid == 0) { + + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Vector3d vtStC( ( i + 0.5) * m_dStep - ptS.x, ( j + 0.5) * m_dStep - ptS.y, 0) ; + Vector3d vtEnC = vtStC - dLen1 * vtV1 ; + + double dX1 = vtStC * vtV1 ; + double dX2 = vtStC * vtV2 ; + + if ( ( dX1 > 0 && dX1 < dLen1 && abs( dX2) < dRad) || + vtStC.SqLen() < dRad * dRad || + vtEnC.SqLen() < dRad * dRad) { + AddIntervals( nGrid, i, j, ptS.z - dHei, ptS.z, - Z_AX, Z_AX) ; + } + } + } + } + else { + Frame3d CylFrame, PolyFrame ; + CylFrame.Set( ptS - dHei * vtAx, vtAx) ; + PolyFrame.Set( ptS - dHei * vtAx, vtV1, vtAx ^ vtV1, vtAx) ; + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep - ptS.x, ( j + 0.5) * m_dStep - ptS.y, 0) ; + + Point3d ptInt1, ptInt2 ; + Vector3d vtN1, vtN2 ; + + if ( IntersLineCylinder( ptC, Z_AX, CylFrame, dHei, dRad, true, true, + ptInt1, vtN1, ptInt2, vtN2)) { + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, - vtN1, - vtN2) ; + } + + if ( IntersLineMyPolyhedron( ptC - dLen1 * vtV1, Z_AX, PolyFrame, dLen1, dRad, dHei, 0, + ptInt1, vtN1, ptInt2, vtN2)) { + AddIntervals( nGrid, i, j, ptInt1.z, ptInt2.z, - vtN1, - vtN2) ; + } + } + } + } + } + else { + ; + } + return true ; + + /* + if ( nGrid == 0) { + + Vector3d vtV1 = ptE - ptS ; + double dLen1 = vtV1.Len() ; + vtV1 / dLen1 ; + Vector3d vtV2 = Z_AX ^ vtV1 ; + + double dSqareCornerRadProj = dCornerRad * dCornerRad - 0.25 * dHei * dHei ; + + if ( dSqareCornerRadProj > 0) { + double dCylRad = dRad - dCornerRad + sqrt( dSquareCornerRadProj) ; + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Vector3d vtStC( ( i + 0.5) * m_dStep - ptS.x, ( j + 0.5) * m_dStep - ptS.y, 0) ; + Vector3d vtEnC = vtStC - dLen1 * vtV1 ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + if ( ( dX1 > 0 && dX1 < dLen1 && abs( dX2) < dCylRad) || + vtStC.SqLen() < dCylRad * dCylRad || + vtEnC.SqLen() < dCylRad * dCylRad) { + AddIntervals( nGrid, i, j, ptS.z - dHei, ptS.z, Z_AX, - Z_AX) ; + } + else if ( dX1 > 0 && dX1 < dLen1 && abs( dX2) < dRad) { + double dr = dCornerRad - ( dRad - abs( dX2)) ; + double dDeltaH = sqrt( max( dCornerRad * dCornerRad - dr * dr, 0)) ; + Vector3d vtMinN = ( dX2 > 0 ? - dr : dr) * vtV2 + Vector3d( 0, 0, dDeltaH) ; + Vector3d vtMaxN = ( dX2 > 0 ? - dr : dr) * vtV2 - Vector3d( 0, 0, dDeltaH) ; + vtMinN.Normalize() ; + vtMaxN.Normalize() ; + AddIntervals( nGrid, i, j, ptS.z - 0.5 * dHei - dDeltaH, ptS.z - 0.5 * dHei + dDeltaH, vtMinN, vtMaxN) ; + } + else if ( vtStC.SqLen() < dRad * dRad || vtEnC.SqLen() < dRad * dRad) { + Vector3d vtR = dX1 > 0 ? vtEnC : vtStC ; + double dLenR = vtR.Len() ; + vtR /= dLenR ; + double dr = dCornerRad - ( dRad - dLenR) ; + double dDeltaH = sqrt( max( dCornerRad * dCornerRad - dr * dr, 0)) ; + Vector3d vtMinN = - dr * vtR + Vector3d( 0, 0, dDeltaH) ; + Vector3d vtMaxN = - dr * vtR - Vector3d( 0, 0, dDeltaH) ; + vtMinN.Normalize() ; + vtMaxN.Normalize() ; + AddIntervals( nGrid, i, j, ptS.z - 0.5 * dHei - dDeltaH, ptS.z - 0.5 * dHei + dDeltaH, vtMinN, vtMaxN) ; + } + } + } + } + else { + double dCylRad = dRad - dCornerRad ; + // Ciclo sui punti + for ( int i = nStartI ; i <= nEndI ; ++ i) { + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + + Vector3d vtStC( ( i + 0.5) * m_dStep - ptS.x, ( j + 0.5) * m_dStep - ptS.y, 0) ; + Vector3d vtEnC = vtStC - dLen1 * vtV1 ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + if ( ( dX1 > 0 && dX1 < dLen1 && abs( dX2) < dCylRad) || + vtStC.SqLen() < dCylRad * dCylRad || + vtEnC.SqLen() < dCylRad * dCylRad) { + AddIntervals( nGrid, i, j, ptS.z - dHei, ptS.z, Z_AX, - Z_AX) ; + } + else if ( dX1 > 0 && dX1 < dLen1 && abs( dX2) < dRad) { + double dr = abs( dX2) - dCylRad ; + double dDeltaH = sqrt( max( dCornerRad * dCornerRad - dr * dr, 0)) ; + Vector3d vtMinN = ( dX2 > 0 ? - dr : dr) * vtV2 + Vector3d( 0, 0, dDeltaH) ; + Vector3d vtMaxN = ( dX2 > 0 ? - dr : dr) * vtV2 - Vector3d( 0, 0, dDeltaH) ; + vtMinN.Normalize() ; + vtMaxN.Normalize() ; + AddIntervals( nGrid, i, j, ptS.z - dHei + dCornerRad - dDeltaH, ptS.z - dCornerRad + dDeltaH, vtMinN, vtMaxN) ; + } + else if ( vtStC.SqLen() < dRad * dRad || vtEnC.SqLen() < dRad * dRad) { + Vector3d vtR = dX1 > 0 ? vtEnC : vtStC ; + double dLenR = vtR.Len() ; + vtR /= dLenR ; + double dr = dLenR - dCylRad) ; + double dDeltaH = sqrt( max( dCornerRad * dCornerRad - dr * dr, 0)) ; + Vector3d vtMinN = - dr * vtR + Vector3d( 0, 0, dDeltaH) ; + Vector3d vtMaxN = - dr * vtR - Vector3d( 0, 0, dDeltaH) ; + vtMinN.Normalize() ; + vtMaxN.Normalize() ; + AddIntervals( nGrid, i, j, ptS.z - dHei + dCornerRad - dDeltaH, ptS.z - dCornerRad + dDeltaH, vtMinN, vtMaxN) ; + } + } + } + } + } + else { + ; + } + */ +} + // ------------------------- BOUNDING BOX -------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -4693,7 +8010,7 @@ inline bool VolZmap::TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV, int& nStI, int& nStJ, int& nEnI, int& nEnJ) { - return TestCompoBBox( nGrid, ptP1, ptP2, vtV, m_Tool.GetRadius(), m_Tool.GetTipRadius(), m_Tool.GetHeigth(), + return TestCompoBBox( nGrid, ptP1, ptP2, vtV, m_vTool[m_nCurrTool].GetRadius(), m_vTool[m_nCurrTool].GetTipRadius(), m_vTool[m_nCurrTool].GetHeigth(), nStI, nStJ, nEnI, nEnJ) ; } @@ -4705,7 +8022,7 @@ VolZmap::TestCompoBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, con { // I punti e i vettori devono essere nel sistema di riferimento opportuno - // Controllo sull'ammissibilità del numero di griglia + // Controllo sull'ammissibilit� del numero di griglia if ( nGrid < 0 || nGrid > 2) return false ; @@ -4744,7 +8061,7 @@ VolZmap::TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const double dSemiDiag = sqrt( dLenX * dLenX + dLenY * dLenY) / 2 ; - // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + // Determinazione dei limiti del pi� piccolo parallelepipedo contenente il movimento double dMinX = min( min( ptS.x, ptSTip.x), min( ptE.x, ptETip.x)) - dSemiDiag ; double dMinY = min( min( ptS.y, ptSTip.y), min( ptE.y, ptETip.y)) - dSemiDiag ; double dMinZ = min( min( ptS.z, ptSTip.z), min( ptE.z, ptETip.z)) - dSemiDiag ;