From b79e9059093b33ebed9be9f7ceed1bbe4452a53a Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Thu, 27 Oct 2016 06:23:36 +0000 Subject: [PATCH] EgtGeomKernel 1.6v5 : - inseriti aggiornamenti per Zmap. --- EgtGeomKernel.rc | Bin 11718 -> 11718 bytes GdbExecutor.cpp | 94 +- GdbExecutor.h | 2 + VolZmap.cpp | 11431 ++++++++++++++++++++++++++++++++++----------- VolZmap.h | 215 +- 5 files changed, 9094 insertions(+), 2648 deletions(-) diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index b030fc09685fa30964c6a3af98a557a5218a451c..60c58e691f1ad7a1a3995f11d1ad44bb17950bc9 100644 GIT binary patch delta 110 zcmX>WeJpyzA2vqQ&G-4vGfl1&(wY2&Q;pGdvZAo=W*@FeEMOU1X1ItOWeJpyzA2vp#&G-4vGfl1&(wY2&Q;pGRvZAo=W*@FeEMOU1X1ItOGetGeoObj( nIdZmap)) ; if ( pZmap == nullptr) return false ; // eseguo la lavorazione + pZmap->SetTolerances( dLinTol, dAngTolDeg) ; return pZmap->MillingStep( ptPs, ptPe, vtDs, vtDe) ; } @@ -2802,6 +2816,82 @@ GdbExecutor::VolZmapSetStdTool( const STRVECTOR& vsParams) return pZmap->SetStdTool( sToolName, nToolType, dH, dTH, dR, dTR, dRc) ; } +//---------------------------------------------------------------------------- +bool GdbExecutor::VolZmapDeepnessMeasure( const STRVECTOR& vsParams) { + + // parametri : ZmapId, frRef, ptP, vtV + if ( vsParams.size() != 4) + return false ; + // recupero lo Zmap + int nZmapId = GetIdParam( vsParams[0]) ; + VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ; + if ( pZmap == nullptr) + return false ; + // recupero il riferimento in cui è immerso lo Zmap + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero punto iniziale + Point3d ptP ; + if ( ! GetPointParam( vsParams[2], frRef, ptP)) + return false ; + // recupero il vettore direzione + Vector3d vtDir ; + if ( ! GetVectorParam( vsParams[3], frRef, vtDir)) + return false ; + + double dIn, dOut ; + + pZmap -> Deepness( ptP, vtDir, dIn, dOut) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams) +{ + // parametri : ZmapId, frRef, BBoxOrig, vtV1, vtV2, ptEnd + if ( vsParams.size() != 6) + return false ; + // recupero lo Zmap + int nZmapId = GetIdParam( vsParams[0]) ; + VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ; + if ( pZmap == nullptr) + return false ; + // recupero il riferimento in cui è immerso lo Zmap + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // definisco il riferimento del bbox + Point3d pt0 ; + if ( ! GetPointParam( vsParams[2], frRef, pt0)) + return false ; + // primo vettore frBBoxFrame + Vector3d vtV1 ; + if ( ! GetVectorParam( vsParams[3], frRef, vtV1)) + return false ; + vtV1.Normalize() ; + // secondo vettore frBBoxFrame + Vector3d vtV2 ; + if ( ! GetVectorParam( vsParams[4], frRef, vtV2)) + return false ; + vtV2.Normalize() ; + // Determino il terzo vettore della terna destrorsa + Vector3d vtV3 = vtV1 ^ vtV2 ; + // Definisco il sistema di riferimento del BBox + Frame3d frBBoxFrame ; frBBoxFrame.Set( pt0, vtV1, vtV2, vtV3) ; + // recupero il punto estremo + Point3d ptEnd ; + if ( ! GetPointParam( vsParams[5], frBBoxFrame, ptEnd)) + return false ; + bool bInt ; + + bInt = pZmap -> BBoxZmapIntersection( frBBoxFrame, ptEnd) ; + + return true ; +} + //---------------------------------------------------------------------------- bool GdbExecutor::ExecuteText( const string& sCmd2, const STRVECTOR& vsParams) diff --git a/GdbExecutor.h b/GdbExecutor.h index 953e4cd..cd64363 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -120,6 +120,8 @@ class GdbExecutor : public IGdbExecutor bool VolZmapMilling( const STRVECTOR& vsParams) ; bool VolZmapSetTool( const STRVECTOR& vsParams) ; bool VolZmapSetStdTool( const STRVECTOR& vsParams) ; + bool VolZmapDeepnessMeasure( const STRVECTOR& vsParams) ; + bool VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams) ; bool ExecuteText( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool TextSimple( const STRVECTOR& vsParams) ; bool TextComplete( const STRVECTOR& vsParams) ; diff --git a/VolZmap.cpp b/VolZmap.cpp index 02fc1c3..4b37fca 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -1,8 +1,8 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2015 +// EgalTech 2015-2016 //---------------------------------------------------------------------------- // File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 -// Contenuto : Implementazione della classe Volume Zmap. +// Contenuto : Implementazione della classe Volume Zmap (singola griglia) // // // @@ -17,8 +17,10 @@ #include "GeoObjFactory.h" #include "NgeWriter.h" #include "NgeReader.h" +#include "GeoConst.h" #include "\EgtDev\Include\EGkIntervals.h" + using namespace std ; //---------------------------------------------------------------------------- @@ -26,7 +28,7 @@ GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ; //---------------------------------------------------------------------------- VolZmap::VolZmap(void) - : m_nStatus( TO_VERIFY), m_nTempProp() + : m_nStatus( TO_VERIFY), m_nTempProp(), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG) { m_dStep = 0 ; m_nNx = 0 ; @@ -390,10 +392,8 @@ bool VolZmap::SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) { unsigned int nPos ; - //unsigned int nKD ; - //unsigned int nKU ; - //unsigned int nDelta ; // Variazione di dimensione del vettore + // Controllo che dMin e dMax non siano quasi coincidenti if ( abs( dMax - dMin) < EPS_SMALL) @@ -470,7 +470,180 @@ VolZmap::SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, doubl i = i + 2 ; } - return true ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SubtractIntervals2( unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + + unsigned int nPos ; + + + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + + return true ; + // Controllo che dMin < dMax + + if ( dMax < dMin ) { + + double dTemp = dMax ; + + dMax = dMin ; + dMin = dTemp ; + } + + // Calcolo nPos + nPos = nJ * m_nNx2 + nI ; + + unsigned int i = 0 ; + + while ( i < m_ZValues2[nPos].size() - 1) { + + if ( m_ZValues2[nPos].size() == 0) + return true ; + // Casi: + // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione + if ( m_ZValues2[nPos][i] > dMax - EPS_SMALL) { + + } + // Intersezione + else if ( m_ZValues2[nPos][i + 1] > dMax + EPS_SMALL) { + // L'intervallo corrente corrente viene limitato a sinistra + if ( m_ZValues2[nPos][i] > dMin - EPS_SMALL) { + + m_ZValues2[nPos][i] = dMax ; + } + // L'intervallo si divide in due intervalli + else { + + m_ZValues2[nPos].resize( m_ZValues2[nPos].size() + 2) ; + + for ( size_t j = m_ZValues2[nPos].size() - 1 ; j >= i + 3 ; -- j) + + m_ZValues2[nPos][j] = m_ZValues2[nPos][j - 2] ; + + m_ZValues2[nPos][i + 1] = dMin ; + m_ZValues2[nPos][i + 2] = dMax ; + + i = i + 2 ; + } + } + else { + // L'intervallo corrente viene eliminato + if ( m_ZValues2[nPos][i] > dMin - EPS_SMALL) { + + for ( unsigned int j = i ; j < m_ZValues2[nPos].size() - 2 ; ++ j) + + m_ZValues2[nPos][j] = m_ZValues2[nPos][j + 2] ; + + m_ZValues2[nPos].resize( m_ZValues2[nPos].size() - 2) ; + + i = i - 2 ; + } + // L'intervallo corrente viene limitato a destra + else if ( m_ZValues2[nPos][i + 1] > dMin + EPS_SMALL) { + + m_ZValues2[nPos][i + 1] = dMin ; + } + // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione + else { + + } + } + + i = i + 2 ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SubtractIntervals3( unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + unsigned int nPos ; + + + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + + return true ; + // Controllo che dMin < dMax + + if ( dMax < dMin ) { + + double dTemp = dMax ; + + dMax = dMin ; + dMin = dTemp ; + } + + // Calcolo nPos + nPos = nJ * m_nNx3 + nI ; + + unsigned int i = 0 ; + + while ( i < m_ZValues3[nPos].size() - 1) { + + if ( m_ZValues3[nPos].size() == 0) + return true ; + // Casi: + // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione + if ( m_ZValues3[nPos][i] > dMax - EPS_SMALL) { + + } + // Intersezione + else if ( m_ZValues3[nPos][i + 1] > dMax + EPS_SMALL) { + // L'intervallo corrente corrente viene limitato a sinistra + if ( m_ZValues3[nPos][i] > dMin - EPS_SMALL) { + + m_ZValues3[nPos][i] = dMax ; + } + // L'intervallo si divide in due intervalli + else { + + m_ZValues3[nPos].resize( m_ZValues3[nPos].size() + 2) ; + + for ( size_t j = m_ZValues3[nPos].size() - 1 ; j >= i + 3 ; -- j) + + m_ZValues3[nPos][j] = m_ZValues3[nPos][j - 2] ; + + m_ZValues3[nPos][i + 1] = dMin ; + m_ZValues3[nPos][i + 2] = dMax ; + + i = i + 2 ; + } + } + else { + // L'intervallo corrente viene eliminato + if ( m_ZValues3[nPos][i] > dMin - EPS_SMALL) { + + for ( unsigned int j = i ; j < m_ZValues3[nPos].size() - 2 ; ++ j) + + m_ZValues3[nPos][j] = m_ZValues3[nPos][j + 2] ; + + m_ZValues3[nPos].resize( m_ZValues3[nPos].size() - 2) ; + + i = i - 2 ; + } + // L'intervallo corrente viene limitato a destra + else if ( m_ZValues3[nPos][i + 1] > dMin + EPS_SMALL) { + + m_ZValues3[nPos][i + 1] = dMin ; + } + // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione + else { + + } + } + + i = i + 2 ; + } + + return true ; } //---------------------------------------------------------------------------- @@ -514,9 +687,7 @@ bool VolZmap::AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) { unsigned int nPos ; - //unsigned int nKD ; - //unsigned int nKU ; - //unsigned int nDelta ; // Variazione di dimensione del vettore + // Controllo che dMin e dMax non siano quasi coincidenti if ( abs( dMax - dMin) < EPS_SMALL) @@ -881,7 +1052,16 @@ VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Poin //---------------------------------------------------------------------------- bool -VolZmap::SetTool( const string& pToolName, const CurveComposite* pToolOutline) +VolZmap::SetTolerances( double dLinTol, double dAngTolDeg) +{ + m_dLinTol = max( dLinTol, LIN_TOL_MIN) ; + m_dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SetTool( const string& pToolName, const ICurveComposite* pToolOutline) { m_sToolName = pToolName ; @@ -889,7 +1069,7 @@ VolZmap::SetTool( const string& pToolName, const CurveComposite* pToolOutline) m_ToolOutline.CopyFrom( pToolOutline) ; - // Dimensioni dell'utensile + // Dimensioni dell'utensile BBox3d Bounding ; m_ToolOutline.GetLocalBBox( Bounding) ; double m_dHeight = Bounding.GetMax().y - Bounding.GetMin().y ; @@ -930,31 +1110,58 @@ VolZmap::SetStdTool( const string& pToolName, unsigned int nToolType, double dH, } else if ( nToolType == BullNoseMill) { - if ( dR < dRc) - + if ( dR < dRc) + return false ; - m_dRCorner = dRc ; - m_dTipHeight = dRc ; - m_dTipRadius = dR - dRc ; - - if ( dRc < EPS_SMALL) { + else if ( dRc < EPS_SMALL) { m_dRCorner = 0 ; + m_dTipHeight = 0 ; + m_dTipRadius = m_dRadius ; m_nToolType = CylindricalMill ; } - - if ( dRc > dR - EPS_SMALL) { + else if ( dRc > dR - EPS_SMALL) { m_dRCorner = m_dRadius ; + m_dTipHeight = m_dRadius ; + m_dTipRadius = 0 ; m_nToolType = BallEndMill ; } + else { + + m_dRCorner = dRc ; + m_dTipHeight = dRc ; + m_dTipRadius = dR - dRc ; + + Point3d pt0( 0, 0, 0) ; + Point3d pt1( m_dRadius, 0, 0) ; + Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; + Point3d pt3( m_dTipRadius, - m_dHeight, 0) ; + Point3d pt4( 0, - m_dHeight, 0) ; + Point3d ptO( m_dTipRadius, - m_dHeight + m_dTipHeight, 0) ; + + CurveLine cvC1, cvC2, cvC4 ; + CurveArc cvC3 ; + + cvC1.Set( pt0, pt1) ; + cvC2.Set( pt1, pt2) ; + cvC3.SetC2P( ptO, pt2, pt3) ; + cvC4.Set( pt3, pt4) ; + + m_ToolOutline.Clear() ; + + m_ToolOutline.AddCurve( cvC1) ; + m_ToolOutline.AddCurve( cvC2) ; + m_ToolOutline.AddCurve( cvC3) ; + m_ToolOutline.AddCurve( cvC4) ; + + m_nToolType = GenericTool ; + } } else if ( nToolType == ConusMill) { - if ( dTH < 0 || dTR < 0) - - return false ; + if ( dTH < 0 || dTR < 0) return false ; if ( abs( dR - dTR) < EPS_SMALL) { @@ -975,10 +1182,16 @@ VolZmap::SetStdTool( const string& pToolName, unsigned int nToolType, double dH, //---------------------------------------------------------------------------- bool -VolZmap::MillingStep( const Point3d& ptPs, const Point3d& ptPe, Vector3d& vtDs, Vector3d& vtDe) +VolZmap::MillingStep( const Point3d& ptPs, const Point3d& ptPe, Vector3d& vtDs, Vector3d& vtDe) { - - // Porto i dati del movimento nel riferimento intrinseco + + // Controllo sull'effettiva esisenza del movimento + if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe)) + return true ; + + // Porto i dati del movimento nel riferimento intrinseco; quest'oprazione è necessaria perché + // viene chiamata la funzione di sottrazione che accetta come parametri gli indici, + // non quella che chiede il punto, nella quale viene eseguita la trasformazione di coordinate. Point3d ptLs = ptPs ; ptLs.ToLoc( m_LocalFrame) ; Point3d ptLe = ptPe ; @@ -988,80 +1201,165 @@ VolZmap::MillingStep( const Point3d& ptPs, const Point3d& ptPe, Vector3d& vtDs, Vector3d vtLe = vtDe ; vtLe.ToLoc( m_LocalFrame) ; - if ( AreSamePointApprox( ptLs, ptLe) && AreSameVectorApprox( vtLs, vtLe)) - return true ; // Normalizzo i vettori vtLs.Normalize() ; vtLe.Normalize() ; // Direzione utensile costante - if ( AreSameVectorApprox( vtLs, vtLe)) { - // Versori della direzione utensile paralleli/ antiparalleli a Z - if ( vtLs.IsZplus() || vtLs.IsZminus()) { + if ( AreSameVectorApprox( vtLs, vtLe)) { + + // Versori della direzione utensile diretti come Z + if ( vtLs.LenXY() < EPS_SMALL) { + // Movimento diretto come direzione utensile if ( AreSamePointXYApprox( ptLs, ptLe)) - return MillingDrillZ( ptLs, ptLe, vtLs) ; + + if ( m_nToolType == GenericTool) + + return DrillZ( ptLs, ptLe, vtLs, m_dLinTol, m_dAngTolDeg) ; + else + return DrillingZ( ptLs, ptLe, vtLs) ; + // Movimento perpendicolare a direzione utensile - else if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) - return MillingPerpZ( ptLs, ptLe, vtLs) ; + if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) + + if ( m_nToolType == 0) + + return MillZ( ptLs, ptLe, vtLs, m_dLinTol, m_dAngTolDeg) ; + else + return MillingPerpZ( ptLs, ptLe, vtLs) ; + // Movimento generico - else + if ( m_nToolType == 0) + + return MillZ( ptLs, ptLe, vtLs, m_dLinTol, m_dAngTolDeg) ; + else return MillingZ( ptLs, ptLe, vtLs) ; } - // Versori della direzione utensile perpendicolari all'asse Z + // Versori della direzione utensile nel piano XY else if ( abs(vtLs * Z_AX) < EPS_SMALL) { + + Vector3d vtDir( vtLs.x, vtLs.y, 0) ; vtDir.Normalize() ; + // Movimento con Z costante (con vettore movimento parallelo od ortogonale al versore dell'utensile) if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) { + + Vector3d vtTest( ptLe.x - ptLs.x, ptLe.y - ptLs.y, 0) ; + Vector3d vtTLong = ( vtTest * vtDir) * vtDir ; + Vector3d vtTOrt = vtTest - vtTLong ; + // Movimento parallelo alla direzione dell'utensile (foratura) - Vector3d vtTest = ptLe - ptLs ; vtTest.Normalize() ; - if ( abs( ( vtTest * vtLs) - 1) < EPS_SMALL) - return MillingDrillXY( ptLs, ptLe, vtLs) ; + if ( vtTOrt.SqLen() < EPS_SMALL * EPS_SMALL) + + if ( m_nToolType == 0) + + return DrillingGT( ptLs, ptLe, vtDir, m_dLinTol, m_dAngTolDeg) ; + else + return DrillingXY( ptLs, ptLe, vtDir) ; + // Movimento perpendicolare alla direzione dell'utensile - else if ( abs( (ptLe - ptLs) * vtLs) < EPS_SMALL) - return MillingPerpXY( ptLs, ptLe, vtLs) ; + if ( vtTLong.SqLen() < EPS_SMALL * EPS_SMALL) + + if ( m_nToolType == GenericTool) + + return MillingGT( ptLs, ptLe, vtDir, m_dLinTol, m_dAngTolDeg) ; + else + return MillingPerpXY( ptLs, ptLe, vtDir) ; + // Movimento nel piano generico + if ( m_nToolType == GenericTool) + + return MillingGT( ptLs, ptLe, vtDir, m_dLinTol, m_dAngTolDeg) ; else - return MillingXYPlaneGen( ptLs, ptLe, vtLs) ; + return MillingXYPlaneGen( ptLs, ptLe, vtDir) ; } // Movimento con Z non costante else { + + if ( m_nToolType == GenericTool) + + return MillingGT( ptLs, ptLe, vtDir, m_dLinTol, m_dAngTolDeg) ; + + + double dSqDistXY = ( ptLe.x - ptLs.x) * ( ptLe.x - ptLs.x) + ( ptLe.y - ptLs.y) * ( ptLe.y - ptLs.y) ; + + // Movimento verticale + if ( dSqDistXY < EPS_SMALL * EPS_SMALL) + + return MillingXYVert( ptLs, ptLe, vtDir) ; + // Grandezze geometriche per selezione Vector3d vtMove = ptLe - ptLs ; - Vector3d vtTest = vtMove - ( vtMove * vtLs) * vtLs ; + Vector3d vtTLong = ( vtMove * vtDir) * vtDir ; + Vector3d vtTOrt = vtMove - vtTLong ; - if ( abs( vtTest * X_AX) < EPS_SMALL && abs( vtTest * Y_AX) < EPS_SMALL) - return MillingXYLongVert( ptLs, ptLe, vtLs) ; - else { - if ( abs( vtMove * vtLs) < EPS_SMALL) { - if ( m_nToolType == 1) - return MillingXYCyl( ptLs, ptLe, vtLs) ; - else if ( m_nToolType == 2) - return MillingXYBall( ptLs, ptLe, vtLs) ; - } - else { - if ( m_nToolType ==1) - return MillingXYPlusCyl( ptLs, ptLe, vtLs) ; - else if ( m_nToolType == 2) - return MillingXYPlusBall( ptLs, ptLe, vtLs) ; - } - } + // Movimento LongVert + if ( vtTOrt.SqLenXY() < EPS_SMALL * EPS_SMALL) + return MillingXYLongVert( ptLs, ptLe, vtDir) ; + + // Movimento perpendicolare alla direzione dell'utensile + if ( vtTLong.SqLenXY() < EPS_SMALL * EPS_SMALL) + return MillingXY( ptLs, ptLe, vtDir) ; + + // Movimento generico con versore direzione nel piano + return Milling( ptLs, ptLe, vtDir) ;//MillingXYPlus( ptLs, ptLe, vtDir) ; } } + else { + + Vector3d vtMove = ptLe - ptLs ; + Vector3d vtLong = ( vtMove * vtLs) * vtLs ; + Vector3d vtOrt = vtMove - vtLong ; + + // Drilling + if ( vtOrt.SqLen() < EPS_SMALL * EPS_SMALL) + + if ( m_nToolType == GenericTool) + + return DrillingGT( ptLs, ptLe, vtLs, m_dLinTol, m_dAngTolDeg) ; + else + return Drilling( ptLs, ptLe, vtLs) ; + + // Milling + else + + if ( m_nToolType == GenericTool) + + return MillingGT( ptLs, ptLe, vtLs, m_dLinTol, m_dAngTolDeg) ; + else + return Milling( ptLs, ptLe, vtLs) ; + } } // Altri casi, non gestiti return false ; } - -// Frese: cylindrical, ball-end e bull-nose ////////////////////////////////// + // Versore utensile parallelo all'asse Z //---------------------------------------------------------------------------- -bool -VolZmap::MillingDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) +bool +VolZmap::DrillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - if ( m_nToolType == 4) + + if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill || + m_nToolType == BullNoseMill) + + return CBTDrillZ( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == ConusMill) + return ConusDrillingZ( ptLs, ptLe, vtToolDir) ; + else + + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CBTDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) +{ + // Bounding box double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; @@ -1107,2543 +1405,6 @@ VolZmap::MillingDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d return true ; } -//---------------------------------------------------------------------------- -bool -VolZmap::MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - if ( m_nToolType == 4) - return ConusPerpZ( ptLs, ptLe, vtToolDir) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; - double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; - double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ; - double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ; - - // Verifico interferisca con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Determino i limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Determino quote estreme del tagliente - double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale - double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente - - // Limite sul quadrato del raggio - double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ; - - // Segmento di movimento (nel piano griglia) - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Point3d ptEnd( ptLe.x, ptLe.y, 0) ; - double dLen ; - Vector3d vtDir ; - DirDist( ptStart, ptEnd, vtDir, dLen) ; - - // Ciclo sui punti nei limiti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - double dX = ( i + 0.5) * m_dStep ; - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - double dY = ( j + 0.5) * m_dStep ; - // punto - Point3d ptQ( dX, dY, 0) ; - // determino il quadrato della distanza del punto dal segmento - double dProiez = vtDir * ( ptQ - ptStart) ; - if ( dProiez < 0) - dProiez = 0 ; - else if ( dProiez > dLen) - dProiez = dLen ; - Point3d ptMinDist = ptStart + vtDir * dProiez ; - double dSqDist = SqDistXY( ptQ, ptMinDist) ; - // se distanza nei limiti, taglio - if ( dSqDist < dSqRad) - GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - if ( m_nToolType == 4) - if ( m_dRadius > m_dTipRadius) - return ConusMillingZDr( ptLs, ptLe, vtToolDir) ; - else - return ConusMillingZSw( ptLs, ptLe, vtToolDir) ; - - // Setto il fattore per l'orientazione in z - double dFactor = ( vtToolDir.z < 0 ? 1 : - 1) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; - double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ; - double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; - double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ; - double dMinZ = min( min( ptLs.z, ptLs.z + dFactor * m_dHeight), min( ptLe.z, ptLe.z + dFactor * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z + dFactor * m_dHeight), max( ptLe.z, ptLe.z + dFactor * m_dHeight)) ; - - // Verifico interferisca con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - // Determino i limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - // - double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale - double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente - - // Limite sul quadrato del raggio - double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ; - - // Segmento di movimento (nel piano griglia) - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Point3d ptEnd( ptLe.x, ptLe.y, 0) ; - double dLen ; - Vector3d vtDir ; - DirDist( ptStart, ptEnd, vtDir, dLen) ; - - // Ciclo sui punti nei limiti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - double dX = ( i + 0.5) * m_dStep ; - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - double dY = ( j + 0.5) * m_dStep ; - // punto - Point3d ptQ( dX, dY, 0) ; - // determino il quadrato della distanza del punto dal segmento - double dProj = vtDir * ( ptQ - ptStart) ; - double dProiez ; - - if ( dProj < 0) - dProiez = 0 ; - else if ( dProj < dLen) - dProiez = dProj ; - else - dProiez = dLen ; - - Point3d ptMinDist = ptStart + vtDir * dProiez ; - double dSqDist = SqDistXY( ptQ, ptMinDist) ; - - // se distanza nei limiti, taglio - if ( dSqDist < dSqRad) - GetMinMaxZGen( i, j, dProj, dSqDist, dLen, dZCutBase, dDeltaZ, vtToolDir) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxZ( unsigned int nI, unsigned int nJ, double dZCutBase, double dDeltaZ, double dSqDist, const Vector3d& vtToolDir) { - - // Definisco variabili - double dSqRad = m_dRadius * m_dRadius ; - double dFactor = ( vtToolDir.z < 0 ? - 1 : 1) ; - double dZtip = ( vtToolDir.z < 0 ? dZCutBase + m_dHeight : dZCutBase - m_dHeight) ; - - double dMin ; double dMax ; - - // Caso utensile generico al momento non gestito - if ( m_nToolType == 0) - - return false; - // Caso Cylindrical Mill - else if ( m_nToolType == 1) { - - if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { // Non è meglio fare if (vt * delta < - Eps_small ) else if ( vt * delta < Eps) else ? - dMin = min(dZCutBase, dZtip) ; - dMax = max(dZCutBase, dZtip) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min(dZtip, dZtip + dDeltaZ) ; - dMax = max(dZtip, dZtip + dDeltaZ) ; - } - else { - dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - // Caso Ball-End Mill - else if ( m_nToolType == 2) { - - if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min(dZCutBase, dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist))) ; - dMax = max(dZCutBase, dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist))) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min(dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)), dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)) + dDeltaZ) ;// ocio - dMax = max(dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)), dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)) + dDeltaZ) ;// ocio - } - else { - dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - // Caso Bull-Nose Mill - else if ( m_nToolType == 3) { - - double dDeltaR = m_dRadius - m_dRCorner ; - - if ( dSqDist < dDeltaR*dDeltaR) { - - if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min(dZCutBase, dZtip) ; - dMax = max(dZCutBase, dZtip) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min(dZtip, dZtip + dDeltaZ) ; - dMax = max(dZtip, dZtip + dDeltaZ) ; - } - else { - dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - else { - - double dSqRadC = m_dRCorner*m_dRCorner ; - double dSqd = dSqDist + dDeltaR*dDeltaR - 2*sqrt(dSqDist)*dDeltaR ; - - if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min(dZCutBase, dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd))) ; - dMax = max(dZCutBase, dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd))) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min(dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)), dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)) + dDeltaZ) ; - dMax = max(dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)), dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)) + dDeltaZ) ; - } - else { - dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - } - // Caso di utensile inesistente ( m_nToolType fuori dai valori concessi) - else - return false ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxZGen( unsigned int nI, unsigned int nJ, double dProj, double dSqd, double dLenPath, double dZheight, double dDelta, const Vector3d& vtToolDir) { - - // Controllo sul tipo di utensile: se 0 utensile generico (al momento non gestito) se maggiore di 3 utensile fuori dai tipi consentiti - if ( m_nToolType == 0 || m_nToolType > 3) - return false ; - - // Definisco variabili quota della punta, minimo e massimo dell'intervallo da sottrarre - double dZTip = ( vtToolDir.z < 0 ? dZheight + m_dHeight : dZheight - m_dHeight) ; - double dMin, dMax ; double dStart ; // dStart è un parametro che esprime l'ascissa in cui la retta congiungente le due posizioni iniziale e finale - double dRSqDist1, dRSqDist2 ; // di un punto del tagliente (nel sistema dell'asse dell'utensile nella posizione iniziale) assume la quota dZheight - - // Nei conti è comodo che dSqd assuma sempre il significato di distanza del punto dall'asse del movimento al quadrato - if ( dProj < 0) - dSqd = dSqd - dProj * dProj ; - else if ( dProj > dLenPath) - dSqd = dSqd - ( dProj - dLenPath) * ( dProj - dLenPath) ; - - // Caso di cylindrical mill - if ( m_nToolType == 1) { - - double dZ1, dZ2 ; - // Se lavora la punta - if ( vtToolDir.z * dDelta < 0) { - dZ1 = dZTip ; - dZ2 = dZheight ; - } - // Se lavora il fondo - else { - dZ1 = dZheight ; - dZ2 = dZTip ; - } - - dStart = sqrt( m_dRadius * m_dRadius - dSqd) ; - dRSqDist1 = dProj * dProj + dSqd ; - dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ; - - if ( dRSqDist1 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) { - - dMin = min( max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ; - dMax = max( min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ; - } - else if ( dRSqDist2 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) { - - dMin = min( min(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ; - dMax = max( max(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ; - } - else { - - dMin = min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ; - dMax = max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ; - } - } - // Caso di ball-end mill - else if ( m_nToolType == 2) { - - if ( dDelta < 0) { - - dDelta = - dDelta ; - dProj = dLenPath - dProj ; - dZheight = dZheight - dDelta ; - dZTip = dZTip - dDelta ; - } - - dStart = sqrt( m_dRadius * m_dRadius - dSqd) ; - dRSqDist1 = dProj * dProj + dSqd ; - dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ; - - if ( vtToolDir.z > 0) { - - // Semi-asse ellisse - double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ; - - if ( dRSqDist2 < m_dRadius * m_dRadius) { - - dMax = dZheight + dDelta ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj - dLenPath > dSemiAxMin * dTest) { - - double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMin = dZTip + m_dRadius + dDelta - dH ; - } - else if ( dProj > dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ; - - dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ; - } - else { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMin = dZTip + m_dRadius - dH ; - } - } - else { - - dMax = dZheight + ( dDelta * ( dProj + dStart)) / dLenPath ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj > dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ; - - dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ; - } - else { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - - dMin = dZTip + m_dRadius - dH ; - } - } - } - else { - - // Semi-asse ellisse - double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ; - - if ( dRSqDist1 < m_dRadius * m_dRadius) { - - dMin = dZheight ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj < - dSemiAxMin * dTest) { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - - dMax = dZTip - m_dRadius + dH ; - } - else if ( dProj - dLenPath < - dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( dPr0 * dPar) / dSemiAxMin ; - - dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ; - } - else { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMax = dZTip - m_dRadius + dDelta + dH ; - } - } - else { - - dMin = dZheight + ( dDelta * ( dProj - dStart)) / dLenPath ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj - dLenPath < - dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( dPr0 * dPar) / dSemiAxMin ; - - dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ; - } - else { - - double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMax = dZTip + dDelta - m_dRadius + dH ; - } - } - } - } - // Caso di bull-nose mill - else - return true ; - - return SubtractIntervals( nI, nJ, dMin, dMax) ; -} - -// Versore utensile nel piano XY -//---------------------------------------------------------------------------- -bool -VolZmap::MillingDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - // Punti per la determinazione del materiale asportato - Vector3d vtMove = ptLe - ptLs ; - // Punti di riferimento dell'asportazione - Point3d ptLNs ; - Point3d ptLNe ; - // Parametro relativo all'utensile altezza della parte non cilindrica e fattore determinante - // la lunghezza della parte lavorata a seconda che lavori la punta o il fondo - double dCylH ; double dFactor ; - - // Caso utensile generico (al momento non gestito) - if ( m_nToolType == 0) - return false ; - // Caso Cylindrical Mill - else if ( m_nToolType == 1) - dCylH = m_dHeight ; - // Caso Ball-end Mill - else if ( m_nToolType == 2) - dCylH = m_dHeight - m_dRadius ; - // Caso Bull-nose Mill - else if ( m_nToolType == 3) - dCylH = m_dHeight - m_dRCorner ; - - // Normalizzo tale vettore e ne determino la lunghezza: - double dLenPath = vtMove.Len() ; vtMove.Normalize() ; - - // Prodotto scalare fra versore direzione utensile e direzione movimento - double dScProd = vtMove * vtToolDir ; - // Se lavora la punta - if ( dScProd < 0) { - // Trovo i punti di riferimento per la lavorazione - ptLNs = ptLs + ( vtMove * dCylH) ; - ptLNe = ptLe + ( vtMove * dCylH) ; - dFactor = 1 ; - } - // Se lavora il fondo - else { - ptLNs = ptLs ; - ptLNe = ptLe ; - dFactor = 0 ; - } - - // Quota z dei punti iniziale e finale - double dHz = ptLNs.z ; - - // Bounding box - double dMinX = min( ptLNs.x, ptLNe.x) - m_dRadius ; - double dMaxX = max( ptLNs.x, ptLNe.x) + m_dRadius ; - double dMinY = min( ptLNs.y, ptLNe.y) - m_dRadius ; - double dMaxY = max( ptLNs.y, ptLNe.y) + m_dRadius ; - double dMinZ = dHz - m_dRadius ; - double dMaxZ = dHz + m_dRadius ; - - // Verifico se il movimento intersca lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - // Determino i limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - //Proietto ptLNs sul piano XY: - Point3d ptStart( ptLNs.x, ptLNs.y, 0) ; - - //Ciclo sui punti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - // Punto da valutare - Point3d ptC( (i + 0.5)*m_dStep, (j + 0.5)*m_dStep, 0) ; - // Vettore spostamento da ptLe a ptC - Vector3d vtC = ( ptC - ptStart) ; - // Componenti parallela e perpendicolare a vtMove - // Vettore ortogonale a vtMove - Vector3d vtOrt = vtMove ; - // Ruoto vtOrt affinché sia ortogonale - vtOrt.Rotate( Z_AX, -90) ; - - double dProj = vtC * vtOrt ; - Vector3d vtPara = vtOrt * dProj ; // Parallelo alla perpendicolare al movimento - Vector3d vtPerp = vtC - vtPara ; // Perpendicolare alla perpendicolare al movimento ( serve per unire le getminmax di drill e perp) - // Distanza di ptC dall'asse dell'untensile - double dSqDist = vtPerp.SqLen() ; - double dLimitMill = dLenPath + dFactor * ( m_dHeight - dCylH) ; - // Se dTestProj è positivo è vtC è dalla parte giusta - double dTestProj = vtC * vtMove ; - - if ( dTestProj > 0 && dSqDist < dLimitMill * dLimitMill) - if ( dProj > - m_dRadius && dProj < m_dRadius) - GetMinMaxXY( i, j, dProj, dHz, dSqDist, 0, dLenPath, dScProd) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - // Determinazione delle posizioni iniziali e finali della punta dell'utensile - Point3d ptTLs = ptLs - vtToolDir * m_dHeight ; - Point3d ptTLe = ptLe - vtToolDir * m_dHeight ; - - // Quota Z - double dZH = ptLs.z ; - - // Estremi Bounding box - double dMinX = min( min( ptLs.x, ptLe.x), min( ptTLs.x, ptTLe.x)) - m_dRadius ; - double dMaxX = max( max( ptLs.x, ptLe.x), max( ptTLs.x, ptTLe.x)) + m_dRadius ; - double dMinY = min( min( ptLs.y, ptLe.y), min( ptTLs.y, ptTLe.y)) - m_dRadius ; - double dMaxY = max( max( ptLs.y, ptLe.y), max( ptTLs.y, ptTLe.y)) + m_dRadius ; - double dMinZ = dZH - m_dRadius ; - double dMaxZ = dZH + m_dRadius ; - - // Verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Proiezione sul piano XY delle grandezze di interesse - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Point3d ptEnd( ptLe.x, ptLe.y, 0) ; - Vector3d vtMove = ptEnd - ptStart ; - double dLenPath = vtMove.Len() ; - // Normalizzo il vettore vtMove congiungente le posizioni iniziale e finale della base dell'utensile - vtMove.Normalize() ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - // Punto su cui ciclare e vettore congiungente posizione iniziale della base a tale punto - Point3d ptC( (i + 0.5) * m_dStep, (j + 0.5) * m_dStep, 0) ; - Vector3d vtC = ptC - ptStart ; - // Proiezione di vtC sulla direzione del movimento - double dProj = vtC * vtMove ; - // Componente di vtC ortogonale al movimento - Vector3d vtPerp = vtC - vtMove * dProj ; - // Lunghezza quadrata del precedente vettore - double dSqDist = vtPerp.SqLen() ; - - if ( dProj > - m_dRadius && dProj < dLenPath + m_dRadius && vtPerp * vtToolDir < 0 && dSqDist < m_dHeight * m_dHeight) - GetMinMaxXY( i, j, dProj, dZH, dSqDist, dLenPath, 0, 0) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI = ptLs ; Point3d ptF = ptLe ; - - // Quote dei punti ptI e ptF - double dZ = ptI.z ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - Vector3d vtMove = ptF - ptI ; - - if ( vtMove * vtToolDir > 0) { - Point3d ptTemp = ptI ; - ptI = ptF ; - ptF = ptTemp ; - vtMove = - vtMove ; - } - - Vector3d vtMoveOrt = vtMove - ( vtMove * vtToolDir) * vtToolDir ; double dLen2 = vtMoveOrt.Len() ; - Vector3d vtMoveLong = ( vtMove * vtToolDir) * vtToolDir ; double dLen1 = vtMoveLong.Len() ; - - // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; - - // Punti iniziale e finale proiettati sul piano - Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - if ( m_nToolType == 1) { - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; - double dProj2 = vtC * vtV2 ; - - GetMMPlaneGenCyl( i, j, dZ, dLen1, dLen2, dProj1, dProj2) ; - } - else if ( m_nToolType == 2) - - GetMMPlaneGenBall( i, j, dZ, dLen1, dLen2, ptIxy, vtMove, vtV1, vtV2) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMMPlaneGenCyl( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, double dProj1, double dProj2) { - - double dMin, dMax ; - - if ( dProj2 > - m_dRadius && dProj2 < 0) { - - if ( dProj1 < 0 && dProj1 > - m_dHeight) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 <= - m_dHeight) { - - if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - m_dHeight - ( dLen1 / dLen2) * ( dProj2 + m_dRadius)) - || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // In questo costrutto if-else non c'è bisogno di specificare nient'altro perché già siamo nella regione - m_dRadius < dProj2 < 0 - - double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; - double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( dProj2 >= 0 && dProj2 < m_dRadius) { - - if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - /* Oppure - double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ; - double dPar2 = ( dLen2 / dLen1) * dPar1 ; */ - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2) { - - if ( dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight) - || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // modificato qui - - double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; - double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( dProj2 >= dLen2 && dProj1 < - dLen1) { - - if ( dProj1 > - m_dHeight - dLen1) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dLen2) * ( dProj2 - dLen2)) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( dProj2 >= m_dRadius && dProj2 < dLen2) { - - if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 > - ( dLen1 / dLen2) * dProj2) { - - double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin , dMax) ; - } - else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight) - || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { - - double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; - double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) { - - if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 >= - dLen1) { - - double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 < - dLen1 && dProj1 > - dLen1 - m_dHeight) { - - double dL = dProj2 - dLen2 ; - double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMMPlaneGenBall( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, Point3d ptIxy, Vector3d vtMove, Vector3d vtV1, Vector3d vtV2) { - - double dMin, dMax ; - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; // vtV1, vtV2 sono paralleli al piano - double dProj2 = vtC * vtV2 ; - - double dCH = m_dHeight - m_dRadius ; - double dLMove = vtMove.LenXY() ; - - Point3d ptCS = ptIxy - dCH * vtV1 ; Point3d ptCE = ptCS + vtMove ; // vtMove è orizzontale - - Vector3d vtCS = ptC - ptCS ; Vector3d vtCE = ptC - ptCE ; - - double dProjMove = ( vtCS * vtMove) / dLMove ; - - Vector3d vtCSP = vtCS - ( ( vtCS * vtMove) / ( dLMove * dLMove)) * vtMove ; - - double dSQDist = vtCSP.SqLenXY() ; - double dSQDistS = vtCS.SqLenXY() ; - double dSQDistE = vtCE.SqLenXY() ; - - // parte cilindrica - - if ( dProj2 > - m_dRadius && dProj2 < 0) { - - if ( dProj1 > - dCH && dProj1 < 0) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( dProj2 >= 0 && dProj2 < m_dRadius) { - - if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - /* Oppure - double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ; - double dPar2 = ( dLen2 / dLen1) * dPar1 ; */ - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 >= dLen2 && dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) { - - double dL = dProj2 - dLen2 ; - double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( dProj2 >= m_dRadius && dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius)) { - - if ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) { - - if ( dProj1 > - dLen1) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) { - - double dL = dProj2 - dLen2 ; - double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - // parte non cilindrica - - - if ( dProjMove > - m_dRadius && dProjMove < 0) { - - if ( dSQDistS < m_dRadius * m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dSQDistS) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( dProjMove >= 0 && dProjMove < dLMove) { - - if ( dSQDist < m_dRadius * m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dSQDist) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else { - - if ( dSQDistE < m_dRadius * m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dSQDistE) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - // Determino posizioni punte - Point3d ptTLs = ptLs - vtToolDir * m_dHeight ; - Point3d ptTLe = ptLe - vtToolDir * m_dHeight ; - - // Variabili utili - double dDelta = ptLe.z - ptLs.z ; double dMin, dMax ; - - // Bounding box - double dMinX = min( min( ptLs.x, ptLe.x), min( ptTLs.x, ptTLe.x)) - m_dRadius ; - double dMaxX = max( max( ptLs.x, ptLe.x), max( ptTLs.x, ptTLe.x)) + m_dRadius ; - double dMinY = min( min( ptLs.y, ptLe.y), min( ptTLs.y, ptTLe.y)) - m_dRadius ; - double dMaxY = max( max( ptLs.y, ptLe.y), max( ptTLs.y, ptTLe.y)) + m_dRadius ; - double dMinZ = min( ptLs.z, ptLs.z + dDelta) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLs.z + dDelta) + m_dRadius ; - - // Controllo su interferenza utensile-Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Definizione delle grandezze geometriche essenziali - Vector3d vtMove = ptLe - ptLs ; - Vector3d vtPlaneMove = ( vtMove * vtToolDir) * vtToolDir ; //( vtMove * vtToolDir < 0 ? ( - vtMove * vtToolDir) * vtToolDir : ( vtMove * vtToolDir) * vtToolDir) ; - Vector3d vtZMove = vtMove - vtPlaneMove ; - - double dLenPlanePath = sqrt( vtPlaneMove * vtPlaneMove) ; - - if ( m_nToolType == 1) { - - if ( abs ( ( vtMove * vtToolDir) * dDelta) < EPS_SMALL) { - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Vector3d vtC = ptC - ptStart ; - double dProj = vtC * vtToolDir ; - Vector3d vtP = vtC - dProj * vtToolDir ; - double dSqD = vtP * vtP ; - double dZH = ptLs.z ; - - if ( dSqD < m_dRadius * m_dRadius && dProj < 0 && dProj > - m_dHeight) { - - double dFactor = ( dDelta > 0 ? 1 : - 1) ; - dMin = min( dZH, dZH + dDelta + dFactor * sqrt( m_dRadius * m_dRadius - dSqD)) ; - dMax = max( dZH, dZH + dDelta + dFactor * sqrt( m_dRadius * m_dRadius - dSqD)) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else { - - Point3d ptSt ; - - if ( vtMove * vtToolDir < 0 && dDelta > 0) - ptSt = ptLs ; - else if ( vtMove * vtToolDir < 0 && dDelta < 0) { - ptSt = ptTLe ; vtPlaneMove = - vtPlaneMove ; dDelta = - dDelta ; - } - else if ( vtMove * vtToolDir > 0 && dDelta < 0) { - ptSt = ptLe ; vtPlaneMove = - vtPlaneMove ; dDelta = - dDelta ; - } - else { - ptSt = ptTLs ;// vtPlaneMove = - vtPlaneMove ; - } - - double dZH = ptSt.z ; - Point3d ptStart ( ptSt.x, ptSt.y, 0) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - vtPlaneMove.Normalize() ; - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - Vector3d vtC = ptC - ptStart ; - - double dProj = vtPlaneMove * vtC ; - - Vector3d vtP = vtC - dProj * vtPlaneMove ; - - double dSqD = vtP * vtP ; - - if ( dSqD < m_dRadius * m_dRadius) { - - if ( dProj > 0 && dProj < m_dHeight) { - - dMin = dZH - sqrt( m_dRadius * m_dRadius - dSqD) ; - - if ( dProj < dLenPlanePath) - dMax = dZH + sqrt( m_dRadius * m_dRadius - dSqD) + ( dDelta/dLenPlanePath) * dProj ; - else - dMax = dZH + dDelta + sqrt( m_dRadius * m_dRadius - dSqD) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj >= m_dHeight && dProj < m_dHeight + dLenPlanePath) { - - dMin = dZH - sqrt( m_dRadius * m_dRadius - dSqD) + ( dDelta/dLenPlanePath) * ( dProj - m_dHeight) ; - - if ( dProj < dLenPlanePath) - dMax = dZH + sqrt( m_dRadius * m_dRadius - dSqD) + ( dDelta/dLenPlanePath) * dProj ; - else - dMax = dZH + dDelta + sqrt( m_dRadius * m_dRadius - dSqD) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - return true ; - } - else if ( m_nToolType == 2) { - - if ( abs ( ( vtMove * vtToolDir) * dDelta) < EPS_SMALL) { - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Vector3d vtC = ptC - ptStart ; - double dProj = vtC * vtToolDir ; - Vector3d vtP = vtC - dProj * vtToolDir ; - double dSqD = vtP * vtP ; - double dZH = ptLs.z ; - - - if ( dProj < 0 && dProj > - m_dHeight + m_dRadius) { - - if ( dSqD < m_dRadius * m_dRadius) { - - dMin = min( dZH - sqrt( m_dRadius * m_dRadius - dSqD), dZH + dDelta - sqrt( m_dRadius * m_dRadius - dSqD)) ; - dMax = max( dZH + sqrt( m_dRadius * m_dRadius - dSqD), dZH + dDelta + sqrt( m_dRadius * m_dRadius - dSqD)) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } // Chiedere per = - else if ( dProj <= - m_dHeight + m_dRadius && dProj > - m_dHeight) { - - double dCylH = m_dHeight - m_dRadius ; - double dL = abs( - dProj - dCylH) ; - double dR = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - if ( dSqD < dR * dR) { - - double dH = ( dR * dR - dSqD > 0 ? sqrt ( dR * dR - dSqD) : 0) ; - - dMin = min( dZH - dH, dZH - dH + dDelta) ; - dMax = max( dZH + dH, dZH + dH + dDelta) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - else { // Movimento obliquo - - Point3d ptStart = ptLs ; - - double dA = m_dRadius / sqrt( 1 + ( dDelta * dDelta) / (dLenPlanePath * dLenPlanePath)) ; - double dSemiAxMin = ( abs( dDelta) * dA) / dLenPlanePath ; - - if ( ( vtToolDir * vtMove) * dDelta < 0) { - - if ( dDelta < 0) { - vtPlaneMove = - vtPlaneMove ; - dDelta = - dDelta ; - ptStart = ptLe ; - } - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - Point3d ptS( ptStart.x, ptStart.y, 0) ; - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - Vector3d vtC = ptC - ptS ; - double dProj = vtC * vtToolDir ; - Vector3d vtP = vtC - ( vtC * vtToolDir) * vtToolDir ; - double dSqD = vtP * vtP ; - double dCylH = m_dHeight - m_dRadius ; - double dZH = ptStart.z ; - - if ( dSqD < m_dRadius * m_dRadius) { - - if ( dProj < 0 && dProj > - m_dHeight - dLenPlanePath) { - - if ( dProj > -dCylH) { - // parte cilindrica orizzontale inferiore - double dH = ( m_dRadius * m_dRadius - dSqD > 0 ? sqrt( m_dRadius * m_dRadius - dSqD) : 0) ; - dMin = dZH - dH ; - } - else if ( dProj > - dCylH - dSemiAxMin * sqrt( 1 - dSqD / ( m_dRadius * m_dRadius))) { - // parte sferica inferiore - double dL = - dProj - dCylH ; - double dR = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dH = ( dR * dR - dSqD > 0 ? sqrt( dR * dR - dSqD) : 0) ; - - dMin = dZH - dH ; - } - else if ( dProj > - dCylH - dLenPlanePath - dSemiAxMin * sqrt( 1 - dSqD / (m_dRadius * m_dRadius))) { - // parte cilindrica obliqua inferiore - double dl = dSemiAxMin * sqrt( 1 - dSqD / (m_dRadius * m_dRadius)) ; - - dMin = dZH - dA * sqrt( 1 - dSqD / (m_dRadius * m_dRadius)) - ( dDelta / dLenPlanePath) * ( dProj + dCylH + dl) ; - } - else if ( dProj > - m_dHeight - dLenPlanePath) { - // seconda parte sferica inferiore - double dL = - dProj - dCylH - dLenPlanePath; - double dR = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dH = ( dR * dR - dSqD > 0 ? sqrt( dR * dR - dSqD) : 0) ; - - dMin = dZH + dDelta - dH ; - } - - if ( dProj > - dLenPlanePath) { - // parte cilindrica obliqua superiore - double dH = sqrt( m_dRadius * m_dRadius - dSqD) ; - - dMax = dZH + dH - ( dDelta / dLenPlanePath) * dProj ; - } - else if ( dProj > - dLenPlanePath - dCylH) { - // parte cilindrica orizzontale superiore - double dH = sqrt( m_dRadius * m_dRadius - dSqD) ; - - dMax = dZH + dDelta + dH ; - } - else if ( dProj > - dLenPlanePath - m_dHeight) { - // parte sferica superiore - double dL = - dProj - dCylH - dLenPlanePath; - double dR = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dH = ( dR * dR - dSqD > 0 ? sqrt( dR * dR - dSqD) : 0) ; - - dMax = dZH + dDelta + dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - return true ; - } - else { - - if ( dDelta > 0) { - vtPlaneMove = - vtPlaneMove ; - dDelta = - dDelta ; - ptStart = ptLe ; - } - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - Point3d ptS( ptStart.x, ptStart.y, 0) ; - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - Vector3d vtC = ptC - ptS ; - double dProj = vtC * vtToolDir ; - Vector3d vtP = vtC - ( vtC * vtToolDir) * vtToolDir ; - double dSqD = vtP * vtP ; - double dCylH = m_dHeight - m_dRadius ; - double dZH = ptStart.z ; - - if ( dSqD < m_dRadius * m_dRadius) { - - if ( dProj < 0 && dProj > - m_dHeight - dLenPlanePath) { - - if ( dProj > - dLenPlanePath) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqD) ; - - dMin = dZH - dH - ( dDelta / dLenPlanePath) * dProj ; - } - else if ( dProj > - dLenPlanePath - dCylH) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqD) ; - - dMin = dZH + dDelta - dH ; - } - else if ( dProj > - dLenPlanePath - m_dHeight) { - - double dL = - dProj - dCylH - dLenPlanePath; - double dR = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dH = ( dR * dR - dSqD > 0 ? sqrt( dR * dR - dSqD) : 0) ; - - dMin = dZH + dDelta - dH ; - } - - if ( dProj > - dCylH) { - - double dH = ( m_dRadius * m_dRadius - dSqD > 0 ? sqrt( m_dRadius * m_dRadius - dSqD) : 0) ; - dMax = dZH + dH ; - } - else if ( dProj > - dCylH - dSemiAxMin * sqrt( 1 - dSqD / ( m_dRadius * m_dRadius))) { - - double dL = - dProj - dCylH ; - double dR = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dH = ( dR * dR - dSqD > 0 ? sqrt( dR * dR - dSqD) : 0) ; - - dMax = dZH + dH ; - } - else if ( dProj > - dCylH - dLenPlanePath - dSemiAxMin * sqrt( 1 - dSqD / (m_dRadius * m_dRadius))) { - - double dl = dSemiAxMin * sqrt( 1 - dSqD / (m_dRadius * m_dRadius)) ; - - dMax = dZH + dA * sqrt( 1 - dSqD / (m_dRadius * m_dRadius)) - ( dDelta / dLenPlanePath) * ( dProj + dCylH + dl) ; - } - else if ( dProj > - m_dHeight - dLenPlanePath) { - - double dL = - dProj - dCylH - dLenPlanePath; - double dR = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dH = ( dR * dR - dSqD > 0 ? sqrt( dR * dR - dSqD) : 0) ; - - dMax = dZH + dDelta + dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - return true ; - } - } - - return true ; - } - else if ( m_nToolType == 3) - return true ; - else - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI, ptF ; - - if ( ptLs.z < ptLe.z) { - ptI = ptLs ; - ptF = ptLe ; - } - else { - ptI = ptLe ; - ptF = ptLs ; - } - - // Quote dei punti ptI e ptF - double dZI = ptI.z ; double dZF = ptF.z ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - Vector3d vtMove = ptF - ptI ; //double dLenPath = vtMove.Len() ; - - // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMove ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determinazione punti notevoli del volume spazzato dall'utensile - Point3d ptPlaneSup, ptPlaneInf ; - - if ( vtV3.z > 0) { - ptPlaneInf = ptI - m_dRadius * vtV3 ; - ptPlaneSup = ptI + m_dRadius * vtV3 ; - } - else { - ptPlaneInf = ptI + m_dRadius * vtV3 ; - ptPlaneSup = ptI - m_dRadius * vtV3 ; - } - - // Prodotti scalari per costruire i piani passanti per i punti notevoli - Vector3d vtR0Inf = ptPlaneInf - ORIG ; - Vector3d vtR0Sup = ptPlaneSup - ORIG ; - - double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; - - // Determinazione delle proiezioni sul piano delle entità geometriche fondamentali - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ; - Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ; - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano - double dProj2 = vtC * vtPlaneMove ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza - - if ( dProj1 < 0 && dProj1 > - m_dHeight && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) { - - - // Minimi - if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) { - - dMin = dZInf ; - } - else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMin = dZF - dH ; - } - // Massimi - if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) { - - dMax = dZSup ; - } - else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMax = dZF + dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } // Fine ciclo - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI, ptF ; - - if ( ptLs.z < ptLe.z) { - ptI = ptLs ; - ptF = ptLe ; - } - else { - ptI = ptLe ; - ptF = ptLs ; - } - - // Quote dei punti ptI e ptF e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - Vector3d vtMove = ptF - ptI ; - - // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMove ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determinazione punti notevoli del volume spazzato dall'utensile - Point3d ptPlaneSup, ptPlaneInf ; - - if ( vtV3.z > 0) { - ptPlaneInf = ptI - m_dRadius * vtV3 ; - ptPlaneSup = ptI + m_dRadius * vtV3 ; - } - else { - ptPlaneInf = ptI + m_dRadius * vtV3 ; - ptPlaneSup = ptI - m_dRadius * vtV3 ; - } - - // Prodotti scalari per costruire i piani passanti per i punti notevoli - Vector3d vtR0Inf = ptPlaneInf - ORIG ; - Vector3d vtR0Sup = ptPlaneSup - ORIG ; - - double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; - - // Determinazione delle proiezioni sul piano delle entità geometriche fondamentali - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ; - Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ; - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - double dCylH = m_dHeight - m_dRadius ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano - double dProj2 = vtC * vtPlaneMove ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza - - // Parte cilindrica - if ( dProj1 < 0 && dProj1 > - dCylH && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) { - - // Minimi - if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) { - - dMin = dZInf ; - } - else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMin = dZF - dH ; - } - // Massimi - if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) { - - dMax = dZSup ; - } - else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMax = dZF + dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - // Parte sferica - else if ( ( dProj2 > - m_dRadius && dProj2 < 0 && dProj2 * dProj2 + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius) || - ( dProj2 >= 0 && dProj2 < dPlanePath && dProj1 > - m_dHeight && dProj1 <= - dCylH) || - ( dProj2 >= dPlanePath && dProj2 < dPlanePath + m_dRadius && ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius)) { - - - double dSemiMin = dPlaneLim ; double dSemiMax = m_dRadius ; // Semi-assi dell'ellisse - double dl = - dProj1 - dCylH ; - - // Massimi - if ( dProj2 < - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dr = sqrt( dProj2 * dProj2 + dl * dl) ; - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMax = dZI + dH ; - } - else if ( dProj2 < dPlanePath - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dCos = abs( vtV3 * Z_AX) ; - - dMax = dZI + sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ; - } - else { - - double dL = dProj2 - dPlanePath ; - double dr = sqrt( dL * dL + dl * dl) ; - - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMax = dZF + dH ; - } - - // Minimi - if ( dProj2 < dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dr = sqrt( dProj2 * dProj2 + dl * dl) ; - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMin = dZI - dH ; - } - else if ( dProj2 < dPlanePath + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dCos = abs( vtV3 * Z_AX) ; - - dMin = dZI - sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ; - } - else { - - double dr = sqrt( ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + dl * dl) ; - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMin = dZF - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } // Fine ciclo - return true ; -} -/* -// DA TENERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI, ptF ; - - if ( ptLs.z <= ptLe.z) { - ptI = ptLs ; - ptF = ptLe ; - } - else { - ptI = ptLe ; - ptF = ptLs ; - } - - // Quote dei punti ptI e ptF e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Vettori di riferimento nello spazio e controllo per simmetria - Vector3d vtMove = ptF - ptI ; - Vector3d vtTool = vtToolDir ; - - if ( vtToolDir * vtMove > 0) { - - Point3d ptTemp = ptI ; - ptI = ptIT ; ptIT = ptTemp ; - ptTemp = ptF ; - ptF = ptFT ; - ptFT = ptTemp ; - vtTool = - vtTool ; - } - - Vector3d vtMoveOrt = vtMove - ( vtMove * vtTool) * vtTool ; double dLen2 = vtMoveOrt.Len() ; - Vector3d vtMoveLong = ( vtMove * vtTool) * vtTool ; double dLen1 = vtMoveLong.Len() ; - - // Vettori di riferimento nel piano - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; - Vector3d vtPlaneMoveLong( vtMoveLong.x, vtMoveLong.y, 0) ; double dPLen1 = vtPlaneMoveLong.LenXY() ; - Vector3d vtPlaneMoveOrt( vtMoveOrt.x, vtMoveOrt.y, 0) ; double dPLen2 = vtPlaneMoveOrt.LenXY() ; vtPlaneMoveOrt.Normalize() ; - - // Punti iniziale e finale proiettati sul piano - Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; - - // Determino i sistemi di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtTool ; - Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determinazione punti notevoli del volume spazzato dall'utensile - Point3d ptPlaneSup, ptPlaneInf ; - - if ( vtV3.z > 0) { - ptPlaneInf = ptI - m_dRadius * vtV3 ; - ptPlaneSup = ptI + m_dRadius * vtV3 ; - } - else { - ptPlaneInf = ptI + m_dRadius * vtV3 ; - ptPlaneSup = ptI - m_dRadius * vtV3 ; - } - - Point3d ptPlaneSupxy( ptPlaneSup.x, ptPlaneSup.y, 0) ; - Point3d ptPlaneInfxy( ptPlaneInf.x, ptPlaneInf.y, 0) ; - - double dr = sqrt( ( ptPlaneSupxy - ptIxy) * ( ptPlaneSupxy - ptIxy)) ; - - // Determinazione degli analoghi punti sulla punta dell'utensile e delle loro proiezioni sul piano XY - Point3d ptPlTInf = ptPlaneInf - m_dHeight * vtTool ; Point3d ptPlTInfxy( ptPlTInf.x, ptPlTInf.y, 0) ; - Point3d ptPlTSup = ptPlaneSup - m_dHeight * vtTool ; Point3d ptPlTSupxy( ptPlTSup.x, ptPlTSup.y, 0) ; - - // Prodotti scalari per costruire i piani passanti per i punti notevoli - Vector3d vtR0Inf = ptPlaneInf - ORIG ; - Vector3d vtR0Sup = ptPlaneSup - ORIG ; - Vector3d vtR0 = ptI - ORIG ; - double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; double dP = vtR0 * vtV3 ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - double dZPInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - double dZPSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano superiore come funzione di x e y - - // Punto e vettori del ciclo - Point3d ptC( dX, dY, 0) ; Vector3d vtCi = ptC - ptIxy ; - // Proiezione fondamentale - double dPro1 = vtCi * vtV1 ; double dPro2 = vtCi * vtPlaneMoveOrt ; - - - // Se il punto cade nella proiezione sul piano XY del volume spazzato si taglia - if ( ((dPro2 > - m_dRadius && dPro2 < m_dRadius) && (((dPro2 < dPLen2 - m_dRadius && (dPro1 > - m_dHeight - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) && dPro1 < 0))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < 0)))) - || ((dPro2 >= m_dRadius && dPro2 < dPLen2 + m_dRadius) && ((dPro2 < dPLen2 - m_dRadius && (dPro1 > - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) - m_dHeight && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius)))))) { - - // Massimi ////////////////////////////////////////////////////////////////////////// - // Prima zona cilindrica superiore - if ( ( dPro2 > - m_dRadius && dPro2 < - dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; - - dMax = dZI + dH ; - } - - // Vettore per seconda zona cilindrica superiore - Vector3d vtCf = ptC - ptFxy ; - // Proiezione per seconda zona cilindrica sueriore - double dPr1 = vtCf * vtV1 ; double dPr2 = vtCf * vtPlaneMoveOrt ; - - // Seconda zona cilindrica superiore - if ( ( dPr2 >= - dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; - - dMax = dZF + dH ; - } - - // Vettore per Piano superiore e zona di fondo superiore - Vector3d vtCS = ptC - ptPlaneSupxy ; - // Proiezioni - double dPrS1 = vtCS * vtV1 ; double dPrS2 = vtCS * vtPlaneMoveOrt ; - - // Piano superiore - if ( dPrS2 >= 0 && dPrS2 < dPLen2 && dPrS1 > - m_dHeight - ( dPLen1/dPLen2) * dPrS2 && dPrS1 <= - ( dPLen1/dPLen2) * dPrS2) - - dMax = dZPSup ; - - // Vettore per zona di punta superiore - Vector3d vtCTS = ptC - ptPlTSupxy ; - // Proiezioni - double dPrTS1 = vtCTS * vtV1 ; double dPrTS2 = vtCTS * vtPlaneMoveOrt ; - - // Zona di punta superiore - if ( dPrTS1 <= 0 && dPrTS1 > - dPLen1) - if ( dPrTS2 <= - ( dPLen2 / dPLen1) * dPrTS1 && dPrTS2 > - ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrTS1) { - - double dDist = - ( dPLen2 / dPLen1) * dPrTS1 - dPrTS2 ; - double dL = dDist + dr ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrTS1 * dPrTS1 + ( ( dPLen2 / dPLen1) * dPrTS1) * ( ( dPLen2 / dPLen1) * dPrTS1)) ; - - dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; - } - - // Zona di fondo superiore - if ( dPrS1 < 0 && dPrS1 > - dPLen1) - if ( dPrS2 > - ( dPLen2 / dPLen1) * dPrS1 && dPrS2 < dr - ( dPLen2 / dPLen1) * dPrS1) { - - double dL = dr - ( dPLen2 / dPLen1) * dPrS1 - dPrS2 ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrS1 * dPrS1 + ( ( dPLen2 / dPLen1) * dPrS1) * ( ( dPLen2 / dPLen1) * dPrS1)) ; - - dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; - } - else if ( dPrS2 >= dr - ( dPLen2 / dPLen1) * dPrS1 && dPrS2 < dr + m_dRadius - ( dPLen2 / dPLen1) * dPrS1) { - - double dL = dPrS2 - ( dr - ( dPLen2 / dPLen1) * dPrS1) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrS1 * dPrS1 + ( ( dPLen2 / dPLen1) * dPrS1) * ( ( dPLen2 / dPLen1) * dPrS1)) ; - - dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; - } - - // Minimi ////////////////////////////////////////////////////////////////////////// - // Prima zona cilindrica inferiore - if ( ( dPro2 > - m_dRadius && dPro2 < dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; - - dMin = dZI - dH ; - } - - // Seconda zona cilindrica inferiore - if ( ( dPr2 >= dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; - - dMin = dZF - dH ; - } - - // Vettore per piano inferiore e zona di fondo inferiore - Vector3d vtCI = ptC - ptPlaneInfxy ; - // Proiezioni - double dPrI1 = vtCI * vtV1 ; double dPrI2 = vtCI * vtPlaneMoveOrt ; - - // Piano inferiore - if ( dPrI2 >= 0 && dPrI2 < dPLen2 && dPrI1 > - m_dHeight - ( dPLen1/dPLen2) * dPrI2 && dPrI1 <= - ( dPLen1/dPLen2) * dPrI2) - - dMin = dZPInf ; - - // Zona di fondo inferiore - if ( dPrI1 <= 0 && dPrI1 > - dPLen1) - if ( dPrI2 > - ( dPLen2 / dPLen1) * dPrI1 && dPrI2 < ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrI1) { - - double dDist = dPrI2 + ( dPLen2 / dPLen1) * dPrI1 ; - double dL = dDist + dr ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrI1 * dPrI1 + ( ( dPLen2 / dPLen1) * dPrI1) * ( ( dPLen2 / dPLen1) * dPrI1)) ; - - dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; - } - - // Vettore per zona di punta inferiore - Vector3d vtCTI = ptC - ptPlTInfxy ; - // Proiezioni - double dPrTI1 = vtCTI * vtV1 ; double dPrTI2 = vtCTI * vtPlaneMoveOrt ; - - // zona di punta inferiore - if ( dPrTI1 <= 0 && dPrTI1 > - dPLen1) - if ( dPrTI2 > - m_dRadius - dr - ( dPLen2 / dPLen1) * dPrTI1 && dPrTI2 <= - dr - ( dPLen2 / dPLen1) * dPrTI1) { - - double dL = - dr - ( dPLen2 / dPLen1) * dPrTI1 - dPrTI2 ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrTI1 * dPrTI1 + ( ( dPLen2 / dPLen1) * dPrTI1) * ( ( dPLen2 / dPLen1) * dPrTI1)) ; - - dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; - } - else if ( dPrTI2 > - dr - ( dPLen2 / dPLen1) * dPrTI1 && dPrTI2 < - ( dPLen2 / dPLen1) * dPrTI1) { - - double dL = dPrTI2 - ( - dr - ( dPLen2 / dPLen1) * dPrTI1 ) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrTI1 * dPrTI1 + ( ( dPLen2 / dPLen1) * dPrTI1) * ( ( dPLen2 / dPLen1) * dPrTI1)) ; - - dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; - } - - - SubtractIntervals( i, j, dMin, dMax) ; - } - } // Fine ciclo - return true ; -}*/ - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI, ptF ; - - if ( ptLs.z <= ptLe.z) { - ptI = ptLs ; - ptF = ptLe ; - } - else { - ptI = ptLe ; - ptF = ptLs ; - } - - // Quote dei punti ptI e ptF e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Vettori di riferimento nello spazio e controllo per simmetria - Vector3d vtMove = ptF - ptI ; - Vector3d vtTool = vtToolDir ; - - if ( vtToolDir * vtMove > 0) { - - Point3d ptTemp = ptI ; - ptI = ptIT ; ptIT = ptTemp ; - ptTemp = ptF ; - ptF = ptFT ; - ptFT = ptTemp ; - vtTool = - vtTool ; - } - - Vector3d vtMoveLong = ( vtMove * vtTool) * vtTool ; double dLen1 = vtMoveLong.Len() ; - Vector3d vtMoveOrt = vtMove - vtMoveLong ; double dLen2 = vtMoveOrt.Len() ; - - // Vettori di riferimento nel piano - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; - Vector3d vtPlaneMoveLong( vtMoveLong.x, vtMoveLong.y, 0) ; double dPLen1 = vtPlaneMoveLong.LenXY() ; - Vector3d vtPlaneMoveOrt( vtMoveOrt.x, vtMoveOrt.y, 0) ; double dPLen2 = vtPlaneMoveOrt.LenXY() ; vtPlaneMoveOrt.Normalize() ; - - // Punti iniziale e finale proiettati sul piano - Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; - - // Determino i sistemi di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtTool ; - Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determinazione punti notevoli del volume spazzato dall'utensile - Point3d ptPlaneSup, ptPlaneInf ; - - if ( vtV3.z > 0) { - ptPlaneInf = ptI - m_dRadius * vtV3 ; - ptPlaneSup = ptI + m_dRadius * vtV3 ; - } - else { - ptPlaneInf = ptI + m_dRadius * vtV3 ; - ptPlaneSup = ptI - m_dRadius * vtV3 ; - } - - Point3d ptPlaneSupxy( ptPlaneSup.x, ptPlaneSup.y, 0) ; - Point3d ptPlaneInfxy( ptPlaneInf.x, ptPlaneInf.y, 0) ; - - double dr = sqrt( ( ptPlaneSupxy - ptIxy) * ( ptPlaneSupxy - ptIxy)) ; - - // Determinazione degli analoghi punti sulla punta dell'utensile e delle loro proiezioni sul piano XY - Point3d ptPlTInf = ptPlaneInf - m_dHeight * vtTool ; Point3d ptPlTInfxy( ptPlTInf.x, ptPlTInf.y, 0) ; - Point3d ptPlTSup = ptPlaneSup - m_dHeight * vtTool ; Point3d ptPlTSupxy( ptPlTSup.x, ptPlTSup.y, 0) ; - - // Prodotti scalari per costruire i piani passanti per i punti notevoli - Vector3d vtR0Inf = ptPlaneInf - ORIG ; - Vector3d vtR0Sup = ptPlaneSup - ORIG ; - Vector3d vtR0 = ptI - ORIG ; - double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; double dP = vtR0 * vtV3 ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - double dZPInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - double dZPSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano superiore come funzione di x e y - - // Punto e vettori del ciclo - Point3d ptC( dX, dY, 0) ; Vector3d vtCi = ptC - ptIxy ; - // Proiezione fondamentale - double dPro1 = vtCi * vtV1 ; double dPro2 = vtCi * vtPlaneMoveOrt ; - - - // Se il punto cade nella proiezione sul piano XY del volume spazzato si taglia - if ( ((dPro2 > - m_dRadius && dPro2 < m_dRadius) && (((dPro2 < dPLen2 - m_dRadius && (dPro1 > - m_dHeight - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) && dPro1 < 0))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < 0)))) - || ((dPro2 >= m_dRadius && dPro2 < dPLen2 + m_dRadius) && ((dPro2 < dPLen2 - m_dRadius && (dPro1 > - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) - m_dHeight && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius)))))) { - - // Massimi ////////////////////////////////////////////////////////////////////////// - // Prima zona cilindrica superiore - if ( ( dPro2 > - m_dRadius && dPro2 < - dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; - - dMax = dZI + dH ; - } - - // Vettore per seconda zona cilindrica superiore - Vector3d vtCf = ptC - ptFxy ; - // Proiezione per seconda zona cilindrica sueriore - double dPr1 = vtCf * vtV1 ; double dPr2 = vtCf * vtPlaneMoveOrt ; - - // Seconda zona cilindrica superiore - if ( ( dPr2 >= - dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; - - dMax = dZF + dH ; - } - - // Vettore per Piano superiore e zona di fondo superiore - Vector3d vtCS = ptC - ptPlaneSupxy ; - // Proiezioni - double dPrS1 = vtCS * vtV1 ; double dPrS2 = vtCS * vtPlaneMoveOrt ; - - // Piano superiore - if ( dPrS2 >= 0 && dPrS2 < dPLen2 && dPrS1 > - m_dHeight - ( dPLen1/dPLen2) * dPrS2 && dPrS1 <= - ( dPLen1/dPLen2) * dPrS2) - - dMax = dZPSup ; - - // Vettore per zona di punta superiore - Vector3d vtCTS = ptC - ptPlTSupxy ; - // Proiezioni - double dPrTS1 = vtCTS * vtV1 ; double dPrTS2 = vtCTS * vtPlaneMoveOrt ; - - // Zona di punta superiore - if ( dPrTS1 <= 0 && dPrTS1 > - dPLen1) - if ( dPrTS2 <= - ( dPLen2 / dPLen1) * dPrTS1 && dPrTS2 > - ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrTS1) { - - double dDist = - ( dPLen2 / dPLen1) * dPrTS1 - dPrTS2 ; - double dL = dDist + dr ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrTS1 * dPrTS1 + ( ( dPLen2 / dPLen1) * dPrTS1) * ( ( dPLen2 / dPLen1) * dPrTS1)) ; - - dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; - } - - // Zona di fondo superiore - if ( dPrS1 < 0 && dPrS1 > - dPLen1) - if ( dPrS2 > - ( dPLen2 / dPLen1) * dPrS1 && dPrS2 < m_dRadius + dr - ( dPLen2 / dPLen1) * dPrS1) { - - double dL = abs( dr - ( dPLen2 / dPLen1) * dPrS1 - dPrS2) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrS1 * dPrS1 + ( ( dPLen2 / dPLen1) * dPrS1) * ( ( dPLen2 / dPLen1) * dPrS1)) ; - - dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; - } - - // Minimi ////////////////////////////////////////////////////////////////////////// - // Prima zona cilindrica inferiore - if ( ( dPro2 > - m_dRadius && dPro2 < dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; - - dMin = dZI - dH ; - } - - // Seconda zona cilindrica inferiore - if ( ( dPr2 >= dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; - - dMin = dZF - dH ; - } - - // Vettore per piano inferiore e zona di fondo inferiore - Vector3d vtCI = ptC - ptPlaneInfxy ; - // Proiezioni - double dPrI1 = vtCI * vtV1 ; double dPrI2 = vtCI * vtPlaneMoveOrt ; - - // Piano inferiore - if ( dPrI2 >= 0 && dPrI2 < dPLen2 && dPrI1 > - m_dHeight - ( dPLen1/dPLen2) * dPrI2 && dPrI1 <= - ( dPLen1/dPLen2) * dPrI2) - - dMin = dZPInf ; - - // Zona di fondo inferiore - if ( dPrI1 <= 0 && dPrI1 > - dPLen1) - if ( dPrI2 > - ( dPLen2 / dPLen1) * dPrI1 && dPrI2 < ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrI1) { - - double dDist = dPrI2 + ( dPLen2 / dPLen1) * dPrI1 ; - double dL = dDist + dr ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrI1 * dPrI1 + ( ( dPLen2 / dPLen1) * dPrI1) * ( ( dPLen2 / dPLen1) * dPrI1)) ; - - dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; - } - - // Vettore per zona di punta inferiore - Vector3d vtCTI = ptC - ptPlTInfxy ; - // Proiezioni - double dPrTI1 = vtCTI * vtV1 ; double dPrTI2 = vtCTI * vtPlaneMoveOrt ; - - // zona di punta inferiore - if ( dPrTI1 <= 0 && dPrTI1 > - dPLen1) - if ( dPrTI2 > - m_dRadius - dr - ( dPLen2 / dPLen1) * dPrTI1 && dPrTI2 < - ( dPLen2 / dPLen1) * dPrTI1) { - - double dL = abs( - dr - ( dPLen2 / dPLen1) * dPrTI1 - dPrTI2) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrTI1 * dPrTI1 + ( ( dPLen2 / dPLen1) * dPrTI1) * ( ( dPLen2 / dPLen1) * dPrTI1)) ; - - dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } // Fine ciclo - return true ; -} - -/* -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - // Parte cilindrica - - m_dHeight = m_dHeight - m_dRadius ; - - MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; - - m_dHeight = m_dHeight + m_dRadius ; - //////////////////////////////////////// - Point3d ptI, ptF ; - - if ( ptLs.z < ptLe.z) { - - ptI = ptLs ; - ptF = ptLe ; - } - else { - - ptI = ptLe ; - ptF = ptLs ; - } - - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - double dCylH = m_dHeight - m_dRadius ; - - Point3d ptCI = ptI - dCylH * vtToolDir ; - Point3d ptCF = ptF - dCylH * vtToolDir ; - - Point3d ptCIxy( ptCI.x, ptCI.y, 0) ; - - // Bounding box - double dMinX = min( ptCI.x, ptCF.x) - m_dRadius ; - double dMaxX = max( ptCI.x, ptCF.x) + m_dRadius ; - double dMinY = min( ptCI.y, ptCF.y) - m_dRadius ; - double dMaxY = max( ptCI.y, ptCF.y) + m_dRadius ; - - Vector3d vtMove = ptF - ptI ; - - // Sistema di riferimento - Vector3d vtV2 = vtMove ; vtV2.Normalize() ; - Vector3d vtV1 ; - - if ( abs( vtV2.y) < EPS_SMALL) - - vtV1 = Y_AX ; - else - vtV1 = X_AX - ( vtV2.x / vtV2.y) * Y_AX ; - - if ( vtV1 * vtToolDir < 0) - - vtV1 = - vtV1 ; - - vtV1.Normalize() ; - - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determino il semi-asse minore - Vector3d vtSemiMin( vtV3.x, vtV3.y, 0) ; - double dSemiAxMin = m_dRadius * vtSemiMin.LenXY() ; - - Vector3d vtMovexy( vtMove.x, vtMove.y, 0) ; double dPlaneLen = vtMovexy.LenXY() ; - Vector3d vtU1 = vtV1 ; - Vector3d vtU2 ; - - if ( abs( vtV2.y) < EPS_SMALL) { - - if ( vtV2.x > 0) - - vtU2 = X_AX ; - else - vtU2 = - X_AX ; - } - else { - - vtU2 = vtMovexy ; vtU2.Normalize() ; - } - - - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - - Vector3d vtC = ptC - ptCIxy ; - - double dProj1 = vtC * vtU1 ; double dProj2 = vtC * vtU2 ; - - double dSqRadDistI = dProj1 * dProj1 + dProj2 * dProj2 ; - double dSqRadDistF = dProj1 * dProj1 + ( dProj2 - dPlaneLen) * ( dProj2 - dPlaneLen) ; - double dSqAxDist = dProj1 * dProj1 ; - - if ( ( dProj2 < 0 && dSqRadDistI < m_dRadius * m_dRadius) || - ( dProj2 >= 0 && dProj2 < dPlaneLen && dSqAxDist < m_dRadius * m_dRadius) || - ( dProj2 >= dPlaneLen && dSqRadDistF < m_dRadius * m_dRadius)) { - - // Massimi - if ( dProj2 < - dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius)) && - dProj2 < dPlaneLen - dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius))) { - - double dProj0 = - dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius)) ; - double dZ0 = dZI + ( dPlaneLen / dDeltaZ) * ( - dProj0) ; - - dMax = dZ0 + ( dDeltaZ / dPlaneLen) * ( dProj2 - dProj0) ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; - - dMax = dZF + dH ; - } - - // Minimi - if ( dProj2 < dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius)) && - dProj2 < dPlaneLen + dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius))) { - - double dProj0 = dSemiAxMin * sqrt( 1 - ( dProj1 * dProj1) / ( m_dRadius * m_dRadius)) ; - double dZ0 = dZI + ( dPlaneLen / dDeltaZ) * ( - dProj0) ; - - dMin = dZ0 + ( dDeltaZ / dPlaneLen) * ( dProj2 - dProj0) ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; - - dMin = dZF - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } // Fine ciclo - - return true ; -} -*/ - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - // Parte cilindrica - - double dCylH = m_dHeight - m_dRadius ; - - m_dHeight = dCylH ; - - MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; - - m_dHeight = m_dHeight + m_dRadius ; - //////////////////////////////////////// - Point3d ptI, ptF ; - - if ( ptLs.z < ptLe.z) { - - ptI = ptLs ; - ptF = ptLe ; - } - else { - - ptI = ptLe ; - ptF = ptLs ; - } - - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - Point3d ptCI = ptI - dCylH * vtToolDir ; - Point3d ptCF = ptF - dCylH * vtToolDir ; - - Point3d ptCIxy( ptCI.x, ptCI.y, 0) ; - - // Bounding box - double dMinX = min( ptCI.x, ptCF.x) - m_dRadius ; - double dMaxX = max( ptCI.x, ptCF.x) + m_dRadius ; - double dMinY = min( ptCI.y, ptCF.y) - m_dRadius ; - double dMaxY = max( ptCI.y, ptCF.y) + m_dRadius ; - - Vector3d vtMove = ptF - ptI ; - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; vtMove.Normalize() ; - - // Sistema di riferimento nel piano - Vector3d vtV2 = vtPlaneMove ; vtV2.Normalize() ; double dComp1 = vtV2 * X_AX ; double dComp2 = vtV2 * Y_AX ; - Vector3d vtV1 = dComp2 * X_AX - dComp1 * Y_AX ; - - // Determino il semi-asse minore - double dOriz = vtMove * Z_AX ; double dVert = vtMove * vtV2 ; - - double dSemiAxMin = m_dRadius * dOriz ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - - Vector3d vtC = ptC - ptCIxy ; - - double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; - - double dSqRadDistI = dProj1 * dProj1 + dProj2 * dProj2 ; - double dSqRadDistF = dProj1 * dProj1 + ( dProj2 - dPLen) * ( dProj2 - dPLen) ; - double dSqAxDist = dProj1 * dProj1 ; - - if ( ( dProj2 < 0 && dSqRadDistI < m_dRadius * m_dRadius) || - ( dProj2 >= 0 && dProj2 < dPLen && dSqAxDist < m_dRadius * m_dRadius) || - ( dProj2 >= dPLen && dSqRadDistF < m_dRadius * m_dRadius)) { - - // Massimi - if ( dProj2 < - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) && - dProj2 < dPLen - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dProj0 = - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ; - double dZ0 = dZI + dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ; - - dMax = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; - - dMax = dZF + dH ; - } - - // Minimi - if ( dProj2 < dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) && - dProj2 < dPLen + dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dProj0 = dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ; - double dZ0 = dZI - dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ; - - dMin = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; - - dMin = dZF - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } // Fine ciclo - - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxXY( unsigned int nI, unsigned int nJ, double dProj, double dZheight, double dSqD, double dPathPerp, double dPathPar, double dScProd) { - - // Definisco la variabile altezza della parte cilindrica dell'utensile - double dCylH ; - // Definisco variabili per determinazione intervallo da sottrarre - double dL, dR, dH ; - - // Caso di utensile generico ( per ora non gestito) - if ( m_nToolType == 0) - return false ; - // Se utensile standard setto altezza della parte cilindrica - else if ( m_nToolType == 1) - dCylH = m_dHeight ; - else if ( m_nToolType == 2) - dCylH = m_dHeight - m_dRadius ; - else if ( m_nToolType == 3) - dCylH = m_dHeight - m_dRCorner ; - // Caso di utensile non definito - else - return false ; - - // Parametri per isolare la lavorazione della parte cilindrica comune a tutti gli utensili standard - // Limite nella direziona parallela all'asse dell'utensile e parametro perpendicolare - double dLimPar, dParPerp ; - - // Tagli perpendicolari all'asse dell'utensile - if ( abs( dScProd) < EPS_SMALL) { - dLimPar = dCylH ; - dParPerp = dPathPerp ; - } - // Tagli paralleli all'asse dell'utensile - else { - dLimPar = dPathPar ; - dParPerp = 0 ; - } - - // Parte cilindrica della lavorazione - if ( dSqD < dLimPar * dLimPar) { - // Qui il raggio del semicerchio è m_dRadius - if ( dProj < 0) - // dH = sqrt( m_dRadius^2 - dProj^2) - dH = sqrt( m_dRadius * m_dRadius - ( dProj * dProj)) ; - // Qui l'altezza è costante - else if ( dProj < dParPerp) - // dH = m_dRadius - dH = m_dRadius ; - // Qui il raggio del semicerchio è m_dRadius - else if ( dProj < dParPerp + m_dRadius) - // dH = sqrt( m_dRadius^2 - ( dProj - dParPerp)^2) - dH = sqrt( m_dRadius * m_dRadius - ( dProj - dParPerp) * ( dProj - dParPerp)) ; - // Eseguo il taglio - return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ; - } - // Parte non cilindrica, questa parte esiste solo nei tagli (dScProd = 0) e nel foro con la punta quindi (dScProd < 0) - // e solo con frese non cilindriche - else { - if ( dScProd < EPS_SMALL) { - // Definisco variabili - // Caso fresa ball-end - if ( m_nToolType == 2) { - // Il raggio è sqrt( m_dRadius^2 - ( sqrt( dSqD) - dLimPar)^2) - if ( dProj < 0) { - dL = sqrt( dSqD) - dLimPar ; - dR = sqrt( m_dRadius * m_dRadius - dL * dL) ; - dH = sqrt( dR * dR - (dProj * dProj)) ; - } - // Qui dH non dipende da dProj - else if ( dProj < dParPerp) { - dL = sqrt( dSqD) - dLimPar ; - dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - } - // E' analogo al primo caso con la sostituzione di dProj con dProj - dParPerp - else if ( dProj < dParPerp + m_dRadius) { // In questo caso è equivalente a else - dL = sqrt( dSqD) - dLimPar ; - dR = sqrt( m_dRadius * m_dRadius - dL * dL) ; - dH = sqrt( dR * dR - ((dProj - dParPerp) * (dProj - dParPerp))) ; - } - } - // Caso di fresa bull-nose - else if ( m_nToolType == 3) { - // Raggio semicerchio m_dRadius - m_dRCorner + sqrt( m_dRCorner^2 - ( sqrt( dSqD) - dLimPar)^2) - if ( dProj < 0) { - dL = sqrt( dSqD) - dLimPar ; - dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; - dH = sqrt( dR * dR - ( dProj * dProj)) ; - } - // Qui dH non dipende da dProj - else if ( dProj < dParPerp) { - dL = sqrt( dSqD) - dLimPar ; - dH = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; - } - // E' analogo al primo caso con la sostituzione di di dProj con dProj - dParPerp - else if ( dProj < dParPerp + m_dRadius) { // In questo caso equivalente a else - dL = sqrt( dSqD) - dLimPar ; - dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; - dH = sqrt( dR * dR - ( ( dProj - dParPerp) * ( dProj - dParPerp))) ; - } - } - return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ; - } - } - return true ; -} - -// Frese conus //---------------------------------------------------------------------------- bool VolZmap::ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { @@ -3775,6 +1536,83 @@ VolZmap::GetMinMaxZDr( const Point3d ptO, unsigned int nStartI, unsigned int nEn return true ; } +//---------------------------------------------------------------------------- +bool +VolZmap::MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill || + m_nToolType == BullNoseMill) + + return CBTMillingPerpZ( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == ConusMill) + + return ConusPerpZ( ptLs, ptLe, vtToolDir) ; + + else return true ; // forse qui ci va il nuovo +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CBTMillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + + // Bounding box + double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; + double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; + double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ; + double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ; + + // Verifico interferisca con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + + // Determino i limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + // Determino quote estreme del tagliente + double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale + double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente + + // Limite sul quadrato del raggio + double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ; + + // Segmento di movimento (nel piano griglia) + Point3d ptStart( ptLs.x, ptLs.y, 0) ; + Point3d ptEnd( ptLe.x, ptLe.y, 0) ; + double dLen ; + Vector3d vtDir ; + DirDist( ptStart, ptEnd, vtDir, dLen) ; + + // Ciclo sui punti nei limiti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + double dX = ( i + 0.5) * m_dStep ; + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + double dY = ( j + 0.5) * m_dStep ; + // punto + Point3d ptQ( dX, dY, 0) ; + // determino il quadrato della distanza del punto dal segmento + double dProiez = vtDir * ( ptQ - ptStart) ; + if ( dProiez < 0) + dProiez = 0 ; + else if ( dProiez > dLen) + dProiez = dLen ; + Point3d ptMinDist = ptStart + vtDir * dProiez ; + double dSqDist = SqDistXY( ptQ, ptMinDist) ; + // se distanza nei limiti, taglio + if ( dSqDist < dSqRad) + GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ; + } + } + + return true ; +} + //---------------------------------------------------------------------------- bool VolZmap::ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { @@ -3910,6 +1748,196 @@ VolZmap::ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtTo return true ; } +//---------------------------------------------------------------------------- +inline bool +VolZmap::GetMinMaxZ( unsigned int nI, unsigned int nJ, double dZCutBase, double dDeltaZ, double dSqDist, const Vector3d& vtToolDir) { + + // Definisco variabili + double dSqRad = m_dRadius * m_dRadius ; + double dFactor = ( vtToolDir.z < 0 ? - 1 : 1) ; + double dZtip = ( vtToolDir.z < 0 ? dZCutBase + m_dHeight : dZCutBase - m_dHeight) ; + + double dMin ; double dMax ; + + // Caso utensile generico al momento non gestito + if ( m_nToolType == 0) + + return false; + // Caso Cylindrical Mill + else if ( m_nToolType == 1) { + + if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { // Non è meglio fare if (vt * delta < - Eps_small ) else if ( vt * delta < Eps) else ? + dMin = min(dZCutBase, dZtip) ; + dMax = max(dZCutBase, dZtip) ; + } + else if ( vtToolDir.z * dDeltaZ < 0) { + dMin = min(dZtip, dZtip + dDeltaZ) ; + dMax = max(dZtip, dZtip + dDeltaZ) ; + } + else { + dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; + dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; + } + return SubtractIntervals( nI, nJ, dMin, dMax) ; + } + // Caso Ball-End Mill + else if ( m_nToolType == 2) { + + if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { + dMin = min(dZCutBase, dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist))) ; + dMax = max(dZCutBase, dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist))) ; + } + else if ( vtToolDir.z * dDeltaZ < 0) { + dMin = min(dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)), dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)) + dDeltaZ) ;// ocio + dMax = max(dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)), dZtip + dFactor*(m_dRadius - sqrt(dSqRad - dSqDist)) + dDeltaZ) ;// ocio + } + else { + dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; + dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; + } + return SubtractIntervals( nI, nJ, dMin, dMax) ; + } + // Caso Bull-Nose Mill + else if ( m_nToolType == 3) { + + double dDeltaR = m_dRadius - m_dRCorner ; + + if ( dSqDist < dDeltaR*dDeltaR) { + + if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { + dMin = min(dZCutBase, dZtip) ; + dMax = max(dZCutBase, dZtip) ; + } + else if ( vtToolDir.z * dDeltaZ < 0) { + dMin = min(dZtip, dZtip + dDeltaZ) ; + dMax = max(dZtip, dZtip + dDeltaZ) ; + } + else { + dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; + dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; + } + return SubtractIntervals( nI, nJ, dMin, dMax) ; + } + else { + + double dSqRadC = m_dRCorner*m_dRCorner ; + double dSqd = dSqDist + dDeltaR*dDeltaR - 2*sqrt(dSqDist)*dDeltaR ; + + if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { + dMin = min(dZCutBase, dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd))) ; + dMax = max(dZCutBase, dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd))) ; + } + else if ( vtToolDir.z * dDeltaZ < 0) { + dMin = min(dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)), dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)) + dDeltaZ) ; + dMax = max(dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)), dZtip + dFactor*(m_dRCorner - sqrt(dSqRadC - dSqd)) + dDeltaZ) ; + } + else { + dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; + dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; + } + return SubtractIntervals( nI, nJ, dMin, dMax) ; + } + } + // Caso di utensile inesistente ( m_nToolType fuori dai valori concessi) + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == 1 || m_nToolType == 2) + + return CBMillingZ( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == 3) + + return false ; + + else if ( m_nToolType == 4) { + + if ( m_dRadius > m_dTipRadius) + + return ConusMillingZDr( ptLs, ptLe, vtToolDir) ; + else + return ConusMillingZSw( ptLs, ptLe, vtToolDir) ; + } + else return true ; // forse ci va il nuovo +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CBMillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + + // Setto il fattore per l'orientazione in z + double dFactor = ( vtToolDir.z < 0 ? 1 : - 1) ; + + // Bounding box + double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; + double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ; + double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; + double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ; + double dMinZ = min( min( ptLs.z, ptLs.z + dFactor * m_dHeight), min( ptLe.z, ptLe.z + dFactor * m_dHeight)) ; + double dMaxZ = max( max( ptLs.z, ptLs.z + dFactor * m_dHeight), max( ptLe.z, ptLe.z + dFactor * m_dHeight)) ; + + // Verifico interferisca con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + // Determino i limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + // + double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale + double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente + + // Limite sul quadrato del raggio + double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ; + + // Segmento di movimento (nel piano griglia) + Point3d ptStart( ptLs.x, ptLs.y, 0) ; + Point3d ptEnd( ptLe.x, ptLe.y, 0) ; + double dLen ; + Vector3d vtDir ; + DirDist( ptStart, ptEnd, vtDir, dLen) ; + + // Ciclo sui punti nei limiti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + double dX = ( i + 0.5) * m_dStep ; + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + double dY = ( j + 0.5) * m_dStep ; + // punto + Point3d ptQ( dX, dY, 0) ; + // determino il quadrato della distanza del punto dal segmento + double dProj = vtDir * ( ptQ - ptStart) ; + double dProiez ; + + if ( dProj < 0) + dProiez = 0 ; + else if ( dProj < dLen) + dProiez = dProj ; + else + dProiez = dLen ; + + Point3d ptMinDist = ptStart + vtDir * dProiez ; + double dSqDist = SqDistXY( ptQ, ptMinDist) ; + + // se distanza nei limiti, taglio + if ( dSqDist < dSqRad) + GetMinMaxZGen( i, j, dProj, dSqDist, dLen, dZCutBase, dDeltaZ, vtToolDir) ; + } + } + return true ; +} + //---------------------------------------------------------------------------- bool VolZmap::ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { @@ -4449,7 +2477,6893 @@ VolZmap::ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d return true ; } +//---------------------------------------------------------------------------- +inline bool +VolZmap::GetMinMaxZGen( unsigned int nI, unsigned int nJ, double dProj, double dSqd, double dLenPath, double dZheight, double dDelta, const Vector3d& vtToolDir) { + // Controllo sul tipo di utensile: se 0 utensile generico (al momento non gestito) se maggiore di 3 utensile fuori dai tipi consentiti + if ( m_nToolType == 0 || m_nToolType > 3) + return false ; + + // Definisco variabili quota della punta, minimo e massimo dell'intervallo da sottrarre + double dZTip = ( vtToolDir.z < 0 ? dZheight + m_dHeight : dZheight - m_dHeight) ; + double dMin, dMax ; double dStart ; // dStart è un parametro che esprime l'ascissa in cui la retta congiungente le due posizioni iniziale e finale + double dRSqDist1, dRSqDist2 ; // di un punto del tagliente (nel sistema dell'asse dell'utensile nella posizione iniziale) assume la quota dZheight + + // Nei conti è comodo che dSqd assuma sempre il significato di distanza del punto dall'asse del movimento al quadrato + if ( dProj < 0) + dSqd = dSqd - dProj * dProj ; + else if ( dProj > dLenPath) + dSqd = dSqd - ( dProj - dLenPath) * ( dProj - dLenPath) ; + + // Caso di cylindrical mill + if ( m_nToolType == 1) { + + double dZ1, dZ2 ; + // Se lavora la punta + if ( vtToolDir.z * dDelta < 0) { + dZ1 = dZTip ; + dZ2 = dZheight ; + } + // Se lavora il fondo + else { + dZ1 = dZheight ; + dZ2 = dZTip ; + } + + dStart = sqrt( m_dRadius * m_dRadius - dSqd) ; + dRSqDist1 = dProj * dProj + dSqd ; + dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ; + + if ( dRSqDist1 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) { + + dMin = min( max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ; + dMax = max( min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ; + } + else if ( dRSqDist2 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) { + + dMin = min( min(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ; + dMax = max( max(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ; + } + else { + + dMin = min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ; + dMax = max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ; + } + } + // Caso di ball-end mill + else if ( m_nToolType == 2) { + + if ( dDelta < 0) { + + dDelta = - dDelta ; + dProj = dLenPath - dProj ; + dZheight = dZheight - dDelta ; + dZTip = dZTip - dDelta ; + } + + dStart = sqrt( m_dRadius * m_dRadius - dSqd) ; + dRSqDist1 = dProj * dProj + dSqd ; + dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ; + + if ( vtToolDir.z > 0) { + + // Semi-asse ellisse + double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; + double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; + double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ; + + if ( dRSqDist2 < m_dRadius * m_dRadius) { + + dMax = dZheight + dDelta ; + + double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; + + if ( dProj - dLenPath > dSemiAxMin * dTest) { + + double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ; + double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; + dMin = dZTip + m_dRadius + dDelta - dH ; + } + else if ( dProj > dSemiAxMin * dTest) { + // Determino l'altezza del punto sull'ellisse da cui passa la retta + double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ; + double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; + double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ; + + dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ; + } + else { + + double dSqrRad = dProj * dProj + dSqd ; + double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; + dMin = dZTip + m_dRadius - dH ; + } + } + else { + + dMax = dZheight + ( dDelta * ( dProj + dStart)) / dLenPath ; + + double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; + + if ( dProj > dSemiAxMin * dTest) { + // Determino l'altezza del punto sull'ellisse da cui passa la retta + double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ; + double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; + double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ; + + dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ; + } + else { + + double dSqrRad = dProj * dProj + dSqd ; + double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; + + dMin = dZTip + m_dRadius - dH ; + } + } + } + else { + + // Semi-asse ellisse + double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; + double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; + double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ; + + if ( dRSqDist1 < m_dRadius * m_dRadius) { + + dMin = dZheight ; + + double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; + + if ( dProj < - dSemiAxMin * dTest) { + + double dSqrRad = dProj * dProj + dSqd ; + double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; + + dMax = dZTip - m_dRadius + dH ; + } + else if ( dProj - dLenPath < - dSemiAxMin * dTest) { + // Determino l'altezza del punto sull'ellisse da cui passa la retta + double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ; + double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; + double dZ0 = ( dPr0 * dPar) / dSemiAxMin ; + + dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ; + } + else { + + double dSqrRad = dProj * dProj + dSqd ; + double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; + dMax = dZTip - m_dRadius + dDelta + dH ; + } + } + else { + + dMin = dZheight + ( dDelta * ( dProj - dStart)) / dLenPath ; + + double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; + + if ( dProj - dLenPath < - dSemiAxMin * dTest) { + // Determino l'altezza del punto sull'ellisse da cui passa la retta + double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ; + double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; + double dZ0 = ( dPr0 * dPar) / dSemiAxMin ; + + dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ; + } + else { + + double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ; + double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; + dMax = dZTip + dDelta - m_dRadius + dH ; + } + } + } + } + // Caso di bull-nose mill + else + return true ; + + return SubtractIntervals( nI, nJ, dMin, dMax) ; +} + + +// Versore utensile nel piano XY + +// DeltaZ = 0 + +//---------------------------------------------------------------------------- +bool +VolZmap::DrillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill || + m_nToolType == BullNoseMill) + + return CBTDrillXY( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == ConusMill) + + return ConusDrillingXY( ptLs, ptLe, vtToolDir) ; + + else + + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CBTDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == ConusMill) + + return ConusDrillingXY( ptLs, ptLe, vtToolDir) ; + + // Punti per la determinazione del materiale asportato + Vector3d vtMove = ptLe - ptLs ; + // Punti di riferimento dell'asportazione + Point3d ptLNs ; + Point3d ptLNe ; + // Parametro relativo all'utensile altezza della parte non cilindrica e fattore determinante + // la lunghezza della parte lavorata a seconda che lavori la punta o il fondo + double dCylH ; double dFactor ; + + // Caso utensile generico (al momento non gestito) + if ( m_nToolType == 0) + return false ; + // Caso Cylindrical Mill + else if ( m_nToolType == 1) + dCylH = m_dHeight ; + // Caso Ball-end Mill + else if ( m_nToolType == 2) + dCylH = m_dHeight - m_dRadius ; + // Caso Bull-nose Mill + else if ( m_nToolType == 3) + dCylH = m_dHeight - m_dRCorner ; + + // Normalizzo tale vettore e ne determino la lunghezza: + double dLenPath = vtMove.Len() ; vtMove.Normalize() ; + + // Prodotto scalare fra versore direzione utensile e direzione movimento + double dScProd = vtMove * vtToolDir ; + // Se lavora la punta + if ( dScProd < 0) { + // Trovo i punti di riferimento per la lavorazione + ptLNs = ptLs + ( vtMove * dCylH) ; + ptLNe = ptLe + ( vtMove * dCylH) ; + dFactor = 1 ; + } + // Se lavora il fondo + else { + ptLNs = ptLs ; + ptLNe = ptLe ; + dFactor = 0 ; + } + + // Quota z dei punti iniziale e finale + double dHz = ptLNs.z ; + + // Bounding box + double dMinX = min( ptLNs.x, ptLNe.x) - m_dRadius ; + double dMaxX = max( ptLNs.x, ptLNe.x) + m_dRadius ; + double dMinY = min( ptLNs.y, ptLNe.y) - m_dRadius ; + double dMaxY = max( ptLNs.y, ptLNe.y) + m_dRadius ; + double dMinZ = dHz - m_dRadius ; + double dMaxZ = dHz + m_dRadius ; + + // Verifico se il movimento intersca lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + // Determino i limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + //Proietto ptLNs sul piano XY: + Point3d ptStart( ptLNs.x, ptLNs.y, 0) ; + + //Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + // Punto da valutare + Point3d ptC( (i + 0.5)*m_dStep, (j + 0.5)*m_dStep, 0) ; + // Vettore spostamento da ptLe a ptC + Vector3d vtC = ( ptC - ptStart) ; + // Componenti parallela e perpendicolare a vtMove + // Vettore ortogonale a vtMove + Vector3d vtOrt = vtMove ; + // Ruoto vtOrt affinché sia ortogonale + vtOrt.Rotate( Z_AX, -90) ; + + double dProj = vtC * vtOrt ; + Vector3d vtPara = vtOrt * dProj ; // Parallelo alla perpendicolare al movimento + Vector3d vtPerp = vtC - vtPara ; // Perpendicolare alla perpendicolare al movimento ( serve per unire le getminmax di drill e perp) + // Distanza di ptC dall'asse dell'untensile + double dSqDist = vtPerp.SqLen() ; + double dLimitMill = dLenPath + dFactor * ( m_dHeight - dCylH) ; + // Se dTestProj è positivo è vtC è dalla parte giusta + double dTestProj = vtC * vtMove ; + + if ( dTestProj > 0 && dSqDist < dLimitMill * dLimitMill) + if ( dProj > - m_dRadius && dProj < m_dRadius) + GetMinMaxXY( i, j, dProj, dHz, dSqDist, 0, dLenPath, dScProd) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ConusDrillingXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { + + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + double dMin, dMax ; + + // Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici + BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + // Parametri geometrici dell'utensile + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dCylH = m_dHeight - m_dTipHeight ; + + Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; vtMove.Normalize() ; + + Point3d ptI = ( vtToolDir * vtMove < 0 ? ptLs : ptLe) ; double dZH = ptI.z ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep , dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptI ; + + double dPL = vtC * vtV1 ; + double dPT = vtC * vtV2 ; + + if ( m_dRadius > m_dTipRadius) { + + if ( dPL < 0 && dPL > - dCylH - dLen && dPT > - dMaxRad && dPT < dMaxRad) { + + double dH = sqrt( dMaxRad * dMaxRad - dPT * dPT) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dPL <= - dCylH - dLen && dPL > - m_dHeight - dLen && + dPT > - dMaxRad + ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight && + dPT < dMaxRad - ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight) { + + double dr = dMaxRad - ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight ; + + double dH = sqrt( dr * dr - dPT * dPT) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else { + + if ( dPL < 0 && dPL > - dCylH && dPT > - dMinRad && dPT < dMinRad) { + + double dH = sqrt( dMinRad * dMinRad - dPT * dPT) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dPL <= - dCylH && dPL > - m_dHeight && + dPT > - dMinRad - ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight && + dPT < dMinRad + ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight) { + + double dr = dMinRad + ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight ; + + double dH = sqrt( dr * dr - dPT * dPT) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dPL <= - m_dHeight && dPL > - m_dHeight - dLen && dPT > - dMaxRad && dPT < dMaxRad) { + + double dH = sqrt( dMaxRad * dMaxRad - dPT * dPT) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + + if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill || + m_nToolType == BullNoseMill) + + return CBTPerpXY( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == ConusMill) + + return ConusPerpXY( ptLs, ptLe, vtToolDir) ; + + else + + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CBTPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == ConusMill) + + return ConusPerpXY( ptLs, ptLe, vtToolDir) ; + + // Determinazione delle posizioni iniziali e finali della punta dell'utensile + Point3d ptTLs = ptLs - vtToolDir * m_dHeight ; + Point3d ptTLe = ptLe - vtToolDir * m_dHeight ; + + // Quota Z + double dZH = ptLs.z ; + + // Estremi Bounding box + double dMinX = min( min( ptLs.x, ptLe.x), min( ptTLs.x, ptTLe.x)) - m_dRadius ; + double dMaxX = max( max( ptLs.x, ptLe.x), max( ptTLs.x, ptTLe.x)) + m_dRadius ; + double dMinY = min( min( ptLs.y, ptLe.y), min( ptTLs.y, ptTLe.y)) - m_dRadius ; + double dMaxY = max( max( ptLs.y, ptLe.y), max( ptTLs.y, ptTLe.y)) + m_dRadius ; + double dMinZ = dZH - m_dRadius ; + double dMaxZ = dZH + m_dRadius ; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + // Determinazione limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + // Proiezione sul piano XY delle grandezze di interesse + Point3d ptStart( ptLs.x, ptLs.y, 0) ; + Point3d ptEnd( ptLe.x, ptLe.y, 0) ; + Vector3d vtMove = ptEnd - ptStart ; + double dLenPath = vtMove.Len() ; + // Normalizzo il vettore vtMove congiungente le posizioni iniziale e finale della base dell'utensile + vtMove.Normalize() ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + // Punto su cui ciclare e vettore congiungente posizione iniziale della base a tale punto + Point3d ptC( (i + 0.5) * m_dStep, (j + 0.5) * m_dStep, 0) ; + Vector3d vtC = ptC - ptStart ; + // Proiezione di vtC sulla direzione del movimento + double dProj = vtC * vtMove ; + // Componente di vtC ortogonale al movimento + Vector3d vtPerp = vtC - vtMove * dProj ; + // Lunghezza quadrata del precedente vettore + double dSqDist = vtPerp.SqLen() ; + + if ( dProj > - m_dRadius && dProj < dLenPath + m_dRadius && vtPerp * vtToolDir < 0 && dSqDist < m_dHeight * m_dHeight) + GetMinMaxXY( i, j, dProj, dZH, dSqDist, dLenPath, 0, 0) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ConusPerpXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { + + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + double dMin, dMax ; + + // Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( Control == false) + + return true ; + + // Parametri geometrici dell'utensile + double dCylH = m_dHeight - m_dTipHeight ; + + Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; + + // Sistema di riferimento + Vector3d vtV1 = - vtToolDir ; + Vector3d vtV2 = vtMove ; vtV2.Normalize() ; + + Point3d ptIC = ptLs ; double dZ = ptLs.z ; + + // Ciclo sui punti + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + double dY = ( j + 0.5) * m_dStep ; double dX = ( i + 0.5) * m_dStep ; + + Point3d ptCC( dX, dY, 0) ; Vector3d vtCC = ptCC - ptIC ; + + double dPCL = vtCC * vtV1 ; double dPCT = vtCC * vtV2 ; + + // Parte cilindrica + if( dPCL > 0 && dPCL < dCylH) { + + if ( dPCT > - m_dRadius && dPCT < 0) { + + double dH = sqrt( m_dRadius * m_dRadius - dPCT * dPCT) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dPCT >= 0 && dPCT < dLen) { + + dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dPCT >= dLen && dPCT < dLen + m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - ( dPCT - dLen) * ( dPCT - dLen)) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + // Parte non cilindrica + else if ( dPCL >= dCylH && dPCL < m_dHeight) { + + double dPNCL = dPCL - dCylH ; double dPNCT = dPCT ; + + if ( dPNCT > - m_dRadius - dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight && dPNCT < 0) { + + double dr = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; + + double dH = sqrt( dr * dr - dPNCT * dPNCT) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dPNCT >= 0 && dPNCT < dLen) { + + double dH = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dPNCT >= dLen && dPNCT < dLen + m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight) { + + double dr = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; + + double dH = sqrt( dr * dr - ( dPNCT - dLen) * ( dPNCT - dLen)) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill) + + return PlaneGenCylBall( ptLs, ptLe, vtToolDir) ; + else + return ConusPlaneGen( ptLs, ptLe, vtToolDir) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::PlaneGenCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; + double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + Point3d ptI = ptLs ; Point3d ptF = ptLe ; + + // Quote dei punti ptI e ptF + double dZ = ptI.z ; + + Point3d ptIT = ptI - vtToolDir * m_dHeight ; + Point3d ptFT = ptF - vtToolDir * m_dHeight ; + + // Bounding box + double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; + double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; + double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; + double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; + + // Seconda verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + + Vector3d vtMove = ptF - ptI ; + + if ( vtMove * vtToolDir > 0) { + Point3d ptTemp = ptI ; + ptI = ptF ; + ptF = ptTemp ; + vtMove = - vtMove ; + } + + Vector3d vtMoveOrt = vtMove - ( vtMove * vtToolDir) * vtToolDir ; double dLen2 = vtMoveOrt.Len() ; + Vector3d vtMoveLong = ( vtMove * vtToolDir) * vtToolDir ; double dLen1 = vtMoveLong.Len() ; + + // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; + + // Punti iniziale e finale proiettati sul piano + Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; + + // Determinazione limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + if ( m_nToolType == 1) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + Vector3d vtC = ptC - ptIxy ; + + double dProj1 = vtC * vtV1 ; + double dProj2 = vtC * vtV2 ; + + GetMMPlaneGenCyl( i, j, dZ, dLen1, dLen2, dProj1, dProj2) ; + } + else if ( m_nToolType == 2) + + GetMMPlaneGenBall( i, j, dZ, dLen1, dLen2, ptIxy, vtMove, vtV1, vtV2) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::GetMinMaxXY( unsigned int nI, unsigned int nJ, double dProj, double dZheight, double dSqD, double dPathPerp, double dPathPar, double dScProd) { + + // Definisco la variabile altezza della parte cilindrica dell'utensile + double dCylH ; + // Definisco variabili per determinazione intervallo da sottrarre + double dL, dR, dH ; + + // Caso di utensile generico ( per ora non gestito) + if ( m_nToolType == 0) + return false ; + // Se utensile standard setto altezza della parte cilindrica + else if ( m_nToolType == 1) + dCylH = m_dHeight ; + else if ( m_nToolType == 2) + dCylH = m_dHeight - m_dRadius ; + else if ( m_nToolType == 3) + dCylH = m_dHeight - m_dRCorner ; + // Caso di utensile non definito + else + return false ; + + // Parametri per isolare la lavorazione della parte cilindrica comune a tutti gli utensili standard + // Limite nella direziona parallela all'asse dell'utensile e parametro perpendicolare + double dLimPar, dParPerp ; + + // Tagli perpendicolari all'asse dell'utensile + if ( abs( dScProd) < EPS_SMALL) { + dLimPar = dCylH ; + dParPerp = dPathPerp ; + } + // Tagli paralleli all'asse dell'utensile + else { + dLimPar = dPathPar ; + dParPerp = 0 ; + } + + // Parte cilindrica della lavorazione + if ( dSqD < dLimPar * dLimPar) { + // Qui il raggio del semicerchio è m_dRadius + if ( dProj < 0) + // dH = sqrt( m_dRadius^2 - dProj^2) + dH = sqrt( m_dRadius * m_dRadius - ( dProj * dProj)) ; + // Qui l'altezza è costante + else if ( dProj < dParPerp) + // dH = m_dRadius + dH = m_dRadius ; + // Qui il raggio del semicerchio è m_dRadius + else if ( dProj < dParPerp + m_dRadius) + // dH = sqrt( m_dRadius^2 - ( dProj - dParPerp)^2) + dH = sqrt( m_dRadius * m_dRadius - ( dProj - dParPerp) * ( dProj - dParPerp)) ; + // Eseguo il taglio + return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ; + } + // Parte non cilindrica, questa parte esiste solo nei tagli (dScProd = 0) e nel foro con la punta quindi (dScProd < 0) + // e solo con frese non cilindriche + else { + if ( dScProd < EPS_SMALL) { + // Definisco variabili + // Caso fresa ball-end + if ( m_nToolType == 2) { + // Il raggio è sqrt( m_dRadius^2 - ( sqrt( dSqD) - dLimPar)^2) + if ( dProj < 0) { + dL = sqrt( dSqD) - dLimPar ; + dR = sqrt( m_dRadius * m_dRadius - dL * dL) ; + dH = sqrt( dR * dR - (dProj * dProj)) ; + } + // Qui dH non dipende da dProj + else if ( dProj < dParPerp) { + dL = sqrt( dSqD) - dLimPar ; + dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; + } + // E' analogo al primo caso con la sostituzione di dProj con dProj - dParPerp + else if ( dProj < dParPerp + m_dRadius) { // In questo caso è equivalente a else + dL = sqrt( dSqD) - dLimPar ; + dR = sqrt( m_dRadius * m_dRadius - dL * dL) ; + dH = sqrt( dR * dR - ((dProj - dParPerp) * (dProj - dParPerp))) ; + } + } + // Caso di fresa bull-nose + else if ( m_nToolType == 3) { + // Raggio semicerchio m_dRadius - m_dRCorner + sqrt( m_dRCorner^2 - ( sqrt( dSqD) - dLimPar)^2) + if ( dProj < 0) { + dL = sqrt( dSqD) - dLimPar ; + dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; + dH = sqrt( dR * dR - ( dProj * dProj)) ; + } + // Qui dH non dipende da dProj + else if ( dProj < dParPerp) { + dL = sqrt( dSqD) - dLimPar ; + dH = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; + } + // E' analogo al primo caso con la sostituzione di di dProj con dProj - dParPerp + else if ( dProj < dParPerp + m_dRadius) { // In questo caso equivalente a else + dL = sqrt( dSqD) - dLimPar ; + dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; + dH = sqrt( dR * dR - ( ( dProj - dParPerp) * ( dProj - dParPerp))) ; + } + } + return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::GetMMPlaneGenCyl( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, double dProj1, double dProj2) { + + double dMin, dMax ; + + if ( dProj2 > - m_dRadius && dProj2 < 0) { + + if ( dProj1 < 0 && dProj1 > - m_dHeight) { + + double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 <= - m_dHeight) { + + if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - m_dHeight - ( dLen1 / dLen2) * ( dProj2 + m_dRadius)) + || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // In questo costrutto if-else non c'è bisogno di specificare nient'altro perché già siamo nella regione - m_dRadius < dProj2 < 0 + + double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; + double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + else if ( dProj2 >= 0 && dProj2 < m_dRadius) { + + if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) { + + double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; + /* Oppure + double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ; + double dPar2 = ( dLen2 / dLen1) * dPar1 ; */ + double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2) { + + if ( dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) { + + dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) { + + if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight) + || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // modificato qui + + double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; + double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + else if ( dProj2 >= dLen2 && dProj1 < - dLen1) { + + if ( dProj1 > - m_dHeight - dLen1) { + + double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dLen2) * ( dProj2 - dLen2)) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + else if ( dProj2 >= m_dRadius && dProj2 < dLen2) { + + if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 > - ( dLen1 / dLen2) * dProj2) { + + double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) { + + dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; + + SubtractIntervals( i, j, dMin , dMax) ; + } + else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) { + + if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight) + || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { + + double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; + double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) { + + if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 >= - dLen1) { + + double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 < - dLen1 && dProj1 > - dLen1 - m_dHeight) { + + double dL = dProj2 - dLen2 ; + double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::GetMMPlaneGenBall( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, Point3d ptIxy, Vector3d vtMove, Vector3d vtV1, Vector3d vtV2) { + + double dMin, dMax ; + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + Vector3d vtC = ptC - ptIxy ; + + double dProj1 = vtC * vtV1 ; // vtV1, vtV2 sono paralleli al piano + double dProj2 = vtC * vtV2 ; + + double dCH = m_dHeight - m_dRadius ; + double dLMove = vtMove.LenXY() ; + + Point3d ptCS = ptIxy - dCH * vtV1 ; Point3d ptCE = ptCS + vtMove ; // vtMove è orizzontale + + Vector3d vtCS = ptC - ptCS ; Vector3d vtCE = ptC - ptCE ; + + double dProjMove = ( vtCS * vtMove) / dLMove ; + + Vector3d vtCSP = vtCS - ( ( vtCS * vtMove) / ( dLMove * dLMove)) * vtMove ; + + double dSQDist = vtCSP.SqLenXY() ; + double dSQDistS = vtCS.SqLenXY() ; + double dSQDistE = vtCE.SqLenXY() ; + + // parte cilindrica + + if ( dProj2 > - m_dRadius && dProj2 < 0) { + + if ( dProj1 > - dCH && dProj1 < 0) { + + double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( dProj2 >= 0 && dProj2 < m_dRadius) { + + if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) { + + double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; + /* Oppure + double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ; + double dPar2 = ( dLen2 / dLen1) * dPar1 ; */ + double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) { + + dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj2 >= dLen2 && dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) { + + double dL = dProj2 - dLen2 ; + double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( dProj2 >= m_dRadius && dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius)) { + + if ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) { + + double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; + double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) { + + dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) { + + if ( dProj1 > - dLen1) { + + double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; + double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) { + + double dL = dProj2 - dLen2 ; + double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + // parte non cilindrica + + + if ( dProjMove > - m_dRadius && dProjMove < 0) { + + if ( dSQDistS < m_dRadius * m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - dSQDistS) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( dProjMove >= 0 && dProjMove < dLMove) { + + if ( dSQDist < m_dRadius * m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - dSQDist) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else { + + if ( dSQDistE < m_dRadius * m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - dSQDistE) ; + + dMin = dZ - dH ; dMax = dZ + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ConusPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( Control == false) + + return true ; + + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dCylH = m_dHeight - m_dTipHeight ; + double dZH = ptLs.z ; + + m_nToolType = CylindricalMill ; + m_dHeight = dCylH ; + + MillingXYPlaneGen( ptLs, ptLe, vtToolDir) ; + + m_nToolType = ConusMill ; + m_dHeight = m_dHeight + m_dTipHeight ; + + Point3d ptI, ptF ; + + Vector3d vtV1 ; + + if ( m_dTipRadius < m_dRadius) { + + vtV1 = vtToolDir ; + ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs - vtV1 * dCylH : ptLe - vtV1 * dCylH) ; + ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe - vtV1 * dCylH : ptLs - vtV1 * dCylH) ; + } + else { + + vtV1 = - vtToolDir ; + ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe + vtV1 * m_dHeight : ptLs + vtV1 * m_dHeight) ; + ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs + vtV1 * m_dHeight : ptLe + vtV1 * m_dHeight) ; + } + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtLong = ( vtMove * vtV1) * vtV1 ; double dLen1 = vtLong.LenXY() ; + Vector3d vtOrt = vtMove - vtLong ; double dLen2 = vtOrt.LenXY() ; + Vector3d vtTemp = vtV1 ; vtTemp.Rotate( Z_AX, 90) ; + + vtMove.Normalize() ; + + Vector3d vtV2 = ( vtMove * vtTemp > 0 ? vtTemp : - vtTemp) ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; + double dCos = dTan * ( vtMove * vtV1) / ( vtMove * vtV2) ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + + double dDeltaR = dMaxRad - dMinRad ; + double dMinLim = dMinRad * dCos ; + double dMaxLim = dMaxRad * dCos ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNInf = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 + ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV3 ; + Vector3d vtNSup = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 - ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV3 ; + Point3d ptV = ptI - vtV1 * ( dMaxRad * m_dTipHeight) / ( dMaxRad - dMinRad) ; + Vector3d vtR0 = ptV - ORIG ; + double dDotInf = vtR0 * vtNInf ; + double dDotSup = vtR0 * vtNSup ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + + Vector3d vtC = ptC - ptIxy ; + + double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; + + if ( dRatio <= m_dTipHeight / dDeltaR) { + + if ( dProj1 > - m_dTipHeight && dProj1 < 0 && + dProj2 > - dMaxRad - dTan * dProj1 && + dProj2 < dMaxLim + dProj1 * ( dMaxLim - dMinLim) / m_dTipHeight) { + + double dr = dMaxRad + dTan * dProj1 ; + double dH = sqrt( dr * dr - dProj2 * dProj2) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j , dMin, dMax) ; + } + else if ( dProj1 > dLen1 - m_dTipHeight && dProj1 < dLen1 && + dProj2 > dLen2 - dMaxRad - dTan * dProj1 && + dProj2 < dLen2 + dMaxLim + dProj1 * ( dMaxLim - dMinLim) / m_dTipHeight) { // Se due sistemi di riferimento hanno stessi versori di base e differiscono semplicemente per le origini, + // le proiezioni di un vettore sugli assi nei due sistemi differiscono per le componenti del vettore che congiunge le origini. + double dr = dMaxRad + dTan * ( dProj1 - dLen1) ; + double dH = sqrt( dr * dr - ( dProj2 - dLen2) * ( dProj2 - dLen2)) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 >= 0 && dProj1 < dLen1 && + dProj2 > - dMaxRad + dProj1 * dLen2 / dLen1 && + dProj2 < dMaxLim + dProj1 * dLen2 / dLen1) { + + double dr = abs( dProj2 - dProj1 * dLen2 / dLen1) ; // Proj2 del punto meno Proj2 del centro del cerchio + double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 > - m_dTipHeight && dProj1 < - m_dTipHeight + dLen1 && // Idem con patate + dProj2 > dMinLim + dProj1 * ( dLen2 / dLen1) && + dProj2 < dMinRad + dProj1 * ( dLen2 / dLen1)) { + + double dr = dProj2 - dProj1 * dLen2 / dLen1 ; + double dH = sqrt( dMinRad * dMinRad - dr * dr) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j , dMin, dMax) ; + } + else { // L'unico dominio non normale lo detrerminiamo per sottrazione :) + + dMin = ( dDotInf - ptC.x * vtNInf.x - ptC.y * vtNInf.y) / vtNInf.z ; + dMax = ( dDotSup - ptC.x * vtNSup.x - ptC.y * vtNSup.y) / vtNSup.z ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else { + + if ( dProj1 > - m_dTipHeight && dProj1 <= 0 && + dProj2 > - dMaxRad - dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight && + dProj2 < dMaxRad + dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight) { + + double dr = dMaxRad + dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = sqrt( dr * dr - dProj2 * dProj2) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dProj1 > 0 && dProj1 < dLen1 && + dProj2 > - dMaxRad + dProj1 * ( dLen2 / dLen1) && + dProj2 < dMaxRad + dProj1 * ( dLen2 / dLen1)) { + + double dr = abs( dProj2 - dProj1 * ( dLen2 / dLen1)) ; + double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ; + + dMin = dZH - dH ; dMax = dZH + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + + +// DeltaZ != 0 + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + double dMin, dMax ; + + // Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( Control == false) + + return true ; + + double dCylH = m_dHeight - m_dTipHeight ; + double dZDown = min( ptLs.z, ptLe.z) ; + double dZUp = max( ptLs.z, ptLe.z) ; + + // Definizione di un sistema di riferimento + Vector3d vtV1 = - vtToolDir ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ; + + Point3d ptIC = ptLs ; Point3d ptINC = ptLs + dCylH * vtV1 ; + + Point3d ptICxy( ptIC.x, ptIC.y, 0) ; Point3d ptINCxy( ptINC.x, ptINC.y, 0) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep , dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtCC = ptC - ptICxy ; Vector3d vtNCC = ptC - ptINCxy ; + + double dCPL = vtCC * vtV1 ; double dCPT = vtCC * vtV2 ; + + double dNCPL = vtNCC * vtV1 ; double dNCPT = vtNCC * vtV2 ; + + // Parte cilindrica + if ( dCPL > 0 && dCPL < dCylH && dCPT > - m_dRadius && dCPT < m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - dCPT * dCPT) ; + + dMin = dZDown - dH ; dMax = dZUp + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Parte non cilindrica + if ( m_nToolType == BallEndMill) { + + double dSqLen = vtNCC.SqLenXY() ; + + if ( dNCPL >= 0 && dSqLen < m_dRadius * m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - dSqLen) ; + + dMin = dZDown - dH ; dMax = dZUp + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( m_nToolType == BullNoseMill) { + + if ( dNCPL >= 0 && dNCPL < m_dTipHeight) { + + double dR = m_dTipRadius + sqrt( m_dRCorner * m_dRCorner - dNCPL * dNCPL) ; + + if ( dNCPT > - dR && dNCPT < dR) { + + double dH = sqrt( dR * dR - dNCPT * dNCPT) ; + + dMin = dZDown - dH ; dMax = dZUp + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + else if ( m_nToolType == ConusMill) { + + if ( dNCPL >= 0 && dNCPL < m_dTipHeight && + dNCPT > - m_dRadius - dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight && + dNCPT < m_dRadius + dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight) { + + double dr = m_dRadius + dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; + + double dH = sqrt( dr * dr - dNCPT * dNCPT) ; + + dMin = dZDown - dH ; dMax = dZUp + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill) + + return XYLongVertCylBall( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == ConusMill) + + return XYLongVertConus( ptLs, ptLe, vtToolDir) ; + + else + // Casi al momento non gestiti + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::XYLongVertCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + + unsigned int nStartI, nEndI, nStartJ, nEndJ ; + double dMin, dMax ; + + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + // Se Control è falso non vi è interferenza fra utensile e Zmap + if ( Control == false) + return true ; + + double dDeltaZ = ptLe.z - ptLs.z; + double dCylH = m_dHeight - m_dTipHeight ; + + Point3d ptI, ptF, ptBI, ptBF ; + Vector3d vtV1, vtV2 ; + Vector3d vtMove = ptLe - ptLs ; + + // Studio della parte sferica + if ( ptLs.z < ptLe.z) { + + ptBI = ptLs - vtToolDir * dCylH ; + ptBF = ptLe - vtToolDir * dCylH ; + } + else { + + ptBI = ptLe - vtToolDir * dCylH ; + ptBF = ptLs - vtToolDir * dCylH ; + } + + Point3d ptBIxy( ptBI.x, ptBI.y, 0) ; + Vector3d vtBMove = ptBF - ptBI ; vtBMove.Normalize() ; + Vector3d vtBV1 = ( vtToolDir * vtBMove > 0 ? vtToolDir : - vtToolDir) ; + + double dDeltaBZ = ptBF.z - ptBI.z ; + double dOriz = vtBMove * Z_AX ; + double dVert = vtBMove * vtBV1 ; + + double dSemiAxMin = m_dRadius * dOriz ; + + // Studio delle simmetrie della parte cilindrica + if ( vtToolDir * vtMove < 0 && dDeltaZ < 0) { + + ptI = ptLe - vtToolDir * dCylH ; + ptF = ptLs - vtToolDir * dCylH ; + vtMove = - vtMove ; + vtV1 = - vtToolDir ; + dDeltaZ = - dDeltaZ ; + } + else if ( vtToolDir * vtMove > 0 && dDeltaZ > 0) { + + ptI = ptLs - vtToolDir * dCylH ; + ptF = ptLe - vtToolDir * dCylH ; + vtV1 = - vtToolDir ; + } + else if ( vtToolDir * vtMove > 0 && dDeltaZ < 0) { + + ptI = ptLe ; + ptF = ptLs ; + vtV1 = vtToolDir ; + vtMove = - vtMove ; + dDeltaZ = - dDeltaZ ; + } + else { + + ptI = ptLs ; + ptF = ptLe ; + vtV1 = vtToolDir ; + } + + Point3d ptIxy( ptI.x, ptI.y, 0) ; double dZI = ptI.z ; + + vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + double dLen = abs( vtMove * vtV1) ; + + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtV2 ; + + Vector3d vtBC = ptC - ptBIxy ; + + double dBpr1 = vtBC * vtBV1 ; double dBpr2 = vtBC * vtV2 ; + + // Parte cilindrica + + if ( dProj2 > - m_dRadius && dProj2 < m_dRadius && + dProj1 > 0 && dProj1 < dLen + dCylH) { + + double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; + + // Massimi + if ( dProj1 > 0 && dProj1 < dLen) { + + double dZ0 = ptI.z + dProj1 * ( dDeltaZ / dLen) ; + + dMax = dZ0 + dH ; + } + else if ( dProj1 >= dLen && dProj1 < dLen + dCylH) + + dMax = ptI.z + dDeltaZ + dH ; + + // Minimi + if ( dProj1 > 0 && dProj1 < dCylH) + + dMin = ptI.z - dH ; + + else if ( dProj1 >= dCylH && dProj1 < dLen + dCylH) { + + double dZ0 = ptI.z + ( dProj1 - dCylH) * ( dDeltaZ / dLen) ; + + dMin = dZ0 - dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Parte Non cilindrica + if ( m_nToolType == BallEndMill) { + + double dSqDistO = dBpr2 * dBpr2 ; + double dSqDistI = vtBC.SqLenXY() ; + double dSqDistF = ( dBpr1 - dLen) * ( dBpr1 - dLen) + dBpr2 * dBpr2 ; + + if ( ( dBpr1 < 0 && dSqDistI < m_dRadius * m_dRadius) || + ( dBpr1 >= 0 && dBpr1 < dLen && dSqDistO < m_dRadius * m_dRadius) || + ( dBpr1 >= dLen && dSqDistF < m_dRadius * m_dRadius)) { + + // Massimi + if ( dBpr1 < - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { + + double dH = sqrt( m_dRadius * m_dRadius - dSqDistI) ; + + dMax = ptBI.z + dH ; + } + else if ( dBpr1 >= - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius)) && + dBpr1 < dLen - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { + + double dZ0 = ptBI.z + dVert * sqrt( m_dRadius * m_dRadius - dSqDistO) ; + + dMax = dZ0 + dDeltaBZ * ( dBpr1 + dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) / dLen ; + } + else { + + double dH = sqrt( m_dRadius * m_dRadius - dSqDistF) ; + + dMax = ptBF.z + dH ; + } + + // Minimi + if ( dBpr1 < dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { + + double dH = sqrt( m_dRadius * m_dRadius - dSqDistI) ; + + dMin = ptBI.z - dH ; + } + else if ( dBpr1 >= dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius)) && + dBpr1 < dLen + dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { + + double dZ0 = ptBI.z - dVert * sqrt( m_dRadius * m_dRadius - dSqDistO) ; + + dMin = dZ0 + dDeltaBZ * ( dBpr1 - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) / dLen ; + } + else { + + double dH = sqrt( m_dRadius * m_dRadius - dSqDistF) ; + + dMin = ptBF.z - dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} +/* +//---------------------------------------------------------------------------- +bool +VolZmap::XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dMin, dMax ; + unsigned int nStartI, nEndI, nStartJ, nEndJ ; + + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( Control == false) + + return true ; + + // Parte cilindrica + m_nToolType = CylindricalMill ; + + double dSafeHeight = m_dHeight ; + double dSafeTipHeight = m_dTipHeight ; + double dCylH = m_dHeight - m_dTipHeight ; + + m_dHeight = dCylH ; + m_dTipHeight = 0 ; + + XYLongVertCylBall( ptLs, ptLe, vtToolDir) ; + + m_nToolType = ConusMill ; + m_dHeight = dSafeHeight ; + m_dTipHeight = dSafeTipHeight ; + + // Parte conica + + Point3d ptI, ptF ; + Vector3d vtV1 ; + + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dDeltaR = dMaxRad - dMinRad ; + + double dStem ; + + if ( m_dRadius > m_dTipRadius) { + + vtV1 = vtToolDir ; + dStem = - dCylH ; + } + else { + + vtV1 = - vtToolDir ; + dStem = m_dHeight ; + } + + + if ( vtV1 * ( ptLe - ptLs) * ( ptLe.z - ptLs.z) > 0) { + + ptI = ( ptLe.z - ptLs.z < 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; + ptF = ( ptLe.z - ptLs.z < 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; + } + else { + + ptI = ( ptLe.z - ptLs.z > 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; + ptF = ( ptLe.z - ptLs.z > 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; + } + + double dZI = ptI.z ; + double dDeltaZ = ptF.z - ptI.z ; + + Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / dDeltaR) ; + + // Apertura del cono e parametri per determinare i piani + double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV3) ; + double dCos = dTan * dRatio ; + double dSen = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 - ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ; + Vector3d vtNd = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 + ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ; + Vector3d vtR0 = ptV - ORIG ; + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; double dOrtLen = abs( dProj2) ; + + if ( ( dProj1 > 0 && dProj1 < dPLen && dOrtLen < dMaxRad) || + ( dProj1 >= dPLen && dProj1 < dPLen + m_dTipHeight && + dOrtLen < dMaxRad + ( dProj1 - dPLen) * ( dDeltaR / m_dTipHeight))) { + + // DeltaZ < 0 + if ( dDeltaZ < 0) { + + if ( dRatio <= 1 / dTan) { + + if ( dProj1 < m_dTipHeight && dOrtLen < dMaxRad * dSen - dProj1 * dDeltaR * dSen / m_dTipHeight) { // Il limite inferiore d dProj1 è già stato imposto dall' if più esterno + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; + + dMax = dZI + dH ; + } + else if ( dProj1 > 0 && dProj1 < dPLen && + dOrtLen > dMaxRad * dSen && dOrtLen < dMaxRad) { + + double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ; + + dMax = dZI + dH + dProj1 * dDeltaZ / dPLen ; + } + else if ( dProj1 > m_dHeight && dProj1 < dPLen + m_dHeight && + dOrtLen < dMinRad * dSen) { + + double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ; + + dMax = dZI + dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ; + } + else if ( dProj1 >= dPLen && + dOrtLen > dMaxRad * dSen - ( dProj1 - dPLen) * dDeltaR * dSen / m_dTipHeight) { // I limiti superiori sono già stati imposti dall' if più esterno + + double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; + + double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; + + dMax = dZI + dDeltaZ + dH ; + } + else + + dMin = ( dOrtLen > 0 ? (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ; + + + + if ( dProj1 < dPLen) { // Limiti su dOrtLen già imposti dall' if esterno + + double dH = sqrt( dMaxRad * dMaxRad - dOrtLen* dOrtLen) ; + + dMin = dZI - dH + ( dProj1 - dPLen) * dDeltaZ / dPLen ; + } + else if ( dProj1 >= dPLen) { // Limiti su dOrtLen e su dProj1 già imposti dall' if esterno + + double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; + + double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; + + dMax = dZI + dDeltaZ - dH ; + } + + SubtractIntervals( i, j, dMax, dMin) ; + } + else { + // dRatio > + } + } + else { // dDeltaZ > 0 + + if () { // dRatio < + + } + else { // dRatio > + + } + + } + } + } + + return true ; +} +*/ + +//---------------------------------------------------------------------------- +bool +VolZmap::XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dZL1, dZL2 ; + unsigned int nStartI, nEndI, nStartJ, nEndJ ; + + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( Control == false) + + return true ; + + // Parte cilindrica + m_nToolType = CylindricalMill ; + + double dSafeHeight = m_dHeight ; + double dSafeTipHeight = m_dTipHeight ; + double dCylH = m_dHeight - m_dTipHeight ; + + m_dHeight = dCylH ; + m_dTipHeight = 0 ; + + XYLongVertCylBall( ptLs, ptLe, vtToolDir) ; + + m_nToolType = ConusMill ; + m_dHeight = dSafeHeight ; + m_dTipHeight = dSafeTipHeight ; + + // Parte conica + + Point3d ptI, ptF ; + Vector3d vtV1 ; + + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dDeltaR = dMaxRad - dMinRad ; + + double dStem ; + + if ( m_dRadius > m_dTipRadius) { + + vtV1 = vtToolDir ; + dStem = - dCylH ; + } + else { + + vtV1 = - vtToolDir ; + dStem = m_dHeight ; + } + + + if ( vtV1 * ( ptLe - ptLs) * ( ptLe.z - ptLs.z) > 0) { + + ptI = ( ptLe.z - ptLs.z < 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; + ptF = ( ptLe.z - ptLs.z < 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; + } + else { + + ptI = ( ptLe.z - ptLs.z > 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; + ptF = ( ptLe.z - ptLs.z > 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; + } + + double dZI = ptI.z ; + double dDeltaZ = ptF.z - ptI.z ; + double dFactor = ( dDeltaZ > 0 ? - 1 : 1) ; + + Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / dDeltaR) ; + + // Apertura del cono e parametri per determinare i piani + double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; + double dRatio = ( dDeltaZ > 0 ? - ( vtMove * vtV1) / ( vtMove * vtV3) : ( vtMove * vtV1) / ( vtMove * vtV3)) ; + double dCos = dTan * dRatio ; + double dSen = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + dFactor * ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 - dFactor * ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ; + Vector3d vtNd = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + dFactor * ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 + dFactor * ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ; + Vector3d vtR0 = ptV - ORIG ; + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtV2 ; double dOrtLen = abs( dProj2) ; + + if ( ( dProj1 > 0 && dProj1 < dPLen && dOrtLen < dMaxRad) || + ( dProj1 >= dPLen && dProj1 < dPLen + m_dTipHeight && + dOrtLen < dMaxRad + ( dProj1 - dPLen) * ( dDeltaR / m_dTipHeight))) { + + + if ( dRatio <= 1 / dTan) { + + if ( dProj1 < m_dTipHeight && dOrtLen < dMaxRad * dSen - dProj1 * dDeltaR * dSen / m_dTipHeight) { // Il limite inferiore d dProj1 è già stato imposto dall' if più esterno + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; + + dZL1 = dZI + dFactor * dH ; + } + else if ( dProj1 > 0 && dProj1 < dPLen && + dOrtLen > dMaxRad * dSen && dOrtLen < dMaxRad) { + + double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ; + + dZL1 = dZI + dFactor * dH + dProj1 * dDeltaZ / dPLen ; + } + else if ( dProj1 > m_dTipHeight && dProj1 < dPLen + m_dHeight && + dOrtLen < dMinRad * dSen) { + + double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ; + + dZL1 = dZI + dFactor * dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ; + } + else if ( dProj1 >= dPLen && + dOrtLen > dMaxRad * dSen - ( dProj1 - dPLen) * dDeltaR * dSen / m_dTipHeight) { // I limiti superiori sono già stati imposti dall' if più esterno + + double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; + + double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; + + dZL1 = dZI + dDeltaZ + dFactor * dH ; + } + else { + + if ( dDeltaZ < 0) + + dZL1 = ( dProj2 > 0 ? (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ; + else + dZL1 = ( dProj2 > 0 ? (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z : (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z) ; + } + + + + if ( dProj1 < dPLen) { // Limiti su dOrtLen già imposti dall' if esterno + + double dH = sqrt( dMaxRad * dMaxRad - dOrtLen* dOrtLen) ; + + dZL2 = dZI - dFactor * dH + dProj1 * dDeltaZ / dPLen ; + } + else if ( dProj1 >= dPLen) { // Limiti su dOrtLen e su dProj1 già imposti dall' if esterno + + double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; + + double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; + + dZL2 = dZI + dDeltaZ - dFactor * dH ; + } + + SubtractIntervals( i, j, dZL1, dZL2) ; + } + else { + + if ( dProj1 < dPLen && dOrtLen < dMaxRad) { + + double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ; + + dZL1 = dZI + dH + dProj1 * dDeltaZ / dPLen ; + dZL2 = dZI - dH + dProj1 * dDeltaZ / dPLen ; + } + else if ( dProj1 >= dPLen) { + + double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; + + double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; + + dZL1 = dZI + dDeltaZ + dH ; + dZL2 = dZI + dDeltaZ - dH ; + } + + SubtractIntervals( i, j, dZL1, dZL2) ; + } + } + } + + + return true ; +} + + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill) + + return MillingXYCyl( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == BallEndMill) + + return MillingXYBall( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == ConusMill) + + return MillingXYConus( ptLs, ptLe, vtToolDir) ; + + else + + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + + double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; + double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + Point3d ptI, ptF ; + + if ( ptLs.z < ptLe.z) { + ptI = ptLs ; + ptF = ptLe ; + } + else { + ptI = ptLe ; + ptF = ptLs ; + } + + // Quote dei punti ptI e ptF + double dZI = ptI.z ; double dZF = ptF.z ; + + Point3d ptIT = ptI - vtToolDir * m_dHeight ; + Point3d ptFT = ptF - vtToolDir * m_dHeight ; + + // Bounding box + double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; + double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; + double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; + double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; + + // Seconda verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + + Vector3d vtMove = ptF - ptI ; //double dLenPath = vtMove.Len() ; + + // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMove ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Determinazione punti notevoli del volume spazzato dall'utensile + Point3d ptPlaneSup, ptPlaneInf ; + + if ( vtV3.z > 0) { + ptPlaneInf = ptI - m_dRadius * vtV3 ; + ptPlaneSup = ptI + m_dRadius * vtV3 ; + } + else { + ptPlaneInf = ptI + m_dRadius * vtV3 ; + ptPlaneSup = ptI - m_dRadius * vtV3 ; + } + + // Prodotti scalari per costruire i piani passanti per i punti notevoli + Vector3d vtR0Inf = ptPlaneInf - ORIG ; + Vector3d vtR0Sup = ptPlaneSup - ORIG ; + + double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; + + // Determinazione delle proiezioni sul piano delle entità geometriche fondamentali + Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ; + Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ; + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Vector3d vtTemp = vtV1 ; vtTemp.Rotate( Z_AX, 90) ; + Vector3d vtW2 = ( vtTemp * vtV2 > 0 ? vtTemp : - vtTemp) ; + + // Determinazione limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dMin, dMax ; + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y + double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano + double dProj2 = vtC * vtW2 ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza + + if ( dProj1 < 0 && dProj1 > - m_dHeight && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) { + + + // Minimi + if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) { + + double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; + + dMin = dZI - dH ; + } + else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) { + + dMin = dZInf ; + } + else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; + + dMin = dZF - dH ; + } + // Massimi + if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) { + + double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; + + dMax = dZI + dH ; + } + else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) { + + dMax = dZSup ; + } + else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; + + dMax = dZF + dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } // Fine ciclo + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; + double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + Point3d ptI, ptF ; + + if ( ptLs.z < ptLe.z) { + ptI = ptLs ; + ptF = ptLe ; + } + else { + ptI = ptLe ; + ptF = ptLs ; + } + + // Quote dei punti ptI e ptF e DeltaZ + double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; + + Point3d ptIT = ptI - vtToolDir * m_dHeight ; + Point3d ptFT = ptF - vtToolDir * m_dHeight ; + + // Bounding box + double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; + double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; + double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; + double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; + + // Seconda verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + + Vector3d vtMove = ptF - ptI ; + + // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMove ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Determinazione punti notevoli del volume spazzato dall'utensile + Point3d ptPlaneSup, ptPlaneInf ; + + if ( vtV3.z > 0) { + ptPlaneInf = ptI - m_dRadius * vtV3 ; + ptPlaneSup = ptI + m_dRadius * vtV3 ; + } + else { + ptPlaneInf = ptI + m_dRadius * vtV3 ; + ptPlaneSup = ptI - m_dRadius * vtV3 ; + } + + // Prodotti scalari per costruire i piani passanti per i punti notevoli + Vector3d vtR0Inf = ptPlaneInf - ORIG ; + Vector3d vtR0Sup = ptPlaneSup - ORIG ; + + double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; + + // Determinazione delle proiezioni sul piano delle entità geometriche fondamentali + Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ; + Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ; + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Vector3d vtTemp = vtToolDir ; vtTemp.Rotate( Z_AX, 90) ; + Vector3d vtW2 = ( vtTemp * vtV2 > 0 ? vtTemp : - vtTemp) ; + + + + // Determinazione limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dMin, dMax ; + double dCylH = m_dHeight - m_dRadius ; + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y + double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano + double dProj2 = vtC * vtW2 ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza + + // Parte cilindrica + if ( dProj1 < 0 && dProj1 > - dCylH && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) { + + // Minimi + if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) { + + double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; + + dMin = dZI - dH ; + } + else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) { + + dMin = dZInf ; + } + else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; + + dMin = dZF - dH ; + } + // Massimi + if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) { + + double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; + + dMax = dZI + dH ; + } + else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) { + + dMax = dZSup ; + } + else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) { + + double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; + + dMax = dZF + dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + // Parte sferica + else if ( dProj1 <= - dCylH && ( ( dProj2 > - m_dRadius && dProj2 < 0 && dProj2 * dProj2 + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius) || + ( dProj2 >= 0 && dProj2 < dPlanePath && dProj1 > - m_dHeight) || + ( dProj2 >= dPlanePath && dProj2 < dPlanePath + m_dRadius && ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius))) { + + + double dSemiMin = dPlaneLim ; double dSemiMax = m_dRadius ; // Semi-assi dell'ellisse + double dl = - dProj1 - dCylH ; + + // Massimi + if ( dProj2 < - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { + + double dr = sqrt( dProj2 * dProj2 + dl * dl) ; + double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; + + dMax = dZI + dH ; + } + else if ( dProj2 < dPlanePath - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { + + double dCos = abs( vtV3 * Z_AX) ; + + dMax = dZI + sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ; + } + else { + + double dL = dProj2 - dPlanePath ; + double dr = sqrt( dL * dL + dl * dl) ; + + double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; + + dMax = dZF + dH ; + } + + // Minimi + if ( dProj2 < dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { + + double dr = sqrt( dProj2 * dProj2 + dl * dl) ; + double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; + + dMin = dZI - dH ; + } + else if ( dProj2 < dPlanePath + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { + + double dCos = abs( vtV3 * Z_AX) ; + + dMin = dZI - sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ; + } + else { + + double dr = sqrt( ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + dl * dl) ; + double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; + + dMin = dZF - dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } // Fine ciclo + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( Control == false) + + return true ; + + double dCylH = m_dHeight - m_dTipHeight ; + + // Parte cilindrica + m_nToolType = CylindricalMill ; + m_dHeight = dCylH ; + + MillingXY( ptLs, ptLe, vtToolDir) ; + + m_nToolType = ConusMill ; + m_dHeight = m_dHeight + m_dTipHeight ; + + Vector3d vtV1, vtV2, vtV3 ; + Point3d ptI, ptF ; + + double dStem ; + + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dDeltaR = dMaxRad - dMinRad ; + + // Studio della parte conica + if ( m_dRadius > m_dTipRadius) { + + vtV1 = vtToolDir ; + dStem = - dCylH ; + } + else { + + vtV1 = - vtToolDir ; + dStem = m_dHeight ; + } + + ptI = ( ptLs.z < ptLe.z ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; + ptF = ( ptLs.z < ptLe.z ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; double dZI = ptI.z ; double dDeltaZ = ptF.z - ptI.z ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ; + Vector3d vtU2 = vtV1 ; vtU2.Rotate(Z_AX, 90) ; + + if ( vtMoveXY * vtU2 < 0) + + vtU2 = - vtU2 ; + + vtV2 = vtMove ; vtV2.Normalize() ; + vtV3 = vtV1 ^ vtV2 ; + + Point3d ptV = ptI - vtV1 * ( dMaxRad * m_dTipHeight / ( dMaxRad - dMinRad)) ; + + Vector3d vtV3XY( vtV3.x, vtV3.y, 0) ; + + double dPrV3 = vtV3XY.LenXY() ; + double dRl = dMaxRad * dPrV3 ; + double drl = dMinRad * dPrV3 ; + double dDl = dDeltaR * dPrV3 ; + + // Apertura del cono e parametri per determinare i piani + double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + double dCos = dTanAlpha * dRatio ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTanAlpha / sqrt( 1 + dTanAlpha * dTanAlpha)) * vtV1 + ( dCos / sqrt( 1 + dTanAlpha * dTanAlpha)) * vtV2 + ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTanAlpha * dTanAlpha)) * vtV3 ; + Vector3d vtNd = - ( dTanAlpha / sqrt( 1 + dTanAlpha * dTanAlpha)) * vtV1 + ( dCos / sqrt( 1 + dTanAlpha * dTanAlpha)) * vtV2 - ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTanAlpha * dTanAlpha)) * vtV3 ; + Vector3d vtR0 = ptV - ORIG ; + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtU2 ; + + if ( dProj1 > 0 && dProj1 < m_dTipHeight && + dProj2 > - dMaxRad + dProj1 * dDeltaR / m_dTipHeight && + dProj2 < dPLen + dMaxRad - dProj1 * dDeltaR / m_dTipHeight) { + /* + if ( dProj2 < - dRl + dProj1 * dDl / m_dTipHeight) { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - dProj2 * dProj2) ; + + dMin = dZI - dH ; + dMax = dZI + dH ; + } + else if ( dProj2 >= - dRl + dProj1 * dDl / m_dTipHeight && + dProj2 < dRl - dProj1 * dDl / m_dTipHeight) { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - dProj2 * dProj2) ; + + dMin = dZI - dH ; + dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + } + else if ( dProj2 >= dRl - dProj1 * dDl / m_dTipHeight && + dProj2 < dPLen - dRl + dProj1 * dDl / m_dTipHeight) { + + dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; + dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + } + else if ( dProj2 >= dPLen - dRl + dProj1 * dDl / m_dTipHeight && + dProj2 < dPLen + dRl - dProj1 * dDl / m_dTipHeight) { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; + + dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; + dMax = dZI + dDeltaZ + dH ; + } + else { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; + + dMin = dZI + dDeltaZ - dH ; + dMax = dZI + dDeltaZ + dH ; + } */ + + // Massimi + if ( dProj2 < - dRl + dProj1 * dDl / m_dTipHeight) { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - dProj2 * dProj2) ; + + dMax = dZI + dH ; + } + else if ( dProj2 >= - dRl + dProj1 * dDl / m_dTipHeight && + dProj2 < dPLen - dRl + dProj1 * dDl / m_dTipHeight) + + dMax = ( vtV3.z < 0 ? ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ; + else { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; + + dMax = dZI + dDeltaZ + dH ; + } + + // Minimi + if ( dProj2 < dRl - dProj1 * dDl / m_dTipHeight) { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - dProj2 * dProj2) ; + + dMin = dZI - dH ; + } + else if ( dProj2 >= dRl - dProj1 * dDl / m_dTipHeight && + dProj2 < dPLen + dRl - dProj1 * dDl / m_dTipHeight) + + dMin = ( vtV3.z < 0 ? ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z : ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z) ; + + else { + + double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; + double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; + + dMin = dZI + dDeltaZ - dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYPlus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill) + + return MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == BallEndMill) + + return MillingXYPlusBall( ptLs, ptLe, vtToolDir) ; + + else if ( m_nToolType == ConusMill) + + return MillingXYPlusConus( ptLs, ptLe, vtToolDir) ; + + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; + double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + Point3d ptI, ptF ; + + if ( ptLs.z <= ptLe.z) { + ptI = ptLs ; + ptF = ptLe ; + } + else { + ptI = ptLe ; + ptF = ptLs ; + } + + // Quote dei punti ptI e ptF e DeltaZ + double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; + + Point3d ptIT = ptI - vtToolDir * m_dHeight ; + Point3d ptFT = ptF - vtToolDir * m_dHeight ; + + // Bounding box + double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; + double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; + double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; + double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; + + // Seconda verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + + // Vettori di riferimento nello spazio e controllo per simmetria + Vector3d vtMove = ptF - ptI ; + Vector3d vtTool = vtToolDir ; + + if ( vtToolDir * vtMove > 0) { + + Point3d ptTemp = ptI ; + ptI = ptIT ; ptIT = ptTemp ; + ptTemp = ptF ; + ptF = ptFT ; + ptFT = ptTemp ; + vtTool = - vtTool ; + } + + Vector3d vtMoveLong = ( vtMove * vtTool) * vtTool ; double dLen1 = vtMoveLong.Len() ; + Vector3d vtMoveOrt = vtMove - vtMoveLong ; double dLen2 = vtMoveOrt.Len() ; + + // Vettori di riferimento nel piano + Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; + Vector3d vtPlaneMoveLong( vtMoveLong.x, vtMoveLong.y, 0) ; double dPLen1 = vtPlaneMoveLong.LenXY() ; + Vector3d vtPlaneMoveOrt( vtMoveOrt.x, vtMoveOrt.y, 0) ; double dPLen2 = vtPlaneMoveOrt.LenXY() ; vtPlaneMoveOrt.Normalize() ; + + // Punti iniziale e finale proiettati sul piano + Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; + + // Determino i sistemi di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento + Vector3d vtV1 = vtTool ; + Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Determinazione punti notevoli del volume spazzato dall'utensile + Point3d ptPlaneSup, ptPlaneInf ; + + if ( vtV3.z > 0) { + ptPlaneInf = ptI - m_dRadius * vtV3 ; + ptPlaneSup = ptI + m_dRadius * vtV3 ; + } + else { + ptPlaneInf = ptI + m_dRadius * vtV3 ; + ptPlaneSup = ptI - m_dRadius * vtV3 ; + } + + Point3d ptPlaneSupxy( ptPlaneSup.x, ptPlaneSup.y, 0) ; + Point3d ptPlaneInfxy( ptPlaneInf.x, ptPlaneInf.y, 0) ; + + double dr = sqrt( ( ptPlaneSupxy - ptIxy) * ( ptPlaneSupxy - ptIxy)) ; + + // Determinazione degli analoghi punti sulla punta dell'utensile e delle loro proiezioni sul piano XY + Point3d ptPlTInf = ptPlaneInf - m_dHeight * vtTool ; Point3d ptPlTInfxy( ptPlTInf.x, ptPlTInf.y, 0) ; + Point3d ptPlTSup = ptPlaneSup - m_dHeight * vtTool ; Point3d ptPlTSupxy( ptPlTSup.x, ptPlTSup.y, 0) ; + + // Prodotti scalari per costruire i piani passanti per i punti notevoli + Vector3d vtR0Inf = ptPlaneInf - ORIG ; + Vector3d vtR0Sup = ptPlaneSup - ORIG ; + Vector3d vtR0 = ptI - ORIG ; + double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; double dP = vtR0 * vtV3 ; + + // Determinazione limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dMin, dMax ; + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + double dZPInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y + double dZPSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano superiore come funzione di x e y + + // Punto e vettori del ciclo + Point3d ptC( dX, dY, 0) ; Vector3d vtCi = ptC - ptIxy ; + // Proiezione fondamentale + double dPro1 = vtCi * vtV1 ; double dPro2 = vtCi * vtPlaneMoveOrt ; + + + // Se il punto cade nella proiezione sul piano XY del volume spazzato si taglia + if ( ((dPro2 > - m_dRadius && dPro2 < m_dRadius) && (((dPro2 < dPLen2 - m_dRadius && (dPro1 > - m_dHeight - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) && dPro1 < 0))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < 0)))) + || ((dPro2 >= m_dRadius && dPro2 < dPLen2 + m_dRadius) && ((dPro2 < dPLen2 - m_dRadius && (dPro1 > - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) - m_dHeight && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius)))))) { + + // Massimi ////////////////////////////////////////////////////////////////////////// + // Prima zona cilindrica superiore + if ( ( dPro2 > - m_dRadius && dPro2 < - dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { + + double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; + + dMax = dZI + dH ; + } + + // Vettore per seconda zona cilindrica superiore + Vector3d vtCf = ptC - ptFxy ; + // Proiezione per seconda zona cilindrica sueriore + double dPr1 = vtCf * vtV1 ; double dPr2 = vtCf * vtPlaneMoveOrt ; + + // Seconda zona cilindrica superiore + if ( ( dPr2 >= - dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { + + double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; + + dMax = dZF + dH ; + } + + // Vettore per Piano superiore e zona di fondo superiore + Vector3d vtCS = ptC - ptPlaneSupxy ; + // Proiezioni + double dPrS1 = vtCS * vtV1 ; double dPrS2 = vtCS * vtPlaneMoveOrt ; + + // Piano superiore + if ( dPrS2 >= 0 && dPrS2 < dPLen2 && dPrS1 > - m_dHeight - ( dPLen1/dPLen2) * dPrS2 && dPrS1 <= - ( dPLen1/dPLen2) * dPrS2) + + dMax = dZPSup ; + + // Vettore per zona di punta superiore + Vector3d vtCTS = ptC - ptPlTSupxy ; + // Proiezioni + double dPrTS1 = vtCTS * vtV1 ; double dPrTS2 = vtCTS * vtPlaneMoveOrt ; + + // Zona di punta superiore + if ( dPrTS1 <= 0 && dPrTS1 > - dPLen1) + if ( dPrTS2 <= - ( dPLen2 / dPLen1) * dPrTS1 && dPrTS2 > - ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrTS1) { + + double dDist = - ( dPLen2 / dPLen1) * dPrTS1 - dPrTS2 ; + double dL = dDist + dr ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + double dl = sqrt( dPrTS1 * dPrTS1 + ( ( dPLen2 / dPLen1) * dPrTS1) * ( ( dPLen2 / dPLen1) * dPrTS1)) ; + + dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; + } + + // Zona di fondo superiore + if ( dPrS1 < 0 && dPrS1 > - dPLen1) + if ( dPrS2 > - ( dPLen2 / dPLen1) * dPrS1 && dPrS2 < m_dRadius + dr - ( dPLen2 / dPLen1) * dPrS1) { + + double dL = abs( dr - ( dPLen2 / dPLen1) * dPrS1 - dPrS2) ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + double dl = sqrt( dPrS1 * dPrS1 + ( ( dPLen2 / dPLen1) * dPrS1) * ( ( dPLen2 / dPLen1) * dPrS1)) ; + + dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; + } + + // Minimi ////////////////////////////////////////////////////////////////////////// + // Prima zona cilindrica inferiore + if ( ( dPro2 > - m_dRadius && dPro2 < dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { + + double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; + + dMin = dZI - dH ; + } + + // Seconda zona cilindrica inferiore + if ( ( dPr2 >= dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { + + double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; + + dMin = dZF - dH ; + } + + // Vettore per piano inferiore e zona di fondo inferiore + Vector3d vtCI = ptC - ptPlaneInfxy ; + // Proiezioni + double dPrI1 = vtCI * vtV1 ; double dPrI2 = vtCI * vtPlaneMoveOrt ; + + // Piano inferiore + if ( dPrI2 >= 0 && dPrI2 < dPLen2 && dPrI1 > - m_dHeight - ( dPLen1/dPLen2) * dPrI2 && dPrI1 <= - ( dPLen1/dPLen2) * dPrI2) + + dMin = dZPInf ; + + // Zona di fondo inferiore + if ( dPrI1 <= 0 && dPrI1 > - dPLen1) + if ( dPrI2 > - ( dPLen2 / dPLen1) * dPrI1 && dPrI2 < ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrI1) { + + double dDist = dPrI2 + ( dPLen2 / dPLen1) * dPrI1 ; + double dL = dDist + dr ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + double dl = sqrt( dPrI1 * dPrI1 + ( ( dPLen2 / dPLen1) * dPrI1) * ( ( dPLen2 / dPLen1) * dPrI1)) ; + + dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; + } + + // Vettore per zona di punta inferiore + Vector3d vtCTI = ptC - ptPlTInfxy ; + // Proiezioni + double dPrTI1 = vtCTI * vtV1 ; double dPrTI2 = vtCTI * vtPlaneMoveOrt ; + + // zona di punta inferiore + if ( dPrTI1 <= 0 && dPrTI1 > - dPLen1) + if ( dPrTI2 > - m_dRadius - dr - ( dPLen2 / dPLen1) * dPrTI1 && dPrTI2 < - ( dPLen2 / dPLen1) * dPrTI1) { + + double dL = abs( - dr - ( dPLen2 / dPLen1) * dPrTI1 - dPrTI2) ; + double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; + double dl = sqrt( dPrTI1 * dPrTI1 + ( ( dPLen2 / dPLen1) * dPrTI1) * ( ( dPLen2 / dPLen1) * dPrTI1)) ; + + dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } // Fine ciclo + return true ; +} + + + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + // Parte cilindrica + + double dCylH = m_dHeight - m_dRadius ; + + m_dHeight = dCylH ; + + MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; + + m_dHeight = m_dHeight + m_dRadius ; + //////////////////////////////////////// + Point3d ptI, ptF ; + + if ( ptLs.z < ptLe.z) { + + ptI = ptLs ; + ptF = ptLe ; + } + else { + + ptI = ptLe ; + ptF = ptLs ; + } + + double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; + + Point3d ptCI = ptI - dCylH * vtToolDir ; + Point3d ptCF = ptF - dCylH * vtToolDir ; + + Point3d ptCIxy( ptCI.x, ptCI.y, 0) ; + + // Bounding box + double dMinX = min( ptCI.x, ptCF.x) - m_dRadius ; + double dMaxX = max( ptCI.x, ptCF.x) + m_dRadius ; + double dMinY = min( ptCI.y, ptCF.y) - m_dRadius ; + double dMaxY = max( ptCI.y, ptCF.y) + m_dRadius ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; vtMove.Normalize() ; + + // Sistema di riferimento nel piano + Vector3d vtV2 = vtPlaneMove ; vtV2.Normalize() ; double dComp1 = vtV2 * X_AX ; double dComp2 = vtV2 * Y_AX ; + Vector3d vtV1 = dComp2 * X_AX - dComp1 * Y_AX ; + + // Determino il semi-asse minore + double dOriz = vtMove * Z_AX ; double dVert = vtMove * vtV2 ; + + double dSemiAxMin = m_dRadius * dOriz ; + + // Determinazione limiti sugli indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dMin, dMax ; + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtC = ptC - ptCIxy ; + + double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; + + double dSqRadDistI = dProj1 * dProj1 + dProj2 * dProj2 ; + double dSqRadDistF = dProj1 * dProj1 + ( dProj2 - dPLen) * ( dProj2 - dPLen) ; + double dSqAxDist = dProj1 * dProj1 ; + + if ( ( dProj2 < 0 && dSqRadDistI < m_dRadius * m_dRadius) || + ( dProj2 >= 0 && dProj2 < dPLen && dSqAxDist < m_dRadius * m_dRadius) || + ( dProj2 >= dPLen && dSqRadDistF < m_dRadius * m_dRadius)) { + + // Massimi + if ( dProj2 < - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { + + double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; + + dMax = dZI + dH ; + } + else if ( dProj2 >= - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) && + dProj2 < dPLen - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { + + double dProj0 = - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ; + double dZ0 = dZI + dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ; + + dMax = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ; + } + else { + + double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; + + dMax = dZF + dH ; + } + + // Minimi + if ( dProj2 < dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { + + double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; + + dMin = dZI - dH ; + } + else if ( dProj2 >= dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) && + dProj2 < dPLen + dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { + + double dProj0 = dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ; + double dZ0 = dZI - dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ; + + dMin = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ; + } + else { + + double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; + + dMin = dZF - dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } // Fine ciclo + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingXYPlusConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + double dMin, dMax ; + + bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir) ; + + if ( Control == false) + + return true ; + + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dDeltaR = dMaxRad - dMinRad ; + + double dCylH = m_dHeight - m_dTipHeight ; + + // Parte cilindrica + m_nToolType = CylindricalMill ; + m_dHeight = dCylH ; + + MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; + + m_nToolType = ConusMill ; + m_dHeight = m_dHeight + m_dTipHeight ; + + // Variabili di interesse per la parte conica + Vector3d vtV1, vtV2, vtV3 ; + Point3d ptI, ptF ; + + double dStem ; + + // Studio della parte conica + if ( m_dRadius > m_dTipRadius) { + + vtV1 = vtToolDir ; + dStem = - dCylH ; + } + else { + + vtV1 = - vtToolDir ; + dStem = m_dHeight ; + } + + ptI = ( ptLs.z < ptLe.z ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; + ptF = ( ptLs.z < ptLe.z ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveLong = ( vtMove * vtV1) * vtV1 ; + Vector3d vtMoveOrt = vtMove - vtMoveLong ; + Vector3d vtMoveLongXY( vtMoveLong.x, vtMoveLong.y, 0) ; + Vector3d vtMoveOrtXY( vtMoveOrt.x, vtMoveOrt.y, 0) ; + + double dPLen1 = vtMoveLongXY.LenXY() ; + double dPLen2 = vtMoveOrtXY.LenXY() ; + double dPLen = sqrt( dPLen1 * dPLen1 + dPLen2 * dPLen2) ; + + vtV2 = ( vtMove * vtV1 > 0 ? vtMoveOrt : - vtMoveOrt) ; vtV2.Normalize() ; + vtV3 = vtV1 ^ vtV2 ; + + Vector3d vtU2 = vtMoveOrtXY ; vtU2.Normalize() ; + + Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / ( dDeltaR)) ; + + // Apertura del cono e parametri per determinare i piani + double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + double dCos = dTan * dRatio ; // dCos è compreso fra 0 e 1 poiché alpha è compreso fra 0 e Pi mezzi + + double dZI = ptI.z ; + double dDeltaZ = ptF.z - ptI.z ; + // double dCornerSlope = atan2( dDeltaZ, dPLen1) ; // dCornerSlope è compreso fra 0 ° e 90 °, per come è costruito il movimento, ma espresso in radianti + + // Punti di tagenza piano cono + Point3d ptPrs = ptI - vtV1 * m_dTipHeight + dMinRad * ( dCos * vtV2 + sqrt( 1 - dCos * dCos) * vtV3) ; + Point3d ptPRs = ptI + dMaxRad * ( dCos * vtV2 + sqrt( 1 - dCos * dCos) * vtV3) ; + Point3d ptPrd = ptI - vtV1 * m_dTipHeight + dMinRad * ( dCos * vtV2 - sqrt( 1 - dCos * dCos) * vtV3) ; + Point3d ptPRd = ptI + dMaxRad * ( dCos * vtV2 - sqrt( 1 - dCos * dCos) * vtV3) ; + + Point3d ptRInf = ( ptPRs.z < ptPRd.z ? ptPRs : ptPRd) ; + Point3d ptRSup = ( ptPRs.z < ptPRd.z ? ptPRd : ptPRs) ; + Point3d ptrInf = ( ptPrs.z < ptPrd.z ? ptPrs : ptPrd) ; + Point3d ptrSup = ( ptPrs.z < ptPrd.z ? ptPrd : ptPrs) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 + ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV3 ; + Vector3d vtNd = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 - ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV3 ; + Vector3d vtR0 = ptV - ORIG ; + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + // Sistema di riferimento del movimento + Vector3d vtU3 = vtV1 ^ vtU2 ; + Frame3d MoveFrame ; MoveFrame.Set( ptI, vtV1, vtU2, vtU3) ; + + ptRInf.LocToLoc( m_LocalFrame, MoveFrame) ; double dPRInf = ptRInf.y ; + ptRSup.LocToLoc( m_LocalFrame, MoveFrame) ; double dPRSup = ptRSup.y ; + ptrInf.LocToLoc( m_LocalFrame, MoveFrame) ; double dPrInf = ptrInf.y ; + ptrSup.LocToLoc( m_LocalFrame, MoveFrame) ; double dPrSup = ptrSup.y ; + + // dMinX dMaxX dMinY dMaxY + double dMinX = min( min( ptI.x, ptF.x), min( ptI.x - vtV1.x * m_dTipHeight, ptF.x - vtV1.x * m_dTipHeight)) - dMaxRad; + double dMinY = min( min( ptI.y, ptF.y), min( ptI.y - vtV1.y * m_dTipHeight, ptF.y - vtV1.y * m_dTipHeight)) - dMaxRad; + double dMaxX = max( max( ptI.x, ptF.x), max( ptI.x - vtV1.x * m_dTipHeight, ptF.x - vtV1.x * m_dTipHeight)) + dMaxRad; + double dMaxY = max( max( ptI.y, ptF.y), max( ptI.y - vtV1.y * m_dTipHeight, ptF.y - vtV1.y * m_dTipHeight)) + dMaxRad; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return true ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return true ; + + // Limiti su indici + unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX, dY ; dX = ( i + 0.5) * m_dStep ; dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dI1 = vtC * vtV1 ; double dI2 = vtC * vtU2 ; + + + if ( dRatio <= 1 / dTan) { + + + if ( vtMove * vtV1 > 0) { + + + double dLimInf = max( - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight, - dMaxRad + dI1 * ( dPLen2 / dPLen1)) ; + double dLimSup = min( dMinRad + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1), dPLen2 + dMinRad + ( dI1 - dPLen1 + m_dTipHeight) * ( dMaxRad - dMinRad) / m_dTipHeight) ; + + if ( dI1 > - m_dTipHeight && dI1 < dPLen1 && dI2 > dLimInf && dI2 < dLimSup) { + + // Massimi + if ( dI1 > 0 && dI2 < dPRSup + dI1 * ( dPLen2 / dPLen1)) { + + double dr = dI1 * ( dPLen2 / dPLen1) - dI2 ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato + double dl = dI1 * sqrt( 1 + (dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; + + dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; + } + else if ( dI1 < dPLen1 - m_dTipHeight && dI2 > dPrSup + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { + + double dr = dI2 - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato + double dl = ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; + // Controllare da qui + dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; + } + else if ( dI1 <= 0 && dI2 < dPRSup + dI1 * ( dPRSup - dPrSup) / m_dTipHeight) { + + double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = sqrt( dr * dr - dI2 * dI2) ; + + dMax = dZI + dH ; + } + else if ( dI1 >= dPLen1 - m_dTipHeight && dI2 > dPLen2 + dPRSup + ( dI1 - dPLen1) * ( dPRSup - dPrSup) / m_dTipHeight) { + + double dr = dMaxRad + ( dI1 - dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) ; + + dMax = dZI + dDeltaZ + dH ; + } + else + + dMax = max( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ; + + + + // Minimi + if ( dI1 > 0 && dI2 < dPRInf + dI1 * ( dPLen2 / dPLen1)) { + + double dr = dI1 * ( dPLen2 / dPLen1) - dI2 ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato + double dl = dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; + + dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; + } + else if ( dI1 < dPLen1 - m_dTipHeight && dI2 > dPrInf + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { + + double dr = dI2 - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato + double dl = ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; + + dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; + } + else if ( dI1 <= 0 && dI2 < dPRInf + dI1 * ( dPRInf - dPrInf) / m_dTipHeight) { + + double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = sqrt( dr * dr - dI2 * dI2) ; + + dMin = dZI - dH ; + } + else if ( dI1 >= dPLen1 - m_dTipHeight && dI2 > dPLen2 + dPRInf + ( dI1 - dPLen1) * ( dPRInf - dPrInf) / m_dTipHeight) { + + double dr = dMaxRad + ( dI1 - dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) ; + + dMin = dZI + dDeltaZ - dH ; + } + else + + dMin = min( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ; + + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + // vtMove * vtV1 < 0 + else { + + double dLimInf = max( - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight, - dMinRad - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) ; + double dLimSup = min( dMaxRad - dI1 * ( dPLen2 / dPLen1), dPLen2 + dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight) ; + + if ( dI1 > - dPLen1 - m_dTipHeight && dI1 < 0 && dI2 > dLimInf && dI2 < dLimSup) { + + // Massimi + if ( dI1 > - m_dTipHeight && dI2 < dPRSup + dI1 * ( dPRSup - dPrSup) / m_dTipHeight) { + + double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = ( dr * dr - dI2 * dI2 > 0 ? sqrt( dr * dr - dI2 * dI2) : 0) ; + + dMax = dZI + dH ; + } + else if ( dI1 < - dPLen1 && dI2 > dPLen2 + dPRSup + (dI1 + dPLen1) * ( dPRSup - dPrSup) / m_dTipHeight) { + + double dr = dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = ( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2) > 0 ? sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) : 0) ; + + dMax = dZI + dDeltaZ + dH ; + } + else if ( dI1 < - m_dTipHeight && dI2 < dPrSup - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { + + double dr = - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) - dI2 ; + double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; + double dl = - ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + + dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; + } + else if ( dI1 > - dPLen1 && dI2 > dPRSup - dI1 * ( dPLen2 / dPLen1)) { + + double dr = dI2 + dI1 * ( dPLen2 / dPLen1) ; + double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; + double dl = - dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + + dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; + } + else + + dMax = max( ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z, ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z ) ; + + + // Minimi + if ( dI1 > - m_dTipHeight && dI2 < dPRInf + dI1 * ( dPRInf - dPrInf) / m_dTipHeight) { + + double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = ( dr * dr - dI2 * dI2 > 0 ? sqrt( dr * dr - dI2 * dI2) : 0) ; + + dMin =dZI - dH ; + } + else if ( dI1 < - dPLen1 && dI2 > dPLen2 + dPRInf + ( dI1 + dPLen1) * ( dPRInf - dPrInf) / m_dTipHeight) { + + double dr = dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = ( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2) > 0 ? sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) : 0) ; + + dMin = dZI + dDeltaZ - dH ; + + } + else if ( dI1 < - m_dTipHeight && dI2 < dPrInf - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { + + double dr = - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) - dI2 ; + double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; + double dl = - ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + + dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; + } + else if ( dI1 > - dPLen1 && dI2 > dPRInf - dI1 * ( dPLen2 / dPLen1)) { + + double dr = dI2 + dI1 * ( dPLen2 / dPLen1) ; + double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; + double dl = - dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + + dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; + } + else + + dMin = min( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ; + + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + // dRatio <= 1 / dTan + else { + + if ( dI1 > - m_dTipHeight && dI1 < 0 && + dI2 > - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight && + dI2 < dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight) { + + double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; + double dH = sqrt( dr * dr - dI2 * dI2) ; + + dMin = dZI - dH ; + dMax = dZI + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( dI1 >= 0 && dI1 < dPLen1 && + dI2 > - dMaxRad + dI1 * ( dPLen2 / dPLen1) && + dI2 < dMaxRad + dI1 * ( dPLen2 / dPLen1)) { + + double dl = dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; + double dr = dI2 - dI1 * dPLen2 / dPLen1 ; + double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ; + + dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; + dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +// Virtual milling per componenti + +// Versore utensile nella direzione dell'asse Z + +// Foratura +//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +bool +VolZmap::DrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) { + + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + Vector3d vtMove = ptLe - ptLs ; + + const ICurve* pCurve ; + + pCurve = m_ToolOutline.GetFirstCurve() ; + + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + LongCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + LongConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + LongConusV( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + else if ( nCurveType == CRV_ARC) { + + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = vtStRad.LenXY() ; + + + const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ; + const ICurve* pNext = m_ToolOutline.GetNextCurve() ; + + pNext = m_ToolOutline.GetNextCurve() ; + + Point3d ptPs, ptCt, ptCb, ptNe ; + Vector3d vtNPf, vtNCi, vtNCf, vtNNi ; + Vector3d vtIProd, vtFProd ; + + ptCt = ptO + Y_AX * dRadius ; + ptCb = ptO - Y_AX * dRadius ; + + pPrev -> GetStartPoint( ptPs) ; + pPrev -> GetEndDir( vtNPf) ; + pCurve -> GetStartDir( vtNCi) ; + vtIProd = vtNPf ^ vtNCi ; + + if ( pNext != nullptr) { + + pNext -> GetEndPoint( ptNe) ; + pCurve -> GetEndDir( vtNCf) ; + pNext -> GetStartDir( vtNNi) ; + vtFProd = vtNCf ^ vtNNi ; + } + + + if ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptPs.y > ptCt.y) && + ( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) || + ( pNext != nullptr && vtFProd.z > 0 && ptCb.y > ptNe.y))) { + + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + Ball( ptOSt, ptOEn, dRadius) ; + } + else { + + PolyLine Polygonal ; + + pCurve -> ApproxWithLines( dLinTol, dAngTolDeg, 10, Polygonal) ; + + Point3d ptLineStart, ptLineEnd, ptAux ; + + Point3d ptIapp = ptI ; + Point3d ptFapp = ptF ; + + Polygonal.GetFirstPoint( ptLineStart) ; + + bool bTest = Polygonal.GetNextPoint( ptLineEnd) ; + + double dAppHeight ; + + while ( bTest == true) { + + dAppHeight = abs( ptLineStart.y - ptLineEnd.y) ; + + if ( abs( ptLineStart.x - ptLineEnd.x) < EPS_SMALL) { + + double dRadius = ptLineStart.x ; + + LongCylV( ptIapp, ptFapp, vtToolDir, dAppHeight, dRadius) ; + } + else if ( ptLineStart.x > ptLineEnd.x) { + + double dMinRad = ptLineEnd.x ; + double dMaxRad = ptLineStart.x ; + + LongConusV( ptIapp, ptFapp, vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + else if ( ptLineStart.x < ptLineEnd.x) { + + double dMinRad = ptLineStart.x ; + double dMaxRad = ptLineEnd.x ; + + Point3d ptIn = ptIapp - vtToolDir * dAppHeight ; + Point3d ptFn = ptIn + vtMove ; + + LongConusV( ptIn, ptFn, - vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + + ptIapp = ptIapp - vtToolDir * dAppHeight ; + ptFapp = ptIapp + vtMove ; + + ptLineStart = ptLineEnd ; + bTest = Polygonal.GetNextPoint( ptLineEnd) ; + } + } + + dHeight = abs( ptStart.y - ptEnd.y) ; + + pNext = m_ToolOutline.GetPrevCurve() ; + + } + + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + + pCurve = m_ToolOutline.GetNextCurve() ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::LongCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) { + + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( Control == false) + + return true ; + + Point3d ptI = ( ( ptLe - ptLs) * vtToolDir > 0 ? ptLe : ptLs) ; + Point3d ptF = ( ( ptLe - ptLs) * vtToolDir > 0 ? ptLs - dHei * vtToolDir : ptLe - dHei * vtToolDir) ; + + if ( ptI.z > ptF.z) { + + Point3d ptTemp = ptI ; + ptI = ptF ; + ptF = ptTemp ; + } + + Point3d ptO( ptI.x, ptI.y, 0) ; + + double dZI = ptI.z ; + double dZF = ptF.z ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; + + double dSqDist = vtC * vtC ; + + if ( dSqDist < dRad * dRad) + + SubtractIntervals( i, j, dZI, dZF) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::LongConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) { + + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( Control == false) + + return true ; + + Point3d ptO( ptLs.x, ptLs.y, 0) ; + + double dZMin, dZMax ; + + double dAngC = dHei / ( dMaxRad - dMinRad) ; + + if ( vtToolDir.z > 0) { + + dZMin = ( ptLs.z < ptLe.z ? ptLs.z - dHei : ptLe.z - dHei) ; + dZMax = ( ptLs.z < ptLe.z ? ptLe.z : ptLs.z) ; + } + else { + + dZMin = ( ptLs.z < ptLe.z ? ptLs.z : ptLe.z) ; + dZMax = ( ptLs.z < ptLe.z ? ptLe.z + dHei : ptLs.z + dHei) ; + } + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; + + double dSqDist = vtC * vtC ; + + if ( dSqDist < dMinRad * dMinRad) + + SubtractIntervals( i, j, dZMin, dZMax) ; + + else if ( dSqDist < dMaxRad * dMaxRad) { + + double dr = sqrt( dSqDist) ; + + if ( vtToolDir.z > 0) + + SubtractIntervals( i, j, dZMin + dAngC * ( dr - dMinRad), dZMax) ; + else + SubtractIntervals( i, j, dZMin, dZMax - dAngC * ( dr - dMinRad)) ; + } + } + + return true ; +} + +// Fresatura + +//---------------------------------------------------------------------------- +bool +VolZmap::MillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) { + + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + Vector3d vtMove = ptLe - ptLs ; + + const ICurve* pCurve ; + + pCurve = m_ToolOutline.GetFirstCurve() ; + + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + MillCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + MillConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + MillConusV( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + else if ( nCurveType == CRV_ARC) { + + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = vtStRad.LenXY() ; + + + const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ; + const ICurve* pNext = m_ToolOutline.GetNextCurve() ; + + pNext = m_ToolOutline.GetNextCurve() ; + + Point3d ptPs, ptCt, ptCb, ptNe ; + Vector3d vtNPf, vtNCi, vtNCf, vtNNi ; + Vector3d vtIProd, vtFProd ; + + ptCt = ptO + Y_AX * dRadius ; + ptCb = ptO - Y_AX * dRadius ; + + pPrev -> GetStartPoint( ptPs) ; + pPrev -> GetEndDir( vtNPf) ; + pCurve -> GetStartDir( vtNCi) ; + vtIProd = vtNPf ^ vtNCi ; + + if ( pNext != nullptr) { + + pNext -> GetEndPoint( ptNe) ; + pCurve -> GetEndDir( vtNCf) ; + pNext -> GetStartDir( vtNNi) ; + vtFProd = vtNCf ^ vtNNi ; + } + + + if ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptPs.y > ptCt.y) && + ( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) || + ( pNext != nullptr && vtFProd.z > 0 && ptCb.y > ptNe.y))) { + + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + Ball( ptOSt, ptOEn, dRadius) ; + } + else { + + PolyLine Polygonal ; + + pCurve -> ApproxWithLines( dLinTol, dAngTolDeg, 10, Polygonal) ; + + Point3d ptLineStart, ptLineEnd, ptAux ; + + Point3d ptIapp = ptI ; + Point3d ptFapp = ptF ; + + Polygonal.GetFirstPoint( ptLineStart) ; + + bool bTest = Polygonal.GetNextPoint( ptLineEnd) ; + + double dAppHeight ; + + while ( bTest == true) { + + dAppHeight = abs( ptLineStart.y - ptLineEnd.y) ; + + if ( abs( ptLineStart.x - ptLineEnd.x) < EPS_SMALL) { + + double dRadius = ptLineStart.x ; + + MillCylV( ptIapp, ptFapp, vtToolDir, dAppHeight, dRadius) ; + } + else if ( ptLineStart.x > ptLineEnd.x) { + + double dMinRad = ptLineEnd.x ; + double dMaxRad = ptLineStart.x ; + + MillConusV( ptIapp, ptFapp, vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + else if ( ptLineStart.x < ptLineEnd.x) { + + double dMinRad = ptLineStart.x ; + double dMaxRad = ptLineEnd.x ; + + Point3d ptIn = ptIapp - vtToolDir * dAppHeight ; + Point3d ptFn = ptIn + vtMove ; + + MillConusV( ptIn, ptFn, - vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + + ptIapp = ptIapp - vtToolDir * dAppHeight ; + ptFapp = ptIapp + vtMove ; + + ptLineStart = ptLineEnd ; + bTest = Polygonal.GetNextPoint( ptLineEnd) ; + } + } + + dHeight = abs( ptStart.y - ptEnd.y) ; + + pNext = m_ToolOutline.GetPrevCurve() ; + + } + + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + + pCurve = m_ToolOutline.GetNextCurve() ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( Control == false) + + return true ; + + Point3d ptI, ptF ; + + + if ( ( ptLe - ptLs) * vtToolDir < 0 && vtToolDir.z > 0) { + + ptI = ptLe ; + ptF = ptLs ; + } + else if ( ( ptLe - ptLs) * vtToolDir < 0 && vtToolDir.z < 0) { + + ptI = ptLs - dHei * vtToolDir ; + ptF = ptLe - dHei * vtToolDir ; + } + else if ( ( ptLe - ptLs) * vtToolDir > 0 && vtToolDir.z < 0) { + + ptI = ptLe - dHei * vtToolDir ; + ptF = ptLs - dHei * vtToolDir ; + } + else { + + ptI = ( vtToolDir.z > 0 ? ptLs : ptLs - vtToolDir * dHei) ; + ptF = ( vtToolDir.z > 0 ? ptLe : ptLe - vtToolDir * dHei) ; + } + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtV1 = ptFxy - ptIxy ; double dPLen = vtV1.LenXY() ; vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + double dZI = ptI.z ; + double dDeltaZ = ptF.z - ptI.z ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; //Vector3d vtCF = ptC - ptFxy ; + + double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; + + if ( dX2 > - dRad && dX2 < dRad && + dX1 > - sqrt( dRad * dRad - dX2 * dX2) && + dX1 < dPLen + sqrt( dRad * dRad - dX2 * dX2)) { + + // Massimi + if( dX1 > - sqrt( dRad * dRad - dX2 * dX2) && + dX1 < dPLen - sqrt( dRad * dRad - dX2 * dX2)) + + dMax = dZI + ( dX1 + sqrt( dRad * dRad - dX2 * dX2)) * dDeltaZ / dPLen ; + + else if ( dX1 >= dPLen - sqrt( dRad * dRad - dX2 * dX2) && + dX1 < dPLen + sqrt( dRad * dRad - dX2 * dX2)) + + dMax = dZI + dDeltaZ ; + + // Minimi + if ( dX1 > - sqrt( dRad * dRad - dX2 * dX2) && + dX1 < sqrt( dRad * dRad - dX2 * dX2)) + + dMin = dZI - dHei ; + + else if ( dX1 >= sqrt( dRad * dRad - dX2 * dX2) && + dX1 < dPLen + sqrt( dRad * dRad - dX2 * dX2)) + + dMin = dZI - dHei + ( dX1 - sqrt( dRad * dRad - dX2 * dX2)) * dDeltaZ / dPLen ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) { + + double dMin, dMax, dPLim, dMLim ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( Control == false) + + return true ; + + + Point3d ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; + Point3d ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + double dZI = ptI.z ; + double dZTI = ptI.z - vtV1.z * dHei ; + double dDeltaZ = ptF.z - ptI.z ; + double dDeltaR = dMaxRad - dMinRad ; + + double dTan = dDeltaR / dHei ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + double dCos = dTan * dRatio ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; + + Vector3d vtNs = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 + ( dSin / sqrt( 1 + dTan * dTan)) * vtV3 ; + Vector3d vtNd = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 - ( dSin / sqrt( 1 + dTan * dTan)) * vtV3 ; + Vector3d vtR0 = ptV - ORIG ; + + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCI = ptC - ptIxy ; double dSqDI = vtCI.SqLenXY() ; + Vector3d vtCF = ptC - ptFxy ; double dSqDF = vtCF.SqLenXY() ; + + double dIDO = vtCI * vtV3 ; + double dIDL = vtCI * vtV2 ; + double dIVarCos = dIDL / sqrt( dSqDI) ; + + double dFDL = vtCF * vtV2 ; + double dFVarCos = dFDL / sqrt( dSqDF) ; + + if ( dSqDI < dMaxRad * dMaxRad || dSqDF < dMaxRad * dMaxRad || + (abs( dIDO) < dMaxRad && dIDL > 0 && dIDL < dLOrt)) { + + // Caso dTan > 1 / dRatio + if ( dRatio > 1 / dTan) { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) + + dPLim = dZI + dDeltaZ ; + + else + + dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) + + dMLim = dZTI ; + + else if ( dSqDI < dMaxRad * dMaxRad) + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + else + + dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + } + else { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) + + dPLim = dZI + dDeltaZ ; + + else + + dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) + + dMLim = dZTI ; + + else if ( dSqDI >= dMinRad * dMinRad && dSqDI < dMaxRad * dMaxRad && dIVarCos < dCos) + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + else if ( dSqDI >= dMinRad * dMinRad && dIVarCos >= dCos && dFVarCos < dCos && abs( dIDO) < dMaxRad * dSin) { // da qui + + if ( dIDO > - dMaxRad * dSin && dIDO <= - dMinRad * dSin) + + dMLim = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + + else if ( dIDO > - dMinRad * dSin && dIDO < dMinRad * dSin) + + dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + else if ( dIDO >= dMinRad * dSin && dIDO < dMaxRad * dSin) + + dMLim = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; // a qui + } + else if ( dFVarCos >= dCos) { + + if ( dSqDF < dMinRad * dMinRad) + + dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + else + + dMLim = dZTI + dDeltaZ + ( sqrt( dSqDF) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + } + else + + dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + } + + dMin = min( dPLim, dMLim) ; + dMax = max( dPLim, dMLim) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +// Direzione generica del versore utensile +// Foratura +//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +bool +VolZmap::Drilling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill) + + LongCyl( ptLs, ptLe, vtToolDir, m_dHeight, m_dRadius) ; + + else if ( m_nToolType == BallEndMill) { + + double dCylH = m_dHeight - m_dTipHeight ; + + LongCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; + + Point3d ptBs = ptLs - vtToolDir * ( m_dHeight - m_dTipHeight) ; + Point3d ptBe = ptLe - vtToolDir * ( m_dHeight - m_dTipHeight) ; + + Ball( ptBs, ptBe, m_dRadius) ; + } + else if ( m_nToolType == BullNoseMill) + // Caso al momento non gestito + return false ; + + else if ( m_nToolType == ConusMill) { + + double dCylH = m_dHeight - m_dTipHeight ; + + LongCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; + + double dMinRad = ( m_dRadius > m_dTipRadius ? m_dTipRadius : m_dRadius) ; + double dMaxRad = ( m_dRadius > m_dTipRadius ? m_dRadius : m_dTipRadius) ; + + Point3d ptCs = ( m_dRadius > m_dTipRadius ? ptLs - dCylH * vtToolDir : ptLs - m_dHeight * vtToolDir) ; + Point3d ptCe = ( m_dRadius > m_dTipRadius ? ptLe - dCylH * vtToolDir : ptLe - m_dHeight * vtToolDir) ; + Vector3d vtDir = ( m_dRadius > m_dTipRadius ? vtToolDir : - vtToolDir) ; + + LongConus( ptCs, ptCe, vtDir, m_dTipHeight, dMaxRad, dMinRad) ; + } + else if ( m_nToolType == GenericTool) + // Caso al momento non gestito + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::DrillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) { + + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + Vector3d vtMove = ptLe - ptLs ; + + const ICurve* pCurve ; + + pCurve = m_ToolOutline.GetFirstCurve() ; + + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + LongCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + LongConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + LongConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + else if ( nCurveType == CRV_ARC) { + + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = vtStRad.LenXY() ; + + + const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ; + const ICurve* pNext = m_ToolOutline.GetNextCurve() ; + + pNext = m_ToolOutline.GetNextCurve() ; + + Point3d ptPs, ptCt, ptCb, ptNe ; + Vector3d vtNPf, vtNCi, vtNCf, vtNNi ; + Vector3d vtIProd, vtFProd ; + + ptCt = ptO + Y_AX * dRadius ; + ptCb = ptO - Y_AX * dRadius ; + + pPrev -> GetStartPoint( ptPs) ; + pPrev -> GetEndDir( vtNPf) ; + pCurve -> GetStartDir( vtNCi) ; + vtIProd = vtNPf ^ vtNCi ; + + if ( pNext != nullptr) { + + pNext -> GetEndPoint( ptNe) ; + pCurve -> GetEndDir( vtNCf) ; + pNext -> GetStartDir( vtNNi) ; + vtFProd = vtNCf ^ vtNNi ; + } + + + if ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptPs.y > ptCt.y) && + ( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) || + ( pNext != nullptr && vtFProd.z > 0 && ptCb.y > ptNe.y))) { + + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + Ball( ptOSt, ptOEn, dRadius) ; + } + else { + + PolyLine Polygonal ; + + pCurve -> ApproxWithLines( dLinTol, dAngTolDeg, 10, Polygonal) ; + + Point3d ptLineStart, ptLineEnd, ptAux ; + + Point3d ptIapp = ptI ; + Point3d ptFapp = ptF ; + + Polygonal.GetFirstPoint( ptLineStart) ; + + bool bTest = Polygonal.GetNextPoint( ptLineEnd) ; + + double dAppHeight ; + + while ( bTest == true) { + + dAppHeight = abs( ptLineStart.y - ptLineEnd.y) ; + + if ( abs( ptLineStart.x - ptLineEnd.x) < EPS_SMALL) { + + double dRadius = ptLineStart.x ; + + LongCyl( ptIapp, ptFapp, vtToolDir, dAppHeight, dRadius) ; + } + else if ( ptLineStart.x > ptLineEnd.x) { + + double dMinRad = ptLineEnd.x ; + double dMaxRad = ptLineStart.x ; + + LongConus( ptIapp, ptFapp, vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + else if ( ptLineStart.x < ptLineEnd.x) { + + double dMinRad = ptLineStart.x ; + double dMaxRad = ptLineEnd.x ; + + Point3d ptIn = ptIapp - vtToolDir * dAppHeight ; + Point3d ptFn = ptIn + vtMove ; + + LongConus( ptIn, ptFn, - vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + + ptIapp = ptIapp - vtToolDir * dAppHeight ; + ptFapp = ptIapp + vtMove ; + + ptLineStart = ptLineEnd ; + bTest = Polygonal.GetNextPoint( ptLineEnd) ; + } + } + + dHeight = abs( ptStart.y - ptEnd.y) ; + + pNext = m_ToolOutline.GetPrevCurve() ; + + } + + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + + pCurve = m_ToolOutline.GetNextCurve() ; + } + + return true ; +} + +// Componenti elementari degli utensili +//---------------------------------------------------------------------------- +bool +VolZmap::LongCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) { + + double dMin, dMax; + unsigned int nStartI, nEndI, nStartJ, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( Control == false) + + return true ; + + + // Studio delle simmetrie + Vector3d vtMove = ptLe - ptLs ; + + Point3d ptI = ( vtMove * vtToolDir > 0 ? ptLe : ptLs) ; + Point3d ptF = ( vtMove * vtToolDir > 0 ? ptLs - dHei * vtToolDir : ptLe - dHei * vtToolDir) ; + + if ( ptI.z > ptF.z) { + + Point3d ptTemp = ptI ; + ptI = ptF ; + ptF = ptTemp ; + } + + double dDeltaZ = ptF.z - ptI.z ; + double dZI = ptI.z ; + + // Definizione + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtCyl = ptF - ptI ; double dLen = sqrt( vtCyl * vtCyl) ; + Vector3d vtCylVer( 0, 0, vtCyl.z) ; double dLVer = abs( vtCyl.z) ; + Vector3d vtCylOri( vtCyl.x, vtCyl.y, 0) ; double dLOri = vtCylOri.LenXY() ; + + double dCos = dLVer / dLen ; // Coseno dell'angolo formato da vtCyl con l'asse Z. + double dSin = dLOri / dLen ; // Seno dell'angolo formato da vtCyl con l'asse Z. + + double dSemiMin = dRad * dCos ; + + // Definizione del sistema di riferimento nel piano + Vector3d vtU1 = vtCylOri ; + + if ( vtU1.LenXY() < EPS_SMALL) { + + vtU1 = ( 1 + sqrt(vtCyl.x * vtCyl.x + vtCyl.y * vtCyl.y)) / sqrt(vtCyl.x * vtCyl.x + vtCyl.y * vtCyl.y) * vtU1 ; + } + + vtU1.Normalize() ; + + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + // Definizione piani + Vector3d vtV = vtMove ; vtV.Normalize() ; + Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV ; + Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; + + double dProjI1 = vtCI * vtU1 ; double dProjI2 = vtCI * vtU2 ; + double dProjF1 = vtCF * vtU1 ; double dProjF2 = vtCF * vtU2 ; + + if ( dProjI1 > - dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) && + dProjI1 < dLOri + dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) && + dProjI2 * dProjI2 < dRad * dRad) { + + // Massimi + if ( dProjI1 < dLOri - dCos * sqrt( dRad * dRad - dProjI2 * dProjI2)) { + + double dZ0 = dSin * sqrt( dRad * dRad - dProjI2 * dProjI2) ; + double dI10 = - dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) ; + + dMax = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; + } + else + + dMax = ( dDotF - vtV.x * dX - vtV.y *dY) / vtV.z ; + + // Minimi + if ( dProjI1 < dCos * sqrt( dRad * dRad - dProjI2 * dProjI2)) + + dMin = ( dDotI - vtV.x * dX - vtV.y *dY) / vtV.z ; + + else { + + double dZ0 = - dSin * sqrt( dRad * dRad - dProjI2 * dProjI2) ; + double dI10 = dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) ; + + dMin = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::LongBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, 0) ; + + if ( Control == false) + + return true ; + + Point3d ptI = ( ( ptLe - ptLs) * vtToolDir < 0 ? ptLs : ptLe) ; + Point3d ptF = ( ( ptLe - ptLs) * vtToolDir < 0 ? ptLe : ptLs) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + double dDeltaZ = ptF.z - ptI.z ; + double dZI = ptI.z ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtMoveVer( 0, 0, vtMove.z) ; double dLVer = abs( vtMove.z) ; + Vector3d vtMoveOri( vtMove.x, vtMove.y, 0) ; double dLOri = vtMoveOri.LenXY() ; + + // Definizione del sistema di riferimento nel piano + Vector3d vtU1 = vtMoveOri ; + + if ( vtU1.LenXY() < EPS_SMALL) + + vtU1 = ( 1 + sqrt(vtMove.x * vtMove.x + vtMove.y * vtMove.y)) / sqrt(vtMove.x * vtMove.x + vtMove.y * vtMove.y) * vtU1 ; + + vtU1.Normalize() ; + + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + double dCos = dLVer / dLen ; // Sempre positivo + double dSin = dLOri / dLen ; // Sempre positivo + + double dSemiMin = dRad * abs( dCos) ; + + Vector3d vtV = vtMove ; vtV.Normalize() ; + + Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; + + double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; + double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; + + // Massimi + if ( ( dPI1 > - dCos * sqrt( dRad * dRad - dPI2 * dPI2) && + dPI1 < dLOri && dPI2 * dPI2 < dRad * dRad) || + ( dPF1 * dPF1 + dPF2 * dPF2 < dRad * dRad)) { + + if ( dDeltaZ > 0) { + + // Massimi + if ( dPI1 < dLOri - dCos * sqrt( dRad * dRad - dPI2 * dPI2)) { + + double dPI0 = - dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; + double dZ0 = dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; + + dMax = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; + } + else { + + double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; + double dH = sqrt( dRad * dRad - dSqD) ; + + dMax = dZI + dDeltaZ + dH ; + } + + // Minimi + if ( dPI1 < dCos * sqrt( dRad * dRad - dPI2 * dPI2)) + + dMin = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; + + else if ( dPI1 < dLOri + dCos * sqrt( dRad * dRad - dPI2 * dPI2)) { + + double dPI0 = dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; + double dZ0 = - dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; + + dMin = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; + } + else { + + double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; + double dH = sqrt( dRad * dRad - dSqD) ; + + dMin = dZI + dDeltaZ - dH ; + } + } + else { + + // Massimi + if ( dPI1 < dCos * sqrt( dRad * dRad - dPI2 * dPI2)) + + dMax = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; + + else if ( dPI1 < dLOri + dCos * sqrt( dRad * dRad - dPI2 * dPI2)) { + + double dPI0 = dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; + double dZ0 = + dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; + + dMax = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; + } + else { + + double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; + double dH = sqrt( dRad * dRad - dSqD) ; + + dMax = dZI + dDeltaZ + dH ; + } + + // Minimi + if ( dPI1 < dLOri - dCos * sqrt( dRad * dRad - dPI2 * dPI2)) { + + double dPI0 = - dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; + double dZ0 = - dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; + + dMin = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; + } + else { + + double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; + double dH = sqrt( dRad * dRad - dSqD) ; + + dMin = dZI + dDeltaZ - dH ; + } + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::LongConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( Control == false) + + return true ; + + + Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.Len() ; + Vector3d vtMZ( 0, 0, vtMove.z) ; double dLVer = abs( vtMove.z) ; + Vector3d vtMXY( vtMove.x, vtMove.y, 0) ; double dLOri = vtMXY.LenXY() ; + + double dSin = dLOri / dLen ; + double dCos = dLVer / dLen ; + + double dSemiMinR = dMaxRad * dCos ; + double dSemiMinr = dMinRad * dCos ; + + // Sistema di riferimento sul cono + Vector3d vtV1 = vtToolDir ; // controllare qui e negli altri coni che le proiezioni non siano troppo piccole FORSE CONVIENE FARE I CONTI CON VTMOVE NORMALIZZATO (QUESTO IN TUTTI I MOVIMENTI) + + double dCoef23 = ( vtV1.z > 0 ? 1 : - 1) ; + double dCoef21 = - dCoef23 * vtV1.z ; // vtV1.z := vtV1 * Z_AX + + Vector3d vtV2 = dCoef21 * vtV1 + dCoef23 * Z_AX ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Simmetrie del problema riguardanti il cono + Point3d ptCBot = ( vtV1 * vtMove > 0 ? ptLs : ptLe) ; + Point3d ptCTip = ptCBot - dHei * vtV1 ; + + double dDeltaR = dMaxRad - dMinRad ; + double dTan = dDeltaR / dHei ; + double dL = ( ( dMaxRad * dHei) / dDeltaR) ; + double dl = dL - dHei ; + + Point3d ptV = ptCBot - vtV1 * dL ; + + // Simmetrie del problema riguardanti il cilinidro + Point3d ptCylI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + Point3d ptCylF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + + double dDeltaZ = ptCylF.z - ptCylI.z ; + double dZCylI = ptCylI.z ; + + // Piani cono + Vector3d vtR0B = ptCBot - ORIG ; double dDotB = vtR0B * vtV1 ; + Vector3d vtR0T = ptCTip - ORIG ; double dDotT = vtR0T * vtV1 ; + + + // Piani cilindro + Vector3d vtR0I = ptCylI - ORIG ; double dDotI = vtR0I * vtV1 ; + Vector3d vtR0F = ptCylF - ORIG ; double dDotF = vtR0F * vtV1 ; + + + // Punti sul piano + Point3d ptCylIxy( ptCylI.x, ptCylI.y, 0) ; + Point3d ptCBotxy( ptCBot.x, ptCBot.y, 0) ; + + + // Riferimenti sul piano + Vector3d vtU1( ptCylF.x - ptCylI.x, ptCylF.y - ptCylI.y, 0) ; vtU1.Normalize() ; + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + Vector3d vtW1( vtV1.x, vtV1.y, 0) ; vtW1.Normalize() ; + Vector3d vtW2 = vtW1 ; vtW2.Rotate( Z_AX, 90) ; + + // Sistema di riferimento del cono + Frame3d ConusFrame ; ConusFrame.Set( ptV, vtV1, vtV2, vtV3) ; + + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptCylIxy ; + + double dPCyl1 = vtC * vtU1 ; double dPCyl2 = vtC * vtU2 ; + + // Parte cilindrica + if ( dPCyl2 * dPCyl2 < dMaxRad * dMaxRad && + dPCyl1 > - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) && + dPCyl1 < dLOri + dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) { + + // Massimi + if ( dPCyl1 < dLOri - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) { + + double dZ0 = dSin * sqrt( dMaxRad * dMaxRad - dPCyl2 * dPCyl2) ; + double dP0 = - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) ; + + dMax = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; + } + else + + dMax = ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; + + // Minimi + if ( dPCyl1 < dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) + + dMin = ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; + + else { + + double dZ0 = - dSin * sqrt( dMaxRad * dMaxRad - dPCyl2 * dPCyl2) ; + double dP0 = dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) ; + + dMin = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Parte conica + Vector3d vtD = Z_AX ; + + ptC.LocToLoc( m_LocalFrame, ConusFrame) ; + + vtD.LocToLoc( m_LocalFrame, ConusFrame) ; + + std::vector vdCoef(3); + std::vector vdRoots; + + vdCoef[0] = ( dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z) ; + vdCoef[1] = 2 * ( dTan * dTan * ptC.x * vtD.x - ptC.y * vtD.y - ptC.z * vtD.z) ; + vdCoef[2] = dTan * dTan * vtD.x * vtD.x - vtD.y * vtD.y - vtD.z * vtD.z ; + + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + if ( nRoot == 1) { + + Point3d ptR1 = ptC + vdRoots[0] * vtD ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( ConusFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nRoot == 2) { + + Point3d ptR1 = ptC + vdRoots[0] * vtD ; + Point3d ptR2 = ptC + vdRoots[1] * vtD ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConusFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConusFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( ConusFrame, m_LocalFrame) ; + ptR2.LocToLoc( ConusFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( ConusFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + return true ; +} + +// Fresatura +//---------------------------------------------------------------------------- +bool +VolZmap::Milling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + + if ( m_nToolType == CylindricalMill) + + return MillCyl( ptLs, ptLe, vtToolDir, m_dHeight, m_dRadius) ; + + else if ( m_nToolType == BallEndMill) { + + double dCylH = m_dHeight - m_dTipHeight ; + + MillCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; + + Point3d ptBs = ptLs - vtToolDir * ( m_dHeight - m_dTipHeight) ; + Point3d ptBe = ptLe - vtToolDir * ( m_dHeight - m_dTipHeight) ; + + Ball( ptBs, ptBe, m_dRadius) ; + return true ; + } + else if ( m_nToolType == BullNoseMill) + // Caso al momento non gestito + return false ; + + else if ( m_nToolType == ConusMill) { + + double dCylH = m_dHeight - m_dTipHeight ; + + MillCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; + + double dMinRad = ( m_dRadius > m_dTipRadius ? m_dTipRadius : m_dRadius) ; + double dMaxRad = ( m_dRadius > m_dTipRadius ? m_dRadius : m_dTipRadius) ; + + Point3d ptCs = ( m_dRadius > m_dTipRadius ? ptLs - dCylH * vtToolDir : ptLs - m_dHeight * vtToolDir) ; + Point3d ptCe = ( m_dRadius > m_dTipRadius ? ptLe - dCylH * vtToolDir : ptLe - m_dHeight * vtToolDir) ; + Vector3d vtDir = ( m_dRadius > m_dTipRadius ? vtToolDir : - vtToolDir) ; + + MillConus( ptCs, ptCe, vtDir, m_dTipHeight, dMaxRad, dMinRad) ; + return true ; + } + else if ( m_nToolType == GenericTool) + // Caso al momento non gestito + return false ; + else + return false ; + +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) +{ + + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + Vector3d vtMove = ptLe - ptLs ; + + const ICurve* pCurve ; + + pCurve = m_ToolOutline.GetFirstCurve() ; + + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + MillCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + MillConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + MillConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + else if ( nCurveType == CRV_ARC) { + + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = vtStRad.LenXY() ; + + + const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ; + const ICurve* pNext = m_ToolOutline.GetNextCurve() ; + + pNext = m_ToolOutline.GetNextCurve() ; + + Point3d ptPs, ptCt, ptCb, ptNe ; + Vector3d vtNPf, vtNCi, vtNCf, vtNNi ; + Vector3d vtIProd, vtFProd ; + + ptCt = ptO + Y_AX * dRadius ; + ptCb = ptO - Y_AX * dRadius ; + + pPrev -> GetStartPoint( ptPs) ; + pPrev -> GetEndDir( vtNPf) ; + pCurve -> GetStartDir( vtNCi) ; + vtIProd = vtNPf ^ vtNCi ; + + if ( pNext != nullptr) { + + pNext -> GetEndPoint( ptNe) ; + pCurve -> GetEndDir( vtNCf) ; + pNext -> GetStartDir( vtNNi) ; + vtFProd = vtNCf ^ vtNNi ; + } + + + if ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptPs.y > ptCt.y) && + ( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) || + ( pNext != nullptr && vtFProd.z > 0 && ptCb.y > ptNe.y))) { + + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + Ball( ptOSt, ptOEn, dRadius) ; + } + else { + + PolyLine Polygonal ; + + pCurve -> ApproxWithLines( dLinTol, dAngTolDeg, 10, Polygonal) ; + + Point3d ptLineStart, ptLineEnd, ptAux ; + + Point3d ptIapp = ptI ; + Point3d ptFapp = ptF ; + + Polygonal.GetFirstPoint( ptLineStart) ; + + bool bTest = Polygonal.GetNextPoint( ptLineEnd) ; + + double dAppHeight ; + + while ( bTest == true) { + + dAppHeight = abs( ptLineStart.y - ptLineEnd.y) ; + + if ( abs( ptLineStart.x - ptLineEnd.x) < EPS_SMALL) { + + double dRadius = ptLineStart.x ; + + MillCyl( ptIapp, ptFapp, vtToolDir, dAppHeight, dRadius) ; + } + else if ( ptLineStart.x > ptLineEnd.x) { + + double dMinRad = ptLineEnd.x ; + double dMaxRad = ptLineStart.x ; + + MillConus( ptIapp, ptFapp, vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + else if ( ptLineStart.x < ptLineEnd.x) { + + double dMinRad = ptLineStart.x ; + double dMaxRad = ptLineEnd.x ; + + Point3d ptIn = ptIapp - vtToolDir * dAppHeight ; + Point3d ptFn = ptIn + vtMove ; + + MillConus( ptIn, ptFn, - vtToolDir, dAppHeight, dMaxRad, dMinRad) ; + } + + ptIapp = ptIapp - vtToolDir * dAppHeight ; + ptFapp = ptIapp + vtMove ; + + ptLineStart = ptLineEnd ; + bTest = Polygonal.GetNextPoint( ptLineEnd) ; + } + } + + dHeight = abs( ptStart.y - ptEnd.y) ; + + pNext = m_ToolOutline.GetPrevCurve() ; + + } + + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + + pCurve = m_ToolOutline.GetNextCurve() ; + } + + return true ; +} + +// Componenti elementari degli utensili +//---------------------------------------------------------------------------- +bool +VolZmap::MillCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) +{ + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( Control == false) + + return true ; + + + Point3d ptI ; + Point3d ptF ; + Vector3d vtV1 ; + + // Studio delle simmetrie + if ( vtToolDir.z < 0) { + + vtV1 = - vtToolDir ; + + ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs + dHei * vtV1 : ptLe + dHei * vtV1) ; + ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe + dHei * vtV1 : ptLs + dHei * vtV1) ; + } + else { + + vtV1 = vtToolDir ; + + ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; + ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; + } + + Point3d ptIT = ptI - vtV1 * dHei ; + Point3d ptFT = ptF - vtV1 * dHei ; + + // Definizione di un sintema di riferimento nel piano + Vector3d vtU1( - vtV1.x, - vtV1.y, 0) ; double dCos = vtV1.z ; double dSin = vtU1.LenXY() ; + vtU1.Normalize() ; // Ocio che la sua lunghezza sia maggiore di EPS_SMALL + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + double dZI = ptI.z ; + double dZF = ptF.z ; + double dDeltaZ = ptIT.z - ptI.z ; + //double dDeltaFz = ptFT.z - ptF.z ; + + double dL = dSin * dHei ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtMLong = ( vtMove * vtV1) * vtV1 ; double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; + + double dCoef = dLOrt / dLLong ; + double dAng = atan( 1 / dCoef) ; + + // vtV1, vtV2 e vtV3 definiscono gli assi dei sistemi di riferimento intrinseci + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + Frame3d CylFrame ; CylFrame.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; + Frame3d TCylFrame ; TCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; + Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; + + + // Altri punti notevoli + Point3d ptIPlus = ptI + dRad * vtV3 ; + Point3d ptIMinus = ptI - dRad * vtV3 ; + Point3d ptFPlus = ptIPlus + vtMove ; + Point3d ptFMinus = ptIMinus + vtMove ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + // Grandezze per la definizione dei piani + Vector3d vtRI = ptI - ORIG ; double dDotI = vtV1 * vtRI ; + Vector3d vtRF = ptF - ORIG ; double dDotF = vtV1 * vtRF ; + + Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtV1 * vtRIT ; + Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtV1 * vtRFT ; + + Vector3d vtRIPlus = ptIPlus - ORIG ; + + Vector3d vtRIMinus = ptIMinus - ORIG ; + + Vector3d vtRFPlus = ptFPlus - ORIG ; + + Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + + Vector3d vtRITPlus = ptIPlus - ORIG - vtV1 * dHei ; + + Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtV3) ; + Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtV3) ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCI = ptC - ptIxy ; + Vector3d vtCF = ptC - ptFxy ; + Vector3d vtC = ptC - ORIG ; + + double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; + double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; + + // Forse queste parti cilindriche andrebbero fatte per intersezione se il versoreutensile è molto verticale + // Parte cilindrica I + if ( dPI1 > - dCos * sqrt( dRad * dRad - dPI2 * dPI2) && + dPI1 < dL + dCos * sqrt( dRad * dRad - dPI2 * dPI2) && + dPI2 * dPI2 < dRad * dRad) { + + // Minimi + if ( dPI1 < dL - dCos * sqrt( dRad * dRad - dPI2 * dPI2)) { + + double dZ0 = - dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; + double dI10 = - dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; + + dMin = dZI + dZ0 + ( dPI1 - dI10) * dDeltaZ / dL ; + } + else + + dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + // Massimi + if ( dPI1 < dCos * sqrt( dRad * dRad - dPI2 * dPI2)) + + dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + else { + + double dZ0 = dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; + double dI10 = dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; + + dMax = dZI + dZ0 + ( dPI1 - dI10) * dDeltaZ / dL ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Parte cilindrica F + if ( dPF1 > - dCos * sqrt( dRad * dRad - dPF2 * dPF2) && + dPF1 < dL + dCos * sqrt( dRad * dRad - dPF2 * dPF2) && + dPF2 * dPF2 < dRad * dRad) { + + // Minimi + if ( dPF1 < dL - dCos * sqrt( dRad * dRad - dPF2 * dPF2)) { + + double dZ0 = - dSin * sqrt( dRad * dRad - dPF2 * dPF2) ; + double dI10 = - dCos * sqrt( dRad * dRad - dPF2 * dPF2) ; + + dMin = dZF + dZ0 + ( dPF1 - dI10) * dDeltaZ / dL ; + } + else + + dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + // Massimi + if ( dPF1 < dCos * sqrt( dRad * dRad - dPF2 * dPF2)) + + dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + else { + + double dZ0 = dSin * sqrt( dRad * dRad - dPF2 * dPF2) ; + double dI10 = dCos * sqrt( dRad * dRad - dPF2 * dPF2) ; + + dMax = dZF + dZ0 + ( dPF1 - dI10) * dDeltaZ / dL ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Parallelepipedo + Point3d ptInt1 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + Point3d ptInt2 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + Point3d ptInt3 = ptC + ( ( ( vtRIPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt4 = ptC + ( ( ( vtRIPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + Point3d ptInt5 = ptC + ( ( ( vtRFPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt6 = ptC + ( ( ( vtRITPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + + + ptInt1.LocToLoc( m_LocalFrame, CylFrame) ; + ptInt2.LocToLoc( m_LocalFrame, CylFrame) ; + ptInt3.LocToLoc( m_LocalFrame, CylFrame) ; + ptInt4.LocToLoc( m_LocalFrame, RotFrame) ; + ptInt5.LocToLoc( m_LocalFrame, CylFrame) ; + ptInt6.LocToLoc( m_LocalFrame, TRotFrame) ; + + bool bFlag = false ; + double dLim1, dLim2 ; + + if ( ptInt1.y >= 0 && ptInt1.y <= dLOrt && + ptInt1.x >= - dHei + ptInt1.y * ( dLLong / dLOrt) && + ptInt1.x <= ptInt1.y * ( dLLong / dLOrt)) { + + ptInt1.LocToLoc( CylFrame, m_LocalFrame) ; + + + dLim1 = ptInt1.z ; + bFlag = true ; + } + + if ( ptInt2.y >= 0 && ptInt2.y <= dLOrt && + ptInt2.x >= - dHei + ptInt2.y * ( dLLong / dLOrt) && + ptInt2.x <= ptInt2.y * ( dLLong / dLOrt)) { + + ptInt2.LocToLoc( CylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt2.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt2.z ; + } + + if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && + ptInt3.x >= - dHei && ptInt3.x <= 0) { + + ptInt3.LocToLoc( CylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt3.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt3.z ; + } + + if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && + ptInt4.y >= 0 && ptInt4.y <= dLen) { + + ptInt4.LocToLoc( RotFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt4.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt4.z ; + } + + if ( ptInt5.z >= - dRad && ptInt5.z <= dRad && + ptInt5.x >= dLLong- dHei && ptInt5.x <= dLLong) { + + ptInt5.LocToLoc( CylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt5.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt5.z ; + } + + if ( ptInt6.z >= - dRad && ptInt6.z <= dRad && + ptInt6.y >= 0 && ptInt6.y <= dLen) { + + ptInt6.LocToLoc( TRotFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt6.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt6.z ; + } + + + if ( bFlag == true) { // Una linea non confinata se entra in un volume chiuso ci deve uscire + + dMin = min( dLim1, dLim2) ; + dMax = max( dLim1, dLim2) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Traslazione dell'ellisse + + Vector3d vtK = Z_AX ; + + vtK.LocToLoc( m_LocalFrame, CylFrame) ; + ptC.LocToLoc( m_LocalFrame, CylFrame) ; + + std::vector vdCoef(3); + std::vector vdRoots; + + vdCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; + vdCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + if ( nRoot == 0 || nRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, CylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( CylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nRoot == 2) { + + Point3d ptInter1 = ptC + vdRoots[0] * vtK ; + Point3d ptInter2 = ptC + vdRoots[1] * vtK ; + + + if ( ptInter1.x > ptInter2.x) { + + Point3d ptTemp = ptInter1 ; + ptInter1 = ptInter2 ; + ptInter2 = ptTemp ; + } + + if ( ptInter1.x > 0 && ptInter1.x < dLLong && + ptInter2.x > dLLong) { + + ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; + + dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { + + ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; + ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; + + dMin = min( ptInter1.z, ptInter2.z) ; + dMax = max( ptInter1.z, ptInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { + + ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + ptC.LocToLoc( CylFrame, TCylFrame) ; + vtK.LocToLoc( CylFrame, TCylFrame) ; + + std::vector vdTCoef(3); + std::vector vdTRoots; + + vdTCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; + vdTCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdTCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + int nTRoot = PolynomialRoots( 2, vdTCoef, vdTRoots) ; + + if ( nTRoot == 0 || nTRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, TCylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( TCylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + + } + else if ( nTRoot == 2) { + + Point3d ptTInter1 = ptC + vdTRoots[0] * vtK ; + Point3d ptTInter2 = ptC + vdTRoots[1] * vtK ; + + if ( ptTInter1.x > ptTInter2.x) { + + Point3d ptTemp = ptTInter1 ; + ptTInter1 = ptTInter2 ; + ptTInter2 = ptTemp ; + } + + if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && + ptTInter2.x > dLLong) { + + ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { + + ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; + ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; + + dMin = min( ptTInter1.z, ptTInter2.z) ; + dMax = max( ptTInter1.z, ptTInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { + + dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { + + ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + dMax = max( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillCyl2( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( Control == false) + + return true ; + + // Punti notevoli + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + Point3d ptIT = ptI - vtToolDir * dHei ; + Point3d ptFT = ptF - vtToolDir * dHei ; + + // Vettori notevoli + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtLong = ( vtMove * vtToolDir) * vtToolDir ; double dLong = vtLong.Len() ; + Vector3d vtOrt = vtMove - vtLong ; double dOrt = vtOrt.Len() ; + + double dCoef = dOrt / dLong ; + double dAng = atan( 1 / dCoef) ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Definizione dei sistemi di riferimento + Frame3d ICylFrame ; ICylFrame.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; + Frame3d ITCylFrame ; ITCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; + Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; + + Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + Vector3d vtW3 = vtV3 ; + + Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtW3) ; + Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtW3) ; + + // Altri vettori notevoi + Vector3d vtKC = Z_AX ; vtKC.LocToLoc( m_LocalFrame, ICylFrame) ; + + Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV1 ; + Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV1 ; + Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtRIT * vtV1 ; + Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtRFT * vtV1 ; + + Vector3d vtRIPlus = vtRI + dRad * vtW3 ; + Vector3d vtRIMinus = vtRI - dRad * vtW3 ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; + + // Cilindro iniziale + ptC.LocToLoc( m_LocalFrame, ICylFrame) ; + + std::vector vdICylCoef(3); + std::vector vdICylRoots; + + vdICylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; + vdICylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; + vdICylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; + + + int nICylRoot = PolynomialRoots( 2, vdICylCoef, vdICylRoots) ; + + if ( nICylRoot == 0 || nICylRoot == 1) { + + Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPb.LocToLoc( m_LocalFrame, ICylFrame) ; + ptPt.LocToLoc( m_LocalFrame, ITCylFrame) ; + + if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && + ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { + + ptPb.LocToLoc( ICylFrame, m_LocalFrame) ; + ptPt.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ptPb.z, ptPt.z) ; + dMax = max( ptPb.z, ptPt.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nICylRoot == 2) { + + Point3d ptR1 = ptC + vdICylRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdICylRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < - dHei && ptR2.x >= - dHei && + ptR2.x < 0) { + + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < - dHei && ptR2.x >= 0) { + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Cilindro finale + ptC.LocToLoc( ICylFrame, FCylFrame) ; + + std::vector vdFCylCoef(3); + std::vector vdFCylRoots; + + vdFCylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; + vdFCylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; + vdFCylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; + + + int nFCylRoot = PolynomialRoots( 2, vdFCylCoef, vdFCylRoots) ; + + if ( nFCylRoot == 0 || nFCylRoot == 1) { + + Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPb.LocToLoc( m_LocalFrame, FCylFrame) ; + ptPt.LocToLoc( m_LocalFrame, FTCylFrame) ; + + if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && + ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { + + ptPb.LocToLoc( FCylFrame, m_LocalFrame) ; + ptPt.LocToLoc( FTCylFrame, m_LocalFrame) ; + + dMin = min( ptPb.z, ptPt.z) ; + dMax = max( ptPb.z, ptPt.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nFCylRoot == 2) { + + Point3d ptR1 = ptC + vdFCylRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdFCylRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < - dHei && ptR2.x >= - dHei && + ptR2.x < 0) { + + ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < - dHei && ptR2.x >= 0) { + + dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { + + ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; + ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { + + ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Traslazione ellisse fondo + + ptC.LocToLoc( FCylFrame, ICylFrame) ; + + std::vector vdEllipseCoef(3); + std::vector vdEllipseRoots; + + vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; + vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; + vdEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; + + + int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; + + if ( nEllipseRoot == 0 || nEllipseRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, ICylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( ICylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nEllipseRoot == 2) { + + Point3d ptR1 = ptC + vdEllipseRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdEllipseRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x >= 0 && + ptR2.x < dLong) { + + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dLong) { + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Traslazione ellisse punta + + ptC.LocToLoc( ICylFrame, ITCylFrame) ; + + std::vector vdTEllipseCoef(3); + std::vector vdTEllipseRoots; + + vdTEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; + vdTEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; + vdTEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; + + + int nTEllipseRoot = PolynomialRoots( 2, vdTEllipseCoef, vdTEllipseRoots) ; + + if ( nTEllipseRoot == 0 || nTEllipseRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, ITCylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( ITCylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nTEllipseRoot == 2) { + + Point3d ptR1 = ptC + vdTEllipseRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdTEllipseRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x >= 0 && + ptR2.x < dLong) { + + ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dLong) { + + dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { + + ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; + ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { + + ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + + // Parallelepipedo + Point3d ptInt1 = ptC + ( ( ( vtRI - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt2 = ptC + ( ( ( vtRI - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + Point3d ptInt3 = ptC + ( ( ( vtRF - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt4 = ptC + ( ( ( vtRIT - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + Point3d ptInt5 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + Point3d ptInt6 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + + + ptInt1.LocToLoc( m_LocalFrame, ICylFrame) ; + ptInt2.LocToLoc( m_LocalFrame, RotFrame) ; + ptInt3.LocToLoc( m_LocalFrame, FCylFrame) ; + ptInt4.LocToLoc( m_LocalFrame, TRotFrame) ; + ptInt5.LocToLoc( m_LocalFrame, ICylFrame) ; + ptInt6.LocToLoc( m_LocalFrame, ICylFrame) ; + + bool bFlag = false ; + double dLim1, dLim2 ; + + + if ( ptInt1.x >= - dHei && ptInt1.x <= 0 && + ptInt1.z >= - dRad && ptInt1.z <= dRad) { + + ptInt1.LocToLoc( ICylFrame, m_LocalFrame) ; + + dLim1 = ptInt1.z ; + bFlag = true ; + } + + if ( ptInt2.y >= 0 && ptInt2.y <= dLen && + ptInt2.z >= - dRad && ptInt2.z <= dRad) { + + ptInt2.LocToLoc( RotFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt2.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt2.z ; + } + + if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && + ptInt3.x >= - dHei && ptInt3.x <= 0) { + + ptInt3.LocToLoc( FCylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt3.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt3.z ; + } + + if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && + ptInt4.y >= 0 && ptInt4.y <= dLen) { + + ptInt4.LocToLoc( TRotFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt4.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt4.z ; + } + + if ( ptInt5.y >= 0 && ptInt5.y <= dOrt && + ptInt5.x >= - dHei + dCoef * ptInt5.y && + ptInt5.x <= dCoef * ptInt5.y) { + + ptInt5.LocToLoc( ICylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt5.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt5.z ; + } + + if ( ptInt6.y >= 0 && ptInt6.y <= dOrt && + ptInt6.x >= - dHei + dCoef * ptInt6.y && + ptInt6.x <= dCoef * ptInt6.y) { + + ptInt6.LocToLoc( ICylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt6.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt6.z ; + } + + + if ( bFlag == true) { // Una linea non confinata se entra in un volume chiuso ci deve uscire + + dMin = min( dLim1, dLim2) ; + dMax = max( dLim1, dLim2) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; + + if ( Control == false) + + return true ; + + + Point3d ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + Point3d ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + + if ( vtMove.x * vtMove.x + vtMove.y * vtMove.y < EPS_SMALL * EPS_SMALL) + + vtMoveXY = ( ( 1 / sqrt( vtMove.x * vtMove.x + vtMove.y * vtMove.y)) * vtMoveXY) ; + + Vector3d vtV1 = vtMoveXY ; vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + double dZI = ptI.z ; + double dDeltaZ = ptF.z - ptI.z ; + double dPLen = vtMove.LenXY() ; + + double dSin = dPLen / vtMove.Len() ; + double dCos = dDeltaZ / vtMove.Len() ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; + + if ( ( dP1 >= 0 && dP1 <= dPLen && abs( dP2) < dRad) || + ( dP1 * dP1 + dP2 * dP2 < dRad * dRad) || + ( ( dP1 - dPLen) * ( dP1 - dPLen) + dP2 * dP2 < dRad * dRad)) { + + // Massimi + if ( dP1 < - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { + + double dH = sqrt( dRad * dRad - dP1 * dP1 - dP2 * dP2) ; + dMax = dZI + dH ; + } + else if ( dP1 < dPLen - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { + + double dP0 = - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; + double dZ0 = dRad * dSin * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; + + dMax = dZI + dZ0 + ( dP1 - dP0) * dDeltaZ / dPLen ; + } + else { + + double dH = sqrt( dRad * dRad - ( dP1 - dPLen) * ( dP1 - dPLen) - dP2 * dP2) ; + dMax = dZI + dDeltaZ + dH ; + } + + // Minimi + if ( dP1 < dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { + + double dH = sqrt( dRad * dRad - dP1 * dP1 - dP2 * dP2) ; + dMin = dZI - dH ; + } + else if ( dP1 < dPLen + dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { + + double dP0 = dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; + double dZ0 = - dRad * dSin * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; + + dMin = dZI + dZ0 + ( dP1 - dP0) * dDeltaZ / dPLen ; + } + else { + + double dH = sqrt( dRad * dRad - ( dP1 - dPLen) * ( dP1 - dPLen) - dP2 * dP2) ; + dMin = dZI + dDeltaZ - dH ; + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( Control == false) + + return true ; + + double dDeltaR = dMaxRad - dMinRad ; + + Point3d ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; + Point3d ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; + + Point3d ptIT = ptI - vtToolDir * dHei ; + Point3d ptFT = ptF - vtToolDir * dHei ; + + double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; + double dl = dL - dHei ; + + Point3d ptIV = ptI - vtToolDir * dL ; + Point3d ptFV = ptF - vtToolDir * dL ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + + Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Apertura del cono e parametri per determinare i piani + double dTan = dDeltaR / dHei ; + double dRatio = dLLong / dLOrt ; + double dCos = dTan * dRatio ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + double dCoef = dLOrt / dLLong ; // Per traslazione ellissi + + if ( dRatio > 1 / dTan) + + return MillConusAux( ptI, ptF, vtV1, vtV2, vtV3, nStartI, nStartJ, nEndI, nEndJ, dHei, dMaxRad, dMinRad, dCoef) ; + + + // Versori normali e prodotti scalari per per determinare i piani + // Piani laterali: + Vector3d vtNs = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 + ( dSin / sqrt( 1 + dTan * dTan)) * vtV3 ; + Vector3d vtNd = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV2 - ( dSin / sqrt( 1 + dTan * dTan)) * vtV3 ; + Vector3d vtRIV = ptIV - ORIG ; + // double dDots = vtRIV * vtNs ; // forse qui è meglio due punti ptIT + vtV3 * dMinRad e ptIT - vtV3 * dMinRad + // double dDotd = vtRIV * vtNd ; + + Vector3d vtS1 = vtNs ; + Vector3d vtS2 = vtMove ; vtS2.Normalize() ; // double dDotTestqs = vtS1 * vtS2 ; + Vector3d vtS3 = vtS1 ^ vtS2 ; + + Vector3d vtD1 = vtNd ; + Vector3d vtD2 = vtS2 ; // double dDotTestD = vtD1 * vtD2 ; + Vector3d vtD3 = vtD1 ^ vtD2 ; + + Point3d ptS = ptI + vtV2 * ( dMaxRad * dCos) + vtV3 * ( dMaxRad * dSin) ; + Point3d ptD = ptI + vtV2 * ( dMaxRad * dCos) - vtV3 * ( dMaxRad * dSin) ; + Point3d ptST = ptIT + vtV2 * ( dMinRad * dCos) + vtV3 * ( dMinRad * dSin) ; + + Vector3d vtLen = ptST - ptS ; + + double dPLong = abs( vtLen * vtS3) ; + double dPOrt = abs( vtLen * vtS2) ; + // Vector3d vtLTr = vtLen - dPLong * vtS3 ; + + // double dPOrt = vtLTr.Len() ; + + // Piani di fondo e punta: + Vector3d vtU1 = - dLOrt * vtV1 + dLLong * vtV2 ; vtU1.Normalize() ; + Vector3d vtU2 = vtMove ; vtU2.Normalize() ; // double dDotTest = vtU1 * vtU2 ; + Vector3d vtU3 = vtU1 ^ vtU2 ; + + Point3d ptU = ptI + vtV2 * ( dMaxRad * dCos) ; + Point3d ptTU = ptIT + vtV2 * ( dMinRad * dCos) ; + + Vector3d vtRU = ptU - ORIG ; // double dDotB = vtRU * vtU1 ; + Vector3d vtRUT = ptTU - ORIG ; // double dDotT = vtRUT * vtU1 ; + + // Piani finale e iniziale: + Vector3d vtVAux = ptTU - ptU ; + + double dAuxOrt = vtVAux * vtV2 ; + double dAuxLong = vtVAux * vtV1 ; // Tenere in considerazione per tronchi con dimensioni tali da poter approssimare tori + + Vector3d vtW1 = - dAuxOrt * vtV1 + dAuxLong * vtV2 ; double dLAux1 = vtW1.Len() ; vtW1.Normalize() ; + Vector3d vtW2 = vtVAux ; double dLAux2 = vtW2.Len() ; vtW2.Normalize() ; // double dDottest = vtW1 * vtW2 ; + Vector3d vtW3 = vtW1 ^ vtW2 ; + + double dPr2 = vtLen * vtW2 ; double prova1 = vtLen * vtW3 ; double prova2 = dSin * dDeltaR ; + + Point3d ptFU = ptU + vtMove ; + + Vector3d vtRFU = ptFU - ORIG ; // double dDotPF = vtRFU * vtW1 ; + + // Piani cono: + Vector3d vtRCI = ptI - ORIG ; double dDotCI = vtRCI * vtV1 ; + Vector3d vtRCIT = ptIT - ORIG ; double dDotCIT = vtRCIT * vtV1 ; + + Vector3d vtRCF = ptF - ORIG ; double dDotCF = vtRCF * vtV1 ; + Vector3d vtRCFT = ptFT - ORIG ; double dDotCFT = vtRCFT * vtV1 ; + + + // Sistemi di riferimento + Frame3d IConeFrame ; IConeFrame.Set( ptIV, vtV1, vtV2, vtV3) ; + Frame3d FConeFrame ; FConeFrame.Set( ptFV, vtV1, vtV2, vtV3) ; + Frame3d PlSFrame ; PlSFrame.Set( ptS, vtS1, vtS2, vtS3) ; + Frame3d PlDFrame ; PlDFrame.Set( ptD, vtD1, vtD2, vtD3) ; + Frame3d PlBFrame ; PlBFrame.Set( ptU, vtU1, vtU2, vtU3) ; + Frame3d PlTFrame ; PlTFrame.Set( ptTU, vtU1, vtU2, vtU3) ; + Frame3d PlIFrame ; PlIFrame.Set( ptU, vtW1, vtW2, vtW3) ; + Frame3d PlFFrame ; PlFFrame.Set( ptFU, vtW1, vtW2, vtW3) ; + Frame3d LargeEllipse ; LargeEllipse.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FLargeEllipse ; FLargeEllipse.Set( ptF, vtV1, vtV2, vtV3) ; + Frame3d SmallEllipse ; SmallEllipse.Set( ptIT, vtV1, vtV2, vtV3) ; + Frame3d FSmallEllipse ; FSmallEllipse.Set( ptFT, vtV1, vtV2, vtV3) ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; Vector3d vtK = Z_AX ; + + // Cono I + ptC.LocToLoc( m_LocalFrame, IConeFrame) ; + vtK.LocToLoc( m_LocalFrame, IConeFrame) ; + + std::vector vdIConeCoef(3); + std::vector vdIConeRoots; + + vdIConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; + vdIConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; + vdIConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; + + int nIConeRoot = PolynomialRoots( 2, vdIConeCoef, vdIConeRoots) ; + + if ( nIConeRoot == 1) { + + Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( IConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nIConeRoot == 2) { + + Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; + Point3d ptR2 = ptC + vdIConeRoots[1] * vtK ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( IConeFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( IConeFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( IConeFrame, m_LocalFrame) ; + ptR2.LocToLoc( IConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( IConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Cono F + ptC.LocToLoc( IConeFrame, FConeFrame) ; + vtK.LocToLoc( IConeFrame, FConeFrame) ; + + std::vector vdFConeCoef(3); + std::vector vdFConeRoots; + + vdFConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; + vdFConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; + vdFConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; + + int nFConeRoot = PolynomialRoots( 2, vdFConeCoef, vdFConeRoots) ; + + if ( nFConeRoot == 1) { + + Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( FConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nFConeRoot == 2) { + + Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; + Point3d ptR2 = ptC + vdFConeRoots[1] * vtK ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( FConeFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( FConeFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( FConeFrame, m_LocalFrame) ; + ptR2.LocToLoc( FConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( FConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Solido interno + + ptC.LocToLoc( FConeFrame, m_LocalFrame) ; + vtK.LocToLoc( FConeFrame, m_LocalFrame) ; + + Point3d ptInt1 = ptC + ( ( ( vtRIV - vtC) * vtS1) / ( vtK * vtS1)) * vtK ; + Point3d ptInt2 = ptC + ( ( ( vtRIV - vtC) * vtD1) / ( vtK * vtD1)) * vtK ; + Point3d ptInt3 = ptC + ( ( ( vtRU - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; + Point3d ptInt4 = ptC + ( ( ( vtRUT - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; + Point3d ptInt5 = ptC + ( ( ( vtRU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; + Point3d ptInt6 = ptC + ( ( ( vtRFU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; + + ptInt1.LocToLoc( m_LocalFrame, PlSFrame) ; + ptInt2.LocToLoc( m_LocalFrame, PlDFrame) ; + ptInt3.LocToLoc( m_LocalFrame, PlBFrame) ; + ptInt4.LocToLoc( m_LocalFrame, PlTFrame) ; + ptInt5.LocToLoc( m_LocalFrame, PlIFrame) ; + ptInt6.LocToLoc( m_LocalFrame, PlFFrame) ; + + double dLim1, dLim2 ; + bool bFlag = false ; + + if ( ptInt1.z >= 0 && ptInt1.z <= dPLong && + ptInt1.y >= - ptInt1.z * dPOrt / dPLong && + ptInt1.y <= dLen - ptInt1.z * dPOrt / dPLong ) { + + ptInt1.LocToLoc( PlSFrame, m_LocalFrame) ; + + dLim1 = ptInt1.z ; + bFlag = true ; + } + + if ( ptInt2.z >= - dPLong && ptInt2.z <= 0 && + ptInt2.y >= ptInt2.z * dPOrt / dPLong && + ptInt2.y <= dLen + ptInt2.z * dPOrt / dPLong) { + + ptInt2.LocToLoc( PlDFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt2.z ; + bFlag = true ; + } + else + + dLim2 = ptInt2.z ; + } + + if ( ptInt3.y >= 0 && ptInt3.y <= dLen && + ptInt3.z > - dMaxRad * dSin && + ptInt3.z < dMaxRad * dSin) { + + ptInt3.LocToLoc( PlBFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt3.z ; + bFlag = true ; + } + else + + dLim2 = ptInt3.z ; + } + + if ( ptInt4.y >= 0 && ptInt4.y <= dLen && + ptInt4.z > - dMinRad * dSin && + ptInt4.z < dMinRad * dSin) { + + ptInt4.LocToLoc( PlTFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt4.z ; + bFlag = true ; + } + else + + dLim2 = ptInt4.z ; + } + + if ( ptInt5.y >= 0 && ptInt5.y <= dPr2 && + ptInt5.z > - dSin * dMaxRad + ptInt5.y * prova1 / dPr2 && + ptInt5.z < dSin * dMaxRad - ptInt5.y * prova1 / dPr2) { + + ptInt5.LocToLoc( PlIFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt5.z ; + bFlag = true ; + } + else + + dLim2 = ptInt5.z ; + } + + if ( ptInt6.y >= 0 && ptInt6.y <= dPr2 && + ptInt6.z > - dSin * dMaxRad + ptInt6.y * prova1 / dPr2 && + ptInt6.z < dSin * dMaxRad - ptInt6.y * prova1 / dPr2) { + + ptInt6.LocToLoc( PlFFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt6.z ; + bFlag = true ; + } + else + + dLim2 = ptInt6.z ; + } + + if( bFlag == true) { + + dMin = min( dLim1, dLim2) ; + dMax = max( dLim1, dLim2) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Traslazioni ellissi + + ptC.LocToLoc( m_LocalFrame, LargeEllipse) ; + vtK.LocToLoc( m_LocalFrame, LargeEllipse) ; + + std::vector vdLargeCoef(3); + std::vector vdLargeRoots; + + vdLargeCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMaxRad * dMaxRad ; + vdLargeCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdLargeCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + + int nLRoot = PolynomialRoots( 2, vdLargeCoef, vdLargeRoots) ; + + if ( nLRoot == 0) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, LargeEllipse) ; + ptPf.LocToLoc( m_LocalFrame, FLargeEllipse) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMaxRad * dMaxRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMaxRad * dMaxRad) { + + ptPi.LocToLoc( LargeEllipse, m_LocalFrame) ; + ptPf.LocToLoc( FLargeEllipse, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nLRoot == 2) { + + Point3d ptInter1 = ptC + vdLargeRoots[0] * vtK ; + Point3d ptInter2 = ptC + vdLargeRoots[1] * vtK ; + + + if ( ptInter1.x > ptInter2.x) { + + Point3d ptTemp = ptInter1 ; + ptInter1 = ptInter2 ; + ptInter2 = ptTemp ; + } + + if ( ptInter1.x > 0 && ptInter1.x < dLLong && + ptInter2.x > dLLong) { + + ptInter1.LocToLoc( LargeEllipse, m_LocalFrame) ; + + dMin = min( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + dMax = max( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { + + ptInter1.LocToLoc( LargeEllipse, m_LocalFrame) ; + ptInter2.LocToLoc( LargeEllipse, m_LocalFrame) ; + + dMin = min( ptInter1.z, ptInter2.z) ; + dMax = max( ptInter1.z, ptInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { + + dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { + + ptInter2.LocToLoc( LargeEllipse, m_LocalFrame) ; + + dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + ptC.LocToLoc( LargeEllipse, SmallEllipse) ; + vtK.LocToLoc( LargeEllipse, SmallEllipse) ; + + std::vector vdSmallCoef(3); + std::vector vdSmallRoots; + + vdSmallCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMinRad * dMinRad ; + vdSmallCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdSmallCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + int nSRoot = PolynomialRoots( 2, vdSmallCoef, vdSmallRoots) ; + + if ( nSRoot == 0) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, SmallEllipse) ; + ptPf.LocToLoc( m_LocalFrame, FSmallEllipse) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMinRad * dMinRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMinRad * dMinRad) { + + ptPi.LocToLoc( SmallEllipse, m_LocalFrame) ; + ptPf.LocToLoc( FSmallEllipse, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nSRoot == 2) { + + Point3d ptTInter1 = ptC + vdSmallRoots[0] * vtK ; + Point3d ptTInter2 = ptC + vdSmallRoots[1] * vtK ; + + if ( ptTInter1.x > ptTInter2.x) { + + Point3d ptTemp = ptTInter1 ; + ptTInter1 = ptTInter2 ; + ptTInter2 = ptTemp ; + } + + if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && + ptTInter2.x > dLLong) { + + ptTInter1.LocToLoc( SmallEllipse, m_LocalFrame) ; + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { + + ptTInter1.LocToLoc( SmallEllipse, m_LocalFrame) ; + ptTInter2.LocToLoc( SmallEllipse, m_LocalFrame) ; + + dMin = min( ptTInter1.z, ptTInter2.z) ; + dMax = max( ptTInter1.z, ptTInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { + + ptTInter2.LocToLoc( SmallEllipse, m_LocalFrame) ; + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillConusAux( const Point3d& ptI, const Point3d& ptF, const Vector3d& vtV1, const Vector3d& vtV2, const Vector3d& vtV3, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dHei, double dMaxRad, double dMinRad, double dCoef) { + + + double dDeltaR = dMaxRad - dMinRad ; + double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; + double dTan = dDeltaR / dHei ; + double dl = dL - dHei ; + + double dLLong = abs( ( ptF - ptI) * vtV1) ; + double dLOrt = abs( ( ptF - ptI) * vtV2) ; + + + Point3d ptV = ptI - vtV1 * dL ; + Point3d ptT = ptI - vtV1 * dHei ; + + Frame3d ConeFrame ; ConeFrame.Set( ptV, vtV1, vtV2, vtV3) ; + Frame3d IEllipseFrame ; IEllipseFrame.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FEllipseFrame ; FEllipseFrame.Set( ptF, vtV1, vtV2, vtV3) ; + + Vector3d vtI = ptI - ORIG ; double dDotI = vtI * vtV1 ; + Vector3d vtT = ptT - ORIG ; double dDotT = vtT * vtV1 ; + Vector3d vtF = ptF - ORIG ; double dDotF = vtF * vtV1 ; + + Vector3d vtK = Z_AX ; + Vector3d vtKC = vtK ; vtKC.LocToLoc( m_LocalFrame, ConeFrame) ; + Vector3d vtKE = vtK ; vtKE.LocToLoc( m_LocalFrame, IEllipseFrame) ; + + + + double dMin, dMax ; + + + for ( unsigned int i = nStI ; i <= nEnI ; ++ i) + for ( unsigned int j = nStJ ; j <= nEnJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; + + // Cono + ptC.LocToLoc( m_LocalFrame, ConeFrame) ; + + std::vector vdConeCoef(3); + std::vector vdConeRoots; + + vdConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; + vdConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtKC.x - ptC.y * vtKC.y - ptC.z * vtKC.z) ; + vdConeCoef[2] = dTan * dTan * vtKC.x * vtKC.x - vtKC.y * vtKC.y - vtKC.z * vtKC.z ; + + int nConeRoot = PolynomialRoots( 2, vdConeCoef, vdConeRoots) ; + + + if ( nConeRoot == 1) { + + Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( ConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nConeRoot == 2) { + + Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdConeRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConeFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConeFrame, m_LocalFrame) ; + + dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( ConeFrame, m_LocalFrame) ; + ptR2.LocToLoc( ConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( ConeFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Tralsazione dell'ellisse + + ptC.LocToLoc( ConeFrame, IEllipseFrame) ; + + std::vector vdEllipseCoef(3); + std::vector vdEllipseRoots; + + vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMaxRad * dMaxRad ; + vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKE.x * ptC.x + vtKE.y * ptC.y + vtKE.z * ptC.z - dCoef * ( vtKE.x * ptC.y + vtKE.y * ptC.x)) ; + vdEllipseCoef[2] = dCoef * dCoef * vtKE.x * vtKE.x + vtKE.y * vtKE.y + vtKE.z * vtKE.z - 2 * dCoef * vtKE.x * vtKE.y ; + + + int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; + + + if ( nEllipseRoot == 0 || nEllipseRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, IEllipseFrame) ; + ptPf.LocToLoc( m_LocalFrame, FEllipseFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMaxRad * dMaxRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMaxRad * dMaxRad) { + + ptPi.LocToLoc( IEllipseFrame, m_LocalFrame) ; + ptPf.LocToLoc( FEllipseFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + if ( nEllipseRoot == 2) { + + Point3d ptInter1 = ptC + vdEllipseRoots[0] * vtKE ; + Point3d ptInter2 = ptC + vdEllipseRoots[1] * vtKE ; + + + if ( ptInter1.x > ptInter2.x) { + + Point3d ptTemp = ptInter1 ; + ptInter1 = ptInter2 ; + ptInter2 = ptTemp ; + } + + if ( ptInter1.x > 0 && ptInter1.x < dLLong && + ptInter2.x > dLLong) { + + ptInter1.LocToLoc( IEllipseFrame, m_LocalFrame) ; + + dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { + + ptInter1.LocToLoc( IEllipseFrame, m_LocalFrame) ; + ptInter2.LocToLoc( IEllipseFrame, m_LocalFrame) ; + + dMin = min( ptInter1.z, ptInter2.z) ; + dMax = max( ptInter1.z, ptInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { + + ptInter2.LocToLoc( IEllipseFrame, m_LocalFrame) ; + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +// Traslazioni +//---------------------------------------------------------------------------- +bool +VolZmap::Ball( const Point3d& ptLs, const Point3d& ptLe, const double& dRad) { + + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, V_NULL, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; + + if ( Control == false) + + return true ; + + + Point3d ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + Point3d ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + + double dVLen = abs( vtMove.z) ; // Verticale e planare rispetto ai dexel + double dPLen = vtMoveXY.LenXY() ; + double dLen = vtMove.Len() ; + + double dR1 = dVLen / dLen ; + double dR2 = dPLen / dLen ; + + double dZI = ptI.z ; + double dDeltaZ = ptF.z - ptI.z ; + + + if ( dPLen < EPS_SMALL) { + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dSqLen = vtC.SqLen() ; + + if ( dSqLen < dRad * dRad) { + + dMin = dZI - sqrt( dRad * dRad - dSqLen) ; + dMax = dZI + dDeltaZ + sqrt( dRad * dRad - dSqLen) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + else { + + Vector3d vtV1 = vtMoveXY ; vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; + + double dX1 = vtCI * vtV1 ; double dX2 = vtCI * vtV2 ; + + double dISqDist = vtCI * vtCI ; double dFSqDist = vtCF * vtCF ; + + if ( dISqDist < dRad * dRad || dFSqDist < dRad * dRad || + ( dX1 > 0 && dX1 < dPLen && dX2 * dX2 < dRad * dRad)) { + + // Massimi + if ( dX1 < - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad * dR2 * dR2)) && + dISqDist < dRad * dRad) + + dMax = dZI + sqrt( dRad * dRad - dISqDist) ; + + else if ( dX1 >= - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && + dX1 < dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) + + dMax = dZI + dR2 * sqrt( dRad * dRad - dX2 * dX2) + ( dX1 + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) * dVLen / dPLen ; + + else if ( dX1 >= dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && + dFSqDist < dRad * dRad) + + dMax = dZI + dDeltaZ + sqrt( dRad * dRad - dFSqDist) ; + + // Minimi + if ( dX1 < dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && + dISqDist < dRad * dRad) + + dMin = dZI - sqrt( dRad * dRad - dISqDist) ; + + else if ( dX1 >= dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && + dX1 < dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) + + dMin = dZI - dR2 * sqrt( dRad * dRad - dX2 * dX2) + ( dX1 - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) * dVLen / dPLen ; + + else if ( dX1 >= dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && + dFSqDist < dRad * dRad) + + dMin = dZI + dDeltaZ - sqrt( dRad * dRad - dFSqDist) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} // Utensile generico //---------------------------------------------------------------------------- @@ -4565,20 +9479,1333 @@ VolZmap::GetMinMaxZGenTool( unsigned int nI, unsigned int nJ, double dZCutBase, } +// Bounding Box, interferenza dell'utensile con lo Zmap e limiti su indici +//---------------------------------------------------------------------------- +inline bool +VolZmap::BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) +{ + + // Determinazione del raggio massimo dell'utensile + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + + // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale + Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; + Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; + + // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad; + double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad; + double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad; + double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad; + double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad; + double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return false ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return false ; + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return false ; + + // Limiti su indici + nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + nEnI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + nEnJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::BoundingBox( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) +{ + // NB: E' vitale che vengano passati i punti e i vettori nel sistema di riferimento + // di riferimento opportuno. + unsigned int nMaxNx, nMaxNy ; + + double dMaxXValue, dMaxYValue ; + double dMinZValue, dMaxZValue ; + + if ( nGrid == 1) { + + nMaxNx = m_nNx ; nMaxNy = m_nNy ; + + dMaxXValue = m_nNx * m_dStep ; dMaxYValue = m_nNy * m_dStep ; + + dMinZValue = m_dMinZ ; dMaxZValue = m_dMaxZ ; + } + else if ( nGrid == 2) { + + nMaxNx = m_nNx2 ; nMaxNy = m_nNy2 ; + + dMaxXValue = m_nNx2 * m_dStep ; dMaxYValue = m_nNy2 * m_dStep ; + + dMinZValue = m_dMinZ2 ; dMaxZValue = m_dMaxZ2 ; + } + else if ( nGrid == 3) { + + nMaxNx = m_nNx3 ; nMaxNy = m_nNy3 ; + + dMaxXValue = m_nNx3 * m_dStep ; dMaxYValue = m_nNy3 * m_dStep ; + + dMinZValue = m_dMinZ3 ; dMaxZValue = m_dMaxZ3 ; + } + + // Determinazione del raggio massimo dell'utensile + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + + // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale + Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; + Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; + + // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad ; + double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad ; + double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad ; + double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad ; + double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad ; + double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad ; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL) + return false ; + if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL) + return false ; + if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL) + return false ; + + // Limiti su indici + nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : static_cast ( dMaxX / m_dStep)) ; + nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2) { + + // Determinazione del raggio massimo dell'utensile + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + + // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale + Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; + Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; + + // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad; + double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad; + double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad; + double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad; + double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad; + double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return false ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return false ; + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return false ; + + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::BBoxComponent( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dRad, double dTipRad, double dHei) { + + // Determinazione del raggio massimo dell'utensile + double dMaxRad = max( dRad, dTipRad) ; + + // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale + Point3d ptP1T = ptP1 - dHei * vtV1 ; + Point3d ptP2T = ptP2 - dHei * vtV2 ; + + // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad; + double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad; + double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad; + double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad; + double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad; + double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return false ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return false ; + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return false ; + + // Limiti su indici + nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + nEnI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + nEnJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + return true ; +} + + +// Profondità materiale +//---------------------------------------------------------------------------- +bool +VolZmap::IsAPointInside( const Point3d& ptP) +{ + if( ptP.x > 0 && ptP.x < m_nNx * m_dStep && + ptP.y > 0 && ptP.y < m_nNy * m_dStep) + + return true ; + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IsThereMat( unsigned int nI, unsigned int nJ, double dZ) +{ + unsigned int nDexelPos = nJ * m_nNx + nI ; + unsigned int nDexelSize = int( m_ZValues[nDexelPos].size()) ; + + if ( dZ < m_ZValues[nDexelPos][0] - EPS_SMALL || + dZ > m_ZValues[nDexelPos][nDexelSize - 1] + EPS_SMALL) + + return false ; + + else { + + unsigned int nIndex = 0 ; + + while ( nIndex <= nDexelSize - 2) { + + if ( dZ >= m_ZValues[nDexelPos][nIndex] - EPS_SMALL && + dZ <= m_ZValues[nDexelPos][nIndex + 1] + EPS_SMALL) + + return true ; + + nIndex = nIndex + 2 ; + } + + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +VolZmap::LineParallelepipedIntersection( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptE1, const Point3d& ptE2, double& dt1, double& dt2) +{ + // Punti e vettore devono essere espressi nel sistema di riferimento dello Zmap, + // e i lati del parallelepipedo devono essere orientati come gli assi dello Zmap. + + Point3d ptFirst, ptLast ; + + double dX = vtV * X_AX ; + double dY = vtV * Y_AX ; + double dZ = vtV * Z_AX ; + + + double dXmin = ptE1.x ; + double dYmin = ptE1.y ; + double dZmin = ptE1.z ; + double dXmax = ptE2.x ; + double dYmax = ptE2.y ; + double dZmax = ptE2.z ; + + double dMatrix[3][4] ; + + dMatrix[0][0] = 1 ; dMatrix[0][1] = dX ; + dMatrix[1][0] = 2 ; dMatrix[1][1] = dY ; + dMatrix[2][0] = 3 ; dMatrix[2][1] = dZ ; + + // Riordina la matrice secondo i coseni direttori i senso decrescente + for ( unsigned int n = 0 ; n < 3 ; ++ n) + for ( unsigned int m = n + 1 ; m < 3 ; ++ m) { + + if ( dMatrix[n][1] < dMatrix[m][1]) { + + double vec[2] ; + + for ( unsigned int k = 0 ; k < 2 ; ++ k) + + vec[k] = dMatrix[n][k] ; + + for ( unsigned int k = 0 ; k < 2 ; ++ k) + + dMatrix[n][k] = dMatrix[m][k] ; + + for ( unsigned int k = 0 ; k < 2 ; ++ k) + + dMatrix[m][k] = vec[k] ; + } + } + + + // Cerco le intersezioni della retta con i piani + unsigned int nInt = 0 ; + + for ( unsigned int i = 0 ; i < 3 ; ++ i) { + + if ( dMatrix[i][0] == 1) { + + dMatrix[i][2] = ( ( ptE1 - ptP) * X_AX) / ( vtV * X_AX) ; + dMatrix[i][3] = ( ( ptE2 - ptP) * X_AX) / ( vtV * X_AX) ; + + Point3d ptInt1 = ptP + dMatrix[i][2] * vtV ; + Point3d ptInt2 = ptP + dMatrix[i][3] * vtV ; + + if ( ptInt1.y >= dYmin && ptInt1.y <= dYmax && + ptInt1.z >= dZmin && ptInt1.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt1 ; + dt1 = dMatrix[i][2] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt1)) { + ptLast = ptInt1 ; + dt2 = dMatrix[i][2] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + + if ( ptInt2.y >= dYmin && ptInt2.y <= dYmax && + ptInt2.z >= dZmin && ptInt2.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt2 ; + dt1 = dMatrix[i][3] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt2)) { + ptLast = ptInt2 ; + dt2 = dMatrix[i][3] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + } + else if ( dMatrix[i][0] == 2) { + + dMatrix[i][2] = ( ( ptE1 - ptP) * Y_AX) / ( vtV * Y_AX) ; + dMatrix[i][3] = ( ( ptE2 - ptP) * Y_AX) / ( vtV * Y_AX) ; + + Point3d ptInt1 = ptP + dMatrix[i][2] * vtV ; + Point3d ptInt2 = ptP + dMatrix[i][3] * vtV ; + + if ( ptInt1.x >= dXmin && ptInt1.x <= dXmax && + ptInt1.z >= dZmin && ptInt1.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt1 ; + dt1 = dMatrix[i][2] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt1)){ + ptLast = ptInt1 ; + dt2 = dMatrix[i][2] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + + if ( ptInt2.x >= dXmin && ptInt2.x <= dXmax && + ptInt2.z >= dZmin && ptInt2.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt2 ; + dt1 = dMatrix[i][3] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt2)) { + ptLast = ptInt2 ; + dt2 = dMatrix[i][3] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + } + else if ( dMatrix[i][0] == 3) { + + dMatrix[i][2] = ( ( ptE1 - ptP) * Z_AX) / ( vtV * Z_AX) ; + dMatrix[i][3] = ( ( ptE2 - ptP) * Z_AX) / ( vtV * Z_AX) ; + + Point3d ptInt1 = ptP + dMatrix[i][2] * vtV ; + Point3d ptInt2 = ptP + dMatrix[i][3] * vtV ; + + if ( ptInt1.x >= dXmin && ptInt1.x <= dXmax && + ptInt1.y >= dYmin && ptInt1.y <= dYmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt1 ; + dt1 = dMatrix[i][2] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt1)) { + ptLast = ptInt1 ; + dt2 = dMatrix[i][2] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + + if ( ptInt2.x >= dXmin && ptInt2.x <= dXmax && + ptInt2.y >= dYmin && ptInt2.y <= dYmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt2 ; + dt1 = dMatrix[i][3] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt2)) { + ptLast = ptInt2 ; + dt2 = dMatrix[i][3] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + } + } + + if ( nInt == 2) + + return true ; + else { + // Valori convenzionali + + dt1 = - 1 ; + dt2 = - 1 ; + + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +VolZmap::LineParallelepipedIntersection( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptEnd, double& dt1, double& dt2) +{ + // Punti e vettore della retta devono essere espressi nel sistema di riferimento del parallelepipedo, + // identificato da estremi diagonale ( Orig e ptEnd) una volta scelto il sistema di riferimento centrato + // in un estremo della diagonale e con assi paralleli ai lati. + // Se c'è intersezione vengono restituiti dt1, dt2 in modo tale che ptInt12 = ptP + dt12 * vtV, ancora + // espressi nel sistema di riferimento del parallelepipedo. + + Point3d ptFirst, ptLast ; + + double dX = vtV * X_AX ; + double dY = vtV * Y_AX ; + double dZ = vtV * Z_AX ; + + double dXmax = ptEnd.x ; + double dYmax = ptEnd.y ; + double dZmax = ptEnd.z ; + + Point3d ptE1 = ORIG ; + Point3d ptE2 = ptEnd ; + + double dMatrix[3][4] ; + + dMatrix[0][0] = 1 ; dMatrix[0][1] = dX ; + dMatrix[1][0] = 2 ; dMatrix[1][1] = dY ; + dMatrix[2][0] = 3 ; dMatrix[2][1] = dZ ; + + // Riordina la matrice secondo i coseni direttori i senso decrescente + for ( unsigned int n = 0 ; n < 3 ; ++ n) + for ( unsigned int m = n + 1 ; m < 3 ; ++ m) { + + if ( dMatrix[n][1] < dMatrix[m][1]) { + + double vec[2] ; + + for ( unsigned int k = 0 ; k < 2 ; ++ k) + + vec[k] = dMatrix[n][k] ; + + for ( unsigned int k = 0 ; k < 2 ; ++ k) + + dMatrix[n][k] = dMatrix[m][k] ; + + for ( unsigned int k = 0 ; k < 2 ; ++ k) + + dMatrix[m][k] = vec[k] ; + } + } + + + // Cerco le intersezioni della retta con i piani + unsigned int nInt = 0 ; + + for ( unsigned int i = 0 ; i < 3 ; ++ i) { + + if ( dMatrix[i][0] == 1) { + + dMatrix[i][2] = ( ( ptE1 - ptP) * X_AX) / ( vtV * X_AX) ; + dMatrix[i][3] = ( ( ptE2 - ptP) * X_AX) / ( vtV * X_AX) ; + + Point3d ptInt1 = ptP + dMatrix[i][2] * vtV ; + Point3d ptInt2 = ptP + dMatrix[i][3] * vtV ; + + if ( ptInt1.y >= 0 && ptInt1.y <= dYmax && + ptInt1.z >= 0 && ptInt1.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt1 ; + dt1 = dMatrix[i][2] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt1)) { + ptLast = ptInt1 ; + dt2 = dMatrix[i][2] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + + if ( ptInt2.y >= 0 && ptInt2.y <= dYmax && + ptInt2.z >= 0 && ptInt2.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt2 ; + dt1 = dMatrix[i][3] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt2)) { + ptLast = ptInt2 ; + dt2 = dMatrix[i][3] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + } + else if ( dMatrix[i][0] == 2) { + + dMatrix[i][2] = ( ( ptE1 - ptP) * Y_AX) / ( vtV * Y_AX) ; + dMatrix[i][3] = ( ( ptE2 - ptP) * Y_AX) / ( vtV * Y_AX) ; + + Point3d ptInt1 = ptP + dMatrix[i][2] * vtV ; + Point3d ptInt2 = ptP + dMatrix[i][3] * vtV ; + + if ( ptInt1.x >= 0 && ptInt1.x <= dXmax && + ptInt1.z >= 0 && ptInt1.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt1 ; + dt1 = dMatrix[i][2] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt1)){ + ptLast = ptInt1 ; + dt2 = dMatrix[i][2] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + + if ( ptInt2.x >= 0 && ptInt2.x <= dXmax && + ptInt2.z >= 0 && ptInt2.z <= dZmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt2 ; + dt1 = dMatrix[i][3] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt2)) { + ptLast = ptInt2 ; + dt2 = dMatrix[i][3] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + } + else if ( dMatrix[i][0] == 3) { + + dMatrix[i][2] = ( ( ptE1 - ptP) * Z_AX) / ( vtV * Z_AX) ; + dMatrix[i][3] = ( ( ptE2 - ptP) * Z_AX) / ( vtV * Z_AX) ; + + Point3d ptInt1 = ptP + dMatrix[i][2] * vtV ; + Point3d ptInt2 = ptP + dMatrix[i][3] * vtV ; + + if ( ptInt1.x >= 0 && ptInt1.x <= dXmax && + ptInt1.y >= 0 && ptInt1.y <= dYmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt1 ; + dt1 = dMatrix[i][2] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt1)) { + ptLast = ptInt1 ; + dt2 = dMatrix[i][2] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + + if ( ptInt2.x >= 0 && ptInt2.x <= dXmax && + ptInt2.y >= 0 && ptInt2.y <= dYmax) { + + nInt = nInt + 1 ; + + if ( nInt == 1) { + ptFirst = ptInt2 ; + dt1 = dMatrix[i][3] ; + } + else if ( nInt == 2) { + if ( ! AreSamePointApprox( ptFirst, ptInt2)) { + ptLast = ptInt2 ; + dt2 = dMatrix[i][3] ; + break ; + } + else + nInt = nInt - 1 ; + } + } + } + } + + if ( nInt == 2) + + return true ; + else { + // Valori convenzionali + + dt1 = - 1 ; + dt2 = - 1 ; + + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersectALineZMapBBox( const Point3d& ptP, const Vector3d& vtV, Point3d& ptFirst, Point3d& ptLast) +{ + + double dt1, dt2 ; + + // Punti per cui passano i piani + Point3d ptR0 = ORIG ; + Point3d ptR1 = ptR0 + m_nNx * m_dStep * X_AX + m_nNy * m_dStep * Y_AX + m_dMaxZ * Z_AX ; + + if ( LineParallelepipedIntersection( ptP, vtV, ptR0, ptR1, dt1, dt2) && ( dt1 > 0 || dt2 > 0)) { + + ptFirst = ptP + dt1 * vtV ; + ptLast = ptP + dt2 * vtV ; + + return true ; + } + else { + // volendo puoi porre i due punti First e Last uguali a ptP + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +VolZmap::LineDexelIntersection( const Point3d& ptP, const Vector3d& vtV, unsigned int nI, unsigned int nJ, double& dOutMatFirst, double& dInMat, double& dOutMatLast) +{ + + // Determino il dexel e la sua dimensione + unsigned int nDexelPos = nJ * m_nNx + nI ; + unsigned int nDexelSize = int( m_ZValues[nDexelPos].size()) ; + + + // Determino estremi della sezione del dexel + double dXmin = nI * m_dStep ; + double dYmin = nJ * m_dStep ; + double dXmax = ( nI + 1) * m_dStep ; + double dYmax = ( nJ + 1) * m_dStep ; + + + // Definisco i punti estremi dei parallelepipedi: la + // sezione non varia, variano solo le limitazioni in z. + Point3d ptE1 ; ptE1.x = dXmin ; ptE1.y = dYmin ; + Point3d ptE2 ; ptE2.x = dXmax ; ptE2.y = dYmax ; + + + // Punti di intersezione e i valori del parametro t a cui + // si ha l'intersezione. + Point3d ptI1, ptI2 ; + double dt1, dt2 ; + + + // Cerchiamo le intersezioni con il parallelepipedo massimale, + // ovvero con estremi in z m_dMinZ e m_dMaxZ + ptE1.z = m_dMinZ ; + ptE2.z = m_dMaxZ ; + + // Se non vi è intersezione non c'è nulla da calcolare + if ( nDexelSize == 0 || ! LineParallelepipedIntersection( ptP, vtV, ptE1, ptE2, dt1, dt2)) + + return false ; + + + if ( dt1 > dt2) { + + double dTemp = dt1 ; + dt1 = dt2 ; + dt2 = dTemp ; + } + + ptI1 = ptP + dt1 * vtV ; + ptI2 = ptP + dt2 * vtV ; + + + // Determiniamo in quali intervalli appartengono le intersezioni + // Enumeriamo gli intervalli con l'indice del loro estremo superiore + unsigned int nFirst, nLast ; + +//// Caso di Punto interno al Dexel /////////////////////////////////////////////////// + if ( dt1 < 0) { + // Valutiamo il primo intervallo vuoto (eventualmente di misura nulla) + unsigned int nP ; + + if ( ptP.z >= m_dMinZ - EPS_SMALL && ptP.z < m_ZValues[nDexelPos][0]) + + nP = 0 ; + + if ( ptI2.z >= m_dMinZ - EPS_SMALL && ptI2.z < m_ZValues[nDexelPos][0]) + + nLast = 0 ; + + // Valutiamo gli intervalli centrali + unsigned int nIndex = 0 ; + + while ( nIndex <= nDexelSize - 2) { + + double dZmin = m_ZValues[nDexelPos][nIndex] ; + double dZmax = m_ZValues[nDexelPos][nIndex + 1] ; + + if ( ptI2.z >= dZmin && ptI2.z < dZmax) + + nLast = nIndex + 1 ; + + if ( ptP.z >= dZmin && ptP.z < dZmax) + + nP = nIndex + 1 ; + + nIndex = nIndex + 1 ; + } + // Intervallo finale vuoto (eventualmente di misura nulla) + if ( ptI2.z >= m_ZValues[nDexelPos][nDexelSize - 1] && ptI2.z < m_dMaxZ + EPS_SMALL) + + nLast = nDexelSize ; + + if ( ptP.z >= m_ZValues[nDexelPos][nDexelSize - 1] && ptP.z < m_dMaxZ + EPS_SMALL) + + nP = nDexelSize ; + // Parte da un vuoto ed esce da un vuoto + if ( nP % 2 == 0 && nLast % 2 == 0) { + // Dal medesimo intervallo + if ( nP == nLast) { + + dOutMatFirst = sqrt( ( ptI2 - ptP) * ( ptI2 - ptP)) ; + dInMat = 0 ; + dOutMatLast = 0 ; + + return true ; + } + // Da diversi intervalli + else { + + ptE1.z = m_ZValues[nDexelPos][nP] ; + ptE2.z = m_ZValues[nDexelPos][nLast - 1] ; + + LineParallelepipedIntersection( ptP, vtV, ptE1, ptE2, dt1, dt2) ; + + if ( dt1 > dt2) { + + double dTemp = dt1 ; + dt1 = dt2 ; + dt2 = dTemp ; + } + + Point3d ptAux1 = ptP + dt1 * vtV ; + Point3d ptAux2 = ptP + dt2 * vtV ; + + dOutMatFirst = sqrt( ( ptAux1 - ptP) * ( ptAux1 - ptP)) ; + dInMat = sqrt( ( ptAux2 - ptAux1) * ( ptAux2 - ptAux1)) ; + dOutMatLast = sqrt( ( ptI2 - ptAux2) * ( ptI2 - ptAux2)) ; + + return true ; + } + } + // Parte da un vuoto ed esce da un pieno + else if ( nP % 2 == 0 && nLast % 2 != 0) { + + ptE1.z = m_ZValues[nDexelPos][nP] ; + ptE2.z = m_ZValues[nDexelPos][nLast] ; + + LineParallelepipedIntersection( ptP, vtV, ptE1, ptE2, dt1, dt2) ; + + if ( dt1 > dt2) { + + double dTemp = dt1 ; + dt1 = dt2 ; + dt2 = dTemp ; + } + + Point3d ptAux1 = ptP + dt1 * vtV ; + Point3d ptAux2 = ptP + dt2 * vtV ; + + dOutMatFirst = sqrt( ( ptAux2 - ptP) * ( ptAux2 - ptP)) ; + dInMat = sqrt( ( ptAux2 - ptAux1) * ( ptAux2 - ptAux1)) ; + dOutMatLast = 0 ; + + return true ; + } + // Parte da un pieno ed esce da un vuoto + else if ( nP % 2 != 0 && nLast % 2 == 0) { + + ptE1.z = m_ZValues[nDexelPos][nP - 1] ; + ptE2.z = m_ZValues[nDexelPos][nLast - 1] ; + + LineParallelepipedIntersection( ptP, vtV, ptE1, ptE2, dt1, dt2) ; + + if ( dt1 > dt2) { + + double dTemp = dt1 ; + dt1 = dt2 ; + dt2 = dTemp ; + } + + Point3d ptAux1 = ptP + dt1 * vtV ; + Point3d ptAux2 = ptP + dt2 * vtV ; + + dOutMatFirst = - 1 ; + dInMat = sqrt( ( ptAux2 - ptP) * ( ptAux2 - ptP)) ; + dOutMatLast = sqrt( ( ptI2 - ptAux2) * ( ptI2 - ptAux2)) ; + + return true ; + } + else if ( nP % 2 != 0 && nLast != 0) { + + dOutMatFirst = - 1 ; + dInMat = sqrt( ( ptI2 - ptP) * ( ptI2 - ptP)) ; + dOutMatLast = 0 ; + + return true ; + } + return false ; //////// + } +//////////////////////////////////////////////////////////////////////////////////////// + + // Valutiamo il primo intervallo vuoto (eventualmente di misura nulla) + if ( ptI1.z >= m_dMinZ && ptI1.z < m_ZValues[nDexelPos][0]) + + nFirst = 0 ; + + if ( ptI2.z >= m_dMinZ && ptI2.z < m_ZValues[nDexelPos][0]) + + nLast = 0 ; + + // Valutiamo gli intervalli centrali + unsigned int nIndex = 0 ; + + while ( nIndex <= nDexelSize - 2) { + + double dZmin = m_ZValues[nDexelPos][nIndex] ; + double dZmax = m_ZValues[nDexelPos][nIndex + 1] ; + + + if ( ptI1.z >= dZmin && ptI1.z < dZmax) + + nFirst = nIndex + 1 ; + + if ( ptI2.z >= dZmin && ptI2.z < dZmax) + + nLast = nIndex + 1 ; + + + nIndex = nIndex + 1 ; + } + + // Valutiamo l'ultimio intervallo vuoto (eventualmente di misura nulla) + if ( ptI1.z >= m_ZValues[nDexelPos][nDexelSize - 1] && ptI1.z <= m_dMaxZ) + + nFirst = nDexelSize ; + + if ( ptI2.z >= m_ZValues[nDexelPos][nDexelSize - 1] && ptI2.z <= m_dMaxZ) + + nLast = nDexelSize ; + + + // Caso di retta che entra ed esce dal parallelepipedo + // massimale in corrispondenza di un vuoto + if ( nFirst % 2 == 0 && nLast % 2 == 0) { + // Entra ed esce in corrispondenza del medesimo intervallo + if ( nFirst == nLast) { + + dOutMatFirst = sqrt( ( ptI2 - ptP) * ( ptI2 - ptP)) ; + dInMat = 0 ; + dOutMatLast = 0 ; + + return true ; + } + // Entra ed esce da intervalli diversi + else { + // Costruisco un nuovo parallelepipedo massimale come guscio convesso + // di tutti gli intervalli pieni compresi fra i due vuoti in questione. + + ptE1.z = m_ZValues[nDexelPos][nFirst] ; + ptE2.z = m_ZValues[nDexelPos][nLast - 1] ; + + LineParallelepipedIntersection( ptP, vtV, ptE1, ptE2, dt1, dt2) ; + + if ( dt1 > dt2) { + + double dTemp = dt1 ; + dt1 = dt2 ; + dt2 = dTemp ; + } + + Point3d ptAux1 = ptP + dt1 * vtV ; + Point3d ptAux2 = ptP + dt2 * vtV ; + + dOutMatFirst = sqrt( ( ptAux1 - ptP) * ( ptAux1 - ptP)) ; + dInMat = sqrt( ( ptAux2 - ptAux1) * ( ptAux2 - ptAux1)) ; + dOutMatLast = sqrt( ( ptI2 - ptAux2) * ( ptI2 - ptAux2)) ; + + return true ; + } + } + // Entra in corrispondenza di un vuoto ed + // esce in corrispondenza di un pieno. + else if ( nFirst % 2 == 0 && nLast % 2 != 0) { + + ptE1.z = m_ZValues[nDexelPos][nFirst] ; + ptE2.z = m_ZValues[nDexelPos][nLast] ; + + LineParallelepipedIntersection( ptP, vtV, ptE1, ptE2, dt1, dt2) ; + + if ( dt1 > dt2) { + + double dTemp = dt1 ; + dt1 = dt2 ; + dt2 = dTemp ; + } + + Point3d ptAux1 = ptP + dt1 * vtV ; + Point3d ptAux2 = ptP + dt2 * vtV ; + + dOutMatFirst = sqrt( ( ptAux2 - ptP) * ( ptAux2 - ptP)) ; + dInMat = sqrt( ( ptAux2 - ptAux1) * ( ptAux2 - ptAux1)) ; + dOutMatLast = 0 ; + + return true ; + } + // Entra in corrispondenza di un pieno ed + // esce in corrispondenza di un vuoto. + else if ( nFirst % 2 != 0 && nLast % 2 == 0) { + + ptE1.z = m_ZValues[nDexelPos][nFirst - 1] ; + ptE2.z = m_ZValues[nDexelPos][nLast - 1] ; + + LineParallelepipedIntersection( ptP, vtV, ptE1, ptE2, dt1, dt2) ; + + if ( dt1 > dt2) { + + double dTemp = dt1 ; + dt1 = dt2 ; + dt2 = dTemp ; + } + + Point3d ptAux1 = ptP + dt1 * vtV ; + Point3d ptAux2 = ptP + dt2 * vtV ; + + dOutMatFirst = sqrt( ( ptI1 - ptP) * ( ptI1 - ptP)) ; + dInMat = sqrt( ( ptAux2 - ptAux1) * ( ptAux2 - ptAux1)) ; + dOutMatLast = sqrt( ( ptI2 - ptAux2) * ( ptI2 - ptAux2)) ; + + return true ; + } + // Entra ed esce in corrispondenza di un pieno + else if ( nFirst % 2 != 0 && nLast % 2 != 0) { + + dOutMatFirst = sqrt( ( ptI1 - ptP) * ( ptI1 - ptP)) ; + dInMat = sqrt( ( ptI2 - ptI1) * ( ptI2 - ptI1)) ; + dOutMatLast = 0 ; + + return true ; + } + + return false ; //////// +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Deepness( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLength, double& dOutLength) +{ + + Vector3d vtV = vtDir ; vtV.ToLoc( m_LocalFrame) ; vtV.Normalize() ; + + Point3d ptP, ptI, ptF, ptI1, ptI2 ; + + ptP = ptPGlob ; ptP.ToLoc( m_LocalFrame) ; + + + // Studio dell'intersezione fra semiretta e Zmap + bool bTest = IntersectALineZMapBBox( ptP, vtV, ptI1, ptI2) ; + // Semiretta esterna + if ( bTest == false) { + + dInLength = - 2 ; + dOutLength = - 2 ; + + return true ; + } + else { + // Una sola interszione + if ( ( ptI1 - ptP) * vtV > 0 && ( ptI2 - ptP) * vtV < 0) { + + ptF = ptI1 ; + ptI = ptP ; + } + // Una sola intersezione + else if ( ( ptI1 - ptP) * vtV < 0 && ( ptI2 - ptP) * vtV > 0) { + + ptF = ptI2 ; + ptI = ptP ; + } + else { + + double dSqLen1 = ( ptI1 - ptP) * ( ptI1 - ptP) ; + double dSqLen2 = ( ptI2 - ptP) * ( ptI2 - ptP) ; + + if ( dSqLen1 < dSqLen2) { + + ptF = ptI2 ; + ptI = ptI1 ; + } + else { + + ptF = ptI1 ; + ptI = ptI2 ; + } + } + + // Determinazione degli indici i j dei punti ptI e ptF + int nIi = int( floor( ptI.x / m_dStep)) ; + nIi = ( nIi == m_nNx ? nIi - 1 : nIi) ; + int nIj = int( floor( ptI.y / m_dStep)) ; + nIj = ( nIj == m_nNy ? nIj - 1 : nIj) ; + int nFi = int( floor( ptF.x / m_dStep)) ; + nFi = ( nFi == m_nNx ? nFi - 1 : nFi) ; + int nFj = int( floor( ptF.y / m_dStep)) ; + nFj = ( nFj == m_nNy ? nFj - 1 : nFj) ; + + + dInLength = 0 ; + dOutLength = 0 ; + bool bSent = false ; + + + double dDeltaX = ptF.x - ptI.x ; + double dDeltaY = ptF.y - ptI.y ; + + double dOutMatFirst, dOutMatLast, dInMat ; + + + // Se devi valutare f(a) / g(b) < h(c) e g(b) + // può annullarsi, valuta f(a) < g(b) * h(c). + if ( abs( dDeltaY) <= abs( dDeltaX)) { + + int nDeltaI = abs( nFi - nIi) ; + int nA = ( nFi >= nIi ? 1 : - 1) ; + unsigned int j = nIj ; + + double db = ( dDeltaY >= 0 ? 1 : - 1) ; + + + for ( int k = 0 ; k <= nDeltaI ; ++ k) { + + unsigned int i = nIi + nA * k ; + + // ci poniamo in un sistema di riferimento opportuno + double dx = abs( ( i + 0.5) * m_dStep - ptI.x) ; + double dAbsDX = abs( dDeltaX) ; + double dy = dx * dDeltaY / dAbsDX ; + + // Determinazione dei dexel + + double dY = ptI.y + dy ; + + + if ( j > 0 && abs( dY - ( j - 0.5) * m_dStep) < abs( dY - ( j + 1.5) * m_dStep) && + abs( dY - ( j - 0.5) * m_dStep) < abs( dY - ( j + 0.5) * m_dStep)) + + j = j - 1 ; + + else if ( j < m_nNy - 1 && abs( dY - ( j + 1.5) * m_dStep) < abs( dY - ( j - 0.5) * m_dStep) && + abs( dY - ( j + 1.5) * m_dStep) < abs( dY - ( j + 0.5) * m_dStep)) + + j = j + 1 ; + + // Analisi del dexel + if ( LineDexelIntersection( ptP, vtV, i, j, dOutMatFirst, dInMat, dOutMatLast)) { + + if ( dInMat > 0) + + dOutLength = dOutMatFirst + dInMat ; + + + if ( bSent == false) { + + dInLength = dOutMatFirst ; + + if( abs( dInLength - 1) < EPS_SMALL || dInMat > 0) + + bSent = true ; + } + } + } + } + else { + + int nDeltaJ = abs( nFj - nIj) ; + int nA = ( nFj >= nIj ? 1 : - 1) ; + unsigned int i = nIi ; + + double db = ( dDeltaX >= 0 ? 1 : - 1) ; + + + for ( int k = 0 ; k <= nDeltaJ ; ++ k) { + + unsigned int j = nIj + nA * k ; + + // ci poniamo in un sistema di riferimento opportuno + double dy = abs( ( j + 0.5) * m_dStep - ptI.y) ; + double dAbsDY = abs( dDeltaY) ; + double dx = dy * dDeltaX / dAbsDY ; + + // Determinazione dei dexel + + double dX = ptI.x + dx ; + + + if ( i > 0 && abs( dX - ( i - 0.5) * m_dStep) < abs( dX - ( i + 1.5) * m_dStep) && + abs( dX - ( i - 0.5) * m_dStep) < abs( dX - ( i + 0.5) * m_dStep)) + + i = i - 1 ; + + else if ( i < m_nNy - 1 && abs( dX - ( i + 1.5) * m_dStep) < abs( dX - ( i - 0.5) * m_dStep) && + abs( dX - ( i + 1.5) * m_dStep) < abs( dX - ( i + 0.5) * m_dStep)) + + i = i + 1 ; + + // Analisi del dexel + if ( LineDexelIntersection( ptP, vtV, i, j, dOutMatFirst, dInMat, dOutMatLast)) { + + if ( dInMat > 0) + + /*dOutLength = dOutMatFirst + dInMat ;*/ + dOutLength = ( abs( dOutMatFirst + 1) < EPS_SMALL ? dInMat : dOutMatFirst + dInMat) ; + + if ( bSent == false) { + + dInLength = dOutMatFirst ; + + // if( abs( dInLength - 1) < EPS_SMALL || dInMat > 0) + if( abs( dInLength + 1) < EPS_SMALL || dInMat > 0) + + bSent = true ; + } + } + } + } + //////////////////// MODIFICATO DA QUI /////////////////////////////////// + // Se non abbiamo incontrato materiale + if ( dInLength > dOutLength + EPS_SMALL || + ( abs( dInLength) < EPS_SMALL && + abs( dOutLength) < EPS_SMALL)) { + + dInLength = - 2 ; + dOutLength = - 2 ; + } + // Se parte da bordo dexel ma c'è materiale + if ( abs( dInLength) < EPS_SMALL && abs( dOutLength) >= EPS_SMALL && + AreSamePointApprox( ptPGlob, ptI)) { + + Point3d ptT = ptI - 0.9 * m_dStep * vtV ; + + unsigned int nIT = unsigned int ( floor( ptT.x / m_dStep)) ; + unsigned int nJT = unsigned int ( floor( ptT.y / m_dStep)) ; + + if ( nIT >= 0 && nIT <= m_nNx - 1 && + nJT >= 0 && nJT <= m_nNy - 1) + + if ( IsThereMat( nIT, nJT, ptPGlob.z)) + + dInLength = - 1 ; + } + + return true ; + } +} + +//---------------------------------------------------------------------------- +bool +VolZmap::BBoxZmapIntersection( const Frame3d& frBBoxFrame, const BBox3d& bbBox) { + + // Punti estremi del bounding box espressi nel suo sistema di riferimento + Point3d ptMin, ptMax ; + return true ; +} +//---------------------------------------------------------------------------- +bool +VolZmap::BBoxZmapIntersection( const Frame3d& frBBoxFrame, const Point3d& ptEnd) { + // Vertici del parallelepipedo + Point3d ptP1( 0, 0, 0) ; + Point3d ptP2( ptEnd.x, 0, 0) ; + Point3d ptP3( ptEnd.x, 0, ptEnd.z) ; + Point3d ptP4( 0, 0, ptEnd.z) ; + Point3d ptP5( 0, ptEnd.y, 0) ; + Point3d ptP6( ptEnd.x, ptEnd.y, 0) ; + Point3d ptP7( ptEnd.x, ptEnd.y, ptEnd.z) ; + Point3d ptP8( 0, ptEnd.y, ptEnd.z) ; + // Dimensioni lineari + // double dX = ptEnd.x ; + // double dY = ptEnd.y ; + // double dZ = ptEnd.z ; + // Vettore direzione dei dexel + Vector3d vtK = Z_AX ; vtK.LocToLoc( m_LocalFrame, frBBoxFrame) ; + // Li esprimo nel sistema di riferimento dello Zmap + ptP1.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptP2.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptP3.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptP4.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptP5.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptP6.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptP7.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptP8.LocToLoc( frBBoxFrame, m_LocalFrame) ; + // Estremi coordinate + double dMinX = min( min( min( ptP1.x, ptP2.x), min( ptP3.x, ptP4.x)), min( min( ptP5.x, ptP6.x), min( ptP7.x, ptP8.x))) ; + double dMaxX = max( max( max( ptP1.x, ptP2.x), max( ptP3.x, ptP4.x)), max( min( ptP5.x, ptP6.x), max( ptP7.x, ptP8.x))) ; + double dMinY = min( min( min( ptP1.y, ptP2.y), min( ptP3.y, ptP4.y)), min( min( ptP5.y, ptP6.y), min( ptP7.y, ptP8.y))) ; + double dMaxY = max( max( max( ptP1.y, ptP2.y), max( ptP3.y, ptP4.y)), max( min( ptP5.y, ptP6.y), max( ptP7.y, ptP8.y))) ; + double dMinZ = min( min( min( ptP1.z, ptP2.z), min( ptP3.z, ptP4.z)), min( min( ptP5.z, ptP6.z), min( ptP7.z, ptP8.z))) ; + double dMaxZ = max( max( max( ptP1.z, ptP2.z), max( ptP3.z, ptP4.z)), max( min( ptP5.z, ptP6.z), max( ptP7.z, ptP8.z))) ; + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) + return false ; + if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) + return false ; + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return false ; + // Limiti su indici + unsigned int nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + unsigned int nEnI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; + unsigned int nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + unsigned int nEnJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; + for ( unsigned int i = nStI ; i <= nEnI ; ++ i) + for ( unsigned int j = nStJ ; j <= nEnJ ; ++ j) { + double dt1, dt2 ; + unsigned int nPos = j * m_nNx + i ; + unsigned int nSize = int( m_ZValues[nPos].size()) ; + Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; + + ptC.LocToLoc( m_LocalFrame, frBBoxFrame) ; + + if ( LineParallelepipedIntersection( ptC, vtK, ptEnd, dt1, dt2)) { + + Point3d ptInt1 = ptC + dt1 * vtK ; + Point3d ptInt2 = ptC + dt2 * vtK ; + + ptInt1.LocToLoc( frBBoxFrame, m_LocalFrame) ; + ptInt2.LocToLoc( frBBoxFrame, m_LocalFrame) ; + + double dZ1 = ptInt1.z ; + double dZ2 = ptInt2.z ; + + if ( dZ1 > dZ2) { + + double dTemp = dZ1 ; + dZ1 = dZ2 ; + dZ2 = dTemp ; + } + + unsigned int nIndex = 0 ; + + while ( nIndex <= nSize - 2) { + + if ( m_ZValues[nPos].size() > 0 && ( + m_ZValues[nPos][nIndex] > dZ1 - EPS_SMALL && m_ZValues[nPos][nIndex] < dZ2 + EPS_SMALL || + m_ZValues[nPos][nIndex + 1] > dZ1 - EPS_SMALL && m_ZValues[nPos][nIndex] < dZ2 + EPS_SMALL)) + + return true ; + + nIndex = nIndex + 2 ; + } + } + } + return false ; +} diff --git a/VolZmap.h b/VolZmap.h index dd2ce81..abee6e3 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -16,17 +16,13 @@ #include "ObjGraphicsMgr.h" #include "DllMain.h" #include "GeoObjRW.h" +#include "CurveLine.h" +#include "CurveArc.h" +#include "CurveComposite.h" #include "/EgtDev/Include/EGkVolZmap.h" #include "/EgtDev/Include/EGkPoint3d.h" #include "/EgtDev/Include/EGkVector3d.h" -#include "CurveComposite.h" - -#include -#include - - -// Tipi utensile -enum ToolType { GenericTool = 0, CylindricalMill = 1, BallEndMill = 2, BullNoseMill = 3, ConusMill = 4} ; +#include "/EgtDev/Include/ENkPolynomialRoots.h" //---------------------------------------------------------------------------- class VolZmap : public IVolZmap, public IGeoObjRW @@ -64,17 +60,27 @@ class VolZmap : public IVolZmap, public IGeoObjRW { return m_nTempProp ; } public : // IVolZmap - virtual bool CopyFrom( const IGeoObj* pGObjSrc) ; - virtual bool GetAllTriangles( TRIA3DLIST& lstTria) const ; - virtual bool GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const ; + bool CopyFrom( const IGeoObj* pGObjSrc) override ; bool CreateMap( const Point3d& ptO, double dPrec, double dLengthX, double dLengthY, double dLengthZ) ; + bool GetAllTriangles( TRIA3DLIST& lstTria) const override ; + bool GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const override ; + bool SetTolerances( double dLinTol, double dAngTolDeg = 90) override ; + bool SetTool( const std::string& pToolName, const ICurveComposite* pToolOutline) override ; + bool SetStdTool( const std::string& pToolName, unsigned int nToolType, + double dH, double dTipH, double dR, double dTipR, double dRc = 0) override ; + bool MillingStep( const Point3d& ptPs, const Point3d& ptPe, Vector3d& vtDs, Vector3d& vtDe) override ; + bool Deepness( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) override ; + bool BBoxZmapIntersection( const Frame3d& frBBox, const Point3d& ptMax) override ; + + bool CreateTriMap( const Point3d& ptO, double dPrec, double dLengthX, double dLengthY, double dLengthZ) ; bool SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; + bool SubtractIntervals2( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; + bool SubtractIntervals3( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; bool SubtractIntervals( const Point3d& ptP, double dMin, double dMax) ; bool AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; bool AddIntervals( const Point3d& ptP, double dMin, double dMax) ; - bool SetTool( const std::string& pToolName, const CurveComposite* pToolOutline) ; - bool SetStdTool( const std::string& pToolName, unsigned int nToolType, double dH, double dTH, double dR, double dTR, double dRc = 0) ; - bool MillingStep( const Point3d& ptPs, const Point3d& ptPe, Vector3d& vtDs, Vector3d& vtDe) ; + bool TriMillingStep( const Point3d& ptPs, const Point3d& ptPe, Vector3d& vtDs, Vector3d& vtDe, double dLinTol, double dAngTolDeg = 90) ; + bool Deepness( const Point3d& ptPGlob, const Vector3d& vtDir, const double& dRadius, double& dInLength, double& dOutLength) ; public : // IGeoObjRW virtual int GetNgeId( void) const ; @@ -99,43 +105,143 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const ; - // frese: cylindrical, ball-end e bull-nose - // Versore utensile parallelo all'asse Z - bool MillingDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + // frese: cylindrical, ball-end, bull-nose e conus + // Versore utensile parallelo all'asse Z + // Fori + bool DrillingZ( const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) ; + + bool CBTDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; + + // Tagli orizzontali + bool MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool CBTMillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; + + inline bool GetMinMaxZSw( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ; + inline bool GetMinMaxZDr( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ; inline bool GetMinMaxZ( unsigned int nI, unsigned int nJ, double dZCutBase, double dDeltaZ, double dSqDist, const Vector3d& vtToolDir) ; + + // generico 3 assi + bool MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool CBMillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; + bool ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; + inline bool GetMinMaxZGen( unsigned int nI, unsigned int nJ, double dProj, double dSqd, double dLenPath, double dZheight, double dDelta, const Vector3d& vtToolDir) ; - // Versore utensile nel piano XY - bool MillingDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + + // Versore utensile nel piano XY + // DeltaZ = 0 + bool DrillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool CBTDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool ConusDrillingXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; + bool MillingPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool CBTPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool ConusPerpXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; + + bool MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool PlaneGenCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool ConusPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + inline bool GetMinMaxXY( unsigned int nI, unsigned int nJ, double dProj, double dZheight, double dSqD, double dPathPerp, double dPathPar, double dScProd) ; inline bool GetMMPlaneGenCyl( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, double dProj1, double dProj2) ; inline bool GetMMPlaneGenBall( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, Point3d ptIxy, Vector3d vtMove, Vector3d vtV1, Vector3d vtV2) ; - - // frese: conus - // Versore utensile parallelo all'asse Z - bool ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - bool ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - //bool ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - //bool ConusMillingZDrP( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - //bool ConusMillingZDrPnew( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - //bool ConusMillingZDrPnew2( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - bool ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - bool ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - inline bool GetMinMaxZSw( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ; - inline bool GetMinMaxZDr( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ; + + // DeltaZ != 0 + bool MillingXYVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - // utensile generico + bool MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool XYLongVertCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool MillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool MillingXYConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool MillingXYPlus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + bool MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool MillingXYPlusConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + + // Virtual milling per componenti elementari + + // Versore utensile parallelo all'asse Z + // Movimento parallelo al versore utensile + bool DrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) ; + + // Componenti + bool LongCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; + bool LongConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + + // Angolo generico fra movimento e versore utensile + bool MillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) ; + + // Componenti + bool MillCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; + bool MillConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + + // Direzione generica del versore utensile + // Movimento parallelo al versore utensile + bool Drilling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool DrillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) ; + + // Componenti elementari degli untensili + bool LongBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) ; + bool LongCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; + bool LongConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + + // Angolo generico fra movimento e versore utensile + bool Milling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool MillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dLinTol, double dAngTolDeg) ; + + // Componenti elementari degli utensili + bool MillCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; + bool MillCyl2( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; + bool MillBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) ; + bool MillConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + bool MillConusAux( const Point3d& ptI, const Point3d& ptF, const Vector3d& vtV1, const Vector3d& vtV2, const Vector3d& vtV3, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dHei, double dMaxRad, double dMinRad, double dCoef) ; + + // Traslazioni + bool Ball( const Point3d& ptLs, const Point3d& ptLe, const double& dRad) ; + + // Utensile generico inline bool GetMinMaxZGenTool( unsigned int nI, unsigned int nJ, double dZCutBase, double dDeltaZ, double dSqDist, const Vector3d& vtToolDir) ; - + // Sottrazione per tridexel + bool ZDrillingCB( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + + // Bounding Box + inline bool BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) ; + inline bool BoundingBox( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) ; + inline bool BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2) ; + inline bool BBoxComponent( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dRad, double dTipRad, double dHei) ; + inline bool BBoxComponent( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dRad, double dTipRad, double dHei) ; + + + bool IsAPointInside( const Point3d& ptP) ; + bool IsThereMat( unsigned int nI, unsigned int nJ, double dZ) ; + bool LineParallelepipedIntersection( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptE1, const Point3d& ptE2, double& dt1, double& dt2) ; + bool LineParallelepipedIntersection( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptEnd, double& dt1, double& dt2) ; + bool IntersectALineZMapBBox( const Point3d& ptP, const Vector3d& vtV, Point3d& ptFirst, Point3d& ptLast) ; + bool LineDexelIntersection( const Point3d& ptP, const Vector3d& vtV, unsigned int nI, unsigned int nJ, double& dOutMatFirst, double& dInMat, double& dOutMatLast) ; + bool BBoxZmapIntersection( const Frame3d& frBBoxFrame, const BBox3d& bbBox) ; + private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; @@ -145,15 +251,36 @@ class VolZmap : public IVolZmap, public IGeoObjRW Status m_nStatus ; // stato int m_nTempProp ; // proprietà temporanea - Frame3d m_LocalFrame ;//////FORSE E' MEGLIO CHIAMARLO INTRINSECO? E IN VISTA DEGLI ALTRI FORSE E' BENE AGGIUNGERE UN IDENTIFICATIVO? + Frame3d m_LocalFrame ; + Frame3d m_LocalFrame2 ; + Frame3d m_LocalFrame3 ; double m_dStep ; + unsigned int m_nNx ; // i = 0, 1, ..., m_nNx - 1 unsigned int m_nNy ; // j = 0, 1, ..., m_nNy - 1 + unsigned int m_nNx2 ; + unsigned int m_nNy2 ; + unsigned int m_nNx3 ; + unsigned int m_nNy3 ; unsigned int m_nDim ; + unsigned int m_nDim2 ; + unsigned int m_nDim3 ; + double m_dMinZ ; double m_dMaxZ ; - std::vector > m_ZValues ; + double m_dMinZ2 ; + double m_dMaxZ2 ; + + double m_dMinZ3 ; + double m_dMaxZ3 ; + + std::vector > m_ZValues ; + std::vector > m_ZValues2 ; + std::vector > m_ZValues3 ; + + double m_dLinTol ; + double m_dAngTolDeg ; std::string m_sToolName ; unsigned int m_nToolType ; CurveComposite m_ToolOutline ;