diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index 46fefe0..0874802 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index fae18f7..7d9fc3f 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -358,6 +358,11 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
+
+
+
@@ -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