From 52a09392c101ad96ea895895a529d52248e4c819 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 7 Nov 2016 07:57:38 +0000 Subject: [PATCH] EgtGeomKernel 1.6w1 : - modifiche e correzioni varie sugli Zmap. --- EgtGeomKernel.rc | Bin 11718 -> 11718 bytes EgtGeomKernel.vcxproj | 7 + EgtGeomKernel.vcxproj.filters | 21 + GdbExecutor.cpp | 91 +- GdbExecutor.h | 3 +- IntersLineSurfTm.cpp | 134 +- IntersLineSurfTm.h | 32 + VolZmap.cpp | 10311 +------------------------------- VolZmap.h | 44 +- VolZmapCalculus.cpp | 313 + VolZmapCreation.cpp | 258 + VolZmapGraphics.cpp | 255 + VolZmapTool.cpp | 261 + VolZmapVolume.cpp | 8531 ++++++++++++++++++++++++++ 14 files changed, 9878 insertions(+), 10383 deletions(-) create mode 100644 IntersLineSurfTm.h create mode 100644 VolZmapCalculus.cpp create mode 100644 VolZmapCreation.cpp create mode 100644 VolZmapGraphics.cpp create mode 100644 VolZmapTool.cpp create mode 100644 VolZmapVolume.cpp diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 46fefe0265efe6fc930a6ebb4654ce4443b03dff..087480245521f7b21a3f1b55af8b69ab0530fed7 100644 GIT binary patch delta 134 zcmX>WeJpyz4>nd~1|0^&&G-4vGfl1&(wY2&Q-!&l!EmyouWeJpyz4>ndK1|0^o&G-4vGfl1&(wY2&Q-!&V!ECaku + + + + + @@ -397,6 +402,7 @@ copy $(TargetPath) \EgtProg\Dll64 + @@ -474,6 +480,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index fea1dea..a3a03b3 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -339,6 +339,21 @@ File di origine\GeoCollision + + File di origine\Geo + + + File di origine\Geo + + + File di origine\Geo + + + File di origine\Geo + + + File di origine\Geo + @@ -755,6 +770,12 @@ File di intestazione\Include + + File di intestazione\Include + + + File di intestazione + diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index fc10ca7..4ba35b8 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -2575,14 +2575,6 @@ GdbExecutor::ExecuteVolZmap(const string& sCmd2, const STRVECTOR& vsParams) if ( sCmd2 == "") { return VolZmapCreate( vsParams) ; } - // se sottrazione intervalli - else if ( sCmd2 == "SUB") { - return VolZmapIntervalsSubtraction( vsParams) ; - } - // se addizione intervalli - else if ( sCmd2 == "ADD") { - return VolZmapIntervalsAddiction( vsParams) ; - } // se lavorazione else if ( sCmd2 == "MIL") { return VolZmapMilling( vsParams) ; @@ -2607,6 +2599,10 @@ GdbExecutor::ExecuteVolZmap(const string& sCmd2, const STRVECTOR& vsParams) else if ( sCmd2 == "FLATZMAP") { return VolZmapCreateFromFlatRegion( vsParams) ; } + // se creazione zmap da trimesh + else if ( sCmd2 == "TRIMESHZMAP") { + return VolZmapCreateFromTriMesh( vsParams) ; + } return false ; } @@ -2643,7 +2639,7 @@ GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams) return false ; PtrOwner pZprova( new VolZmap) ; - pZprova->CreateMap( ptO, dLengthX, dLengthY, dLengthZ, dPrec); + pZprova->Create( ptO, dLengthX, dLengthY, dLengthZ, dPrec); // inserisco nel DB return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; @@ -2676,74 +2672,39 @@ GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams) return false ; // creo Zmap PtrOwner pZprova( new VolZmap) ; - pZprova->CreateMapFromFlatRegion( *pRegion, dLengthZ, dPrec); + pZprova->CreateFromFlatRegion( *pRegion, dLengthZ, dPrec); // inserisco nel DB return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; } -//---------------------------------------------------------------------------- -bool -GdbExecutor::VolZmapIntervalsSubtraction( const STRVECTOR& vsParams) -{ - // parametri : Id, IdParent, ptP, dMin, dMax - if ( vsParams.size() != 5) - return false ; - // recupero il riferimento in cui è immerso - Frame3d frRef ; - if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) - return false ; - // recupero punto - Point3d ptP ; - if ( ! GetPointParam( vsParams[2], frRef, ptP)) - return false ; - // recupero minimo - double dMin ; - if ( ! FromString( vsParams[3], dMin)) - return false ; - // recupero massimo - double dMax ; - if ( ! FromString( vsParams[4], dMax)) - return false ; - // recupero lo Zmap - int nIdZmap = GetIdParam( vsParams[0]) ; - VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nIdZmap)) ; - if ( pZmap == nullptr) - return false ; - // eseguo la sottrazione - return pZmap->SubtractIntervals( ptP, dMin, dMax) ; -} - //---------------------------------------------------------------------------- bool -GdbExecutor::VolZmapIntervalsAddiction( const STRVECTOR& vsParams) +GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams) { - // parametri : Id, IdParent, ptP, dMin, dMax - if ( vsParams.size() != 5) + // parametri : Id, IdParent, idSurf, dPrec + if ( vsParams.size() != 4) return false ; - // recupero il riferimento in cui è immerso + // recupero il riferimento in cui è immerso Frame3d frRef ; if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) - return false ; - // recupero punto - Point3d ptP ; - if ( ! GetPointParam( vsParams[2], frRef, ptP)) return false ; - // recupero minimo - double dMin ; - if ( ! FromString( vsParams[3], dMin)) + // recupero id flatregion + int nIdSurf = GetIdParam( vsParams[2]) ; + // recupero precisione + double dPrec ; + if ( ! FromString( vsParams[3], dPrec)) return false ; - // recupero massimo - double dMax ; - if ( ! FromString( vsParams[4], dMax)) + // recupero puntatore a Trimesh + SurfTriMesh* pSurf = GetBasicSurfTriMesh( m_pGDB->GetGeoObj( nIdSurf)) ; + if ( pSurf == nullptr) return false ; - // recupero lo Zmap - int nIdZmap = GetIdParam( vsParams[0]) ; - VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nIdZmap)) ; - if ( pZmap == nullptr) - return false ; - // eseguo l'addizione - return pZmap->AddIntervals( ptP, dMin, dMax) ; + // creo Zmap + PtrOwner pZprova( new VolZmap) ; + pZprova->CreateFromTriMesh( * pSurf, dPrec); + + // inserisco nel DB + return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; } //---------------------------------------------------------------------------- @@ -2880,7 +2841,7 @@ bool GdbExecutor::VolZmapDeepnessMeasure( const STRVECTOR& vsParams) { double dIn, dOut ; - pZmap -> Deepness( ptP, vtDir, dIn, dOut) ; + pZmap->GetDepth( ptP, vtDir, dIn, dOut) ; return true ; } @@ -2925,7 +2886,7 @@ GdbExecutor::VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams) return false ; bool bInt ; - bInt = pZmap -> BBoxZmapIntersection( frBBoxFrame, ptEnd) ; + bInt = ! pZmap->AvoidBox( frBBoxFrame, ptEnd - ORIG) ; return true ; } diff --git a/GdbExecutor.h b/GdbExecutor.h index 642d39a..d538cfc 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -116,8 +116,7 @@ class GdbExecutor : public IGdbExecutor bool ExecuteVolZmap( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool VolZmapCreate( const STRVECTOR& vsParams) ; bool VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams) ; - bool VolZmapIntervalsSubtraction( const STRVECTOR& vsParams) ; - bool VolZmapIntervalsAddiction( const STRVECTOR& vsParams) ; + bool VolZmapCreateFromTriMesh( const STRVECTOR& vsParams) ; bool VolZmapMilling( const STRVECTOR& vsParams) ; bool VolZmapSetAdvTool( const STRVECTOR& vsParams) ; bool VolZmapSetGenTool( const STRVECTOR& vsParams) ; diff --git a/IntersLineSurfTm.cpp b/IntersLineSurfTm.cpp index da5b830..c6fd1ce 100644 --- a/IntersLineSurfTm.cpp +++ b/IntersLineSurfTm.cpp @@ -14,12 +14,46 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ProjPlane.h" +#include "IntersLineSurfTm.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkIntersLineTria.h" -#include "/EgtDev/Include/EGkIntersLineSurfTm.h" using namespace std ; +//---------------------------------------------------------------------------- +void +UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen, + int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo) +{ + Point3d ptInt, ptInt2 ; + int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2) ; + if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) { + double dU = ( ptInt - ptL) * vtDir ; + double dCosDN = vtDir * Tria.GetN() ; + vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ; + } + else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) { + double dU = ( ptInt - ptL) * vtDir ; + double dU2 = ( ptInt2 - ptL) * vtDir ; + double dCosDN = vtDir * Tria.GetN() ; + vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ; + } +} + +//---------------------------------------------------------------------------- +void +OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo) +{ + // se non trovati, esco + if ( vInfo.size() == 0) + return ; + // ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea + sort( vInfo.begin(), vInfo.end(), + []( const IntLinStmInfo& a, const IntLinStmInfo& b) { return ( a.dU < b.dU) ; }) ; +} + +//---------------------------------------------------------------------------- +// Intersezione di una linea con una superficie TriMesh //---------------------------------------------------------------------------- bool IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfTriMesh& Stm, @@ -35,32 +69,92 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS // verifico parametro di ritorno if ( &vInfo == nullptr) return false ; + vInfo.clear() ; // cerco i triangoli intersecati dalla linea Triangle3d Tria ; int nT = Stm.GetFirstTriangle( Tria) ; while ( nT != SVT_NULL) { - Point3d ptInt, ptInt2 ; - int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2) ; - if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) { - double dU = ( ptInt - ptL) * vtDir ; - double dCosDN = vtDir * Tria.GetN() ; - vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ; - } - else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) { - double dU = ( ptInt - ptL) * vtDir ; - double dU2 = ( ptInt2 - ptL) * vtDir ; - double dCosDN = vtDir * Tria.GetN() ; - vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ; - } + // aggiorno info con intersezione + UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo) ; + // passo al prossimo triangolo nT = Stm.GetNextTriangle( nT, Tria) ; } - // se non trovati, esco - if ( vInfo.size() == 0) - return true ; - // ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea - sort( vInfo.begin(), vInfo.end(), - []( const IntLinStmInfo& a, const IntLinStmInfo& b) { return ( a.dU < b.dU) ; }) ; + // ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea + OrderInfoIntersLineSurfTm( vInfo) ; + + return true ; +} + +//---------------------------------------------------------------------------- +// Intersezione di molte linee parallele con una superficie TriMesh +//---------------------------------------------------------------------------- +IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm) + : m_bOk( false), m_frLines( frLines), m_pSTm( &Stm) +{ + // verifico esistenza superficie + if ( m_pSTm == nullptr || ! m_pSTm->IsValid()) + return ; + + // creo HashGrid 2d + const int LIM_HG_TRIA = 128 ; + m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ; + + // riempio HashGrid + Triangle3d Tria ; + int nT = Stm.GetFirstTriangle( Tria) ; + while ( nT != SVT_NULL) { + // calcolo il BBox del triangolo nel riferimento scelto + Tria.ToLoc( m_frLines) ; + BBox3d b3Tria ; + b3Tria.Add( Tria.GetP( 0)) ; + b3Tria.Add( Tria.GetP( 1)) ; + b3Tria.Add( Tria.GetP( 2)) ; + // inserisco nella griglia + if ( ! m_HGrids.Add( nT, b3Tria)) + return ; + // passo al prossimo triangolo + nT = Stm.GetNextTriangle( nT, Tria) ; + } + // aggiorno + m_bOk = m_HGrids.Update() ; +} + +//---------------------------------------------------------------------------- +bool +IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vInfo) +{ + // verifico validità + if ( ! m_bOk) + return false ; + // verifico parametro di ritorno + if ( &vInfo == nullptr) + return false ; + vInfo.clear() ; + + // calcolo box linea (nel riferimento) + BBox3d b3Line ; + b3Line.Add( ptL) ; + + // calcolo punto nel riferimento trimesh + Point3d ptLL = ptL ; + ptLL.ToGlob( m_frLines) ; + + // recupero indici triangoli che intersecano box in 2d + INTVECTOR vnIds ; + if ( m_HGrids.Find( b3Line, vnIds)) { + for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) { + int nT = vnIds[i] ; + Triangle3d Tria ; + m_pSTm->GetTriangle( nT, Tria) ; + // aggiorno info con intersezione + UpdateInfoIntersLineSurfTm( ptLL, m_frLines.VersZ(), dLen, nT, Tria, vInfo) ; + } + } + + // ordino il vettore delle eventuali intersezioni secondo il senso crescente del parametro di linea + OrderInfoIntersLineSurfTm( vInfo) ; + return true ; } \ No newline at end of file diff --git a/IntersLineSurfTm.h b/IntersLineSurfTm.h new file mode 100644 index 0000000..fad6cea --- /dev/null +++ b/IntersLineSurfTm.h @@ -0,0 +1,32 @@ +//---------------------------------------------------------------------------- +// EgalTech 2016-2016 +//---------------------------------------------------------------------------- +// File : IntersLineSurfTm.h Data : 06.11.16 Versione : 1.6w2 +// Contenuto : Dichiarazioni per intersezioni Linea/SurfTriMesh. +// +// +// +// Modifiche : 06.11.16 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "HashGrids2d.h" +#include "/EgtDev/Include/EGkIntersLineSurfTm.h" + + +//----------------------------------------------------------------------------- +class IntersParLinesSurfTm +{ + public : + IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm) ; + bool GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vInfo) ; + + private : + bool m_bOk ; + const Frame3d m_frLines ; + const ISurfTriMesh* m_pSTm ; + HashGrids2d m_HGrids ; +} ; diff --git a/VolZmap.cpp b/VolZmap.cpp index 79a3645..f1a946e 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -217,19 +217,32 @@ VolZmap::GetLocalBBox( BBox3d& b3Loc, int nFlag) const return false ; // reset box b3Loc.Reset() ; - // ciclo sui dexel - double dY = 0.5 * m_dStep ; - for ( size_t i = 0 ; i < m_nNy ; ++ i) { - double dX = 0.5 * m_dStep ; - for ( size_t j = 0 ; j < m_nNx ; ++ j) { - size_t nPos = j + i * m_nNx ; + // se richiesto approssimato + if ( ( nFlag & BBF_EXACT) == 0) { + b3Loc.Add( ORIG) ; + b3Loc.Add( Point3d( m_nNx * m_dStep, m_nNy * m_dStep, m_dMaxZ)) ; + b3Loc.ToGlob( m_LocalFrame) ; + return true ; + } + // calcolo preciso + // ciclo sui dexel (punti in basso con ciclo aggiunto per punti in alto di ultima riga) + double dY = 0 ; + for ( size_t j = 0 ; j <= m_nNy ; ++ j) { + size_t jc = ( ( j != m_nNy) ? j : m_nNy -1) ; + double dX = 0 ; + // punto a sinistra di ogni dexel (aggiungo un ciclo per fare punto a destra di ultimo) + for ( size_t i = 0 ; i <= m_nNx ; ++ i) { + size_t ic = ( ( i != m_nNx) ? i : m_nNx -1) ; + size_t nPos = ic + jc * m_nNx ; if ( m_ZValues[nPos].size() > 0) { Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; b3Loc.Add( ptP + m_ZValues[nPos][0] * m_LocalFrame.VersZ()) ; b3Loc.Add( ptP + m_ZValues[nPos][m_ZValues[nPos].size()-1] * m_LocalFrame.VersZ()) ; } + // passo al punto successivo dX += m_dStep ; } + // passo alla riga successiva dY += m_dStep ; } @@ -248,19 +261,32 @@ VolZmap::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const // trasformo il riferimento locale tramite quello passato Frame3d frUse = m_LocalFrame ; frUse.ToGlob( frRef) ; - // ciclo sui dexel - double dY = 0.5 * m_dStep ; - for ( size_t i = 0 ; i < m_nNy ; ++ i) { - double dX = 0.5 * m_dStep ; - for ( size_t j = 0 ; j < m_nNx ; ++ j) { - size_t nPos = j + i * m_nNx ; + // se richiesto approssimato + if ( ( nFlag & BBF_EXACT) == 0) { + b3Ref.Add( ORIG) ; + b3Ref.Add( Point3d( m_nNx * m_dStep, m_nNy * m_dStep, m_dMaxZ)) ; + b3Ref.ToGlob( frUse) ; + return true ; + } + // calcolo preciso + // ciclo sui dexel (punti in basso con ciclo aggiunto per punti in alto di ultima riga) + double dY = 0 ; + for ( size_t j = 0 ; j <= m_nNy ; ++ j) { + size_t jc = ( ( j != m_nNy) ? j : m_nNy -1) ; + double dX = 0 ; + // punto a sinistra di ogni dexel (aggiungo un ciclo per fare punto a destra di ultimo) + for ( size_t i = 0 ; i <= m_nNx ; ++ i) { + size_t ic = ( ( i != m_nNx) ? i : m_nNx -1) ; + size_t nPos = ic + jc * m_nNx ; if ( m_ZValues[nPos].size() > 0) { Point3d ptP = frUse.Orig() + dX * frUse.VersX() + dY * frUse.VersY() ; b3Ref.Add( ptP + m_ZValues[nPos][0] * frUse.VersZ()) ; b3Ref.Add( ptP + m_ZValues[nPos][m_ZValues[nPos].size()-1] * frUse.VersZ()) ; } + // passo al punto successivo dX += m_dStep ; } + // passo alla riga successiva dY += m_dStep ; } @@ -363,10270 +389,9 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) return m_LocalFrame.LocToLoc( frOri, frDest) ; } -//---------------------------------------------------------------------------- -bool -VolZmap::CreateMap( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec) -{ - // Controlli sui parametri - if ( dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) - return false ; - // Definisco il sistema di riferimento in trinseco dello Zmap - m_LocalFrame.Set( ptO, X_AX, Y_AX, Z_AX) ; - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL - m_dStep = max( dPrec, 100 * EPS_SMALL) ; - // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe - // della griglia Zmap e da questi la dimensione del vettore di dexel - m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; - m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; - m_nDim = m_nNx * m_nNy ; - // Ridimensiono il vettore di dexel e creo lo Zmap - m_ZValues.resize( m_nDim) ; - - for ( int i = 0 ; i < int( m_nDim) ; i++) { - m_ZValues[i].resize(2) ; - m_ZValues[i][0] = 0 ; - m_ZValues[i][1] = dLengthZ ; - } - - // Assegno il minimo e massimo valore di Z della mappa - m_dMinZ = 0 ; - m_dMaxZ = dLengthZ ; - - m_nStatus = OK ; - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CreateMapFromFlatRegion( const ISurfFlatRegion& Surf, double dLengthZ, double dPrec) -{ - Point3d ptMapOrig, ptMapEnd ; - - // Determino il bounding box della flat region - BBox3d SurfBBox ; - Surf.GetLocalBBox( SurfBBox, 2) ; - - // Determino i punti estremi del bounding box - SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; - - // Sistema di riferimento mappa - m_LocalFrame.Set( ptMapOrig, X_AX, Y_AX, Z_AX) ; - - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL - m_dStep = max( dPrec, 100 * EPS_SMALL) ; - - // Determino le dimensioni lineari X Y della griglia - double dLengthX = ptMapEnd.x - ptMapOrig.x ; - double dLengthY = ptMapEnd.y - ptMapOrig.y ; - - // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe - // della griglia Zmap e da questi la dimensione del vettore di dexel - m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; - m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; - - m_nDim = m_nNx * m_nNy ; - - // Ridimensiono il vettore di dexel e creo lo Zmap - m_ZValues.resize( m_nDim) ; - - // Determinazione e ridimensionamento dei dexel - // interni alla regione - for( unsigned int i = 0 ; i < m_nNx ; ++ i) { - - // Definisco la retta da intersecare con la regione - double dX = ( i + 0.5) * m_dStep ; - Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; - CurveLine GridLine ; - GridLine.SetPVL( ptP0, Y_AX, dLengthY) ; - - // Determino le intersezioni della retta con la regione - CRVCVECTOR IntersectionResults ; - Surf.GetCurveClassification( GridLine, IntersectionResults) ; - // Parti di cui la retta analizzata è composta - int nPart = int( IntersectionResults.size()) ; - - // Analizzio le parti - for ( int k = 0 ; k < nPart ; ++ k) { - - // Tipo di curva - int nType = IntersectionResults[k].nClass ; - - // Se la retta è interna alla regione o coincidente con parte della sua frontiera - if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { - - // Parametri iniziale e finale - double dt1 = IntersectionResults[k].dParS ; - double dt2 = IntersectionResults[k].dParE ; - - // Indici corrispondenti alle coordinate dei punti - unsigned int nStartJ = static_cast ( floor( dt1 * m_nNy)) ; - unsigned int nEndJ = static_cast ( floor( dt2 * m_nNy)) ; - - nEndJ = ( nEndJ >= m_nNy ? m_nNy - 1 : nEndJ) ; - - // Ridimensiono e riempio i dexel - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - // Determino il dexel - unsigned int nPos = j * m_nNx + i ; - - m_ZValues[nPos].resize( 2) ; - // Aggiorno le quote estreme del segmento - m_ZValues[nPos][0] = 0 ; - m_ZValues[nPos][1] = dLengthZ ; - } - } - } - } - - // Assegno il minimo e massimo valore di Z della mappa - m_dMinZ = 0 ; - m_dMaxZ = dLengthZ ; - - m_nStatus = OK ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) -{ - // Controllo che dMin e dMax non siano quasi coincidenti - if ( abs( dMax - dMin) < EPS_SMALL) - return true ; - - // Controllo che dMin < dMax - if ( dMax < dMin ) - swap( dMax, dMin) ; - - // Calcolo nPos dello spillone - unsigned int nPos = nJ * m_nNx + nI ; - - // Ciclo sugli intervalli dello spillone - bool bModified = false ; - unsigned int i = 0 ; - while ( i + 1 < m_ZValues[nPos].size()) { - - // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione - if ( m_ZValues[nPos][i] > dMax - EPS_SMALL) { - ; - } - - // Intersezione - else if ( m_ZValues[nPos][i + 1] > dMax + EPS_SMALL) { - // L'intervallo corrente corrente viene limitato a sinistra - if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i] = dMax ; - } - // L'intervallo si divide in due intervalli - else { - bModified = true ; - m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; - - for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 3 ; -- j) - - m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ; - - m_ZValues[nPos][i + 1] = dMin ; - m_ZValues[nPos][i + 2] = dMax ; - - i = i + 2 ; - } - } - - else { - // L'intervallo corrente viene eliminato - if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { - bModified = true ; - for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j) - - m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ; - - m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ; - - i = i - 2 ; - } - // L'intervallo corrente viene limitato a destra - else if ( m_ZValues[nPos][i + 1] > dMin + EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i + 1] = dMin ; - } - // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione - else { - ; - } - } - - i = i + 2 ; - } - - // Se eseguita modifica, imposto ricalcolo della grafica - if ( bModified) - m_OGrMgr.Reset() ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::SubtractIntervals( const Point3d& ptP, double dMin, double dMax) -{ - // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) - Point3d ptPL = ptP ; - ptPL.ToLoc( m_LocalFrame) ; - - double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco - double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) - - dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; - dhMin = dZ + dMin ; dhMax = dZ + dMax ; - - // Cerco il punto della griglia più vicino (indice è l'intero appena più basso) - double integerPartX = floor( dX / m_dStep) ; - double integerPartY = floor( dY / m_dStep) ; - - unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. - unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 - - // Controllo se le coordinate x e y del punto dato siano all'interno della griglia: - // se sono dentro la griglia chiamo l'altra subtract - if ( dX < m_dStep * m_nNx && - dY < m_dStep * m_nNy && - dX >= 0 && dY >= 0) { - // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e - // si esce dai limiti dell vector e vi è errore runtime - return SubtractIntervals( i, j, dhMin, dhMax) ; - } - - // altrimenti non succede niente - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) -{ - // Controllo che dMin e dMax non siano quasi coincidenti - if ( abs( dMax - dMin) < EPS_SMALL) - return true ; - - // Controllo che dMin < dMax - if ( dMax < dMin) - swap( dMax, dMin) ; - - // Calcolo nPos - unsigned int nPos = nJ * m_nNx + nI ; - - // Se spillone vuoto - if ( m_ZValues[nPos].size() == 0) { - - m_ZValues[nPos].resize( 2) ; - - m_ZValues[nPos][0] = dMin ; - m_ZValues[nPos][1] = dMax ; - - m_OGrMgr.Reset() ; - - return true ; - } - - // Ciclo sugli intervalli dello spillone - bool bModified = false ; - unsigned int i = 0 ; - while ( i + 1 < m_ZValues[nPos].size()) { - - // Eventuale aggiustamento di intervalli sovrapposti - if ( i > 0) { - if ( m_ZValues[nPos][i] < m_ZValues[nPos][i - 1] + EPS_SMALL) { - // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva - if ( m_ZValues[nPos][i - 1] < m_ZValues[nPos][i + 1] + EPS_SMALL) - - m_ZValues[nPos][i - 1] = m_ZValues[nPos][i + 1] ; - - for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j) - m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ; - - m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ; - - i = i - 2 ; - } - } - - // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente - if ( m_ZValues[nPos][i] > dMax + EPS_SMALL) { - bModified = true ; - - m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; - - for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 2 ; -- j) - m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ; - - m_ZValues[nPos][i] = dMin ; - m_ZValues[nPos][i + 1] = dMax ; - - i = i + 2 ; - } - - // Casi d'intersezione: - else if ( m_ZValues[nPos][i + 1] > dMax - EPS_SMALL) { - // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente - if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i] = dMin ; - } - } - - else { - // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi - if ( m_ZValues[nPos][i] > dMin + EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i] = dMin ; - m_ZValues[nPos][i + 1] = dMax ; - } - // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente - else if ( m_ZValues[nPos][i + 1] > dMin - EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i + 1] = dMax ; - } - else { - // Aggiungo intervallo a destra dell'ultimo intervallo - if ( i == m_ZValues[nPos].size() - 2) { - bModified = true ; - m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; - - m_ZValues[nPos][i + 2] = dMin ; - m_ZValues[nPos][i + 3] = dMax ; - - i = i + 2 ; - } - } - } - - i = i + 2 ; - } - - // se eseguita modifica, imposto ricalcolo della grafica - if ( bModified) - m_OGrMgr.Reset() ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::AddIntervals( const Point3d& ptP, double dMin, double dMax) -{ - // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) - Point3d ptPL = ptP ; - ptPL.ToLoc( m_LocalFrame) ; - - double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco - double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) - - dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; - dhMin = dZ + dMin ; dhMax = dZ + dMax ; - - // Cerco il punto della griglia più vicino - double integerPartX = floor( dX / m_dStep) ; - double integerPartY = floor( dY / m_dStep) ; - - unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. - unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 - - // Controllo se le coordinate x e y del punto dato siano all'interno della griglia: - // se sono dentro la griglia chiamo l'altra subtract - if ( dX < m_dStep*m_nNx && dY < m_dStep*m_nNy - && dX >= 0 && dY >= 0) { - // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e - // si esce dai limiti dell vector e vi è errore runtime - return AddIntervals( i, j, dhMin, dhMax) ; - } - - // altrimenti non succede niente - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const -{ - // per ora solo perpendicolari a XY (1) - if ( nDir != 1) - return false ; - // verifiche sugli indici - if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) - return false ; - int nPos = nPos1 + nPos2 * m_nNx ; - if ( nPos < 0 || nPos >= int( m_ZValues.size())) - return false ; - // calcolo coordinate punto - double dX = m_dStep * ( 0.5 + nPos1) ; - double dY = m_dStep * ( 0.5 + nPos2) ; - Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; - // creo le polilinee - for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { - // aggiungo polilinea a lista - lstPL.emplace_back() ; - // inserisco punti estremi - lstPL.back().AddUPoint( 0, ptP + m_ZValues[nPos][i-1] * m_LocalFrame.VersZ()) ; - lstPL.back().AddUPoint( 1, ptP + m_ZValues[nPos][i] * m_LocalFrame.VersZ()) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const -{ - const int MAX_DIM_CHUNK = 128 ; - for ( int i = 0 ; i < int( m_nNx) ; i += MAX_DIM_CHUNK) { - int nDimChunkX = min( MAX_DIM_CHUNK, int( m_nNx) - i) ; - for ( int j = 0 ; j < int( m_nNy) ; j += MAX_DIM_CHUNK) { - int nDimChunkY = min( MAX_DIM_CHUNK, int( m_nNy) - j) ; - GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, MAX_DIM_CHUNK, lstTria) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk, TRIA3DLIST& lstTria) const -{ - // determino se è un semplice parallelepipedo - bool bIsSimple = true ; - double dBotZ ; - double dTopZ ; - for ( int i = 0 ; i < nDim1 && bIsSimple ; ++ i) { - for ( int j = 0 ; j < nDim2 && bIsSimple ; ++ j) { - int nPos = ( nPos1 + i) + ( nPos2 + j) * m_nNx ; - if ( nPos > int( m_nDim) || - int( m_ZValues[nPos].size()) != 2) - bIsSimple = false ; - else if ( i == 0 && j == 0) { - dBotZ = m_ZValues[nPos][0] ; - dTopZ = m_ZValues[nPos][1] ; - } - else if ( abs( m_ZValues[nPos][0] - dBotZ) > EPS_SMALL || - abs( m_ZValues[nPos][1] - dTopZ) > EPS_SMALL) - bIsSimple = false ; - } - } - - // se semplice parallelepipedo - if ( bIsSimple) { - CalcChunkPrisms( nPos1, nPos2, nDim1, nDim2, lstTria) ; - } - // se chunk di dimensioni accettabili - else if ( nDimChk >= 4) { - int nNewDimChk = nDimChk / 2 ; - for ( int i = nPos1 ; i < int( nPos1 + nDim1) ; i += nNewDimChk) { - int nDimChunkX = min( nNewDimChk, int( nPos1 + nDim1) - i) ; - for ( int j = nPos2 ; j < int( nPos2 + nDim2) ; j += nNewDimChk) { - int nDimChunkY = min( nNewDimChk, int( nPos2 + nDim2) - j) ; - GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, nNewDimChk, lstTria) ; - } - } - } - // altrimenti - else { - // elaboro ogni singolo dexel - for ( int i = 0 ; i < nDim1 ; ++ i) { - for ( int j = 0 ; j < nDim2 ; ++ j) { - CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ; - } - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const -{ - // verifiche sugli indici - if ( nPos1 < 0 || nPos1 + nDim1 > int( m_nNx) || nPos2 < 0 || nPos2 + nDim2 > int( m_nNy)) - return false ; - int nPos = nPos1 + nPos2 * m_nNx ; - if ( nPos < 0 || nPos >= int( m_nDim)) - return false ; - - // calcolo coordinate punti - double dX = m_dStep * nPos1 ; - double dY = m_dStep * nPos2 ; - Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; - Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_LocalFrame.VersX() ; - Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_LocalFrame.VersY() ; - Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_LocalFrame.VersY() ; - - // creo le facce sopra e sotto - Vector3d vtDZt = m_ZValues[nPos][1] * m_LocalFrame.VersZ() ; - Vector3d vtDZb = m_ZValues[nPos][0] * m_LocalFrame.VersZ() ; - // faccia superiore P1t->P2t->P3t->P4t : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; - // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; - - // creo le facce laterali - for ( int j = 0 ; j < nDim2 ; ++ j) { - int nPosD = nPos + nDim1 - 1 + j * m_nNx ; - int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nNx - 1) ? nPosD + 1 : - 1) ; - Point3d ptP2D = ptP2 + j * m_dStep * m_LocalFrame.VersY() ; - Point3d ptP3D = ptP2D + m_dStep * m_LocalFrame.VersY() ; - AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; - } - for ( int i = 0 ; i < nDim1 ; ++ i) { - int nPosD = nPos + ( nDim2 - 1) * m_nNx + i ; - int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nNy - 1) ? nPosD + m_nNx : - 1) ; - Point3d ptP4D = ptP4 + i * m_dStep * m_LocalFrame.VersX() ; - Point3d ptP3D = ptP4D + m_dStep * m_LocalFrame.VersX() ; - AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; - } - for ( int j = 0 ; j < nDim2 ; ++ j) { - int nPosD = nPos + j * m_nNx ; - int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ; - Point3d ptP1D = ptP1 + j * m_dStep * m_LocalFrame.VersY() ; - Point3d ptP4D = ptP1D + m_dStep * m_LocalFrame.VersY() ; - AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; - } - for ( int i = 0 ; i < nDim1 ; ++ i) { - int nPosD = nPos + i ; - int nPosSud = ( nPos2 > 0 ? nPosD - m_nNx : - 1) ; - Point3d ptP1D = ptP1 + i * m_dStep * m_LocalFrame.VersX() ; - Point3d ptP2D = ptP1D + m_dStep * m_LocalFrame.VersX() ; - AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const -{ - // verifiche sugli indici - if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) - return false ; - int nPos = nPos1 + nPos2 * m_nNx ; - if ( nPos < 0 || nPos >= int( m_nDim)) - return false ; - - // calcolo coordinate punto - double dX = m_dStep * nPos1 ; - double dY = m_dStep * nPos2 ; - Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; - Point3d ptP2 = ptP1 + m_dStep * m_LocalFrame.VersX() ; - Point3d ptP3 = ptP2 + m_dStep * m_LocalFrame.VersY() ; - Point3d ptP4 = ptP1 + m_dStep * m_LocalFrame.VersY() ; - - // creo le facce sopra e sotto di ogni intervallo (sempre visibili) - for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { - Vector3d vtDZt = m_ZValues[nPos][i] * m_LocalFrame.VersZ() ; - Vector3d vtDZb = m_ZValues[nPos][i-1] * m_LocalFrame.VersZ() ; - // faccia superiore P1t->P2t->P3t->P4t : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; - // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; - } - - // creo le facce laterali - int nPosEst = ( nPos1 < int( m_nNx - 1) ? nPos + 1 : - 1) ; - AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; - int nPosNord = ( nPos2 < int( m_nNy - 1) ? nPos + m_nNx : - 1) ; - AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; - int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ; - AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; - int nPosSud = ( nPos2 > 0 ? nPos - m_nNx : - 1) ; - AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, - const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const -{ - Intervals intFace ; - for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) - intFace.Add( m_ZValues[nPos][i-1], m_ZValues[nPos][i]) ; - if ( nPosAdj > 0) { - for ( int i = 1 ; i < int( m_ZValues[nPosAdj].size()) ; i += 2) - intFace.Subtract( m_ZValues[nPosAdj][i-1], m_ZValues[nPosAdj][i]) ; - } - double dMin, dMax ; - bool bFound = intFace.GetFirst( dMin, dMax) ; - while ( bFound) { - Vector3d vtDZt = dMax * vtZ ; - Vector3d vtDZb = dMin * vtZ ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP + vtDZb, ptQ + vtDZb, ptQ + vtDZt, vtNorm) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptQ + vtDZt, ptP + vtDZt, ptP + vtDZb, vtNorm) ; - bFound = intFace.GetNext( dMin, dMax) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::SetTolerances( double dLinTol, double dAngTolDeg) -{ - m_dLinTol = max( dLinTol, LIN_TOL_MIN) ; - m_dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::SetStdTool( const string& sToolName, double dH, double dR, double dCornR) -{ - // reset nome - m_sToolName.clear() ; - // verifica minime dimensioni globali - if ( dH < EPS_SMALL || dR < EPS_SMALL) - return false ; - // utensile cilindrico - if ( dCornR < EPS_SMALL) { - m_nToolType = CylindricalMill ; - m_dHeight = dH ; - m_dRadius = dR ; - m_dTipHeight = 0 ; - m_dTipRadius = m_dRadius ; - m_dRCorner = 0 ; - } - // utensile naso di toro - else if ( dCornR < dR - EPS_SMALL) { - m_nToolType = BullNoseMill ; - m_dHeight = dH ; - m_dRadius = dR ; - m_dTipHeight = dCornR ; - m_dTipRadius = dR - dCornR ; - m_dRCorner = dCornR ; - // come profilo - m_nToolType = GenericTool ; - Point3d pt0( 0, 0, 0) ; - Point3d pt1( m_dRadius, 0, 0) ; - Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; - Point3d pt3( m_dTipRadius, - m_dHeight, 0) ; - Point3d pt4( 0, - m_dHeight, 0) ; - m_ToolOutline.Clear() ; - CurveLine Line ; - Line.Set( pt0, pt1) ; - m_ToolOutline.AddCurve( Line) ; - m_ToolOutline.AddLine( pt2); - m_ToolOutline.AddArcTg( pt3) ; - m_ToolOutline.AddLine( pt4) ; - return SetGenTool( sToolName, &m_ToolOutline) ; - } - // utensile sferico - else if ( dCornR < dR + EPS_SMALL) { - m_nToolType = BallEndMill ; - m_dHeight = dH ; - m_dRadius = dR ; - m_dTipHeight = m_dRadius ; - m_dTipRadius = 0 ; - m_dRCorner = m_dRadius ; - } - // impossibile - else - return false ; - // assegno il nome - m_sToolName = sToolName ; - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::SetAdvTool( const string& sToolName, double dH, double dR, - double dTipH, double dTipR, double dCornR) -{ - // reset nome - m_sToolName.clear() ; - // verifica dimensioni globali - if ( dH < EPS_SMALL || dR < EPS_SMALL) - return false ; - // se altezza punta nulla, ricado nel caso standard - if ( dTipH < EPS_SMALL) - return SetStdTool( sToolName, dH, dR, dCornR) ; - // caso avanzato - if ( abs( dTipR - dR) < EPS_SMALL) { - m_nToolType = CylindricalMill ; - m_dHeight = dH ; - m_dRadius = dR ; - m_dTipHeight = 0 ; - m_dTipRadius = m_dRadius ; - m_dRCorner = 0 ; - } - else { - m_nToolType = ConusMill ; - m_dHeight = dH ; - m_dRadius = dR ; - m_dTipHeight = dTipH ; - m_dTipRadius = max( dTipR, 0.) ; - m_dRCorner = dCornR ; - } - // assegno il nome - m_sToolName = sToolName ; - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline) -{ - // Aggiorno il nome dell'utensile - m_sToolName = sToolName ; - - // Aggiorno il tipo di utensile - m_nToolType = GenericTool ; - - // Copio il profilo - m_ToolOutline.CopyFrom( pToolOutline) ; - - // Se ci fosse una Bézier la convertiamo in archi e rette - m_ToolOutline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg) ; - - // Puntatore a curva costante - const ICurve* pCurve = m_ToolOutline.GetFirstCurve() ; - - // Ciclo sulle curve componenti - while ( pCurve != nullptr) { - - // Se la curva è un arco valuto approssimarlo - if ( pCurve->GetType() == CRV_ARC) { - - // Centro e punti iniziale e finale dell'arco - Point3d ptStart, ptEnd, ptO ; - - pCurve->GetStartPoint( ptStart) ; - pCurve->GetEndPoint( ptEnd) ; - pCurve->GetCenterPoint( ptO) ; - - // Vettore congiungente il centro con i punti iniziale e finale - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - // Calcolo del raggio dell'arco - double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ; - - // Recupero la curva precedente e quella successiva - const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ; - const ICurve* pNext = m_ToolOutline.GetNextCurve() ; - pNext = m_ToolOutline.GetNextCurve() ; - - // Valuto la necessità di approssimare l'arco o meno - - // Punto Iniziale della curva precedente e finale della successiva - Point3d ptStartPrev, ptEndNext ; - - // Vettori tangenti alle curve precedente corrente e successiva - // rispettivamente nei punti finale, iniziale e finale e iniziale - // e prodotti vettore fra i suddetti - Vector3d vtPrevEndDir, vtCurrentStartDir, vtCurrentEndDir, vtNextStartDir ; - Vector3d vtIProd, vtFProd ; - - Point3d ptTopCurrent = ptO + Y_AX * dRadius ; - Point3d ptBottomCurrent = ptO - Y_AX * dRadius ; - - // Valuto le relazioni geometriche fra la - // curva corrente e quella precedente. - pPrev->GetStartPoint( ptStartPrev) ; - pPrev->GetEndDir( vtPrevEndDir) ; - pCurve->GetStartDir( vtCurrentStartDir) ; - vtIProd = vtPrevEndDir ^ vtCurrentStartDir ; - - // Se la curva successiva esiste valuto le - // medesime relazioni con la quest'ultima - if ( pNext != nullptr) { - - pNext->GetEndPoint( ptEndNext) ; - pCurve->GetEndDir( vtCurrentEndDir) ; - pNext->GetStartDir( vtNextStartDir) ; - vtFProd = vtCurrentEndDir ^ vtNextStartDir ; - } - - // Se devo approssimare - if ( ! ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptStartPrev.y > ptTopCurrent.y) && - ( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) || - ( pNext != nullptr && vtFProd.z > 0 && ptBottomCurrent.y > ptEndNext.y)))) { - - // Copio la parte precedente - const ICurve* pAux = m_ToolOutline.GetFirstCurve() ; - - while ( pAux != pCurve) { - - m_ToolArcLineApprox.AddCurve( * pAux, true) ; - - pAux = m_ToolOutline.GetNextCurve() ; - } - - // Creo la polyline approssimante - PolyLine Polygonal ; - - pCurve->ApproxWithLines( m_dLinTol, m_dAngTolDeg, 10, Polygonal) ; - - // Definisco una curva composita a partire dalla polyline - CurveComposite cvTemp ; cvTemp.FromPolyLine( Polygonal) ; - - // Aggiungo la parte approssimata - pAux = cvTemp.GetFirstCurve() ; - - while ( pAux != nullptr) { - - m_ToolArcLineApprox.AddCurve( * pAux, true) ; - - pAux = cvTemp.GetNextCurve() ; - } - } - // Se non deve essere approssimato - else { - // Se è già stato definito m_ToolArcLineApprox deve - // essere completo, aggiungo quindi l'arco corrente - if ( m_ToolArcLineApprox.GetCurveCount() != 0) - m_ToolArcLineApprox.AddCurve( * pCurve, true) ; - } - } - // Se è segmento - else { - // Se è già stato definito m_ToolArcLineApprox deve - // essere completo, aggiungo quindi il segmento corrente - if ( m_ToolArcLineApprox.GetCurveCount() != 0) - m_ToolArcLineApprox.AddCurve( * pCurve, true) ; - } - - pCurve = m_ToolOutline.GetNextCurve() ; - } - - // Dimensioni dell'utensile - BBox3d Bounding ; - m_ToolOutline.GetLocalBBox( Bounding) ; - double m_dHeight = Bounding.GetMax().y - Bounding.GetMin().y ; - double m_dRadius = Bounding.GetMax().x - Bounding.GetMin().x ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) -{ - // Controllo sull'effettiva esistenza del movimento - if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe)) - return true ; - - // Porto i dati del movimento nel riferimento intrinseco; quest'operazione è 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 ; ptLe.ToLoc( m_LocalFrame) ; - Vector3d vtLs = vtDs ; vtLs.ToLoc( m_LocalFrame) ; - Vector3d vtLe = vtDe ; vtLe.ToLoc( m_LocalFrame) ; - - // Normalizzo i vettori - if ( ! vtLs.Normalize() || ! vtLe.Normalize()) - return false ; - - // Direzione utensile costante - 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)) { - if ( m_nToolType == GenericTool) - return DrillZ( ptLs, ptLe, vtLs) ; - else - return DrillingZ( ptLs, ptLe, vtLs) ; - } - - // Movimento perpendicolare a direzione utensile - if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) { - if ( m_nToolType == 0) - return MillZ( ptLs, ptLe, vtLs) ; - else - return MillingPerpZ( ptLs, ptLe, vtLs) ; - } - - // Movimento generico - if ( m_nToolType == 0) - return MillZ( ptLs, ptLe, vtLs) ; - else - return MillingZ( ptLs, ptLe, vtLs) ; - } - - // Versori della direzione utensile nel piano XY - else if ( abs( vtLs.z) < 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) - if ( vtTOrt.SqLen() < EPS_SMALL * EPS_SMALL) { - if ( m_nToolType == 0) - return DrillingGT( ptLs, ptLe, vtDir) ; - else - return DrillingXY( ptLs, ptLe, vtDir) ; - } - - // Movimento perpendicolare alla direzione dell'utensile - if ( vtTLong.SqLen() < EPS_SMALL * EPS_SMALL) { - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtDir) ; - else - return MillingPerpXY( ptLs, ptLe, vtDir) ; - } - - // Movimento nel piano generico - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtDir) ; - else - return MillingXYPlaneGen( ptLs, ptLe, vtDir) ; - } - - // Movimento con Z non costante - else { - - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtDir) ; - - // Movimento verticale - if ( SqDistXY( ptLs, ptLe) < EPS_SMALL * EPS_SMALL) - return MillingXYVert( ptLs, ptLe, vtDir) ; - - // Grandezze geometriche per selezione - Vector3d vtMove = ptLe - ptLs ; - Vector3d vtTLong = ( vtMove * vtDir) * vtDir ; - Vector3d vtTOrt = vtMove - ( vtMove * vtDir) * vtDir ; - - // 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) ; - } - } - - // Caso generico - else { - - Vector3d vtMove = ptLe - ptLs ; - Vector3d vtOrt = vtMove - ( vtMove * vtLs) * vtLs ; - - // Drilling - if ( vtOrt.SqLen() < EPS_SMALL * EPS_SMALL) { - if ( m_nToolType == GenericTool) - return DrillingGT( ptLs, ptLe, vtLs) ; - else - return Drilling( ptLs, ptLe, vtLs) ; - } - // Milling - else { - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtLs) ; - else - return Milling( ptLs, ptLe, vtLs) ; - } - } - } - - // Altri casi, non gestiti - return false ; -} - -// Versore utensile parallelo all'asse Z -//---------------------------------------------------------------------------- -bool -VolZmap::DrillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Cilindro sfera toro - if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill || - m_nToolType == BullNoseMill) - - return CBTDrillZ( ptLs, ptLe, vtToolDir) ; - // Coni - 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 ; - 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 dMax = ptLs.z - m_dHeight ; // Volendo si può effettuare un controllo su quota punto finale e iniziale, - double dMin = ptLe.z - m_dHeight ; // ma non è necessaria dal momento che Subtract intervals scambia min con max se max < min - 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) ; - - // 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 - double dSqDist = SqDistXY( ptQ, ptLe) ; - // se distanza nei limiti, taglio - if ( dSqDist < dSqRad) - GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { - - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = ptLs.x - dMaxRad ; - double dMaxX = ptLs.x + dMaxRad ; - double dMinY = ptLs.y - dMaxRad ; - double dMaxY = ptLs.y + dMaxRad ; - - // 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 ; - - double dDeltaZ = abs( ptLe.z - ptLs.z) ; - - Point3d ptO( ptLs.x, ptLs.y, 0) ; - - // 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)) ; - - - if ( m_dRadius < m_dTipRadius) - // Coda di rondine - return GetMinMaxZSw( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ; - // Punta di trapano - else - return GetMinMaxZDr( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::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) -{ - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - // Determinazione della posizione xy del dexel rispetto - // all'asse di simmetria dell'utensile - 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 ; - - // Se il dexel cade nel cerchio di interesse taglio - if ( dSqDist < dMaxRad * dMaxRad) { - - double dMin, dMax ; - - if ( dSqDist < dMinRad * dMinRad) { - dMin = dMinZ ; - dMax = dMaxZ ; - } - - else { - double dR = sqrt( dSqDist) ; - if ( dDir > 0) { - dMin = dMinZ ; - dMax = dMinZ + dDeltaZ + ( m_dTipHeight * ( dMaxRad - dR)) / ( dMaxRad - dMinRad) ; - } - else { - dMin = dMaxZ - dDeltaZ + ( m_dTipHeight * ( dR - dMaxRad)) / ( dMaxRad - dMinRad) ; - dMax = dMaxZ ; - } - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::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) -{ - 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 ; - - // Se il dexel cade nel cerchio di interesse taglio - if ( dSqDist < dMaxRad * dMaxRad) { - - double dMin, dMax ; - - if ( dSqDist < dMinRad * dMinRad) { - dMin = dMinZ ; - dMax = dMaxZ ; - } - - else { - double dR = sqrt( dSqDist) ; - if ( dDir > 0) { - dMin = dMinZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMaxRad - dMinRad) ; - dMax = dMaxZ ; - } - else { - dMin = dMinZ ; - dMax = dMaxZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMinRad - dMaxRad) ; - } - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - // Cilindro sfera toro - if ( m_nToolType == CylindricalMill || - m_nToolType == BallEndMill || - m_nToolType == BullNoseMill) - - return CBTMillingPerpZ( ptLs, ptLe, vtToolDir) ; - // Coni - else if ( m_nToolType == ConusMill) - - return ConusPerpZ( ptLs, ptLe, vtToolDir) ; - - else - return false ; -} - -//---------------------------------------------------------------------------- -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) -{ - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; - double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; - double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; - double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; // Ricordati del caso balordo da mettere nella documentazione - - // 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 ; - - Point3d ptO( ptLs.x, ptLs.y, 0) ; - Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; - Vector3d vtV1 = vtMove ; vtV1.Normalize() ; - - double dZBase = ptLs.z ; - double dZStem = ptLs.z - ( m_dHeight - m_dTipHeight) * vtToolDir.z ; - double dZTip = ptLs.z - m_dHeight * vtToolDir.z ; - - // 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 dMin, dMax ; - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; - - double dProj1 = vtC * vtV1 ; - Vector3d vtOrt = vtC - dProj1 * vtV1 ; - - if ( dProj1 < 0) { - - double dSqDist = vtC * vtC ; - - if ( dSqDist < dMinRad * dMinRad) { - - dMin = min( dZBase, dZTip) ; - dMax = max( dZBase, dZTip) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { - - double dr = sqrt( dSqDist) ; - - if ( m_dRadius < m_dTipRadius) { - - dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - } - else { - dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - else if ( dProj1 >= 0 && dProj1 < dLen) { - - double dSqDist = vtOrt * vtOrt ; - - if ( dSqDist < dMinRad * dMinRad) { - - dMin = min( dZBase, dZTip) ; - dMax = max( dZBase, dZTip) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { - - double dr = sqrt( dSqDist) ; - - if ( m_dRadius < m_dTipRadius) { - dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - } - - else { - dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - else if ( dProj1 >= dLen) { - - Vector3d vtCn = vtC - vtMove ; - - double dSqDist = vtCn * vtCn ; - - if ( dSqDist < dMinRad * dMinRad) { - dMin = min( dZBase, dZTip) ; - dMax = max( dZBase, dZTip) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { - - double dr = sqrt( dSqDist) ; - - if ( m_dRadius < m_dTipRadius) { - dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - } - - else { - dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - 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) ; - - // Caso utensile generico al momento non gestito - if ( m_nToolType == 0) - return false ; - - // Caso Cylindrical Mill - else if ( m_nToolType == 1) { - double dMin, dMax ; - - 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) { - double dMin, dMax ; - - double dH = sqrt( dSqRad - dSqDist) ; - - if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ; - dMax = max( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min( dZtip + dFactor*( m_dRadius - dH), - dZtip + dFactor*( m_dRadius - dH) + dDeltaZ) ;// ocio - dMax = max( dZtip + dFactor*( m_dRadius - dH), - dZtip + dFactor*( m_dRadius - dH) + 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) { - - double dMin, dMax ; - - 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 ; - double dSqrt = sqrt(dSqRadC - dSqd) ; - - double dMin, dMax ; - if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ; - dMax = max( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min( dZtip + dFactor *( m_dRCorner - dSqrt), - dZtip + dFactor *( m_dRCorner - dSqrt) + dDeltaZ) ; - dMax = max( dZtip + dFactor *( m_dRCorner - dSqrt), - dZtip + dFactor *( m_dRCorner - dSqrt) + 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) -{ - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; - double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; - double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; - double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; - - // 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 ; - - // Punti iniziale e finale e proiezione sul piano del punto iniziale - Point3d ptI, ptF, ptO ; - - if ( vtToolDir.z > 0) { - ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - } - else { - ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - } - - // Quote iniziale e finale della base dell'utensile e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - // Vettori di movimento - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; - - // Sistema di riferimento sul cono e vertice del cono - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Point3d ptV = ptI - ( m_dHeight + m_dTipHeight * dMinRad / ( dMaxRad - dMinRad)) * vtV1 ; - - // 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 ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 + - ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 - - ( dSin / dDen) * vtV3 ; - - Vector3d vtR0 = ptV - ORIG ; - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - // 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) { - // Grandezze per determinare la configurazione geometrica dell'utensile - 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 - ptO ; - Vector3d vtCf = vtC - vtMoveXY ; - - Vector3d vtUC = vtC ; vtUC.Normalize() ; - Vector3d vtUCf = vtCf ; vtUCf.Normalize() ; - - double dCCos = vtUC * vtV2 ; - double dCCosf = vtUCf * vtV2 ; - - double dProj = vtC * vtV2 ; - Vector3d vtOrt = vtC - dProj * vtV2 ; - - double dSqDistI = vtC * vtC ; - double dSqDistM = vtOrt * vtOrt ; - double dSqDistF = vtCf * vtCf ; - - // Se dentro la zona interessata dalla lavorazione valuto - // la tipologia di tale zona - if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || - ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || - ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { - - // Caso vettore utensile equiverso all'asse Z - if ( vtToolDir.z > 0) { - // Massimi - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - if ( dProj < dLen - dPMaxI) - - dMax = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxI) ; - else - dMax = dZF ; - - // Minimi - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZI - m_dHeight ; - - else { - - if ( ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMin = dZI - m_dHeight + ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - else - dMin = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMin = dZF - m_dHeight + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - - dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - else { - - if ( dSqDistI < dMaxRad * dMaxRad) - - dMin = dZI - m_dHeight + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) - - dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - } - // Caso vettore utensile opposto all'asse Z - else { - // Massimi - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZI + m_dHeight ; - - else { - - if ( - ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMax = dZI + m_dHeight - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMax = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - else - dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMax = dZF + m_dHeight - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - - dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - else { - - if ( dSqDistI < dMaxRad * dMaxRad) - - dMax = dZI + m_dHeight - ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - - else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) - - dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - } - // Minimi - double dPMaxCirc = sqrt( dMaxRad * dMaxRad - dSqDistM) ; - - if ( dProj > dLen - dPMaxCirc) - dMin = dZF ; - else - dMin = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxCirc) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) -{ - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; - double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; - double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; - double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; - - // 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 ; - - // Punti iniziale e finale e proiezione sul piano del punto iniziale - Point3d ptI, ptF, ptO ; - - if ( vtToolDir.z > 0) { - - ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - } - - else { - ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - } - - Point3d ptICyl = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - - double dDeltaH = m_dHeight - m_dTipHeight ; - double dMinZCyl = min( ptICyl.z, ptICyl.z - vtToolDir.z * dDeltaH) ; - - // Punti contatto cono cilindro - Point3d ptIS = ptI - ( m_dHeight - m_dTipHeight) * vtToolDir ; - Point3d ptFS = ptF - ( m_dHeight - m_dTipHeight) * vtToolDir ; - - // Quote iniziali e finali e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; - double dDeltaZ = dZF - dZI ; double dADeltaZ = abs( dDeltaZ) ; - double dZIS = ptIS.z ; double dZFS = ptFS.z ; - - // Vettori di movimento - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; - - // Sistema di riferimento sul cono e vertice del cono - Vector3d vtV1 = - vtToolDir ; - Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Point3d ptV = ptI + ( m_dHeight - m_dTipHeight * ( 1 + dMinRad / ( dMaxRad - dMinRad))) * vtV1 ; - - // 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 ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1- dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNp = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 + - ( dSin / dDen) * vtV3 ; - Vector3d vtNm = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 - - ( dSin / dDen) * vtV3 ; - - Vector3d vtR0 = ptV - ORIG ; - double dDotp = vtR0 * vtNp ; - double dDotm = vtR0 * vtNm ; - - // 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 dMin, dMax ; - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; Vector3d vtCf = vtC - vtMoveXY ; - - Vector3d vtUC = vtC ; Vector3d vtUCf = vtCf ; vtUC.Normalize() ; vtUCf.Normalize() ; - - double dCCos = vtUC * vtV2 ; double dCCosf = vtUCf * vtV2 ; - - double dProj = vtC * vtV2 ; - Vector3d vtOrt = vtC - dProj * vtV2 ; - - double dSqDistI = vtC * vtC ; - double dSqDistM = vtOrt * vtOrt ; - double dSqDistF = vtCf * vtCf ; - - if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || - ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || - ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { - // Caso vettore utensile equiverso all'asse Z - if ( vtV1.z < 0) { - - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - // Massimi - if ( dRatio <= 1 / dTanAlpha) { - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZIS ; - - else { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMax = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; - else - dMax = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMax = dZFS - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - else { - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZIS ; - - else if ( dSqDistI < dMaxRad * dMaxRad) - - dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else { - - if ( dProj >= dPMaxI) - - dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - // Minimi - - if ( dSqDistF < dMaxRad * dMaxRad) - - dMin = dZFS - m_dTipHeight ; - - else if ( dProj <= dLen - dPMaxI) - - dMin = dZIS - m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; - - } - // Caso vettore utensile opposto all'asse Z - else { - - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - // Massimi - if ( dSqDistF < dMaxRad * dMaxRad) - - dMax = dZFS + m_dTipHeight ; - - else if ( dProj <= dLen - dPMaxI) - - dMax = dZIS + m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; - - // Minimi - if ( dRatio <= 1 / dTanAlpha) { - - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZIS ; - - else { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMin = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; - else - dMin = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMin = dZFS + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - else { - - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZIS ; - - else if ( dSqDistI < dMaxRad * dMaxRad) - - dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else - - dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - } - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Parte cilindrica - Vector3d vtCyl = ( vtV1.z < 0 ? vtCf : vtC) ; - Vector3d vtCylf = ( vtV1.z < 0 ? vtC : vtCf) ; - Vector3d vtMot = ( vtV1.z < 0 ? - vtV2 : vtV2) ; - - double dCylProj = vtCyl * vtMot ; - double dCylSqDistI = vtCyl * vtCyl ; - double dCylSqDistF = vtCylf * vtCylf ; - double dCylSqDistM = ( vtCyl - dCylProj * vtMot) * ( vtCyl - dCylProj * vtMot) ; - - - if ( dCylSqDistI < dMinRad * dMinRad - || dCylSqDistF < dMinRad * dMinRad - || ( dCylProj > 0 && dCylProj < dLen && dCylSqDistM < dMinRad * dMinRad)) { - - double dSt = sqrt( dMinRad * dMinRad - dCylSqDistM) ; - - // Minimi - if ( dCylSqDistI < dMinRad * dMinRad ) - - dMin = dMinZCyl ; - - else if ( dCylProj >= dSt) - - dMin = dMinZCyl + ( dCylProj - dSt) * dADeltaZ / dLen ; - - // Massimi - if ( dCylSqDistF < dMinRad * dMinRad) - - dMax = dMinZCyl + dDeltaH + dADeltaZ ; - - else if ( dCylProj <= dLen - dSt) - - dMax = dMinZCyl + dDeltaH + ( dCylProj + dSt) * dADeltaZ / dLen ; - - SubtractIntervals( i, j, dMin, dMax) ; - - } - } - } - 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 bControl = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( bControl == 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 dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTan * dRatio ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - double dDeltaR = dMaxRad - dMinRad ; - double dMinLim = dMinRad * dCos ; - double dMaxLim = dMaxRad * dCos ; - - - // Versori normali e prodotti scalari per determinare i piani - Vector3d vtNInf = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNSup = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) - 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) - 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) - 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 dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTan / dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 - dFactor * ( dSin / dDen) * vtV2 ; - Vector3d vtNd = - ( dTan /dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 + dFactor * ( dSin / dDen) * 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 * dSin - dProj1 * dDeltaR * dSin / 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 * dSin && 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 * dSin) { - - double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ; - - dZL1 = dZI + dFactor * dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ; - } - else if ( dProj1 >= dPLen && - dOrtLen > dMaxRad * dSin - ( dProj1 - dPLen) * dDeltaR * dSin / 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) ; - } - } - } - - 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) ; - } - } - } - - 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) - 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 ; - double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) ; - } - } - } - - 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) ; - } - } - } - - 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 dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - 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 / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve ; - - pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso segmento - 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) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - LongCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - LongConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utesile - 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 ; - } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.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) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve ; - - pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso segmento - 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) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - MillCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - MillConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utensile - else if ( ptStart.x < ptEnd.x) { - - double dMaxRad = ptEnd.x ; - double dMinRad = ptStart.x ; - - Point3d ptIn = ptI - vtToolDir * dHeight ; - Point3d ptFn = ptIn + vtMove ; - - MillConusV( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - } - else - dHeight = 0 ; - } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.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) - 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 ; - - double dLimX1 = sqrt( dRad * dRad - dX2 * dX2) ; - - if ( dX2 > - dRad && dX2 < dRad && - dX1 > - dLimX1 && - dX1 < dPLen + dLimX1) { - - // Massimi - if( dX1 > - dLimX1 && dX1 < dPLen - dLimX1) - - dMax = dZI + ( dX1 + dLimX1) * dDeltaZ / dPLen ; - - else if ( dX1 >= dPLen - dLimX1 && - dX1 < dPLen + dLimX1) - - dMax = dZI + dDeltaZ ; - - // Minimi - if ( dX1 > - dLimX1 && dX1 < dLimX1) - - dMin = dZI - dHei ; - - else if ( dX1 >= dLimX1 && - dX1 < dPLen + dLimX1) - - dMin = dZI - dHei + ( dX1 - dLimX1) * 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) - 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) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; - - Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve ; - - pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso di semento - 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) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - LongCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - LongConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utensile - else if ( ptStart.x < ptEnd.x) { - - double dMaxRad = ptEnd.x ; - double dMinRad = ptStart.x ; - - Point3d ptIn = ptI - vtToolDir * dHeight ; - Point3d ptFn = ptIn + vtMove ; - - LongConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - } - else - dHeight = 0 ; - } - - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.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) - 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) { - - double dLenVector = sqrt(vtCyl.x * vtCyl.x + vtCyl.y * vtCyl.y) ; - - vtU1 = ( 1 + dLenVector) / dLenVector * 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) - 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) { - - double dLenVector = sqrt(vtMove.x * vtMove.x + vtMove.y * vtMove.y) ; - - vtU1 = ( 1 + dLenVector) / dLenVector * 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 ; - - double dLimP1 = sqrt( dRad * dRad - dPI2 * dPI2) ; - - // Dexel nella regione interessata dalla lavorazione - if ( ( dPI1 > - dCos * dLimP1 && - dPI1 < dLOri && dPI2 * dPI2 < dRad * dRad) || - ( dPF1 * dPF1 + dPF2 * dPF2 < dRad * dRad)) { - - if ( dDeltaZ > 0) { - - // Massimi - if ( dPI1 < dLOri - dCos * dLimP1) { - - double dPI0 = - dCos * dLimP1 ; - double dZ0 = dSin * dLimP1 ; - - 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 * dLimP1) - - dMin = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; - - else if ( dPI1 < dLOri + dCos * dLimP1) { - - double dPI0 = dCos * dLimP1 ; - double dZ0 = - dSin * dLimP1 ; - - 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 * dLimP1) - - dMax = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; - - else if ( dPI1 < dLOri + dCos * dLimP1) { - - double dPI0 = dCos * dLimP1 ; - double dZ0 = + dSin * dLimP1 ; - - 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 * dLimP1) { - - double dPI0 = - dCos * dLimP1 ; - double dZ0 = - dSin * dLimP1 ; - - 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) - 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) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - int i = m_ToolArcLineApprox.GetCurveCount() ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso di semento - 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) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - MillCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - MillConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utensile - else if ( ptStart.x < ptEnd.x) { - - double dMaxRad = ptEnd.x ; - double dMinRad = ptStart.x ; - - Point3d ptIn = ptI - vtToolDir * dHeight ; - Point3d ptFn = ptIn + vtMove ; - - MillConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - } - else - dHeight = 0 ; - } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.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) - 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) - 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) - 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) - 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 dDen = sqrt( 1 + dTan * dTan) ; - 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 / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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, 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) - 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) { - - double dH = sqrt( dRad * dRad - dSqLen) ; - - dMin = dZI - dH ; - dMax = dZI + dDeltaZ + dH ; - - 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 ; -} - - -// 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 a69838c..a605194 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -14,15 +14,14 @@ #pragma once #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 "/EgtDev/Include/ENkPolynomialRoots.h" +#include "/EgtDev/Include/EgkIntersLinesurfTm.h" +#include "SurfFlatRegion.h" //---------------------------------------------------------------------------- class VolZmap : public IVolZmap, public IGeoObjRW @@ -61,8 +60,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW public : // IVolZmap bool CopyFrom( const IGeoObj* pGObjSrc) override ; - bool CreateMap( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dPrec) ; - bool CreateMapFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec) ; + bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dPrec) override ; + bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec) override ; + bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec) override ; 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 ; @@ -71,13 +71,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW double dH, double dR, double dTipH, double dTipR, double dCornR) override ; bool SetGenTool( const std::string& pToolName, const ICurveComposite* pToolOutline) override ; bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const 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 SubtractIntervals( 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 GetDepth( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) override ; + bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) override ; public : // IGeoObjRW virtual int GetNgeId( void) const ; @@ -108,6 +103,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const ; bool AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const ; + + bool SubtractIntervals( 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) ; // frese: cylindrical, ball-end, bull-nose e conus // Versore utensile parallelo all'asse Z @@ -224,8 +224,10 @@ class VolZmap : public IVolZmap, public IGeoObjRW 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, + 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, @@ -234,15 +236,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW 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) ; - + bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, + const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ; + bool IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) ; + bool IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nI, unsigned int nJ, + double& dU1, double& dU2) ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp new file mode 100644 index 0000000..ae88760 --- /dev/null +++ b/VolZmapCalculus.cpp @@ -0,0 +1,313 @@ +//---------------------------------------------------------------------------- +// EgalTech 2016-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 03.11.16 Versione : 1.6w1 +// Contenuto : Implementazione della classe Volume Zmap : intersezioni. +// +// +// +// Modifiche : 03.11.16 LM Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "VolZmap.h" +#include "GeoConst.h" +#include "\EgtDev\Include\EgtNumUtils.h" + +using namespace std ; + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, + const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) +{ + // Il box è allineato agli assi + + dU1 = - INFINITO ; + dU2 = INFINITO ; + + // confronto con piani YZ (perpendicolari ad asse X) + if ( vtV.x > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ; + dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ; + } + else if ( vtV.x < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ; + dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ; + } + else if ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL) + return false ; + + // confronto con piani ZX (perpendicolari ad asse Y) + if ( vtV.y > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ; + dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ; + } + else if ( vtV.y < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ; + dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ; + } + else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL) + return false ; + + // confronto con piani XZ (perpendicolari ad asse Z) + if ( vtV.z > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ; + dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ; + } + else if ( vtV.z < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ; + dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ; + } + else if ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL) + return false ; + + return ( dU2 >= dU1) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) +{ + // Punti estremi del box dello Zmap + Point3d ptMin = ORIG ; + Point3d ptMax = ptMin + m_nNx * m_dStep * X_AX + m_nNy * m_dStep * Y_AX + m_dMaxZ * Z_AX ; + + if ( IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) && ( dU1 > 0 || dU2 > 0)) { + return true ; + } + + else { + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nI, + unsigned int nJ, double& dU1, double& dU2) +{ + // Determino l'indice del dexel e il doppio del numero di suo intervalli + unsigned int nDexelPos = nJ * m_nNx + nI ; + unsigned int nDexelSize = unsigned int( m_ZValues[nDexelPos].size()) ; + + // Se non c'è materiale non devo fare alcunché + if ( nDexelSize == 0) + return false ; + + // Determino estremi nel piano XY intrinseco del dexel + double dXmin = nI * m_dStep ; + double dYmin = nJ * m_dStep ; + double dXmax = ( nI + 1) * m_dStep ; + double dYmax = ( nJ + 1) * m_dStep ; + + // ciclo sugli intervalli + dU1 = INFINITO ; + dU2 = - INFINITO ; + bool bInters = false ; + for ( unsigned int nIndex = 0 ; nIndex < nDexelSize ; nIndex += 2) { + // estremi del box del singolo intervallo + Point3d ptE1( dXmin, dYmin, m_ZValues[nDexelPos][nIndex]) ; + Point3d ptE2( dXmax, dYmax, m_ZValues[nDexelPos][nIndex+1]) ; + double dt1, dt2 ; + if ( IntersLineBox( ptP, vtV, ptE1, ptE2, dt1, dt2)) { + bInters = true ; + dU1 = min( dU1, dt1) ; + dU2 = max( dU2, dt2) ; + } + } + + return bInters ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLength, double& dOutLength) +{ + // Porto il raggio nel riferimento intrinseco + Point3d ptP = ptPGlob ; + ptP.ToLoc( m_LocalFrame) ; + Vector3d vtV = vtDir ; + vtV.ToLoc( m_LocalFrame) ; + vtV.Normalize() ; + + // Studio dell'intersezione fra semiretta e BBox dello Zmap + double dU1, dU2 ; + bool bTest = IntersLineZMapBBox( ptP, vtV, dU1, dU2) ; + + // Semiretta esterna al box dello Zmap + if ( ! bTest) { + dInLength = - 2 ; + dOutLength = - 2 ; + return true ; + } + + Point3d ptI, ptF ; + // Una sola intersezione valida ( punto interno, intersezione valida 2) + if ( dU1 < 0 && dU2 > 0) { + ptI = ptP ; + ptF = ptP + dU2 * vtV ; + } + // due soluzioni valide ( punto esterno) + else { + ptI = ptP + dU1 * vtV ; + ptF = ptP + dU2 * vtV ; + } + + // Determinazione degli indici i j dei punti ptI e ptF + int nIi = Clamp( int( floor( ptI.x / m_dStep)), 0, m_nNx - 1) ; + int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nNy - 1) ; + int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nNx - 1) ; + int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nNy - 1) ; + + // Inizializzo distanze + dInLength = INFINITO ; + dOutLength = - INFINITO ; + + // Variazioni + double dDeltaX = ptF.x - ptI.x ; + double dDeltaY = ptF.y - ptI.y ; + + // se inclinazione da asse X minore di 45 gradi (in assoluto) + if ( abs( dDeltaY) <= abs( dDeltaX)) { + // mi muovo lungo X (i) + int nIncrI = ( nFi >= nIi ? 1 : - 1) ; + for ( int i = nIi, j = nIj ; + i != nFi + nIncrI ; + i += nIncrI) { + + // Controllo con nuovo i e j corrente (considero il bordo sinistro del dexel) + double dU1, dU2 ; + if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + + // Mi sposto sul bordo destro del dexel + double dMoveX = ( ( i + max( nIncrI, 0)) * m_dStep - ptI.x) ; + double dMoveY = dMoveX * dDeltaY / dDeltaX ; + double dY = ptI.y + dMoveY ; + int OldJ = j ; + j = Clamp( int( floor( dY / m_dStep)), 0, m_nNy - 1) ; + + // Analisi del dexel + if ( j != OldJ) { + double dU1, dU2 ; + if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + } + } + } + + // altrimenti + else { + // mi muovo lungo Y (j) + int nIncrJ = ( nFj >= nIj ? 1 : - 1) ; + for ( int i = nIi, j = nIj ; + j != nFj + nIncrJ ; + j += nIncrJ) { + + // Controllo con nuovo j e i corrente (considero il bordo sotto del dexel) + double dU1, dU2 ; + if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + + // Mi sposto sul bordo sopra del dexel + double dMoveY = ( ( j + max( nIncrJ, 0)) * m_dStep - ptI.y) ; + double dMoveX = dMoveY * dDeltaX / dDeltaY ; + double dX = ptI.x + dMoveX ; + int OldI = i ; + i = Clamp( int( floor( dX / m_dStep)), 0, m_nNx - 1) ; + + // Analisi del dexel + if ( i != OldI) { + double dU1, dU2 ; + if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + } + } + } + + // Se non abbiamo incontrato materiale + if ( dInLength > dOutLength - EPS_SMALL) { + dInLength = - 2 ; + dOutLength = - 2 ; + return true ; + } + + // Se parto dall'interno + if ( dInLength < - EPS_SMALL) + dInLength = - 1 ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) +{ + // BBox + BBox3d b3Box( ORIG, ORIG + vtDiag) ; + + // lo porto nel riferimento intrinseco dello Zmap + b3Box.LocToLoc( frBox, m_LocalFrame) ; + + // BBox dello Zmap nel suo riferimento intrinseco + BBox3d b3Zmap( ORIG, Point3d( m_nNx * m_dStep, m_nNy * m_dStep, m_dMaxZ)) ; + + // Se non interferiscono, posso uscire + BBox3d b3Int ; + if ( ! b3Zmap.FindIntersection( b3Box, b3Int)) + return true ; + + // Limiti su indici + int nStI = Clamp( int( b3Int.GetMin().x / m_dStep), 0, m_nNx -1) ; + int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nNx -1) ; + int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nNy -1) ; + int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy -1) ; + + // Vettore direzione dei dexel nel riferimento del Box + Vector3d vtK = Z_AX ; vtK.LocToLoc( m_LocalFrame, frBox) ; + + // Riferimento intrinseco dei dexel nel riferimento del box + Point3d ptO = ORIG ; ptO.LocToLoc( m_LocalFrame, frBox) ; + Vector3d vtX = X_AX ; vtX.LocToLoc( m_LocalFrame, frBox) ; + Vector3d vtY = Y_AX ; vtY.LocToLoc( m_LocalFrame, frBox) ; + + // Ciclo di intersezione dei dexel con il BBox + for ( int i = nStI ; i <= nEnI ; ++ i) { + + for ( int j = nStJ ; j <= nEnJ ; ++ j) { + + int nPos = j * m_nNx + i ; + int nSize = int( m_ZValues[nPos].size()) ; + if ( nSize == 0) + continue ; + + Point3d ptC = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ; + + double dZmin, dZmax ; + if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) { + + for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 2) { + if ( m_ZValues[nPos].size() == 0) + continue ; + if ( ! ( dZmax < m_ZValues[nPos][nIndex] - EPS_SMALL || + dZmin > m_ZValues[nPos][nIndex + 1] + EPS_SMALL)) + return false ; + } + } + } + } + + return true ; +} diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp new file mode 100644 index 0000000..7b25667 --- /dev/null +++ b/VolZmapCreation.cpp @@ -0,0 +1,258 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (singola griglia) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "CurveLine.h" +#include "VolZmap.h" +#include "GeoConst.h" +#include "IntersLineSurfTm.h" +#include "\EgtDev\Include\EgtNumUtils.h" + +using namespace std ; + + +//---------- Creazione da parallelepipedo ------------------------------------ +//---------------------------------------------------------------------------- +bool +VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec) +{ + // Controlli sui parametri + if ( dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) + return false ; + + // Definisco il sistema di riferimento in trinseco dello Zmap + m_LocalFrame.Set( ptO, X_AX, Y_AX, Z_AX) ; + + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + m_dStep = max( dPrec, 100 * EPS_SMALL) ; + + // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe + // della griglia Zmap e da questi la dimensione del vettore di dexel + m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; + m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; + + m_nDim = m_nNx * m_nNy ; + + // Ridimensiono il vettore di dexel e creo lo Zmap + m_ZValues.resize( m_nDim) ; + + for ( int i = 0 ; i < int( m_nDim) ; i++) { + m_ZValues[i].resize(2) ; + m_ZValues[i][0] = 0 ; + m_ZValues[i][1] = dLengthZ ; + } + + // Assegno il minimo e massimo valore di Z della mappa + m_dMinZ = 0 ; + m_dMaxZ = dLengthZ ; + + m_nStatus = OK ; + return true ; +} + +//---------- Creazione da flat region ---------------------------------------- +//---------------------------------------------------------------------------- +bool +VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dLengthZ, double dPrec) +{ + Point3d ptMapOrig, ptMapEnd ; + + // Determino il bounding box della flat region + BBox3d SurfBBox ; + Surf.GetLocalBBox( SurfBBox, BBF_EXACT) ; + + // Determino i punti estremi del bounding box + SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; + + // Sistema di riferimento mappa + m_LocalFrame.Set( ptMapOrig, X_AX, Y_AX, Z_AX) ; + + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + m_dStep = max( dPrec, 100 * EPS_SMALL) ; + + // Determino le dimensioni lineari X Y della griglia + double dLengthX = ptMapEnd.x - ptMapOrig.x ; + double dLengthY = ptMapEnd.y - ptMapOrig.y ; + + // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe + // della griglia Zmap e da questi la dimensione del vettore di dexel + m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; + m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; + + m_nDim = m_nNx * m_nNy ; + + // Ridimensiono il vettore di dexel e creo lo Zmap + m_ZValues.resize( m_nDim) ; + + // Determinazione e ridimensionamento dei dexel + // interni alla regione + for ( unsigned int i = 0 ; i < m_nNx ; ++ i) { + + // Definisco la retta da intersecare con la regione + double dX = ( i + 0.5) * m_dStep ; + Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; + CurveLine GridLine ; + GridLine.SetPVL( ptP0, Y_AX, dLengthY) ; + + // Determino le intersezioni della retta con la regione + CRVCVECTOR IntersectionResults ; + Surf.GetCurveClassification( GridLine, IntersectionResults) ; + // Parti di cui la retta analizzata è composta + int nPart = int( IntersectionResults.size()) ; + + // Analizzo le parti + for ( int k = 0 ; k < nPart ; ++ k) { + + // Tipo di curva + int nType = IntersectionResults[k].nClass ; + + // Se la retta è interna alla regione o coincidente con parte della sua frontiera + if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { + + // Parametri iniziale e finale + double dt1 = IntersectionResults[k].dParS ; + double dt2 = IntersectionResults[k].dParE ; + + // Indici corrispondenti alle coordinate dei punti + int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep + 0.5)), 0, m_nNy - 1) ; + int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep - 0.5)), 0, m_nNy - 1) ; + + // Ridimensiono e riempio i dexel + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + // Determino il dexel + int nPos = j * m_nNx + i ; + + m_ZValues[nPos].resize( 2) ; + // Aggiorno le quote estreme del segmento + m_ZValues[nPos][0] = 0 ; + m_ZValues[nPos][1] = dLengthZ ; + } + } + } + } + + // Assegno il minimo e massimo valore di Z della mappa + m_dMinZ = 0 ; + m_dMaxZ = dLengthZ ; + + m_nStatus = OK ; + + return true ; +} + +//---------- Creazione da trimesh -------------------------------------------- +//---------------------------------------------------------------------------- +bool +VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec) +{ + // Se la superficie non è chiusa non ha senso continuare + if ( ! Surf.IsClosed()) + return false ; + + // Determino il bounding box della TriMesh + BBox3d SurfBBox ; + Surf.GetLocalBBox( SurfBBox) ; + + // Determino i punti estremi del bounding box + Point3d ptMapOrig, ptMapEnd ; + SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; + + // Sistema di riferimento mappa + m_LocalFrame.Set( ptMapOrig, Frame3d::TOP) ; + + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + m_dStep = max( dPrec, 100 * EPS_SMALL) ; + + // Determino le dimensioni lineari X Y della griglia + double dLengthX = ptMapEnd.x - ptMapOrig.x ; + double dLengthY = ptMapEnd.y - ptMapOrig.y ; + double dLengthZ = ptMapEnd.z - ptMapOrig.z ; + + // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe + // della griglia Zmap e da questi la dimensione del vettore di dexel + m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; + m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; + + m_nDim = m_nNx * m_nNy ; + + // Ridimensiono il vettore di dexel e creo lo Zmap + m_ZValues.resize( m_nDim) ; + + // Oggetto per calcolo massivo intersezioni + IntersParLinesSurfTm intPLSTM( m_LocalFrame, Surf) ; + + // Determinazione e ridimensionamento dei dexel interni alla trimesh + for ( unsigned int i = 0 ; i < m_nNx ; ++ i) { + + for ( unsigned int j = 0 ; j < m_nNy ; ++ j) { + + // Definisco la retta da intersecare con la trimesh + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + Point3d ptP0( dX, dY, 0) ; + + // Determino le intersezioni della retta con la TriMesh + ILSIVECTOR IntersectionResults ; + intPLSTM.GetInters( ptP0, dLengthZ, IntersectionResults) ; + + int nInt = int( IntersectionResults.size()) ; + + unsigned int nPos = j * m_nNx + i ; + + bool bInside = false ; + Point3d ptIn ; + for ( int k = 0 ; k < nInt ; ++ k) { + + int nIntType = IntersectionResults[k].nILTT ; + + // Se c'è intersezione + if ( nIntType != ILTT_NO) { + + double dCos = IntersectionResults[k].dCosDN ; + + // entro nella superficie trimesh + if ( dCos < - EPS_SMALL) { + + ptIn = IntersectionResults[k].ptI ; + + bInside = true ; + } + + // esco dalla superficie trimesh + else if ( dCos > EPS_SMALL && bInside) { + + Point3d ptOut = IntersectionResults[k].ptI ; + + unsigned int nCurrentSize = unsigned int( m_ZValues[nPos].size()) ; + + m_ZValues[nPos].resize( nCurrentSize + 2) ; + + m_ZValues[nPos][nCurrentSize] = ptIn.z - ptMapOrig.z ; + m_ZValues[nPos][nCurrentSize + 1] = ptOut.z - ptMapOrig.z ; + + bInside = false ; + } + } + } + } + } + + // Assegno il minimo e massimo valore di Z della mappa + m_dMinZ = 0 ; + m_dMaxZ = dLengthZ ; + + m_nStatus = OK ; + + return true ; +} \ No newline at end of file diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp new file mode 100644 index 0000000..9d8bf66 --- /dev/null +++ b/VolZmapGraphics.cpp @@ -0,0 +1,255 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (singola griglia) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "VolZmap.h" +#include "GeoConst.h" +#include "\EgtDev\Include\EGkIntervals.h" + +using namespace std ; + +//---------------------------------------------------------------------------- +bool +VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const +{ + // per ora solo perpendicolari a XY (1) + if ( nDir != 1) + return false ; + // verifiche sugli indici + if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) + return false ; + int nPos = nPos1 + nPos2 * m_nNx ; + if ( nPos < 0 || nPos >= int( m_ZValues.size())) + return false ; + // calcolo coordinate punto + double dX = m_dStep * ( 0.5 + nPos1) ; + double dY = m_dStep * ( 0.5 + nPos2) ; + Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; + // creo le polilinee + for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { + // aggiungo polilinea a lista + lstPL.emplace_back() ; + // inserisco punti estremi + lstPL.back().AddUPoint( 0, ptP + m_ZValues[nPos][i-1] * m_LocalFrame.VersZ()) ; + lstPL.back().AddUPoint( 1, ptP + m_ZValues[nPos][i] * m_LocalFrame.VersZ()) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const +{ + const int MAX_DIM_CHUNK = 128 ; + for ( int i = 0 ; i < int( m_nNx) ; i += MAX_DIM_CHUNK) { + int nDimChunkX = min( MAX_DIM_CHUNK, int( m_nNx) - i) ; + for ( int j = 0 ; j < int( m_nNy) ; j += MAX_DIM_CHUNK) { + int nDimChunkY = min( MAX_DIM_CHUNK, int( m_nNy) - j) ; + GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, MAX_DIM_CHUNK, lstTria) ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk, TRIA3DLIST& lstTria) const +{ + // determino se è un semplice parallelepipedo + bool bIsSimple = true ; + double dBotZ ; + double dTopZ ; + for ( int i = 0 ; i < nDim1 && bIsSimple ; ++ i) { + for ( int j = 0 ; j < nDim2 && bIsSimple ; ++ j) { + int nPos = ( nPos1 + i) + ( nPos2 + j) * m_nNx ; + if ( nPos > int( m_nDim) || + int( m_ZValues[nPos].size()) != 2) + bIsSimple = false ; + else if ( i == 0 && j == 0) { + dBotZ = m_ZValues[nPos][0] ; + dTopZ = m_ZValues[nPos][1] ; + } + else if ( abs( m_ZValues[nPos][0] - dBotZ) > EPS_SMALL || + abs( m_ZValues[nPos][1] - dTopZ) > EPS_SMALL) + bIsSimple = false ; + } + } + + // se semplice parallelepipedo + if ( bIsSimple) { + CalcChunkPrisms( nPos1, nPos2, nDim1, nDim2, lstTria) ; + } + // se chunk di dimensioni accettabili + else if ( nDimChk >= 4) { + int nNewDimChk = nDimChk / 2 ; + for ( int i = nPos1 ; i < int( nPos1 + nDim1) ; i += nNewDimChk) { + int nDimChunkX = min( nNewDimChk, int( nPos1 + nDim1) - i) ; + for ( int j = nPos2 ; j < int( nPos2 + nDim2) ; j += nNewDimChk) { + int nDimChunkY = min( nNewDimChk, int( nPos2 + nDim2) - j) ; + GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, nNewDimChk, lstTria) ; + } + } + } + // altrimenti + else { + // elaboro ogni singolo dexel + for ( int i = 0 ; i < nDim1 ; ++ i) { + for ( int j = 0 ; j < nDim2 ; ++ j) { + CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const +{ + // verifiche sugli indici + if ( nPos1 < 0 || nPos1 + nDim1 > int( m_nNx) || nPos2 < 0 || nPos2 + nDim2 > int( m_nNy)) + return false ; + int nPos = nPos1 + nPos2 * m_nNx ; + if ( nPos < 0 || nPos >= int( m_nDim)) + return false ; + + // calcolo coordinate punti + double dX = m_dStep * nPos1 ; + double dY = m_dStep * nPos2 ; + Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; + Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_LocalFrame.VersX() ; + Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_LocalFrame.VersY() ; + Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_LocalFrame.VersY() ; + + // creo le facce sopra e sotto + Vector3d vtDZt = m_ZValues[nPos][1] * m_LocalFrame.VersZ() ; + Vector3d vtDZb = m_ZValues[nPos][0] * m_LocalFrame.VersZ() ; + // faccia superiore P1t->P2t->P3t->P4t : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; + // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; + + // creo le facce laterali + for ( int j = 0 ; j < nDim2 ; ++ j) { + int nPosD = nPos + nDim1 - 1 + j * m_nNx ; + int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nNx - 1) ? nPosD + 1 : - 1) ; + Point3d ptP2D = ptP2 + j * m_dStep * m_LocalFrame.VersY() ; + Point3d ptP3D = ptP2D + m_dStep * m_LocalFrame.VersY() ; + AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; + } + for ( int i = 0 ; i < nDim1 ; ++ i) { + int nPosD = nPos + ( nDim2 - 1) * m_nNx + i ; + int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nNy - 1) ? nPosD + m_nNx : - 1) ; + Point3d ptP4D = ptP4 + i * m_dStep * m_LocalFrame.VersX() ; + Point3d ptP3D = ptP4D + m_dStep * m_LocalFrame.VersX() ; + AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; + } + for ( int j = 0 ; j < nDim2 ; ++ j) { + int nPosD = nPos + j * m_nNx ; + int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ; + Point3d ptP1D = ptP1 + j * m_dStep * m_LocalFrame.VersY() ; + Point3d ptP4D = ptP1D + m_dStep * m_LocalFrame.VersY() ; + AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; + } + for ( int i = 0 ; i < nDim1 ; ++ i) { + int nPosD = nPos + i ; + int nPosSud = ( nPos2 > 0 ? nPosD - m_nNx : - 1) ; + Point3d ptP1D = ptP1 + i * m_dStep * m_LocalFrame.VersX() ; + Point3d ptP2D = ptP1D + m_dStep * m_LocalFrame.VersX() ; + AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const +{ + // verifiche sugli indici + if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) + return false ; + int nPos = nPos1 + nPos2 * m_nNx ; + if ( nPos < 0 || nPos >= int( m_nDim)) + return false ; + + // calcolo coordinate punto + double dX = m_dStep * nPos1 ; + double dY = m_dStep * nPos2 ; + Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; + Point3d ptP2 = ptP1 + m_dStep * m_LocalFrame.VersX() ; + Point3d ptP3 = ptP2 + m_dStep * m_LocalFrame.VersY() ; + Point3d ptP4 = ptP1 + m_dStep * m_LocalFrame.VersY() ; + + // creo le facce sopra e sotto di ogni intervallo (sempre visibili) + for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { + Vector3d vtDZt = m_ZValues[nPos][i] * m_LocalFrame.VersZ() ; + Vector3d vtDZb = m_ZValues[nPos][i-1] * m_LocalFrame.VersZ() ; + // faccia superiore P1t->P2t->P3t->P4t : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; + // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; + } + + // creo le facce laterali + int nPosEst = ( nPos1 < int( m_nNx - 1) ? nPos + 1 : - 1) ; + AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; + int nPosNord = ( nPos2 < int( m_nNy - 1) ? nPos + m_nNx : - 1) ; + AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; + int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ; + AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; + int nPosSud = ( nPos2 > 0 ? nPos - m_nNx : - 1) ; + AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, + const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const +{ + Intervals intFace ; + for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) + intFace.Add( m_ZValues[nPos][i-1], m_ZValues[nPos][i]) ; + if ( nPosAdj > 0) { + for ( int i = 1 ; i < int( m_ZValues[nPosAdj].size()) ; i += 2) + intFace.Subtract( m_ZValues[nPosAdj][i-1], m_ZValues[nPosAdj][i]) ; + } + double dMin, dMax ; + bool bFound = intFace.GetFirst( dMin, dMax) ; + while ( bFound) { + Vector3d vtDZt = dMax * vtZ ; + Vector3d vtDZb = dMin * vtZ ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP + vtDZb, ptQ + vtDZb, ptQ + vtDZt, vtNorm) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptQ + vtDZt, ptP + vtDZt, ptP + vtDZb, vtNorm) ; + bFound = intFace.GetNext( dMin, dMax) ; + } + return true ; +} + diff --git a/VolZmapTool.cpp b/VolZmapTool.cpp new file mode 100644 index 0000000..ca8bed2 --- /dev/null +++ b/VolZmapTool.cpp @@ -0,0 +1,261 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (singola griglia) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "CurveLine.h" +#include "CurveArc.h" +#include "VolZmap.h" +#include "GeoConst.h" + +using namespace std ; + +//---------- Tolleranza nell'approssimazione di curve profilo ---------------- +//---------------------------------------------------------------------------- +bool +VolZmap::SetTolerances( double dLinTol, double dAngTolDeg) +{ + m_dLinTol = max( dLinTol, LIN_TOL_MIN) ; + m_dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SetStdTool( const string& sToolName, double dH, double dR, double dCornR) +{ + // reset nome + m_sToolName.clear() ; + // verifica minime dimensioni globali + if ( dH < EPS_SMALL || dR < EPS_SMALL) + return false ; + // utensile cilindrico + if ( dCornR < EPS_SMALL) { + m_nToolType = CylindricalMill ; + m_dHeight = dH ; + m_dRadius = dR ; + m_dTipHeight = 0 ; + m_dTipRadius = m_dRadius ; + m_dRCorner = 0 ; + } + // utensile naso di toro + else if ( dCornR < dR - EPS_SMALL) { + m_nToolType = BullNoseMill ; + m_dHeight = dH ; + m_dRadius = dR ; + m_dTipHeight = dCornR ; + m_dTipRadius = dR - dCornR ; + m_dRCorner = dCornR ; + // come profilo + m_nToolType = GenericTool ; + Point3d pt0( 0, 0, 0) ; + Point3d pt1( m_dRadius, 0, 0) ; + Point3d pt2( m_dRadius, - m_dHeight + m_dTipHeight, 0) ; + Point3d pt3( m_dTipRadius, - m_dHeight, 0) ; + Point3d pt4( 0, - m_dHeight, 0) ; + m_ToolOutline.Clear() ; + CurveLine Line ; + Line.Set( pt0, pt1) ; + m_ToolOutline.AddCurve( Line) ; + m_ToolOutline.AddLine( pt2); + m_ToolOutline.AddArcTg( pt3) ; + m_ToolOutline.AddLine( pt4) ; + return SetGenTool( sToolName, &m_ToolOutline) ; + } + // utensile sferico + else if ( dCornR < dR + EPS_SMALL) { + m_nToolType = BallEndMill ; + m_dHeight = dH ; + m_dRadius = dR ; + m_dTipHeight = m_dRadius ; + m_dTipRadius = 0 ; + m_dRCorner = m_dRadius ; + } + // impossibile + else + return false ; + // assegno il nome + m_sToolName = sToolName ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SetAdvTool( const string& sToolName, double dH, double dR, + double dTipH, double dTipR, double dCornR) +{ + // reset nome + m_sToolName.clear() ; + // verifica dimensioni globali + if ( dH < EPS_SMALL || dR < EPS_SMALL) + return false ; + // se altezza punta nulla, ricado nel caso standard + if ( dTipH < EPS_SMALL) + return SetStdTool( sToolName, dH, dR, dCornR) ; + // caso avanzato + if ( abs( dTipR - dR) < EPS_SMALL) { + m_nToolType = CylindricalMill ; + m_dHeight = dH ; + m_dRadius = dR ; + m_dTipHeight = 0 ; + m_dTipRadius = m_dRadius ; + m_dRCorner = 0 ; + } + else { + m_nToolType = ConusMill ; + m_dHeight = dH ; + m_dRadius = dR ; + m_dTipHeight = dTipH ; + m_dTipRadius = max( dTipR, 0.) ; + m_dRCorner = dCornR ; + } + // assegno il nome + m_sToolName = sToolName ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SetGenTool( const string& sToolName, const ICurveComposite* pToolOutline) +{ + // Aggiorno il nome dell'utensile + m_sToolName = sToolName ; + + // Aggiorno il tipo di utensile + m_nToolType = GenericTool ; + + // Copio il profilo + m_ToolOutline.CopyFrom( pToolOutline) ; + + // Se ci fosse una Bézier la convertiamo in archi e rette + m_ToolOutline.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, m_dAngTolDeg) ; + + // Puntatore a curva costante + const ICurve* pCurve = m_ToolOutline.GetFirstCurve() ; + + // Ciclo sulle curve componenti + while ( pCurve != nullptr) { + + // Se la curva è un arco valuto approssimarlo + if ( pCurve->GetType() == CRV_ARC) { + + // Centro e punti iniziale e finale dell'arco + Point3d ptStart, ptEnd, ptO ; + + pCurve->GetStartPoint( ptStart) ; + pCurve->GetEndPoint( ptEnd) ; + pCurve->GetCenterPoint( ptO) ; + + // Vettore congiungente il centro con i punti iniziale e finale + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + // Calcolo del raggio dell'arco + double dRadius = GetBasicCurveArc( pCurve)->GetRadius() ; + + // Recupero la curva precedente e quella successiva + const ICurve* pPrev = m_ToolOutline.GetPrevCurve() ; + const ICurve* pNext = m_ToolOutline.GetNextCurve() ; + pNext = m_ToolOutline.GetNextCurve() ; + + // Valuto la necessità di approssimare l'arco o meno + + // Punto Iniziale della curva precedente e finale della successiva + Point3d ptStartPrev, ptEndNext ; + + // Vettori tangenti alle curve precedente corrente e successiva + // rispettivamente nei punti finale, iniziale e finale e iniziale + // e prodotti vettore fra i suddetti + Vector3d vtPrevEndDir, vtCurrentStartDir, vtCurrentEndDir, vtNextStartDir ; + Vector3d vtIProd, vtFProd ; + + Point3d ptTopCurrent = ptO + Y_AX * dRadius ; + Point3d ptBottomCurrent = ptO - Y_AX * dRadius ; + + // Valuto le relazioni geometriche fra la + // curva corrente e quella precedente. + pPrev->GetStartPoint( ptStartPrev) ; + pPrev->GetEndDir( vtPrevEndDir) ; + pCurve->GetStartDir( vtCurrentStartDir) ; + vtIProd = vtPrevEndDir ^ vtCurrentStartDir ; + + // Se la curva successiva esiste valuto le + // medesime relazioni con la quest'ultima + if ( pNext != nullptr) { + + pNext->GetEndPoint( ptEndNext) ; + pCurve->GetEndDir( vtCurrentEndDir) ; + pNext->GetStartDir( vtNextStartDir) ; + vtFProd = vtCurrentEndDir ^ vtNextStartDir ; + } + + // Se devo approssimare + if ( ! ( ( abs( ptO.x) < EPS_SMALL && vtIProd.z > 0 && ptStartPrev.y > ptTopCurrent.y) && + ( ( pNext == nullptr && abs( ptEnd.x) < EPS_SMALL) || + ( pNext != nullptr && vtFProd.z > 0 && ptBottomCurrent.y > ptEndNext.y)))) { + + // Copio la parte precedente + const ICurve* pAux = m_ToolOutline.GetFirstCurve() ; + + while ( pAux != pCurve) { + + m_ToolArcLineApprox.AddCurve( * pAux, true) ; + + pAux = m_ToolOutline.GetNextCurve() ; + } + + // Creo la polyline approssimante + PolyLine Polygonal ; + + pCurve->ApproxWithLines( m_dLinTol, m_dAngTolDeg, 10, Polygonal) ; + + // Definisco una curva composita a partire dalla polyline + CurveComposite cvTemp ; cvTemp.FromPolyLine( Polygonal) ; + + // Aggiungo la parte approssimata + pAux = cvTemp.GetFirstCurve() ; + + while ( pAux != nullptr) { + + m_ToolArcLineApprox.AddCurve( * pAux, true) ; + + pAux = cvTemp.GetNextCurve() ; + } + } + // Se non deve essere approssimato + else { + // Se è già stato definito m_ToolArcLineApprox deve + // essere completo, aggiungo quindi l'arco corrente + if ( m_ToolArcLineApprox.GetCurveCount() != 0) + m_ToolArcLineApprox.AddCurve( * pCurve, true) ; + } + } + // Se è segmento + else { + // Se è già stato definito m_ToolArcLineApprox deve + // essere completo, aggiungo quindi il segmento corrente + if ( m_ToolArcLineApprox.GetCurveCount() != 0) + m_ToolArcLineApprox.AddCurve( * pCurve, true) ; + } + + pCurve = m_ToolOutline.GetNextCurve() ; + } + + // Dimensioni dell'utensile + BBox3d Bounding ; + m_ToolOutline.GetLocalBBox( Bounding) ; + double m_dHeight = Bounding.GetMax().y - Bounding.GetMin().y ; + double m_dRadius = Bounding.GetMax().x - Bounding.GetMin().x ; + + return true ; +} \ No newline at end of file diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp new file mode 100644 index 0000000..980c088 --- /dev/null +++ b/VolZmapVolume.cpp @@ -0,0 +1,8531 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (singola griglia) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "VolZmap.h" +#include "GeoConst.h" + +using namespace std ; + +//---------- Sottrazione intervalli ------------------------------------------ + +//---------------------------------------------------------------------------- +bool +VolZmap::SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + return true ; + + // Controllo che dMin < dMax + if ( dMax < dMin ) + swap( dMax, dMin) ; + + // Calcolo nPos dello spillone + unsigned int nPos = nJ * m_nNx + nI ; + + // Ciclo sugli intervalli dello spillone + bool bModified = false ; + unsigned int i = 0 ; + while ( i + 1 < m_ZValues[nPos].size()) { + + // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione + if ( m_ZValues[nPos][i] > dMax - EPS_SMALL) { + ; + } + + // Intersezione + else if ( m_ZValues[nPos][i + 1] > dMax + EPS_SMALL) { + // L'intervallo corrente corrente viene limitato a sinistra + if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { + bModified = true ; + m_ZValues[nPos][i] = dMax ; + } + // L'intervallo si divide in due intervalli + else { + bModified = true ; + m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; + + for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 3 ; -- j) + + m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ; + + m_ZValues[nPos][i + 1] = dMin ; + m_ZValues[nPos][i + 2] = dMax ; + + i = i + 2 ; + } + } + + else { + // L'intervallo corrente viene eliminato + if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { + bModified = true ; + for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j) + + m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ; + + m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ; + + i = i - 2 ; + } + // L'intervallo corrente viene limitato a destra + else if ( m_ZValues[nPos][i + 1] > dMin + EPS_SMALL) { + bModified = true ; + m_ZValues[nPos][i + 1] = dMin ; + } + // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione + else { + ; + } + } + + i = i + 2 ; + } + + // Se eseguita modifica, imposto ricalcolo della grafica + if ( bModified) + m_OGrMgr.Reset() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SubtractIntervals( const Point3d& ptP, double dMin, double dMax) +{ + // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) + Point3d ptPL = ptP ; + ptPL.ToLoc( m_LocalFrame) ; + + double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco + double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) + + dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; + dhMin = dZ + dMin ; dhMax = dZ + dMax ; + + // Cerco il punto della griglia più vicino (indice è l'intero appena più basso) + double integerPartX = floor( dX / m_dStep) ; + double integerPartY = floor( dY / m_dStep) ; + + unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. + unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 + + // Controllo se le coordinate x e y del punto dato siano all'interno della griglia: + // se sono dentro la griglia chiamo l'altra subtract + if ( dX < m_dStep * m_nNx && + dY < m_dStep * m_nNy && + dX >= 0 && dY >= 0) { + // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e + // si esce dai limiti dell vector e vi è errore runtime + return SubtractIntervals( i, j, dhMin, dhMax) ; + } + + // altrimenti non succede niente + return true ; +} + +//---------- Addizione intervalli -------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + return true ; + + // Controllo che dMin < dMax + if ( dMax < dMin) + swap( dMax, dMin) ; + + // Calcolo nPos + unsigned int nPos = nJ * m_nNx + nI ; + + // Se spillone vuoto + if ( m_ZValues[nPos].size() == 0) { + + m_ZValues[nPos].resize( 2) ; + + m_ZValues[nPos][0] = dMin ; + m_ZValues[nPos][1] = dMax ; + + m_OGrMgr.Reset() ; + + return true ; + } + + // Ciclo sugli intervalli dello spillone + bool bModified = false ; + unsigned int i = 0 ; + while ( i + 1 < m_ZValues[nPos].size()) { + + // Eventuale aggiustamento di intervalli sovrapposti + if ( i > 0) { + if ( m_ZValues[nPos][i] < m_ZValues[nPos][i - 1] + EPS_SMALL) { + // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva + if ( m_ZValues[nPos][i - 1] < m_ZValues[nPos][i + 1] + EPS_SMALL) + + m_ZValues[nPos][i - 1] = m_ZValues[nPos][i + 1] ; + + for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j) + m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ; + + m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ; + + i = i - 2 ; + } + } + + // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente + if ( m_ZValues[nPos][i] > dMax + EPS_SMALL) { + bModified = true ; + + m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; + + for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 2 ; -- j) + m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ; + + m_ZValues[nPos][i] = dMin ; + m_ZValues[nPos][i + 1] = dMax ; + + i = i + 2 ; + } + + // Casi d'intersezione: + else if ( m_ZValues[nPos][i + 1] > dMax - EPS_SMALL) { + // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente + if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { + bModified = true ; + m_ZValues[nPos][i] = dMin ; + } + } + + else { + // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi + if ( m_ZValues[nPos][i] > dMin + EPS_SMALL) { + bModified = true ; + m_ZValues[nPos][i] = dMin ; + m_ZValues[nPos][i + 1] = dMax ; + } + // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente + else if ( m_ZValues[nPos][i + 1] > dMin - EPS_SMALL) { + bModified = true ; + m_ZValues[nPos][i + 1] = dMax ; + } + else { + // Aggiungo intervallo a destra dell'ultimo intervallo + if ( i == m_ZValues[nPos].size() - 2) { + bModified = true ; + m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; + + m_ZValues[nPos][i + 2] = dMin ; + m_ZValues[nPos][i + 3] = dMax ; + + i = i + 2 ; + } + } + } + + i = i + 2 ; + } + + // se eseguita modifica, imposto ricalcolo della grafica + if ( bModified) + m_OGrMgr.Reset() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddIntervals( const Point3d& ptP, double dMin, double dMax) +{ + // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) + Point3d ptPL = ptP ; + ptPL.ToLoc( m_LocalFrame) ; + + double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco + double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) + + dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; + dhMin = dZ + dMin ; dhMax = dZ + dMax ; + + // Cerco il punto della griglia più vicino + double integerPartX = floor( dX / m_dStep) ; + double integerPartY = floor( dY / m_dStep) ; + + unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. + unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 + + // Controllo se le coordinate x e y del punto dato siano all'interno della griglia: + // se sono dentro la griglia chiamo l'altra subtract + if ( dX < m_dStep*m_nNx && dY < m_dStep*m_nNy + && dX >= 0 && dY >= 0) { + // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e + // si esce dai limiti dell vector e vi è errore runtime + return AddIntervals( i, j, dhMin, dhMax) ; + } + + // altrimenti non succede niente + return false ; +} + +//---------- Volumi ---------------------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) +{ + // Controllo sull'effettiva esistenza del movimento + if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe)) + return true ; + + // Porto i dati del movimento nel riferimento intrinseco; quest'operazione è 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 ; ptLe.ToLoc( m_LocalFrame) ; + Vector3d vtLs = vtDs ; vtLs.ToLoc( m_LocalFrame) ; + Vector3d vtLe = vtDe ; vtLe.ToLoc( m_LocalFrame) ; + + // Normalizzo i vettori + if ( ! vtLs.Normalize() || ! vtLe.Normalize()) + return false ; + + // Direzione utensile costante + 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)) { + if ( m_nToolType == GenericTool) + return DrillZ( ptLs, ptLe, vtLs) ; + else + return DrillingZ( ptLs, ptLe, vtLs) ; + } + + // Movimento perpendicolare a direzione utensile + if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) { + if ( m_nToolType == 0) + return MillZ( ptLs, ptLe, vtLs) ; + else + return MillingPerpZ( ptLs, ptLe, vtLs) ; + } + + // Movimento generico + if ( m_nToolType == 0) + return MillZ( ptLs, ptLe, vtLs) ; + else + return MillingZ( ptLs, ptLe, vtLs) ; + } + + // Versori della direzione utensile nel piano XY + else if ( abs( vtLs.z) < 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) + if ( vtTOrt.SqLen() < EPS_SMALL * EPS_SMALL) { + if ( m_nToolType == 0) + return DrillingGT( ptLs, ptLe, vtDir) ; + else + return DrillingXY( ptLs, ptLe, vtDir) ; + } + + // Movimento perpendicolare alla direzione dell'utensile + if ( vtTLong.SqLen() < EPS_SMALL * EPS_SMALL) { + if ( m_nToolType == GenericTool) + return MillingGT( ptLs, ptLe, vtDir) ; + else + return MillingPerpXY( ptLs, ptLe, vtDir) ; + } + + // Movimento nel piano generico + if ( m_nToolType == GenericTool) + return MillingGT( ptLs, ptLe, vtDir) ; + else + return MillingXYPlaneGen( ptLs, ptLe, vtDir) ; + } + + // Movimento con Z non costante + else { + + if ( m_nToolType == GenericTool) + return MillingGT( ptLs, ptLe, vtDir) ; + + // Movimento verticale + if ( SqDistXY( ptLs, ptLe) < EPS_SMALL * EPS_SMALL) + return MillingXYVert( ptLs, ptLe, vtDir) ; + + // Grandezze geometriche per selezione + Vector3d vtMove = ptLe - ptLs ; + Vector3d vtTLong = ( vtMove * vtDir) * vtDir ; + Vector3d vtTOrt = vtMove - ( vtMove * vtDir) * vtDir ; + + // 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) ; + } + } + + // Caso generico + else { + + Vector3d vtMove = ptLe - ptLs ; + Vector3d vtOrt = vtMove - ( vtMove * vtLs) * vtLs ; + + // Drilling + if ( vtOrt.SqLen() < EPS_SMALL * EPS_SMALL) { + if ( m_nToolType == GenericTool) + return DrillingGT( ptLs, ptLe, vtLs) ; + else + return Drilling( ptLs, ptLe, vtLs) ; + } + // Milling + else { + if ( m_nToolType == GenericTool) + return MillingGT( ptLs, ptLe, vtLs) ; + else + return Milling( ptLs, ptLe, vtLs) ; + } + } + } + + // Altri casi, non gestiti + return false ; +} + +// Versore utensile parallelo all'asse Z +//---------------------------------------------------------------------------- +bool +VolZmap::DrillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) +{ + // Cilindro sfera toro + if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill || + m_nToolType == BullNoseMill) + + return CBTDrillZ( ptLs, ptLe, vtToolDir) ; + // Coni + 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 ; + 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 dMax = ptLs.z - m_dHeight ; // Volendo si può effettuare un controllo su quota punto finale e iniziale, + double dMin = ptLe.z - m_dHeight ; // ma non è necessaria dal momento che Subtract intervals scambia min con max se max < min + 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) ; + + // 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 + double dSqDist = SqDistXY( ptQ, ptLe) ; + // se distanza nei limiti, taglio + if ( dSqDist < dSqRad) + GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { + + double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), + min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), + max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + + // Bounding box + double dMinX = ptLs.x - dMaxRad ; + double dMaxX = ptLs.x + dMaxRad ; + double dMinY = ptLs.y - dMaxRad ; + double dMaxY = ptLs.y + dMaxRad ; + + // 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 ; + + double dDeltaZ = abs( ptLe.z - ptLs.z) ; + + Point3d ptO( ptLs.x, ptLs.y, 0) ; + + // 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)) ; + + + if ( m_dRadius < m_dTipRadius) + // Coda di rondine + return GetMinMaxZSw( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ; + // Punta di trapano + else + return GetMinMaxZDr( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::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) +{ + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + // Determinazione della posizione xy del dexel rispetto + // all'asse di simmetria dell'utensile + 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 ; + + // Se il dexel cade nel cerchio di interesse taglio + if ( dSqDist < dMaxRad * dMaxRad) { + + double dMin, dMax ; + + if ( dSqDist < dMinRad * dMinRad) { + dMin = dMinZ ; + dMax = dMaxZ ; + } + + else { + double dR = sqrt( dSqDist) ; + if ( dDir > 0) { + dMin = dMinZ ; + dMax = dMinZ + dDeltaZ + ( m_dTipHeight * ( dMaxRad - dR)) / ( dMaxRad - dMinRad) ; + } + else { + dMin = dMaxZ - dDeltaZ + ( m_dTipHeight * ( dR - dMaxRad)) / ( dMaxRad - dMinRad) ; + dMax = dMaxZ ; + } + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::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) +{ + 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 ; + + // Se il dexel cade nel cerchio di interesse taglio + if ( dSqDist < dMaxRad * dMaxRad) { + + double dMin, dMax ; + + if ( dSqDist < dMinRad * dMinRad) { + dMin = dMinZ ; + dMax = dMaxZ ; + } + + else { + double dR = sqrt( dSqDist) ; + if ( dDir > 0) { + dMin = dMinZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMaxRad - dMinRad) ; + dMax = dMaxZ ; + } + else { + dMin = dMinZ ; + dMax = dMaxZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMinRad - dMaxRad) ; + } + } + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { + // Cilindro sfera toro + if ( m_nToolType == CylindricalMill || + m_nToolType == BallEndMill || + m_nToolType == BullNoseMill) + + return CBTMillingPerpZ( ptLs, ptLe, vtToolDir) ; + // Coni + else if ( m_nToolType == ConusMill) + + return ConusPerpZ( ptLs, ptLe, vtToolDir) ; + + else + return false ; +} + +//---------------------------------------------------------------------------- +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) +{ + double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + + // Bounding box + double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; + double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; + double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; + double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; // Ricordati del caso balordo da mettere nella documentazione + + // 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 ; + + Point3d ptO( ptLs.x, ptLs.y, 0) ; + Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; + Vector3d vtV1 = vtMove ; vtV1.Normalize() ; + + double dZBase = ptLs.z ; + double dZStem = ptLs.z - ( m_dHeight - m_dTipHeight) * vtToolDir.z ; + double dZTip = ptLs.z - m_dHeight * vtToolDir.z ; + + // 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 dMin, dMax ; + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; + + double dProj1 = vtC * vtV1 ; + Vector3d vtOrt = vtC - dProj1 * vtV1 ; + + if ( dProj1 < 0) { + + double dSqDist = vtC * vtC ; + + if ( dSqDist < dMinRad * dMinRad) { + + dMin = min( dZBase, dZTip) ; + dMax = max( dZBase, dZTip) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + + else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { + + double dr = sqrt( dSqDist) ; + + if ( m_dRadius < m_dTipRadius) { + + dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; + dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; + } + else { + dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; + dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; + } + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + else if ( dProj1 >= 0 && dProj1 < dLen) { + + double dSqDist = vtOrt * vtOrt ; + + if ( dSqDist < dMinRad * dMinRad) { + + dMin = min( dZBase, dZTip) ; + dMax = max( dZBase, dZTip) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + + else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { + + double dr = sqrt( dSqDist) ; + + if ( m_dRadius < m_dTipRadius) { + dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; + dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; + } + + else { + dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; + dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; + } + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + else if ( dProj1 >= dLen) { + + Vector3d vtCn = vtC - vtMove ; + + double dSqDist = vtCn * vtCn ; + + if ( dSqDist < dMinRad * dMinRad) { + dMin = min( dZBase, dZTip) ; + dMax = max( dZBase, dZTip) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + + else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { + + double dr = sqrt( dSqDist) ; + + if ( m_dRadius < m_dTipRadius) { + dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; + dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; + } + + else { + dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; + dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; + } + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + } + 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) ; + + // Caso utensile generico al momento non gestito + if ( m_nToolType == 0) + return false ; + + // Caso Cylindrical Mill + else if ( m_nToolType == 1) { + double dMin, dMax ; + + 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) { + double dMin, dMax ; + + double dH = sqrt( dSqRad - dSqDist) ; + + if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) { + dMin = min( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ; + dMax = max( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ; + } + else if ( vtToolDir.z * dDeltaZ < 0) { + dMin = min( dZtip + dFactor*( m_dRadius - dH), + dZtip + dFactor*( m_dRadius - dH) + dDeltaZ) ;// ocio + dMax = max( dZtip + dFactor*( m_dRadius - dH), + dZtip + dFactor*( m_dRadius - dH) + 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) { + + double dMin, dMax ; + + 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 ; + double dSqrt = sqrt(dSqRadC - dSqd) ; + + double dMin, dMax ; + if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) { + dMin = min( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ; + dMax = max( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ; + } + else if ( vtToolDir.z * dDeltaZ < 0) { + dMin = min( dZtip + dFactor *( m_dRCorner - dSqrt), + dZtip + dFactor *( m_dRCorner - dSqrt) + dDeltaZ) ; + dMax = max( dZtip + dFactor *( m_dRCorner - dSqrt), + dZtip + dFactor *( m_dRCorner - dSqrt) + 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) +{ + double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), + min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), + max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + + // Bounding box + double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; + double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; + double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; + double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; + + // 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 ; + + // Punti iniziale e finale e proiezione sul piano del punto iniziale + Point3d ptI, ptF, ptO ; + + if ( vtToolDir.z > 0) { + ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + } + else { + ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + } + + // Quote iniziale e finale della base dell'utensile e DeltaZ + double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; + + // Vettori di movimento + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; + + // Sistema di riferimento sul cono e vertice del cono + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + Point3d ptV = ptI - ( m_dHeight + m_dTipHeight * dMinRad / ( dMaxRad - dMinRad)) * vtV1 ; + + // 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 ; + double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 + + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 - + ( dSin / dDen) * vtV3 ; + + Vector3d vtR0 = ptV - ORIG ; + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + // 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) { + // Grandezze per determinare la configurazione geometrica dell'utensile + 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 - ptO ; + Vector3d vtCf = vtC - vtMoveXY ; + + Vector3d vtUC = vtC ; vtUC.Normalize() ; + Vector3d vtUCf = vtCf ; vtUCf.Normalize() ; + + double dCCos = vtUC * vtV2 ; + double dCCosf = vtUCf * vtV2 ; + + double dProj = vtC * vtV2 ; + Vector3d vtOrt = vtC - dProj * vtV2 ; + + double dSqDistI = vtC * vtC ; + double dSqDistM = vtOrt * vtOrt ; + double dSqDistF = vtCf * vtCf ; + + // Se dentro la zona interessata dalla lavorazione valuto + // la tipologia di tale zona + if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || + ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || + ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { + + // Caso vettore utensile equiverso all'asse Z + if ( vtToolDir.z > 0) { + // Massimi + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + if ( dProj < dLen - dPMaxI) + + dMax = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxI) ; + else + dMax = dZF ; + + // Minimi + if ( dSqDistI < dMinRad * dMinRad) + + dMin = dZI - m_dHeight ; + + else { + + if ( ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMin = dZI - m_dHeight + ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; + else + dMin = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMin = dZF - m_dHeight + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + + dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + else { + + if ( dSqDistI < dMaxRad * dMaxRad) + + dMin = dZI - m_dHeight + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) + + dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + } + // Caso vettore utensile opposto all'asse Z + else { + // Massimi + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + if ( dSqDistI < dMinRad * dMinRad) + + dMax = dZI + m_dHeight ; + + else { + + if ( - ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMax = dZI + m_dHeight - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMax = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; + else + dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMax = dZF + m_dHeight - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + + dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + + } + else { + + if ( dSqDistI < dMaxRad * dMaxRad) + + dMax = dZI + m_dHeight - ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + + else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) + + dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + + } + } + // Minimi + double dPMaxCirc = sqrt( dMaxRad * dMaxRad - dSqDistM) ; + + if ( dProj > dLen - dPMaxCirc) + dMin = dZF ; + else + dMin = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxCirc) ; + } + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) +{ + double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), + min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), + max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; + + // Prima verifica sull'interferenza dell'utensile con lo Zmap + if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) + return true ; + + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + + // Bounding box + double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; + double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; + double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; + double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; + + // 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 ; + + // Punti iniziale e finale e proiezione sul piano del punto iniziale + Point3d ptI, ptF, ptO ; + + if ( vtToolDir.z > 0) { + + ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + } + + else { + ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + } + + Point3d ptICyl = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + + double dDeltaH = m_dHeight - m_dTipHeight ; + double dMinZCyl = min( ptICyl.z, ptICyl.z - vtToolDir.z * dDeltaH) ; + + // Punti contatto cono cilindro + Point3d ptIS = ptI - ( m_dHeight - m_dTipHeight) * vtToolDir ; + Point3d ptFS = ptF - ( m_dHeight - m_dTipHeight) * vtToolDir ; + + // Quote iniziali e finali e DeltaZ + double dZI = ptI.z ; double dZF = ptF.z ; + double dDeltaZ = dZF - dZI ; double dADeltaZ = abs( dDeltaZ) ; + double dZIS = ptIS.z ; double dZFS = ptFS.z ; + + // Vettori di movimento + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; + + // Sistema di riferimento sul cono e vertice del cono + Vector3d vtV1 = - vtToolDir ; + Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + Point3d ptV = ptI + ( m_dHeight - m_dTipHeight * ( 1 + dMinRad / ( dMaxRad - dMinRad))) * vtV1 ; + + // 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 ; + double dSin = ( abs( dCos) < 1 ? sqrt( 1- dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNp = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 + + ( dSin / dDen) * vtV3 ; + Vector3d vtNm = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 - + ( dSin / dDen) * vtV3 ; + + Vector3d vtR0 = ptV - ORIG ; + double dDotp = vtR0 * vtNp ; + double dDotm = vtR0 * vtNm ; + + // 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 dMin, dMax ; + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; Vector3d vtCf = vtC - vtMoveXY ; + + Vector3d vtUC = vtC ; Vector3d vtUCf = vtCf ; vtUC.Normalize() ; vtUCf.Normalize() ; + + double dCCos = vtUC * vtV2 ; double dCCosf = vtUCf * vtV2 ; + + double dProj = vtC * vtV2 ; + Vector3d vtOrt = vtC - dProj * vtV2 ; + + double dSqDistI = vtC * vtC ; + double dSqDistM = vtOrt * vtOrt ; + double dSqDistF = vtCf * vtCf ; + + if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || + ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || + ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { + // Caso vettore utensile equiverso all'asse Z + if ( vtV1.z < 0) { + + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + // Massimi + if ( dRatio <= 1 / dTanAlpha) { + + if ( dSqDistI < dMinRad * dMinRad) + + dMax = dZIS ; + + else { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMax = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; + else + dMax = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMax = dZFS - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + else { + + if ( dSqDistI < dMinRad * dMinRad) + + dMax = dZIS ; + + else if ( dSqDistI < dMaxRad * dMaxRad) + + dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else { + + if ( dProj >= dPMaxI) + + dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + // Minimi + + if ( dSqDistF < dMaxRad * dMaxRad) + + dMin = dZFS - m_dTipHeight ; + + else if ( dProj <= dLen - dPMaxI) + + dMin = dZIS - m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; + + } + // Caso vettore utensile opposto all'asse Z + else { + + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + // Massimi + if ( dSqDistF < dMaxRad * dMaxRad) + + dMax = dZFS + m_dTipHeight ; + + else if ( dProj <= dLen - dPMaxI) + + dMax = dZIS + m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; + + // Minimi + if ( dRatio <= 1 / dTanAlpha) { + + if ( dSqDistI < dMinRad * dMinRad) + + dMin = dZIS ; + + else { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMin = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; + else + dMin = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMin = dZFS + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + else { + + if ( dSqDistI < dMinRad * dMinRad) + + dMin = dZIS ; + + else if ( dSqDistI < dMaxRad * dMaxRad) + + dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else + + dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + + } + } + SubtractIntervals( i, j, dMin, dMax) ; + } + + // Parte cilindrica + Vector3d vtCyl = ( vtV1.z < 0 ? vtCf : vtC) ; + Vector3d vtCylf = ( vtV1.z < 0 ? vtC : vtCf) ; + Vector3d vtMot = ( vtV1.z < 0 ? - vtV2 : vtV2) ; + + double dCylProj = vtCyl * vtMot ; + double dCylSqDistI = vtCyl * vtCyl ; + double dCylSqDistF = vtCylf * vtCylf ; + double dCylSqDistM = ( vtCyl - dCylProj * vtMot) * ( vtCyl - dCylProj * vtMot) ; + + + if ( dCylSqDistI < dMinRad * dMinRad + || dCylSqDistF < dMinRad * dMinRad + || ( dCylProj > 0 && dCylProj < dLen && dCylSqDistM < dMinRad * dMinRad)) { + + double dSt = sqrt( dMinRad * dMinRad - dCylSqDistM) ; + + // Minimi + if ( dCylSqDistI < dMinRad * dMinRad ) + + dMin = dMinZCyl ; + + else if ( dCylProj >= dSt) + + dMin = dMinZCyl + ( dCylProj - dSt) * dADeltaZ / dLen ; + + // Massimi + if ( dCylSqDistF < dMinRad * dMinRad) + + dMax = dMinZCyl + dDeltaH + dADeltaZ ; + + else if ( dCylProj <= dLen - dSt) + + dMax = dMinZCyl + dDeltaH + ( dCylProj + dSt) * dADeltaZ / dLen ; + + SubtractIntervals( i, j, dMin, dMax) ; + + } + } + } + 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 bControl = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( bControl == 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 dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + + double dCos = dTan * dRatio ; + double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + + double dDeltaR = dMaxRad - dMinRad ; + double dMinLim = dMinRad * dCos ; + double dMaxLim = dMaxRad * dCos ; + + + // Versori normali e prodotti scalari per determinare i piani + Vector3d vtNInf = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNSup = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) + 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) + 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) + 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 dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTan / dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 - dFactor * ( dSin / dDen) * vtV2 ; + Vector3d vtNd = - ( dTan /dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 + dFactor * ( dSin / dDen) * 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 * dSin - dProj1 * dDeltaR * dSin / 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 * dSin && 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 * dSin) { + + double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ; + + dZL1 = dZI + dFactor * dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ; + } + else if ( dProj1 >= dPLen && + dOrtLen > dMaxRad * dSin - ( dProj1 - dPLen) * dDeltaR * dSin / 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) ; + } + } + } + + 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) ; + } + } + } + + 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) + 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 ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) ; + } + } + } + + 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) ; + } + } + } + + 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 dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + + 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 / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + // vettore movimento + Vector3d vtMove = ptLe - ptLs ; + + CurveComposite ToolProfile ; + + // Settaggio profilo + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + ToolProfile.CopyFrom( & m_ToolOutline) ; + else + // altrimenti usi l'approssimazione + ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; + + // Dichiaro un puntatore a curva da usare nel ciclo + const ICurve* pCurve ; + + pCurve = ToolProfile.GetFirstCurve() ; + + // Ciclo sulle curve + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso segmento + 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) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + LongCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + LongConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utesile + 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 ; + } + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + Ball( ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = ToolProfile.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) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + // vettore movimento + Vector3d vtMove = ptLe - ptLs ; + + CurveComposite ToolProfile ; + + // Settaggio profilo + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + ToolProfile.CopyFrom( & m_ToolOutline) ; + else + // altrimenti usi l'approssimazione + ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; + + // Dichiaro un puntatore a curva da usare nel ciclo + const ICurve* pCurve ; + + pCurve = ToolProfile.GetFirstCurve() ; + + // Ciclo sulle curve + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso segmento + 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) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + MillCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + MillConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + MillConusV( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + Ball( ptOSt, ptOEn, dRadius) ; + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = ToolProfile.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) + 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 ; + + double dLimX1 = sqrt( dRad * dRad - dX2 * dX2) ; + + if ( dX2 > - dRad && dX2 < dRad && + dX1 > - dLimX1 && + dX1 < dPLen + dLimX1) { + + // Massimi + if( dX1 > - dLimX1 && dX1 < dPLen - dLimX1) + + dMax = dZI + ( dX1 + dLimX1) * dDeltaZ / dPLen ; + + else if ( dX1 >= dPLen - dLimX1 && + dX1 < dPLen + dLimX1) + + dMax = dZI + dDeltaZ ; + + // Minimi + if ( dX1 > - dLimX1 && dX1 < dLimX1) + + dMin = dZI - dHei ; + + else if ( dX1 >= dLimX1 && + dX1 < dPLen + dLimX1) + + dMin = dZI - dHei + ( dX1 - dLimX1) * 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) + 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) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + + Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; + + Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + // vettore movimento + Vector3d vtMove = ptLe - ptLs ; + + CurveComposite ToolProfile ; + + // Settaggio profilo + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + ToolProfile.CopyFrom( & m_ToolOutline) ; + else + // altrimenti usi l'approssimazione + ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; + + // Dichiaro un puntatore a curva da usare nel ciclo + const ICurve* pCurve ; + + pCurve = ToolProfile.GetFirstCurve() ; + + // Ciclo sulle curve + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso di semento + 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) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + LongCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + LongConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + LongConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + Ball( ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = ToolProfile.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) + 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) { + + double dLenVector = sqrt(vtCyl.x * vtCyl.x + vtCyl.y * vtCyl.y) ; + + vtU1 = ( 1 + dLenVector) / dLenVector * 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) + 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) { + + double dLenVector = sqrt(vtMove.x * vtMove.x + vtMove.y * vtMove.y) ; + + vtU1 = ( 1 + dLenVector) / dLenVector * 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 ; + + double dLimP1 = sqrt( dRad * dRad - dPI2 * dPI2) ; + + // Dexel nella regione interessata dalla lavorazione + if ( ( dPI1 > - dCos * dLimP1 && + dPI1 < dLOri && dPI2 * dPI2 < dRad * dRad) || + ( dPF1 * dPF1 + dPF2 * dPF2 < dRad * dRad)) { + + if ( dDeltaZ > 0) { + + // Massimi + if ( dPI1 < dLOri - dCos * dLimP1) { + + double dPI0 = - dCos * dLimP1 ; + double dZ0 = dSin * dLimP1 ; + + 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 * dLimP1) + + dMin = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; + + else if ( dPI1 < dLOri + dCos * dLimP1) { + + double dPI0 = dCos * dLimP1 ; + double dZ0 = - dSin * dLimP1 ; + + 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 * dLimP1) + + dMax = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; + + else if ( dPI1 < dLOri + dCos * dLimP1) { + + double dPI0 = dCos * dLimP1 ; + double dZ0 = + dSin * dLimP1 ; + + 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 * dLimP1) { + + double dPI0 = - dCos * dLimP1 ; + double dZ0 = - dSin * dLimP1 ; + + 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) + 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) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + // vettore movimento + Vector3d vtMove = ptLe - ptLs ; + + CurveComposite ToolProfile ; + int i = m_ToolArcLineApprox.GetCurveCount() ; + + // Settaggio profilo + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + ToolProfile.CopyFrom( & m_ToolOutline) ; + else + // altrimenti usi l'approssimazione + ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; + + // Dichiaro un puntatore a curva da usare nel ciclo + const ICurve* pCurve = ToolProfile.GetFirstCurve() ; + + // Ciclo sulle curve + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso di semento + 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) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + MillCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + MillConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + MillConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + Ball( ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = ToolProfile.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) + 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) + 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) + 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) + 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 dDen = sqrt( 1 + dTan * dTan) ; + 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 / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * 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, 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) + 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) { + + double dH = sqrt( dRad * dRad - dSqLen) ; + + dMin = dZI - dH ; + dMax = dZI + dDeltaZ + dH ; + + 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 ; +} + + +// 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 ; +} \ No newline at end of file