diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index 55956b3..a677cd9 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index 7d9fc3f..e39d247 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -357,12 +357,12 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
+
+
-
-
-
-
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index a3a03b3..4d4b58d 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -339,19 +339,19 @@
File di origine\GeoCollision
-
- File di origine\Geo
-
-
- File di origine\Geo
-
-
- File di origine\Geo
-
File di origine\Geo
-
+
+ File di origine\Geo
+
+
+ File di origine\Geo
+
+
+ File di origine\Geo
+
+
File di origine\Geo
diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp
index 4ba35b8..2c496aa 100644
--- a/GdbExecutor.cpp
+++ b/GdbExecutor.cpp
@@ -2610,8 +2610,8 @@ GdbExecutor::ExecuteVolZmap(const string& sCmd2, const STRVECTOR& vsParams)
bool
GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams)
{
- // parametri : Id, IdParent, ptO, dPrec, dLengthX, dLengthY, dLengthZ
- if ( vsParams.size() != 7)
+ // parametri : Id, IdParent, ptO, dLengthX, dLengthY, dLengthZ, dPrec [, bTriDexel]
+ if ( vsParams.size() < 7)
return false ;
// recupero il riferimento in cui è immerso
Frame3d frRef ;
@@ -2621,27 +2621,32 @@ GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams)
Point3d ptO ;
if ( ! GetPointParam( vsParams[2], frRef, ptO))
return false ;
- // recupero precisione
- double dPrec ;
- if ( ! FromString( vsParams[3], dPrec))
- return false ;
// recupero LunghezzaX
double dLengthX ;
- if ( ! FromString( vsParams[4], dLengthX))
+ if ( ! FromString( vsParams[3], dLengthX))
return false ;
// recupero LunghezzaY
double dLengthY ;
- if ( ! FromString( vsParams[5], dLengthY))
+ if ( ! FromString( vsParams[4], dLengthY))
return false ;
// recupero LunghezzaZ
double dLengthZ ;
- if ( ! FromString( vsParams[6], dLengthZ))
+ if ( ! FromString( vsParams[5], dLengthZ))
return false ;
+ // recupero precisione
+ double dPrec ;
+ if ( ! FromString( vsParams[6], dPrec))
+ return false ;
+ // recupero flag tipo Zmap
+ bool bTriDexel = false ;
+ if ( vsParams.size() >= 8 && vsParams[7] != "0")
+ bTriDexel = true ;
+ // creo Zmap
PtrOwner pZprova( new VolZmap) ;
- pZprova->Create( ptO, dLengthX, dLengthY, dLengthZ, dPrec);
+ pZprova->Create( ptO, dLengthX, dLengthY, dLengthZ, dPrec, bTriDexel) ;
- // inserisco nel DB
+ // inserisco nel DB
return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ;
}
@@ -2649,8 +2654,8 @@ GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams)
bool
GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams)
{
- // parametri : Id, IdParent, idCurv, dPrec, dLengthZ
- if ( vsParams.size() != 5)
+ // parametri : Id, IdParent, idCurv, dPrec, dLengthZ [, bTriDexel]
+ if ( vsParams.size() < 5)
return false ;
// recupero il riferimento in cui è immerso
Frame3d frRef ;
@@ -2658,21 +2663,26 @@ GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams)
return false ;
// recupero id flatregion
int nIdFlat = GetIdParam( vsParams[2]) ;
- // recupero precisione
- double dPrec ;
- if ( ! FromString( vsParams[4], dPrec))
- return false ;
// recupero dimensioneZ
double dLengthZ ;
if ( ! FromString( vsParams[3], dLengthZ))
return false ;
+ // recupero precisione
+ double dPrec ;
+ if ( ! FromString( vsParams[4], dPrec))
+ return false ;
// recupero puntatore a FlatRegion
ISurfFlatRegion* pRegion = GetSurfFlatRegion( m_pGDB->GetGeoObj( nIdFlat)) ;
if ( pRegion == nullptr)
return false ;
+ // Flag tipo di mappa
+ bool bTriDexel = false ;
+ if ( vsParams.size() >= 6 && vsParams[5] != "0")
+ bTriDexel = true ;
+
// creo Zmap
PtrOwner pZprova( new VolZmap) ;
- pZprova->CreateFromFlatRegion( *pRegion, dLengthZ, dPrec);
+ pZprova->CreateFromFlatRegion( *pRegion, dLengthZ, dPrec, bTriDexel) ;
// inserisco nel DB
return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ;
@@ -2682,8 +2692,8 @@ GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams)
bool
GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams)
{
- // parametri : Id, IdParent, idSurf, dPrec
- if ( vsParams.size() != 4)
+ // parametri : Id, IdParent, idSurf, dPrec, bFlag
+ if ( vsParams.size() != 5)
return false ;
// recupero il riferimento in cui è immerso
Frame3d frRef ;
@@ -2695,13 +2705,17 @@ GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams)
double dPrec ;
if ( ! FromString( vsParams[3], dPrec))
return false ;
+ // Flag tipo di mappa
+ bool bType= false ;
+ if ( vsParams.size() >= 5 && vsParams[4] != "0")
+ bType = true ;
// recupero puntatore a Trimesh
SurfTriMesh* pSurf = GetBasicSurfTriMesh( m_pGDB->GetGeoObj( nIdSurf)) ;
if ( pSurf == nullptr)
return false ;
// creo Zmap
PtrOwner pZprova( new VolZmap) ;
- pZprova->CreateFromTriMesh( * pSurf, dPrec);
+ pZprova->CreateFromTriMesh( * pSurf, dPrec, bType) ;
// inserisco nel DB
return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ;
@@ -2711,8 +2725,8 @@ GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams)
bool
GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams)
{
- // parametri : Id, IdParent, ptPs, ptPe, vtVs, vtVe, dLinTol, dAngTolDeg (gli ultimi due servono per lavorazione con utensile generico)
- if ( vsParams.size() != 8)
+ // parametri : Id, IdParent, ptPs, ptPe, vtVs, vtVe, dLinTol, dAngTolDeg (dLinTol e dAngTol sono per lavo con gen tool), bType
+ if ( vsParams.size() != 9)
return false ;
// recupero il riferimento in cui è immerso
Frame3d frRef ;
@@ -2741,6 +2755,10 @@ GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams)
double dAngTolDeg ;
if ( ! FromString( vsParams[7], dAngTolDeg))
return false ;
+ bool bType = false ;
+ if ( vsParams.size() >= 9 && vsParams[2] != "0")
+ bType = true ;
+
// recupero lo Zmap
int nIdZmap = GetIdParam( vsParams[0]) ;
VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nIdZmap)) ;
@@ -2748,7 +2766,10 @@ GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams)
return false ;
// eseguo la lavorazione
pZmap->SetTolerances( dLinTol, dAngTolDeg) ;
- return pZmap->MillingStep( ptPs, vtDs, ptPe, vtDe) ;
+ //if ( bType)
+ return pZmap->MillingStep( ptPs, vtDs, ptPe, vtDe) ;
+ //else
+ // return pZmap->MillingStep( ptPs, vtDs, ptPe, vtDe) ;
}
//----------------------------------------------------------------------------
diff --git a/MC_Tables.h b/MC_Tables.h
new file mode 100644
index 0000000..0869577
--- /dev/null
+++ b/MC_Tables.h
@@ -0,0 +1,298 @@
+
+// Tabella segmenti
+static int EdgeTable[256] = {
+
+ 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
+ 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
+ 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
+ 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
+ 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
+ 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
+ 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
+ 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
+ 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
+ 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
+ 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
+ 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
+ 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
+ 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
+ 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
+ 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
+ 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
+ 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
+ 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
+ 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
+ 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
+ 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
+ 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
+ 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
+ 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
+ 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
+ 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
+ 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
+ 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
+ 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
+ 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
+ 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
+} ;
+
+// Tabella triangoli
+static int TriangleTable[256][16] = {
+
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+ {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+ {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+ {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+ {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
+ {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+ {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+ {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+ {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+ {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
+ {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
+ {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
+ {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+ {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+ {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+ {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
+ {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+ {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+ {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
+ {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
+ {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+ {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+ {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+ {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+ {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
+ {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
+ {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
+ {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+ {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+ {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
+ {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
+ {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
+ {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
+ {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+ {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
+ {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+ {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
+ {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+ {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
+ {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+ {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
+ {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+ {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
+ {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+ {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+ {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
+ {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
+ {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
+ {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+ {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+ {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
+ {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
+ {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+ {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
+ {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
+ {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
+ {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
+ {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+ {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+ {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
+ {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+ {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
+ {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+ {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
+ {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
+ {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
+ {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+ {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+ {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
+ {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
+ {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+ {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
+ {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+ {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+ {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
+ {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
+ {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
+ {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
+ {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
+ {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+ {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+ {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+ {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
+ {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+ {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
+ {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
+ {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+ {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
+ {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
+ {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+ {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+ {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
+ {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
+ {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
+ {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
+ {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+ {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
+ {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+ {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
+ {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+ {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
+ {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+ {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+ {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
+ {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+ {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
+ {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
+ {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
+ {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
+ {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
+ {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
+ {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
+ {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
+ {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
+ {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
+ {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+ {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
+ {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
+ {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
+ {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
+ {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
+ {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
+ {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
+ {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+ {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
+ {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
+ {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
+ {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
+ {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
+ {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
+ {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
+ {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
+ {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
+ {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+ {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
+ {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
+ {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
+ {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+ {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+ {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+ {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
+ {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
+ {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
+ {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
+ {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
+ {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
+ {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
+ {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+ {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
+ {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
+ {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
+ {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
+ {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
+ {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
+ {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
+ {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
+ {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+ {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
+ {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
+ {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
+ {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
+ {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
+ {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+ {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
+ {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+ {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
+ {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
+} ;
\ No newline at end of file
diff --git a/VolTriZmapCalculus.cpp b/VolTriZmapCalculus.cpp
new file mode 100644
index 0000000..36d58ce
--- /dev/null
+++ b/VolTriZmapCalculus.cpp
@@ -0,0 +1,736 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2016
+//----------------------------------------------------------------------------
+// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
+// Contenuto : Implementazione della classe Volume Zmap (tre griglie)
+//
+//
+//
+// 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 ;
+
+//----------------------------------------------------------------------------
+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( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2)
+{
+ // Punti estremi del box dello Zmap
+ Point3d ptMin = ORIG ;
+ Point3d ptMax = ptMin + Vector3d( m_nVNx[nGrid] * m_dStep, m_nVNy[nGrid] * m_dStep, m_dVMaxZ[nGrid]) ;
+
+ return ( IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) && ( dU1 > 0 || dU2 > 0)) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IntersLineDexel( unsigned int nGrid, 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_nVNx[nGrid] + nI ;
+ unsigned int nDexelSize = unsigned int( m_TriZValues[nGrid][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_TriZValues[nGrid][nDexelPos][nIndex]) ;
+ Point3d ptE2( dXmax, dYmax, m_TriZValues[nGrid][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_MapFrame[0]) ;
+ Vector3d vtV = vtDir ;
+ vtV.ToLoc( m_MapFrame[0]) ;
+ vtV.Normalize() ;
+
+ // Studio dell'intersezione fra semiretta e BBox dello Zmap
+ double dU1, dU2 ;
+ bool bTest = IntersLineZMapBBox( 0, 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_nVNx[0] - 1) ;
+ int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nVNy[0] - 1) ;
+ int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nVNx[0] - 1) ;
+ int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nVNy[0] - 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( 0, 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_nVNy[0] - 1) ;
+
+ // Analisi del dexel
+ if ( j != OldJ) {
+ double dU1, dU2 ;
+ if ( IntersLineDexel( 0, 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( 0, 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_nVNx[0] - 1) ;
+
+ // Analisi del dexel
+ if ( i != OldI) {
+ double dU1, dU2 ;
+ if ( IntersLineDexel( 0, 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_MapFrame[0]) ;
+
+ // BBox dello Zmap nel suo riferimento intrinseco
+ BBox3d b3Zmap( ORIG, Point3d( m_nVNx[0] * m_dStep, m_nVNy[0] * m_dStep, m_dVMaxZ[0])) ;
+
+ // 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_nVNx[0] -1) ;
+ int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nVNx[0] -1) ;
+ int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nVNy[0] -1) ;
+ int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nVNy[0] -1) ;
+
+ // Vettore direzione dei dexel nel riferimento del Box
+ Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame[0], frBox) ;
+
+ // Riferimento intrinseco dei dexel nel riferimento del box
+ Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame[0], frBox) ;
+ Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame[0], frBox) ;
+ Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame[0], 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_nVNx[0] + i ;
+ int nSize = int( m_TriZValues[0][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 ( ! ( dZmax < m_TriZValues[0][nPos][nIndex] - EPS_SMALL ||
+ dZmin > m_TriZValues[0][nPos][nIndex + 1] + EPS_SMALL))
+ return false ;
+ }
+ }
+ }
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
+ const Frame3d& CylFrame, double dL, double dR,
+ Point3d& ptInt1, Point3d& ptInt2)
+{
+ // NB: L'origine del sistema di riferimento deve essere
+ // nel centro della circonferenza di base e l'asse di simmetria
+ // deve coincidere con l'asse x.
+ // La funzione restituisce true in caso di intersezione,
+ // false altrimenti.
+
+ Point3d ptP = ptLineSt ;
+ Vector3d vtV = vtLineDir ;
+
+ // Trasformazione delle coordinate
+ ptP.ToLoc( CylFrame) ;
+ vtV.ToLoc( CylFrame) ;
+
+ DBLVECTOR vdCoef(3) ;
+ DBLVECTOR vdRoots ;
+
+ double dSqRad = dR * dR ;
+
+ vdCoef[0] = ptP.y * ptP.y + ptP.z * ptP.z - dSqRad ;
+ vdCoef[1] = 2 * ( ptP.y * vtV.y + ptP.z * vtV.z) ;
+ vdCoef[2] = vtV.y * vtV.y + vtV.z * vtV.z ;
+
+ // Computo radici
+ int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ;
+
+ // Nessuna soluzione
+ if ( nRoot == 0) {
+
+ if ( abs( vtV.x) > EPS_ZERO) {
+
+ ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ;
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+
+ if ( ptInt1.y * ptInt1.y + ptInt1.z * ptInt1.z <= dSqRad &&
+ ptInt2.y * ptInt2.y + ptInt2.z * ptInt2.z <= dSqRad) {
+
+ ptInt1.ToGlob( CylFrame) ;
+ ptInt2.ToGlob( CylFrame) ;
+
+ return true ;
+ }
+ // Nessuna intersezione
+ else
+ return false ;
+ }
+ // Nessuna intersezione
+ else
+ return false ;
+ }
+
+ // L'equazione ammette o due soluzioni (eventualmente
+ // coincidenti) oppure nessuna o infinite se la la retta
+ // appartiene alla superficie
+
+ if ( nRoot == 2) {
+
+ ptInt1 = ptP + vdRoots[0] * vtV ;
+ ptInt2 = ptP + vdRoots[1] * vtV ;
+
+ if ( ptInt1.x > ptInt2.x)
+ swap( ptInt1, ptInt2) ;
+
+ if ( ptInt1.x < 0 && ptInt2.x >= 0 && ptInt2.x <= dL) {
+
+ ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ;
+ }
+ else if ( ptInt1.x < 0 && ptInt2.x > dL) {
+
+ ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ;
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptInt1.x >= 0 && ptInt2.x <= dL) {
+
+ ;
+ }
+ else if ( ptInt1.x >= 0 && ptInt1.x < dL && ptInt2.x >= dL) {
+
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ // Intersezioni esterne alla regione di interesse
+ // (quella compresa fra 0 e dL)
+ else
+ return false ;
+
+ // Riporto le coordinate nel sistema di riferimento griglia
+ ptInt1.ToGlob( CylFrame) ;
+ ptInt2.ToGlob( CylFrame) ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IntersZLineCylinder( const Point3d& ptLine,
+ const Point3d& ptBase, const Point3d& ptTop, const Vector3d& vtDir, double dCylR,
+ double& dInfZ, double& dSupZ)
+{
+ // NB: Le coordinate sono espresse nel sistema griglia
+ // La funzione restituisce true in caso di intersezione,
+ // false altrimenti.
+
+ double dSqRad = dCylR * dCylR ;
+
+ // Cilindro verticale
+ if ( AreSamePointXYApprox( ptBase, ptTop)) {
+
+ // Intersezione
+ if ( SqDistXY( ptLine, ptBase) <= dSqRad) {
+ dInfZ = min( ptBase.z, ptTop.z) ;
+ dSupZ = max( ptBase.z, ptTop.z) ;
+ return true ;
+ }
+
+ // Non vi è intersezione
+ else
+ return false ;
+ }
+
+ // Cilindro non verticale
+ else {
+
+ // Studio delle simmetrie
+ Point3d ptS = ( ptBase.z < ptTop.z ? ptBase : ptTop) ;
+ Point3d ptE = ( ptBase.z < ptTop.z ? ptTop : ptBase) ;
+
+ Vector3d vtV1 = ptE - ptS ; vtV1.z = 0 ;
+
+ double dLenXY = vtV1.LenXY() ;
+ double dSZ = ptS.z ;
+ double dEZ = ptE.z ;
+ double dDeltaZ = dEZ - dSZ ;
+
+ Vector3d vtL( ptLine.x - ptS.x, ptLine.y - ptS.y, 0) ;
+
+ // vtV1 e vtV2 formano un sistema ortonormale
+ // sul piano e insieme a ptSxy formano un sistema
+ // di riferimento bidimensionale
+ vtV1.Normalize() ;
+ Vector3d vtV2 = vtV1 ;
+ vtV2.Rotate( Z_AX, 90) ;
+
+ double dLen = ( ptE - ptS).Len() ;
+
+ // Sono seno e coseno dell'angolo complementare
+ // rispetto a quello formato dal vettore movimento
+ // con il piano, per questo motivo si ha dCos con
+ // dDeltaZ e dSin con dLenXY
+ double dCos = dDeltaZ / dLen ;
+ double dSin = dLenXY / dLen ;
+
+ // Nuove coordinate piane del punto
+ double dLocX1 = vtL * vtV1 ;
+ double dLocX2 = vtL * vtV2 ;
+
+ double dSqRoot = sqrt( dSqRad - dLocX2 * dLocX2) ;
+ double dX1_0 = dCos * dSqRoot ;
+
+ if ( dLocX1 >= - dX1_0 && dLocX1 <= dLenXY + dX1_0 &&
+ abs( dLocX2) < dCylR) {
+
+ // Minimi
+ if ( dLocX1 < dX1_0) {
+
+ double dDotS = vtDir * ( ptS - ORIG) ;
+ // Qui usiamo ptLine perché servono coordinate griglia
+ dInfZ = ( dDotS - vtDir.x * ptLine.x - vtDir.y * ptLine.y) / vtDir.z ;
+ }
+ else {
+
+ double dZ0 = - dSin * dSqRoot ;
+
+ dInfZ = dSZ + dZ0 + ( dLocX1 - dX1_0) * dDeltaZ / dLenXY ;
+ }
+
+ // Massimi
+ if ( dLocX1 < dLenXY - dX1_0) {
+
+ double dZ0 = dSin * dSqRoot ;
+
+ dSupZ = dSZ + dZ0 + ( dLocX1 - dX1_0) * dDeltaZ / dLenXY ;
+ }
+ else {
+
+ double dDotE = vtDir * ( ptE - ORIG) ;
+ // Qui usiamo ptLine perché servono coordinate griglia
+ dSupZ = ( dDotE - vtDir.x * ptLine.x - vtDir.y * ptLine.y) / vtDir.z ;
+ }
+
+ return true ;
+ }
+
+ return false ;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir,
+ const Frame3d& ConusFrame, double dTan, double dl, double dL,
+ Point3d& ptInt1, Point3d& ptInt2)
+{
+ // NB: L'origine del sistema di riferimento deve essere
+ // nel vertice del cono e l'asse di simmetria deve coincidere
+ // con l'asse x.
+ // La funzione restituisce true in caso di intersezione,
+ // false altrimenti.
+
+ Point3d ptP = ptLineSt ;
+ Vector3d vtV = vtLineDir ;
+
+ // Trasformazione delle coordinate
+ ptP.ToLoc( ConusFrame) ;
+ vtV.ToLoc( ConusFrame) ;
+
+ DBLVECTOR vdCoef(3) ;
+ DBLVECTOR vdRoots ;
+
+ double dSqTan = dTan * dTan ;
+
+ vdCoef[0] = dSqTan * ptP.x * ptP.x - ptP.y * ptP.y - ptP.z * ptP.z ;
+ vdCoef[1] = 2 * ( dSqTan * ptP.x * vtV.x - ptP.y * vtV.y - ptP.z * vtV.z) ;
+ vdCoef[2] = dSqTan * vtV.x * vtV.x - vtV.y * vtV.y - vtV.z * vtV.z ;
+
+ // Computo radici
+ int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ;
+
+ // Nessuna soluzione
+ if ( nRoot == 0)
+ return false ;
+
+ // Una soluzione: la retta iterseca superficie
+ // laterale e un piano
+ if ( nRoot == 1) {
+
+ ptInt1 = ptP + vdRoots[0] * vtV ;
+
+ if ( ptInt1.x >= dl && ptInt1.x < dL) {
+
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptInt1.x >= 0 && ptInt1.x < dl) {
+
+ ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ;
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+
+ // Riporto le coordinate nel sistema di riferimento
+ // griglia
+ ptInt1.ToGlob( ConusFrame) ;
+ ptInt2.ToGlob( ConusFrame) ;
+ }
+ // Due soluzioni: la retta interseca due volte la
+ // superficie laterale
+ else if ( nRoot == 2) {
+
+ ptInt1 = ptP + vdRoots[0] * vtV ;
+ ptInt2 = ptP + vdRoots[1] * vtV ;
+
+ if ( ptInt1.x > ptInt2.x) {
+ swap( ptInt1, ptInt2) ;
+ }
+
+ if ( ptInt1.x < 0 && ptInt2.x > 0 && ptInt2.x < dl) {
+
+ ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ;
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptInt1.x < 0 && ptInt2.x >= dl && ptInt2.x < dL) {
+
+ ptInt1 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptInt1.x > 0 && ptInt1.x < dl && ptInt2.x >= dl && ptInt2.x < dL) {
+
+ ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptInt1.x > 0 && ptInt1.x < dl && ptInt2.x >= dL) {
+
+ ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ;
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptInt1.x >= dl && ptInt1.x < dL && ptInt2.x < dL) {
+
+ ;
+ }
+ else if ( ptInt1.x >= dl && ptInt1.x < dL && ptInt2.x >= dL) {
+
+ ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ // Intersezioni esterne alla regione di interesse
+ // (quella compresa fra dl e dL)
+ else
+ return false ;
+
+ // Riporto le coordinate nel sistema di riferimento
+ // griglia
+ ptInt1.ToGlob( ConusFrame) ;
+ ptInt2.ToGlob( ConusFrame) ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IntersLineEllipticalCylinder( const Frame3d & CircFrame, const Vector3d & vtLineDir, const Point3d & ptLineSt,
+ std::vector & ptInters, double dObCoef, double dSqRad, double dL)
+{
+ // NB: L'origine del sistema di riferimento deve essere
+ // nel centro della circonferenza di base, la cui tralsazione obliqua
+ // genera il cilindro ellittico, e l'asse x deve essere l'asse
+ // di simmetria di tale circonferenza.
+ // La funzione restituisce true in caso di intersezione,
+ // false altrimenti.
+ // NB: Il Parametro dObCoef è il coeffociente angolare della retta movimento
+ // rispetto all'asse x, e dSqRad è il quadrato del raggio della circonferenza.
+
+ double dSqCoef = dObCoef * dObCoef ;
+
+ Point3d ptP = ptLineSt ;
+ Vector3d vtV = vtLineDir ;
+
+ // Sistema di riferimanto grigia
+ Frame3d GridFrame ;
+ GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ;
+
+ // Trasformazione delle coordinate
+ ptP.LocToLoc( GridFrame, CircFrame) ;
+ vtV.LocToLoc( GridFrame, CircFrame) ;
+
+ std::vector vdCoef(3) ;
+ std::vector vdRoots ;
+
+ vdCoef[0] = dSqCoef * ptP.x * ptP.x + ptP.y * ptP.y + ptP.z * ptP.z - 2 * dObCoef * ptP.x * ptP.y - dSqRad ;
+ vdCoef[1] = 2 * ( dSqCoef * vtV.x * ptP.x + vtV.y * ptP.y + vtV.z * ptP.z - dObCoef * ( vtV.x * ptP.y + vtV.y * ptP.x)) ;
+ vdCoef[2] = dSqCoef * vtV.x * vtV.x + vtV.y * vtV.y + vtV.z * vtV.z - 2 * dObCoef * vtV.x * vtV.y ;
+
+ int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ;
+
+ Point3d ptR1, ptR2 ;
+
+ // Nessuna soluzione
+ if ( nRoot == 0) {
+
+ if ( abs( vtV.x) > EPS_ZERO) {
+
+ ptR1 = ptP - ( ptP.x / vtV.x) * vtV ;
+ ptR2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+
+ if ( ptR1.y * ptR1.y + ptR1.z * ptR1.z < dSqRad &&
+ ptR1.y * ptR1.y + ptR1.z * ptR1.z < dSqRad) {
+
+ ptR1.LocToLoc( CircFrame, GridFrame) ;
+ ptR2.LocToLoc( CircFrame, GridFrame) ;
+
+ ptInters.resize(2) ;
+
+ ptInters[0] = ptR1 ;
+ ptInters[0] = ptR2 ;
+
+ return true ;
+ }
+ // Nessuna intersezione
+ else
+ return false ;
+ }
+ // Nessuna intersezione
+ else
+ return false ;
+ }
+
+ // L'equazione ammette o due soluzioni (eventualmente
+ // coincidenti) oppure nessuna o infinite se la la retta
+ // appartiene alla superficie
+
+ ptInters.resize(2) ;
+
+ if ( nRoot == 2) {
+
+ ptR1 = ptP + vdRoots[0] * vtV ;
+ ptR2 = ptP + vdRoots[1] * vtV ;
+
+
+ if ( ptR1.x > ptR2.x) {
+
+ Point3d ptTemp = ptR1 ;
+ ptR1 = ptR2 ;
+ ptR2 = ptTemp ;
+ }
+
+ if ( ptR1.x >= 0 && ptR1.x < dL &&
+ ptR2.x > dL) {
+
+ ptR1 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptR1.x >= 0 && ptR2.x <= dL) {
+
+ ;
+ }
+ else if ( ptR1.x < 0 && ptR2.x > dL) {
+
+ ptR1 = ptP - ( ptP.x / vtV.x) * vtV ;
+ ptR2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ;
+ }
+ else if ( ptR1.x < 0 && ptR2.x >= 0 && ptR2.x <= dL) {
+
+ ptR1 = ptP - ( ptP.x / vtV.x) * vtV ;
+ }
+
+ // Riporto le coordinate nel sistema di riferimento
+ // griglia
+ ptR1.LocToLoc( CircFrame, GridFrame) ;
+ ptR2.LocToLoc( CircFrame, GridFrame) ;
+
+ ptInters[0] = ptR1 ;
+ ptInters[1] = ptR2 ;
+ }
+
+ return true ;
+}
\ No newline at end of file
diff --git a/VolTriZmapCreation.cpp b/VolTriZmapCreation.cpp
new file mode 100644
index 0000000..2936b89
--- /dev/null
+++ b/VolTriZmapCreation.cpp
@@ -0,0 +1,595 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2016
+//----------------------------------------------------------------------------
+// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
+// Contenuto : Implementazione della classe Volume Zmap (tre griglie)
+//
+//
+//
+// 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 MAPPA --------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec, bool bFlag)
+{
+
+ // Controlli l'ammissibilità delle dimensioni lineari del grezzo e del passo
+ if ( dPrec < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL)
+ return false ;
+
+ // Aggiorno il passo
+ m_dStep = dPrec ;
+
+ // Aggiorno la dimensione della mappa 1 o 3
+ m_nMapNum = ( bFlag ? 3 : 1) ;
+
+ // Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z
+ // di uno si ottengono da una permutazione ciclica di quelle del precedente sistema.
+ // es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1)
+
+ // Definisco i sistemi di riferimento
+ m_MapFrame[0].Set( ptO, X_AX, Y_AX, Z_AX) ;
+
+ // Definisco i vettori dei limiti su indici
+ m_nVNx[0] = static_cast ( ceil( dLengthX / m_dStep)) ;
+ m_nVNy[0] = static_cast ( ceil( dLengthY / m_dStep)) ;
+
+ if ( m_nMapNum > 1) {
+
+ m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ;
+ m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ;
+
+ m_nVNx[1] = static_cast ( ceil( dLengthY / m_dStep)) ;
+ m_nVNy[1] = static_cast ( ceil( dLengthZ / m_dStep)) ;
+
+ m_nVNx[2] = static_cast ( ceil( dLengthZ / m_dStep)) ;
+ m_nVNy[2] = static_cast ( ceil( dLengthX / m_dStep)) ;
+ }
+ else {
+
+ m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ;
+ m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ;
+
+ m_nVNx[1] = 0 ;
+ m_nVNy[1] = 0 ;
+
+ m_nVNx[2] = 0 ;
+ m_nVNy[2] = 0 ;
+ }
+
+ // Definizione della mappa
+
+ // Creazione delle mappe
+ // Calcolo del numero di celle per ogni mappa
+ for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i)
+
+ m_nVDim[i] = m_nVNx[i] * m_nVNy[i] ;
+
+ // Creazione delle celle per ogni mappa
+ for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i)
+
+ m_TriZValues[i].resize( m_nVDim[i]) ;
+
+ // Riempimento delle celle
+ for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i)
+ for ( unsigned int j = 0 ; j < m_nVDim[i] ; ++ j) {
+
+ m_TriZValues[i][j].resize(2) ;
+
+ m_TriZValues[i][j][0] = 0 ;
+
+ if ( i == 0)
+ m_TriZValues[i][j][1] = dLengthZ ;
+ else if ( i == 1)
+ m_TriZValues[i][j][1] = dLengthX ;
+ else if ( i == 2)
+ m_TriZValues[i][j][1] = dLengthY ;
+ }
+
+ // Definizione delle limitazioni iniziali in Z per ogni mappa
+ for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
+
+ m_dVMinZ[i] = 0 ;
+
+ if ( i == 0)
+ m_dVMaxZ[i] = dLengthZ ;
+ else if ( i == 1)
+ m_dVMaxZ[i] = dLengthX ;
+ else if ( i == 2)
+ m_dVMaxZ[i] = dLengthY ;
+ }
+
+ // Aggiornamento dello stato
+ m_nStatus = OK ;
+
+ return true ;
+}
+
+bool
+VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec, bool bFlag)
+{
+
+ Point3d ptMapOrig, ptMapEnd ;
+
+ // Aggiorno la dimensione della mappa 1 o 3
+ m_nMapNum = ( bFlag ? 3 : 1) ;
+
+ // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL
+ m_dStep = max( dPrec, 100 * EPS_SMALL) ;
+
+ // 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_MapFrame[0].Set( ptMapOrig, X_AX, Y_AX, Z_AX) ;
+
+
+ // 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_nVNx[0] = static_cast ( ceil( dLengthX / m_dStep)) ;
+ m_nVNy[0] = static_cast ( ceil( dLengthY / m_dStep)) ;
+
+ m_nVDim[0] = m_nVNx[0] * m_nVNy[0] ;
+
+ // Ridimensiono il vettore di dexel e creo lo Zmap
+ m_TriZValues[0].resize( m_nVDim[0]) ;
+
+ // Se Tridexel ridimensiono anche gli altri vettori
+ if ( bFlag) {
+
+ m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ;
+ m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
+
+ m_nVNx[1] = static_cast ( ceil( dLengthY / m_dStep)) ;
+ m_nVNy[1] = static_cast ( ceil( dDimZ / m_dStep)) ;
+
+ m_nVDim[1] = m_nVNx[1] * m_nVNy[1] ;
+
+ m_nVNx[2] = static_cast ( ceil( dDimZ / m_dStep)) ;
+ m_nVNy[2] = static_cast ( ceil( dLengthX / m_dStep)) ;
+
+ m_nVDim[2] = m_nVNx[2] * m_nVNy[2] ;
+
+ m_TriZValues[1].resize( m_nVDim[1]) ;
+ m_TriZValues[2].resize( m_nVDim[2]) ;
+ }
+ else {
+
+ m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ;
+ m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
+
+ m_nVNx[1] = 0 ;
+ m_nVNy[1] = 0 ;
+
+ m_nVDim[1] = 0 ;
+
+ m_nVNx[2] = 0 ;
+ m_nVNy[2] = 0 ;
+
+ m_nVDim[2] = 0 ;
+ }
+
+ // Determinazione e ridimensionamento dei dexel
+ // interni alla regione
+
+ // Griglia 0
+ for ( unsigned int i = 0 ; i < m_nVNx[0] ; ++ 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 ;
+
+ // Parametri iniziale e finale
+ double dt1 = IntersectionResults[k].dParS ;
+ double dt2 = IntersectionResults[k].dParE ;
+
+ // 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) {
+
+ // Indici corrispondenti alle coordinate dei punti
+ int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep + 0.5)), 0, m_nVNy[0] - 1) ;
+ int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep - 0.5)), 0, m_nVNy[0] - 1) ;
+
+ // Ridimensiono e riempio i dexel
+ for ( int j = nStartJ ; j <= nEndJ ; ++ j) {
+ // Determino il dexel
+ int nPos0 = j * m_nVNx[0] + i ;
+
+ m_TriZValues[0][nPos0].resize( 2) ;
+ // Aggiorno le quote estreme del segmento
+ m_TriZValues[0][nPos0][0] = 0 ;
+ m_TriZValues[0][nPos0][1] = dDimZ ;
+ }
+
+ // Se tridexel riempio i singoli dexel della
+ // griglia 2 con gli intervalli
+ if ( bFlag) {
+
+ for ( size_t a = 0 ; a < m_nVNx[2] ; ++ a) {
+
+ size_t nPos2 = i * m_nVNx[2] + a ;
+
+ size_t nCurrentSize = m_TriZValues[2][nPos2].size( ) ;
+
+ m_TriZValues[2][nPos2].resize( nCurrentSize + 2) ;
+
+ m_TriZValues[2][nPos2][nCurrentSize] = dt1 * dLengthY ;
+ m_TriZValues[2][nPos2][nCurrentSize + 1] = dt2 * dLengthY ;
+ }
+ }
+ }
+ }
+ }
+
+ // Se tridexel resta la griglia 1
+ if ( bFlag) {
+
+ for ( unsigned int i = 0 ; i < m_nVNx[1] ; ++ i) {
+
+ // Definisco la retta da intersecare con la regione
+ double dX = ( i + 0.5) * m_dStep ;
+ Point3d ptP0 = ptMapOrig + Vector3d( 0, dX, 0) ;
+ CurveLine GridLine ;
+ GridLine.SetPVL( ptP0, X_AX, dLengthX) ;
+
+ // 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 ;
+
+ for ( size_t j = 0 ; j < m_nVNy[1] ; ++ j) {
+
+ size_t nPos1 = j * m_nVNx[1] + i ;
+
+ size_t nCurrentSize = m_TriZValues[1][nPos1].size( ) ;
+
+ m_TriZValues[1][nPos1].resize( nCurrentSize + 2) ;
+
+ m_TriZValues[1][nPos1][nCurrentSize] = dt1 * dLengthX ;
+ m_TriZValues[1][nPos1][nCurrentSize + 1] = dt2 * dLengthX ;
+ }
+ }
+ }
+ }
+ }
+
+
+ m_dVMinZ[0] = 0 ;
+ m_dVMaxZ[0] = dDimZ ;
+
+ if ( bFlag) {
+
+ m_dVMinZ[1] = 0 ;
+ m_dVMaxZ[1] = dLengthX ;
+ m_dVMinZ[2] = 0 ;
+ m_dVMaxZ[2] = dLengthY ;
+ }
+ else {
+
+ m_dVMinZ[1] = 0 ;
+ m_dVMaxZ[1] = 0 ;
+ m_dVMinZ[2] = 0 ;
+ m_dVMaxZ[2] = 0 ;
+ }
+
+ // Aggiornamento dello stato
+ m_nStatus = OK ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bFlag)
+{
+ // Se la superficie non è chiusa non ha senso continuare
+ if ( ! Surf.IsClosed())
+ return false ;
+
+ // Aggiorno la dimensione della mappa 1 o 3
+ m_nMapNum = ( bFlag ? 3 : 1) ;
+
+ // 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_MapFrame[0].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 del BBox
+ 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_nVNx[0] = static_cast ( ceil( dLengthX / m_dStep)) ;
+ m_nVNy[0] = static_cast ( ceil( dLengthY / m_dStep)) ;
+
+ m_nVDim[0] = m_nVNx[0] * m_nVNy[0] ;
+
+ // Ridimensiono il vettore di dexel e creo lo Zmap
+ m_TriZValues[0].resize( m_nVDim[0]) ;
+
+ // Se Tridexel ridimensiono anche gli altri vettori
+ if ( bFlag) {
+
+ m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ; // Sarà Front Left
+ m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
+
+ m_nVNx[1] = static_cast ( ceil( dLengthY / m_dStep)) ;
+ m_nVNy[1] = static_cast ( ceil( dLengthZ / m_dStep)) ;
+
+ m_nVDim[1] = m_nVNx[1] * m_nVNy[1] ;
+
+ m_nVNx[2] = static_cast ( ceil( dLengthZ / m_dStep)) ;
+ m_nVNy[2] = static_cast ( ceil( dLengthX / m_dStep)) ;
+
+ m_nVDim[2] = m_nVNx[2] * m_nVNy[2] ;
+
+ m_TriZValues[1].resize( m_nVDim[1]) ;
+ m_TriZValues[2].resize( m_nVDim[2]) ;
+ }
+
+
+ // Oggetto per calcolo massivo intersezioni
+ IntersParLinesSurfTm intPLSTM( m_MapFrame[0], Surf) ;
+
+ // Determinazione e ridimensionamento dei dexel interni alla trimesh
+ for ( unsigned int i = 0 ; i < m_nVNx[0] ; ++ i) {
+ for ( unsigned int j = 0 ; j < m_nVNy[0] ; ++ 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_nVNx[0] + 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_TriZValues[0][nPos].size()) ;
+
+ m_TriZValues[0][nPos].resize( nCurrentSize + 2) ;
+
+ m_TriZValues[0][nPos][nCurrentSize] = ptIn.z - ptMapOrig.z ;
+ m_TriZValues[0][nPos][nCurrentSize + 1] = ptOut.z - ptMapOrig.z ;
+
+ bInside = false ;
+ }
+ }
+ }
+ }
+ }
+
+ if ( bFlag) {
+
+ IntersParLinesSurfTm intPLSTM1( m_MapFrame[1], Surf) ;
+
+ // Determinazione e ridimensionamento dei dexel interni alla trimesh
+ for ( unsigned int i = 0 ; i < m_nVNx[1] ; ++ i) {
+ for ( unsigned int j = 0 ; j < m_nVNy[1] ; ++ 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 ;
+ intPLSTM1.GetInters( ptP0, dLengthX, IntersectionResults) ;
+
+ int nInt = int( IntersectionResults.size()) ;
+
+ unsigned int nPos = j * m_nVNx[1] + 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_TriZValues[1][nPos].size()) ;
+
+ m_TriZValues[1][nPos].resize( nCurrentSize + 2) ;
+
+ m_TriZValues[1][nPos][nCurrentSize] = ptIn.x - ptMapOrig.x ;
+ m_TriZValues[1][nPos][nCurrentSize + 1] = ptOut.x - ptMapOrig.x ;
+
+ bInside = false ;
+ }
+ }
+ }
+ }
+ }
+
+ IntersParLinesSurfTm intPLSTM2( m_MapFrame[2], Surf) ;
+
+ // Determinazione e ridimensionamento dei dexel interni alla trimesh
+ for ( unsigned int i = 0 ; i < m_nVNx[2] ; ++ i) {
+ for ( unsigned int j = 0 ; j < m_nVNy[2] ; ++ 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 ;
+ intPLSTM2.GetInters( ptP0, dLengthY, IntersectionResults) ;
+
+ int nInt = int( IntersectionResults.size()) ;
+
+ unsigned int nPos = j * m_nVNx[2] + 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_TriZValues[2][nPos].size()) ;
+
+ m_TriZValues[2][nPos].resize( nCurrentSize + 2) ;
+
+ m_TriZValues[2][nPos][nCurrentSize] = ptIn.y - ptMapOrig.y ;
+ m_TriZValues[2][nPos][nCurrentSize + 1] = ptOut.y - ptMapOrig.y ;
+
+ bInside = false ;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Assegno il minimo e massimo valore di Z della mappa
+ m_dVMinZ[0] = 0 ;
+ m_dVMaxZ[0] = dLengthZ ;
+
+ if ( bFlag) {
+
+ m_dVMinZ[1] = 0 ;
+ m_dVMaxZ[1] = dLengthX ;
+ m_dVMinZ[2] = 0 ;
+ m_dVMaxZ[2] = dLengthY ;
+ }
+ else {
+
+ m_dVMinZ[1] = 0 ;
+ m_dVMaxZ[1] = 0 ;
+ m_dVMinZ[2] = 0 ;
+ m_dVMaxZ[2] = 0 ;
+ }
+
+
+
+ m_nStatus = OK ;
+
+ return true ;
+}
\ No newline at end of file
diff --git a/VolTriZmapGraphics.cpp b/VolTriZmapGraphics.cpp
new file mode 100644
index 0000000..4e816a1
--- /dev/null
+++ b/VolTriZmapGraphics.cpp
@@ -0,0 +1,1026 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2016
+//----------------------------------------------------------------------------
+// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
+// Contenuto : Implementazione della classe Volume Zmap (tre griglie)
+//
+//
+//
+// 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\EGkIntervals.h"
+#include "\EgtDev\Include\EgtNumUtils.h"
+#include "MC_Tables.h"
+
+
+using namespace std ;
+
+// ------------------------- VISUALIZZAZIONE --------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const
+{
+ // Controllo l'ammissibilità della griglia
+ if ( nDir < 0 || nDir > 2)
+ return false ;
+
+ // Verifiche sugli indici
+ if ( nPos1 < 0 || nPos1 >= int( m_nVNx[nDir]) || nPos2 < 0 || nPos2 >= int( m_nVNy[nDir]))
+ return false ;
+
+ int nPos = nPos1 + nPos2 * m_nVNx[nDir] ;
+
+ if ( nPos < 0 || nPos >= int( m_TriZValues[nDir].size()))
+ return false ;
+
+ // Calcolo coordinate punto
+ double dX = m_dStep * ( 0.5 + nPos1) ;
+ double dY = m_dStep * ( 0.5 + nPos2) ;
+
+ // Determino il punto di partensa sulla griglia
+ Point3d ptP = m_MapFrame[nDir].Orig() + dX * m_MapFrame[nDir].VersX() + dY * m_MapFrame[nDir].VersY() ;
+
+ // Creo le polilinee
+ for ( int j = 1 ; j < int( m_TriZValues[nDir][nPos].size()) ; j += 2) {
+ // aggiungo polilinea a lista
+ lstPL.emplace_back() ;
+ // inserisco punti estremi
+ lstPL.back().AddUPoint( 0, ptP + m_TriZValues[nDir][nPos][j-1] * m_MapFrame[nDir].VersZ()) ;
+ lstPL.back().AddUPoint( 1, ptP + m_TriZValues[nDir][nPos][j] * m_MapFrame[nDir].VersZ()) ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const
+{
+ if ( m_nMapNum == 1) {
+ const int MAX_DIM_CHUNK = 128 ;
+ for ( int i = 0 ; i < int( m_nVNx[0]) ; i += MAX_DIM_CHUNK) {
+ int nDimChunkX = min( MAX_DIM_CHUNK, int( m_nVNx[0]) - i) ;
+ for ( int j = 0 ; j < int( m_nVNy[0]) ; j += MAX_DIM_CHUNK) {
+ int nDimChunkY = min( MAX_DIM_CHUNK, int( m_nVNy[0]) - j) ;
+ GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, MAX_DIM_CHUNK, lstTria) ;
+ }
+ }
+ }
+ else
+ MarchingCubes( 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_nVNx[0] ;
+ if ( nPos > int( m_nVDim[0]) ||
+ int( m_TriZValues[0][nPos].size()) != 2)
+ bIsSimple = false ;
+ else if ( i == 0 && j == 0) {
+ dBotZ = m_TriZValues[0][nPos][0] ;
+ dTopZ = m_TriZValues[0][nPos][1] ;
+ }
+ else if ( abs( m_TriZValues[0][nPos][0] - dBotZ) > EPS_SMALL ||
+ abs( m_TriZValues[0][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_nVNx[0]) || nPos2 < 0 || nPos2 + nDim2 > int( m_nVNy[0]))
+ return false ;
+ int nPos = nPos1 + nPos2 * m_nVNx[0] ;
+ if ( nPos < 0 || nPos >= int( m_nVDim[0]))
+ return false ;
+
+ // calcolo coordinate punti
+ double dX = m_dStep * nPos1 ;
+ double dY = m_dStep * nPos2 ;
+ Point3d ptP1 = m_MapFrame[0].Orig() + dX * m_MapFrame[0].VersX() + dY * m_MapFrame[0].VersY() ;
+ Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_MapFrame[0].VersX() ;
+ Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_MapFrame[0].VersY() ;
+ Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_MapFrame[0].VersY() ;
+
+ // creo le facce sopra e sotto
+ Vector3d vtDZt = m_TriZValues[0][nPos][1] * m_MapFrame[0].VersZ() ;
+ Vector3d vtDZb = m_TriZValues[0][nPos][0] * m_MapFrame[0].VersZ() ;
+ // faccia superiore P1t->P2t->P3t->P4t : sempre visibile
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_MapFrame[0].VersZ()) ;
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_MapFrame[0].VersZ()) ;
+ // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_MapFrame[0].VersZ()) ;
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_MapFrame[0].VersZ()) ;
+
+ // creo le facce laterali
+ for ( int j = 0 ; j < nDim2 ; ++ j) {
+ int nPosD = nPos + nDim1 - 1 + j * m_nVNx[0] ;
+ int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nVNx[0] - 1) ? nPosD + 1 : - 1) ;
+ Point3d ptP2D = ptP2 + j * m_dStep * m_MapFrame[0].VersY() ;
+ Point3d ptP3D = ptP2D + m_dStep * m_MapFrame[0].VersY() ;
+ AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_MapFrame[0].VersZ(), m_MapFrame[0].VersX(), lstTria) ;
+ }
+ for ( int i = 0 ; i < nDim1 ; ++ i) {
+ int nPosD = nPos + ( nDim2 - 1) * m_nVNx[0] + i ;
+ int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nVNy[0] - 1) ? nPosD + m_nVNx[0] : - 1) ;
+ Point3d ptP4D = ptP4 + i * m_dStep * m_MapFrame[0].VersX() ;
+ Point3d ptP3D = ptP4D + m_dStep * m_MapFrame[0].VersX() ;
+ AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_MapFrame[0].VersZ(), m_MapFrame[0].VersY(), lstTria) ;
+ }
+ for ( int j = 0 ; j < nDim2 ; ++ j) {
+ int nPosD = nPos + j * m_nVNx[0] ;
+ int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ;
+ Point3d ptP1D = ptP1 + j * m_dStep * m_MapFrame[0].VersY() ;
+ Point3d ptP4D = ptP1D + m_dStep * m_MapFrame[0].VersY() ;
+ AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_MapFrame[0].VersZ(), - m_MapFrame[0].VersX(), lstTria) ;
+ }
+ for ( int i = 0 ; i < nDim1 ; ++ i) {
+ int nPosD = nPos + i ;
+ int nPosSud = ( nPos2 > 0 ? nPosD - m_nVNx[0] : - 1) ;
+ Point3d ptP1D = ptP1 + i * m_dStep * m_MapFrame[0].VersX() ;
+ Point3d ptP2D = ptP1D + m_dStep * m_MapFrame[0].VersX() ;
+ AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_MapFrame[0].VersZ(), - m_MapFrame[0].VersY(), lstTria) ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const
+{
+ // verifiche sugli indici
+ if ( nPos1 < 0 || nPos1 >= int( m_nVNx[0]) || nPos2 < 0 || nPos2 >= int( m_nVNy[0]))
+ return false ;
+ int nPos = nPos1 + nPos2 * m_nVNx[0] ;
+ if ( nPos < 0 || nPos >= int( m_nVDim[0]))
+ return false ;
+
+ // calcolo coordinate punto
+ double dX = m_dStep * nPos1 ;
+ double dY = m_dStep * nPos2 ;
+ Point3d ptP1 = m_MapFrame[0].Orig() + dX * m_MapFrame[0].VersX() + dY * m_MapFrame[0].VersY() ;
+ Point3d ptP2 = ptP1 + m_dStep * m_MapFrame[0].VersX() ;
+ Point3d ptP3 = ptP2 + m_dStep * m_MapFrame[0].VersY() ;
+ Point3d ptP4 = ptP1 + m_dStep * m_MapFrame[0].VersY() ;
+
+ // creo le facce sopra e sotto di ogni intervallo (sempre visibili)
+ for ( int i = 1 ; i < int( m_TriZValues[0][nPos].size()) ; i += 2) {
+ Vector3d vtDZt = m_TriZValues[0][nPos][i] * m_MapFrame[0].VersZ() ;
+ Vector3d vtDZb = m_TriZValues[0][nPos][i-1] * m_MapFrame[0].VersZ() ;
+ // faccia superiore P1t->P2t->P3t->P4t : sempre visibile
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_MapFrame[0].VersZ()) ;
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_MapFrame[0].VersZ()) ;
+ // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_MapFrame[0].VersZ()) ;
+ lstTria.emplace_back() ;
+ lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_MapFrame[0].VersZ()) ;
+ }
+
+ // creo le facce laterali
+ int nPosEst = ( nPos1 < int( m_nVNx[0] - 1) ? nPos + 1 : - 1) ;
+ AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_MapFrame[0].VersZ(), m_MapFrame[0].VersX(), lstTria) ;
+ int nPosNord = ( nPos2 < int( m_nVNy[0] - 1) ? nPos + m_nVNx[0] : - 1) ;
+ AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_MapFrame[0].VersZ(), m_MapFrame[0].VersY(), lstTria) ;
+ int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ;
+ AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_MapFrame[0].VersZ(), - m_MapFrame[0].VersX(), lstTria) ;
+ int nPosSud = ( nPos2 > 0 ? nPos - m_nVNx[0] : - 1) ;
+ AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_MapFrame[0].VersZ(), - m_MapFrame[0].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_TriZValues[0][nPos].size()) ; i += 2)
+ intFace.Add( m_TriZValues[0][nPos][i-1], m_TriZValues[0][nPos][i]) ;
+ if ( nPosAdj > 0) {
+ for ( int i = 1 ; i < int( m_TriZValues[0][nPosAdj].size()) ; i += 2)
+ intFace.Subtract( m_TriZValues[0][nPosAdj][i-1], m_TriZValues[0][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::MarchingCubes( TRIA3DLIST& lstTria)
+{
+ // Limiti superiori sui tre indici
+ unsigned int nLimI = m_nVNx[0] ;
+ unsigned int nLimJ = m_nVNy[0] ;
+ unsigned int nLimK = m_nVNy[1] ;
+
+ struct Corner {
+
+ int nCornerNumber ;
+ unsigned int nI, nJ, nK ;
+ } ;
+
+ // Ciclo su tutti i voxel dello Zmap
+ for ( unsigned int k = 0 ; k < nLimK ; ++ k) {
+ for ( unsigned int i = 0 ; i < nLimI ; ++ i) {
+ for ( unsigned int j = 0 ; j < nLimJ ; ++ j) {
+ }
+ }
+ }
+ return true ;
+}
+*/
+
+/*
+//----------------------------------------------------------------------------
+bool
+VolZmap::MarchingCubes( TRIA3DLIST& lstTria)
+{
+ unsigned int nLimI = m_nVNx[0] ;
+ unsigned int nLimJ = m_nVNy[0] ;
+ unsigned int nLimK = m_nVNy[1] ;
+
+
+ // Ciclo su tutti i voxel dello Zmap
+ for ( unsigned int k = 0 ; k < nLimK ; ++ k) {
+ for ( unsigned int i = 0 ; i < nLimI ; ++ i) {
+ for ( unsigned int j = 0 ; j < nLimJ ; ++ j) {
+
+ // Indici i,j,k dei vertici
+ int IndexCorner[8][3] = {
+
+ { i, j, k},
+ { i + 1, j, k},
+ { i + 1, j + 1, k},
+ { i, j + 1, k},
+ { i, j, k + 1},
+ { i + 1, j, k + 1},
+ { i + 1, j + 1, k + 1},
+ { i, j + 1, k + 1}
+ } ;
+
+ int nIndex = 0 ;
+
+ bool CornerTF[8] = { false, false, false, false,
+ false, false, false, false,} ;
+
+ // Classificazione dei vertici: interni o esterni al materiale
+ if ( IsThereMat( i, j, k)) {
+ nIndex |= ( 1 << 0) ;
+ CornerTF[0] = true ;
+ }
+ if ( IsThereMat( i + 1, j, k)) {
+ nIndex |= ( 1 << 1) ;
+ CornerTF[1] = true ;
+ }
+ if ( IsThereMat( i + 1, j + 1, k)) {
+ nIndex |= ( 1 << 2) ;
+ CornerTF[2] = true ;
+ }
+ if ( IsThereMat( i, j + 1, k)) {
+ nIndex |= ( 1 << 3) ;
+ CornerTF[3] = true ;
+ }
+ if ( IsThereMat( i, j, k + 1)) {
+ nIndex |= ( 1 << 4) ;
+ CornerTF[4] = true ;
+ }
+ if ( IsThereMat( i + 1, j, k + 1)) {
+ nIndex |= ( 1 << 5) ;
+ CornerTF[5] = true ;
+ }
+ if ( IsThereMat( i + 1, j + 1, k + 1)) {
+ nIndex |= ( 1 << 6) ;
+ CornerTF[6] = true ;
+ }
+ if ( IsThereMat( i, j + 1, k + 1)) {
+ nIndex |= ( 1 << 7) ;
+ CornerTF[7] = true ;
+ }
+
+ // Se vi è qualche intersezione fra segmenti e superficie
+ // continuo altrimenti passo al prossimo voxel
+ if ( EdgeTable[nIndex] != 0) {
+
+ static int intersections[12][2] = {
+
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 },
+ { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }
+ } ;
+
+ Point3d ptIntPoint[12] ;
+
+ // Ciclo sui segmenti
+ for ( int i = 0 ; i < 12 ; ++ i) {
+ // Se il segmento non attraversa la superficie
+ // passo al successivo
+ if ( ! ( EdgeTable[nIndex] & ( 1 << i)))
+ continue ;
+
+ int n1 = intersections[i][0];
+ int n2 = intersections[i][1];
+
+ // Determino con precisione il punto di intersezione sullo spigolo
+ IntersPos( IndexCorner[n1], IndexCorner[n2], ptIntPoint[i]) ;
+ }
+
+ // Costruzione dei triangoli
+ for ( int i = 0 ; TriangleTable[nIndex][i] != - 1 ; ++ i) {
+
+ // Costruzione triangolo
+ int i0 = TriangleTable[nIndex][i] ;
+ int i1 = TriangleTable[nIndex][i+1] ;
+ int i2 = TriangleTable[nIndex][i+2] ;
+
+ Triangle3d CurrentTriangle ;
+
+ Vector3d vtV1 = ptIntPoint[i1] - ptIntPoint[i0] ;
+ Vector3d vtV2 = ptIntPoint[i2] - ptIntPoint[i0] ;
+ Vector3d vtN = vtV1 ^ vtV2 ;
+
+ vtN.Normalize() ;
+
+ int nCorner = intersections[i0][0] ;
+
+ Point3d ptCorner( IndexCorner[nCorner][0] * m_dStep,
+ IndexCorner[nCorner][1] * m_dStep,
+ IndexCorner[nCorner][2] * m_dStep) ;
+
+ Vector3d vtT = ptCorner - ptIntPoint[i0] ;
+
+ vtT.Normalize() ;
+
+ if ( CornerTF[nCorner]) {
+ if ( vtN * vtT < 0)
+ vtN = - vtN ;
+ }
+ else {
+ if ( vtN * vtT > 0)
+ vtN = - vtN ;
+ }*/
+
+ /*
+ oppure:
+ if( nIndex & ( 1 << nCorner)) {
+ if( vtN * vtT < 0)
+ }
+ else {
+ if ( vtN * vtT > 0)
+ vtN = - vtN ;
+ }
+ */ /*
+
+ CurrentTriangle.Set( ptIntPoint[i0], ptIntPoint[i1], ptIntPoint[i2], vtN) ;
+
+ // Aggiungo triangolo
+ lstTria.emplace_back( CurrentTriangle) ;
+ }
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IsThereMat( unsigned int nI, unsigned int nJ, unsigned int nK)
+{
+ double dZ[3] ;
+
+ dZ[0] = ( nI + 0.5) * m_dStep ;
+ dZ[1] = ( nK + 0.5) * m_dStep ;
+ dZ[2] = ( nJ + 0.5) * m_dStep ;
+
+ int nCount = 0 ;
+
+ for ( int nGrid = 0 ; nGrid < int ( m_nMapNum) ; ++ nGrid) {
+
+ unsigned int nGrI, nGrJ ;
+
+ if ( nGrid == 0) {
+ nGrI = nI ;
+ nGrJ = nJ ;
+ }
+ else if ( nGrid == 1) {
+ nGrI = nJ ;
+ nGrJ = nK ;
+ }
+ else {
+ nGrI = nK ;
+ nGrJ = nI ;
+ }
+
+ unsigned int nPos = nGrJ * m_nVNx[nGrid] + nGrI ;
+ unsigned int nDexSize = m_TriZValues[nGrid][nPos].size() ;
+ unsigned int nIndex = 0 ;
+
+ while ( nIndex < nDexSize) {
+
+ if ( dZ[nGrid] > m_TriZValues[nGrid][nPos][nIndex] + EPS_SMALL ||
+ dZ[nGrid] < m_TriZValues[nGrid][nPos][nIndex + 1] - EPS_SMALL) {
+
+ ++ nCount ;
+ break ;
+ }
+ ++ nIndex ;
+ }
+ }
+
+ if ( nCount > 1)
+ return true ;
+ return false ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d & ptInt) {
+
+ if ( nVec1[0] != nVec2[0]) {
+
+ int nMinI = min( nVec1[0], nVec2[0]) ;
+ int nMaxI = max( nVec1[0], nVec2[0]) ;
+
+ double dMinX = nMinI * m_dStep ;
+ double dMaxX = nMaxI * m_dStep ;
+
+ unsigned int nDexel = nVec1[2] * m_nVNx[1] + nVec1[1] ;
+ unsigned int nSize = m_TriZValues[1][nDexel].size() ;
+
+ ptInt.y = nVec1[1] * m_dStep ;
+ ptInt.z = nVec1[2] * m_dStep ;
+
+ for ( unsigned int i = 0 ; i < nSize ; i += 2) {
+
+ double dx1 = m_TriZValues[1][nDexel][i] ;
+ double dx2 = m_TriZValues[1][nDexel][i+1] ;
+
+ if ( dx1 < dMinX && dx2 > dMinX && dx2 < dMaxX) {
+
+ ptInt.x = dx2 ;
+ break ;
+ }
+ else if ( dx1 > dMinX && dx1 < dMaxX && dx2 > dMaxX) {
+
+ ptInt.x = dx1 ;
+ break ;
+ }
+ }
+ }
+ else if ( nVec1[1] != nVec2[1]) {
+
+ int nMinJ = min( nVec1[1], nVec2[1]) ;
+ int nMaxJ = max( nVec1[1], nVec2[1]) ;
+
+ double dMinY = nMinJ * m_dStep ;
+ double dMaxY = nMaxJ * m_dStep ;
+
+ unsigned int nDexel = nVec1[2] * m_nVNx[2] + nVec1[0] ;
+ unsigned int nSize = m_TriZValues[2][nDexel].size() ;
+
+ ptInt.x = nVec1[0] * m_dStep ;
+ ptInt.z = nVec1[2] * m_dStep ;
+
+ for ( unsigned int j = 0 ; j < nSize ; j += 2) {
+
+ double dy1 = m_TriZValues[2][nDexel][j] ;
+ double dy2 = m_TriZValues[2][nDexel][j+1] ;
+
+ if ( dy1 < dMinY && dy2 > dMinY && dy2 < dMaxY) {
+
+ ptInt.y = dy2 ;
+ break ;
+ }
+ else if ( dy1 > dMinY && dy1 < dMaxY && dy2 > dMaxY) {
+
+ ptInt.y = dy1 ;
+ break ;
+ }
+ }
+ }
+ else if ( nVec1[2] != nVec2[2]) {
+
+ int nMinK = min( nVec1[2], nVec2[2]) ;
+ int nMaxK = max( nVec1[2], nVec2[2]) ;
+
+ double dMinZ = nMinK * m_dStep ;
+ double dMaxZ = nMaxK * m_dStep ;
+
+ unsigned int nDexel = nVec1[1] * m_nVNx[0] + nVec1[0] ;
+ unsigned int nSize = m_TriZValues[0][nDexel].size() ;
+
+ ptInt.x = nVec1[0] * m_dStep ;
+ ptInt.y = nVec1[1] * m_dStep ;
+
+ for ( unsigned int k = 0 ; k < nSize ; k += 2) {
+
+ double dz1 = m_TriZValues[0][nDexel][k] ;
+ double dz2 = m_TriZValues[0][nDexel][k+1] ;
+
+ if ( dz1 < dMinZ && dz2 > dMinZ && dz2 < dMaxZ) {
+
+ ptInt.z = dz2 ;
+ break ;
+ }
+ else if ( dz1 > dMinZ && dz1 < dMaxZ && dz2 > dMaxZ) {
+
+ ptInt.z = dz1 ;
+ break ;
+ }
+ }
+ }
+ return true ;
+} */
+
+// Prova
+
+bool function( const Vector3d & vtV)
+{
+ if ( 100 - vtV * vtV < 0)
+ return true ;
+ return false ;
+}
+
+bool midpoint( int nVec1[], int nVec2[], Point3d & ptInt, double dStep)
+{
+ Point3d pt1( ( nVec1[0] + 0.5) * dStep,
+ ( nVec1[1] + 0.5) * dStep,
+ ( nVec1[2] + 0.5) * dStep) ;
+
+ Point3d pt2( ( nVec2[0] + 0.5) * dStep,
+ ( nVec2[1] + 0.5) * dStep,
+ ( nVec2[2] + 0.5) * dStep) ;
+
+
+ ptInt = pt1 + 0.5 * ( pt2 - pt1) ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::MarchingCubes( TRIA3DLIST& lstTria) const
+{
+
+ Point3d ptMapOrig = m_MapFrame[0].Orig() ;
+
+ int nLimI = int( m_nVNx[0]) ;
+ int nLimJ = int( m_nVNy[0]) ;
+ int nLimK = int( m_nVNy[1]) ;
+
+
+ // Ciclo su tutti i voxel dello Zmap
+ for ( int i = - 1 ; i < nLimI ; ++ i) {
+ for ( int j = - 1 ; j < nLimJ ; ++ j) {
+ for ( int k = - 1 ; k < nLimK ; ++ k) {
+
+ if ( i == 0 && j == 6 && k == 8) {
+
+ double bau = 1 ;
+ }
+
+ // Indici i,j,k dei vertici
+ int IndexCorner[8][3] = {
+
+ { i, j, k},
+ { i + 1, j, k},
+ { i + 1, j + 1, k},
+ { i, j + 1, k},
+ { i, j, k + 1},
+ { i + 1, j, k + 1},
+ { i + 1, j + 1, k + 1},
+ { i, j + 1, k + 1}
+ } ;
+
+
+ int nIndex = 0 ;
+
+ // Classificazione dei vertici: interni o esterni al materiale
+ if ( IsThereMat( i, j, k))
+ nIndex |= ( 1 << 0) ;
+
+ if ( IsThereMat( i + 1, j, k))
+ nIndex |= ( 1 << 1) ;
+
+ if ( IsThereMat( i + 1, j + 1, k))
+ nIndex |= ( 1 << 2) ;
+
+ if ( IsThereMat( i, j + 1, k))
+ nIndex |= ( 1 << 3) ;
+
+ if ( IsThereMat( i, j, k + 1))
+ nIndex |= ( 1 << 4) ;
+
+ if ( IsThereMat( i + 1, j, k + 1))
+ nIndex |= ( 1 << 5) ;
+
+ if ( IsThereMat( i + 1, j + 1, k + 1))
+ nIndex |= ( 1 << 6) ;
+
+ if ( IsThereMat( i, j + 1, k + 1))
+ nIndex |= ( 1 << 7) ;
+
+
+ // Se vi è qualche intersezione fra segmenti e superficie
+ // continuo altrimenti passo al prossimo voxel
+ if ( EdgeTable[nIndex] == 0)
+ continue ;
+
+ static int intersections[12][2] = {
+
+ { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 },
+ { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 }
+ } ;
+
+ Point3d ptIntPoint[12] ;
+
+ // Ciclo sui segmenti
+ for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) {
+ // Se il segmento non attraversa la superficie
+ // passo al successivo
+ if ( ! ( EdgeTable[nIndex] & ( 1 << EdgeIndex)))
+ continue ;
+
+ int n1 = intersections[EdgeIndex][0] ;
+ int n2 = intersections[EdgeIndex][1] ;
+
+ // Determino con precisione il punto di intersezione sullo spigolo
+ IntersPos( IndexCorner[n1], IndexCorner[n2], ptIntPoint[EdgeIndex]) ;
+ // midpoint( IndexCorner[n1], IndexCorner[n2], ptIntPoint[EdgeIndex], m_dStep) ;
+
+ ptIntPoint[EdgeIndex] = ptIntPoint[EdgeIndex] ;
+
+ ptIntPoint[EdgeIndex].ToGlob( m_MapFrame[0]) ;
+ }
+
+ // Costruzione dei triangoli
+ for ( int TriIndex = 0 ; TriangleTable[nIndex][TriIndex] != - 1 ; TriIndex += 3) {
+
+ // Costruzione triangolo
+ int i0 = TriangleTable[nIndex][TriIndex + 2] ;
+ int i1 = TriangleTable[nIndex][TriIndex + 1] ;
+ int i2 = TriangleTable[nIndex][TriIndex] ;
+
+ Triangle3d CurrentTriangle ;
+
+ Vector3d vtN = ( ptIntPoint[i1] - ptIntPoint[i0]) ^ ( ptIntPoint[i2] - ptIntPoint[i1]) ;
+
+ vtN.Normalize() ;
+
+ vtN.ToGlob( m_MapFrame[0]) ;
+
+ // Il triangolo è pronto
+ CurrentTriangle.Set( ptIntPoint[i0], ptIntPoint[i1], ptIntPoint[i2], vtN) ;
+
+ // Aggiungo triangolo
+ lstTria.emplace_back( CurrentTriangle) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IsThereMat( int nI, int nJ, int nK) const
+{
+
+ if ( nI == - 1 || nI == m_nVNx[0] ||
+ nJ == - 1 || nJ == m_nVNy[0] ||
+ nK == - 1 || nK == m_nVNy[1])
+
+ return false ;
+
+ double dZ[3] ;
+
+ dZ[0] = ( nK + 0.5) * m_dStep ;
+ dZ[1] = ( nI + 0.5) * m_dStep ;
+ dZ[2] = ( nJ + 0.5) * m_dStep ;
+
+ int nCount = 0 ;
+
+ for ( int nGrid = 0 ; nGrid < int ( m_nMapNum) ; ++ nGrid) {
+
+ unsigned int nGrI, nGrJ ;
+
+ if ( nGrid == 0) {
+ nGrI = nI ;
+ nGrJ = nJ ;
+ }
+ else if ( nGrid == 1) {
+ nGrI = nJ ;
+ nGrJ = nK ;
+ }
+ else {
+ nGrI = nK ;
+ nGrJ = nI ;
+ }
+
+ unsigned int nPos = nGrJ * m_nVNx[nGrid] + nGrI ;
+ size_t nDexSize = m_TriZValues[nGrid][nPos].size() ;
+ unsigned int nIndex = 0 ;
+
+ while ( nIndex < nDexSize) {
+
+ if ( dZ[nGrid] > m_TriZValues[nGrid][nPos][nIndex] &&
+ dZ[nGrid] < m_TriZValues[nGrid][nPos][nIndex + 1]) {
+
+ ++ nCount ;
+ break ;
+ }
+ nIndex += 2 ;
+ }
+ }
+ //if ( nCount > 0)
+ if ( nCount == 3)
+ return true ;
+ return false ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IsThereMat( const int nMatr[][3], int nNum, double & dHx, double & dHy, double & dHz) const
+{
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d & ptInt) const
+{
+
+ if ( nVec1[0] != nVec2[0]) {
+
+ int nMinI = min( nVec1[0], nVec2[0]) ;
+ int nMaxI = max( nVec1[0], nVec2[0]) ;
+
+ double dMinX = ( nMinI + 0.5) * m_dStep ;
+ double dMaxX = ( nMaxI + 0.5) * m_dStep ;
+
+ unsigned int nDexel = nVec1[2] * m_nVNx[1] + nVec1[1] ;
+ size_t nSize = m_TriZValues[1][nDexel].size() ;
+
+ ptInt.y = ( nVec1[1] + 0.5) * m_dStep ;
+ ptInt.z = ( nVec1[2] + 0.5) * m_dStep ;
+
+ unsigned int i ;
+
+ for ( i = 0 ; i < nSize ; i += 2) {
+
+ double dx1 = m_TriZValues[1][nDexel][i] ;
+ double dx2 = m_TriZValues[1][nDexel][i+1] ;
+
+ if ( dx1 <= dMinX && dx2 >= dMinX && dx2 <= dMaxX) {
+
+ ptInt.x = dx2 ;
+ break ;
+ }
+ else if ( dx1 >= dMinX && dx1 <= dMaxX && dx2 >= dMaxX) {
+
+ ptInt.x = dx1 ;
+ break ;
+ }
+ }
+
+ if ( i == nSize)
+ ptInt.x = 0.5 * ( dMinX + dMaxX) ;
+ }
+ else if ( nVec1[1] != nVec2[1]) {
+
+ int nMinJ = min( nVec1[1], nVec2[1]) ;
+ int nMaxJ = max( nVec1[1], nVec2[1]) ;
+
+ double dMinY = ( nMinJ + 0.5) * m_dStep ;
+ double dMaxY = ( nMaxJ + 0.5) * m_dStep ;
+ // 2 0
+ unsigned int nDexel = nVec1[0] * m_nVNx[2] + nVec1[2] ;
+ size_t nSize = m_TriZValues[2][nDexel].size() ;
+
+ ptInt.x = ( nVec1[0] + 0.5) * m_dStep ;
+ ptInt.z = ( nVec1[2] + 0.5) * m_dStep ;
+
+ unsigned int j ;
+
+ for ( j = 0 ; j < nSize ; j += 2) {
+
+ double dy1 = m_TriZValues[2][nDexel][j] ;
+ double dy2 = m_TriZValues[2][nDexel][j+1] ;
+
+ if ( dy1 <= dMinY && dy2 >= dMinY && dy2 <= dMaxY) {
+
+ ptInt.y = dy2 ;
+ break ;
+ }
+ else if ( dy1 >= dMinY && dy1 <= dMaxY && dy2 >= dMaxY) {
+
+ ptInt.y = dy1 ;
+ break ;
+ }
+ }
+
+ if ( j == nSize)
+ ptInt.y = 0.5 * ( dMinY + dMaxY) ;
+ }
+ else if ( nVec1[2] != nVec2[2]) {
+
+ int nMinK = min( nVec1[2], nVec2[2]) ;
+ int nMaxK = max( nVec1[2], nVec2[2]) ;
+
+ double dMinZ = ( nMinK + 0.5) * m_dStep ;
+ double dMaxZ = ( nMaxK + 0.5) * m_dStep ;
+
+ unsigned int nDexel = nVec1[1] * m_nVNx[0] + nVec1[0] ;
+ size_t nSize = m_TriZValues[0][nDexel].size() ;
+
+ ptInt.x = ( nVec1[0] + 0.5) * m_dStep ;
+ ptInt.y = ( nVec1[1] + 0.5) * m_dStep ;
+
+ unsigned int k ;
+
+ for ( k = 0 ; k < nSize ; k += 2) {
+
+ double dz1 = m_TriZValues[0][nDexel][k] ;
+ double dz2 = m_TriZValues[0][nDexel][k+1] ;
+
+ if ( dz1 <= dMinZ && dz2 >= dMinZ && dz2 <= dMaxZ) {
+
+ ptInt.z = dz2 ;
+ break ;
+ }
+ else if ( dz1 >= dMinZ && dz1 <= dMaxZ && dz2 >= dMaxZ) {
+
+ ptInt.z = dz1 ;
+ break ;
+ }
+ }
+
+ if ( k == nSize)
+ ptInt.z = 0.5 * ( dMinZ + dMaxZ) ;
+ }
+ return true ;
+}
+
+/*
+ Point3d ptProva[8] ;
+ Vector3d vtProva[8] ;
+
+ ptProva[0].x = ( i + 0.5) * m_dStep ;
+ ptProva[0].y = ( j + 0.5) * m_dStep ;
+ ptProva[0].z = ( k + 0.5) * m_dStep ;
+ ptProva[1].x = ( i + 1.5) * m_dStep ;
+ ptProva[1].y = ( j + 0.5) * m_dStep ;
+ ptProva[1].z = ( k + 0.5) * m_dStep ;
+ ptProva[2].x = ( i + 1.5) * m_dStep ;
+ ptProva[2].y = ( j + 1.5) * m_dStep ;
+ ptProva[2].z = ( k + 0.5) * m_dStep ;
+ ptProva[3].x = ( i + 0.5) * m_dStep ;
+ ptProva[3].y = ( j + 1.5) * m_dStep ;
+ ptProva[3].z = ( k + 0.5) * m_dStep ;
+ ptProva[4].x = ( i + 0.5) * m_dStep ;
+ ptProva[4].y = ( j + 0.5) * m_dStep ;
+ ptProva[4].z = ( k + 1.5) * m_dStep ;
+ ptProva[5].x = ( i + 1.5) * m_dStep ;
+ ptProva[5].y = ( j + 0.5) * m_dStep ;
+ ptProva[5].z = ( k + 1.5) * m_dStep ;
+ ptProva[6].x = ( i + 1.5) * m_dStep ;
+ ptProva[6].y = ( j + 1.5) * m_dStep ;
+ ptProva[6].z = ( k + 1.5) * m_dStep ;
+ ptProva[7].x = ( i + 0.5) * m_dStep ;
+ ptProva[7].y = ( j + 1.5) * m_dStep ;
+ ptProva[7].z = ( k + 1.5) * m_dStep ;
+
+ Point3d ptC( 10, 10, 10) ;
+
+ for ( int boh = 0 ; boh < 8 ; ++ boh)
+
+ vtProva[boh] = ptProva[boh] - ptC ; */
+
+/*
+ if ( function( vtProva[0]))
+ nIndex |= ( 1 << 0) ;
+
+ if ( function( vtProva[1]))
+ nIndex |= ( 1 << 1) ;
+
+ if ( function( vtProva[2]))
+ nIndex |= ( 1 << 2) ;
+
+ if ( function( vtProva[3]))
+ nIndex |= ( 1 << 3) ;
+
+ if ( function( vtProva[4]))
+ nIndex |= ( 1 << 4) ;
+
+ if ( function( vtProva[5]))
+ nIndex |= ( 1 << 5) ;
+
+ if ( function( vtProva[6]))
+ nIndex |= ( 1 << 6) ;
+
+ if ( function( vtProva[7]))
+ nIndex |= ( 1 << 7) ; */
+
+/*
+ Vector3d vtV1 = ptIntPoint[i1] - ptIntPoint[i0] ;
+ Vector3d vtV2 = ptIntPoint[i2] - ptIntPoint[i0] ;
+ Vector3d vtN = vtV1 ^ vtV2 ;
+
+ vtN.Normalize() ;
+
+ int nCorner = intersections[i0][0] ;
+
+ Point3d ptCorner( IndexCorner[nCorner][0] * m_dStep,
+ IndexCorner[nCorner][1] * m_dStep,
+ IndexCorner[nCorner][2] * m_dStep) ;
+
+ Vector3d vtT = ptCorner - ptIntPoint[i0] ;
+
+ vtT.Normalize() ;
+
+
+ if( nIndex & ( 1 << nCorner)) {
+ if( vtN * vtT < 0)
+ vtN = - vtN ;
+ }
+ else {
+ if ( vtN * vtT > 0)
+ vtN = - vtN ;
+ }*/
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VolTriZmapVolume.cpp b/VolTriZmapVolume.cpp
new file mode 100644
index 0000000..24bd458
--- /dev/null
+++ b/VolTriZmapVolume.cpp
@@ -0,0 +1,6204 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2016
+//----------------------------------------------------------------------------
+// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4
+// Contenuto : Implementazione della classe Volume Zmap (tre griglie)
+//
+//
+//
+// 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 ;
+
+
+
+
+
+// ------------------------- OPERAZIONI SU INTERVALLI --------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::SubtractIntervals( unsigned int nGrid, 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 il numero di griglia sia entro i limiti
+ if ( nGrid < 0 || nGrid > 2)
+ return false ;
+
+ // Controllo che dMin < dMax
+ if ( dMin > dMax)
+ swap( dMin, dMax) ;
+
+ // Controllo che indici nI, nJ siano entro i limiti
+ if ( nI < 0 && nI >= m_nVNx[nGrid] &&
+ nJ < 0 && nJ >= m_nVNy[nGrid])
+ return false ;
+
+ // Calcolo nPos
+ unsigned int nPos = nJ * m_nVNx[nGrid] + nI ; // O nJ*m_Nx + nI + 1 ?
+
+ /* Non serve: se size == 0 non entra nel ciclo
+ // Se il dexel è vuoto non succede niente
+ if ( m_TriZValues[nGrid][nPos].size() == 0)
+ return true ; */
+
+ // Ciclo sugli intervalli del singolo dexel
+ bool bModified = false ;
+ unsigned int i = 0 ;
+
+ while ( i + 1 < m_TriZValues[nGrid][nPos].size()) {
+
+ // Casi:
+ // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione
+ if ( m_TriZValues[nGrid][nPos][i] > dMax - EPS_SMALL) {
+ ;
+ }
+ // Intersezione
+ else if ( m_TriZValues[nGrid][nPos][i + 1] > dMax + EPS_SMALL) {
+ // L'intervallo corrente corrente viene limitato a sinistra
+ if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) {
+ bModified = true ;
+ m_TriZValues[nGrid][nPos][i] = dMax ;
+ }
+ // L'intervallo si divide in due intervalli
+ else {
+ bModified = true ;
+ m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ;
+
+ for ( size_t j = m_TriZValues[nGrid][nPos].size() - 1 ; j >= i + 3 ; -- j)
+
+ m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j - 2] ;
+
+ m_TriZValues[nGrid][nPos][i + 1] = dMin ;
+ m_TriZValues[nGrid][nPos][i + 2] = dMax ;
+
+ i = i + 2 ;
+ }
+ }
+ else {
+ // L'intervallo corrente viene eliminato
+ if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) {
+ bModified = true ;
+ for ( unsigned int j = i ; j < m_TriZValues[nGrid][nPos].size() - 2 ; ++ j)
+
+ m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j + 2] ;
+
+ m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() - 2) ;
+
+ i = i - 2 ;
+ }
+ // L'intervallo corrente viene limitato a destra
+ else if ( m_TriZValues[nGrid][nPos][i + 1] > dMin + EPS_SMALL) {
+ bModified = true ;
+ m_TriZValues[nGrid][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( unsigned int nGrid, const Point3d & ptP, double dMin, double dMax)
+{
+ // Controllo che il numero di griglia sia entro i limiti.
+ if ( nGrid < 0 || nGrid > 2)
+ return false ;
+
+ // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame)
+ Point3d ptPL = ptP ;
+ ptPL.ToLoc( m_MapFrame[nGrid]) ;
+
+ 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 che gli indici ottenuti siano nella griglia:
+ // se sono dentro la griglia chiamo l'altra subtract
+ if ( i >= 0 && i < m_nVNx[nGrid] &&
+ j >= 0 && j < m_nVNy[nGrid])
+
+ return SubtractIntervals( nGrid, i, j, dhMin, dhMax) ;
+ // altrimenti non succede niente
+ else
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::AddIntervals( unsigned int nGrid, 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 il numero di griglia sia entro i limiti
+ if ( nGrid < 0 || nGrid > 2)
+ return false ;
+
+ // Controllo che indici nI, nJ siano entro i limiti
+ if ( nI < 0 && nI >= m_nVNx[nGrid] &&
+ nJ < 0 && nJ >= m_nVNy[nGrid])
+ return false ;
+
+ // Calcolo nPos
+ unsigned int nPos = nJ * m_nVNx[nGrid] + nI ;
+
+ // Controllo che dMin < dMax
+ swap( dMin, dMax) ;
+
+ // Se spillone vuoto
+ if ( m_TriZValues[nGrid][nPos].size() == 0) {
+
+ m_TriZValues[nGrid][nPos].resize( 2) ;
+
+ m_TriZValues[nGrid][nPos][0] = dMin ;
+ m_TriZValues[nGrid][nPos][1] = dMax ;
+
+ if ( dMax > m_dVMaxZ[nGrid])
+ m_dVMinZ[nGrid] = dMax ;
+
+ if ( dMin < m_dVMinZ[nGrid])
+ m_dVMinZ[nGrid] = dMin ;
+
+ m_OGrMgr.Reset() ;
+
+ return true ;
+ }
+
+ // Ciclo sugli intervalli dello spillone
+ bool bModified = false ;
+ unsigned int i = 0 ;
+ while ( i + 1 < m_TriZValues[nGrid][nPos].size()) {
+
+ // Eventuale aggiustamento di intervalli sovrapposti
+ if ( i > 0) {
+ if ( m_TriZValues[nGrid][nPos][i] < m_TriZValues[nGrid][nPos][i - 1] + EPS_SMALL) {
+ // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva
+ if ( m_TriZValues[nGrid][nPos][i - 1] < m_TriZValues[nGrid][nPos][i + 1] + EPS_SMALL)
+
+ m_TriZValues[nGrid][nPos][i - 1] = m_TriZValues[nGrid][nPos][i + 1] ;
+
+ for ( unsigned int j = i ; j < m_TriZValues[nGrid][nPos].size() - 2 ; ++ j)
+ m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j + 2] ;
+
+ m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() - 2) ;
+
+ i = i - 2 ;
+ }
+ }
+
+ // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente
+ if ( m_TriZValues[nGrid][nPos][i] > dMax + EPS_SMALL) {
+ bModified = true ;
+
+ m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ;
+
+ for ( size_t j = m_TriZValues[nGrid][nPos].size() - 1 ; j >= i + 2 ; -- j)
+ m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j - 2] ;
+
+ m_TriZValues[nGrid][nPos][i] = dMin ;
+ m_TriZValues[nGrid][nPos][i + 1] = dMax ;
+
+ i = i + 2 ;
+ }
+
+ // Casi d'intersezione:
+ else if ( m_TriZValues[nGrid][nPos][i + 1] > dMax - EPS_SMALL) {
+ // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente
+ if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) {
+ bModified = true ;
+ m_TriZValues[nGrid][nPos][i] = dMin ;
+ }
+ }
+
+ else {
+ // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi
+ if ( m_TriZValues[nGrid][nPos][i] > dMin + EPS_SMALL) {
+ bModified = true ;
+ m_TriZValues[nGrid][nPos][i] = dMin ;
+ m_TriZValues[nGrid][nPos][i + 1] = dMax ;
+ }
+ // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente
+ else if ( m_TriZValues[nGrid][nPos][i + 1] > dMin - EPS_SMALL) {
+ bModified = true ;
+ m_TriZValues[nGrid][nPos][i + 1] = dMax ;
+ }
+ else {
+ // Aggiungo intervallo a destra dell'ultimo intervallo
+ if ( i == m_TriZValues[nGrid][nPos].size() - 2) {
+ bModified = true ;
+ m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ;
+
+ m_TriZValues[nGrid][nPos][i + 2] = dMin ;
+ m_TriZValues[nGrid][nPos][i + 3] = dMax ;
+
+ i = i + 2 ;
+ }
+ }
+ }
+
+ i = i + 2 ;
+ }
+
+ // se eseguita modifica, imposto ricalcolo della grafica
+ if ( bModified) {
+
+ m_OGrMgr.Reset() ;
+
+ if ( dMax > m_dVMaxZ[nGrid])
+ m_dVMinZ[nGrid] = dMax ;
+
+ if ( dMin < m_dVMinZ[nGrid])
+ m_dVMinZ[nGrid] = dMin ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::AddIntervals( unsigned int nGrid, const Point3d & ptP, double dMin, double dMax)
+{
+ // Controllo che il numero di griglia sia entro i limiti.
+ if ( nGrid < 0 || nGrid > 2)
+ return false ;
+
+ // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame)
+ Point3d ptPL = ptP ;
+ ptPL.ToLoc( m_MapFrame[nGrid]) ;
+
+ 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 che gli indici ottenuti siano nella griglia:
+ // se sono dentro la griglia chiamo l'altra add
+ if ( i >= 0 && i < m_nVNx[nGrid] &&
+ j >= 0 && j < m_nVNy[nGrid])
+
+ return AddIntervals( nGrid, i, j, dhMin, dhMax) ;
+ else
+ // altrimenti non succede niente
+ return false ;
+}
+
+// ------------------------- LAVORAZIONI --------------------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe)
+{
+
+ // Controllo sull'effettiva esisenza del movimento
+ if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe))
+ return true ;
+
+ // Punti nei sistemi di riferimento intrinseci dello Zmap
+ Point3d ptLs[3] ;
+ Point3d ptLe[3] ;
+
+ ptLs[0] = ptPs ;
+ ptLs[0].ToLoc( m_MapFrame[0]) ;
+
+ ptLe[0] = ptPe ;
+ ptLe[0].ToLoc( m_MapFrame[0]) ;
+
+ if ( m_nMapNum > 1) {
+
+ ptLs[1].x = ptLs[0].y ; ptLs[1].y = ptLs[0].z ; ptLs[1].z = ptLs[0].x ;
+ ptLs[2].x = ptLs[0].z ; ptLs[2].y = ptLs[0].x ; ptLs[2].z = ptLs[0].y ;
+
+ ptLe[1].x = ptLe[0].y ; ptLe[1].y = ptLe[0].z ; ptLe[1].z = ptLe[0].x ;
+ ptLe[2].x = ptLe[0].z ; ptLe[2].y = ptLe[0].x ; ptLe[2].z = ptLe[0].y ;
+ }
+ else {
+
+ ptLs[1].x = 0 ; ptLs[1].y = 0 ; ptLs[1].z = 0 ;
+ ptLs[2].x = 0 ; ptLs[2].y = 0 ; ptLs[2].z = 0 ;
+
+ ptLe[1].x = 0 ; ptLe[1].y = 0 ; ptLe[1].z = 0 ;
+ ptLe[2].x = 0 ; ptLe[2].y = 0 ; ptLe[2].z = 0 ;
+ }
+
+
+ // Vettori nei sistemi di riferimento intrinseci dello Zmap
+ Vector3d vtLs [3] ;
+ Vector3d vtLe [3] ;
+
+ vtLs[0] = vtDs ;
+ vtLs[0].ToLoc( m_MapFrame[0]) ;
+
+ vtLe[0] = vtDe ;
+ vtLe[0].ToLoc( m_MapFrame[0]) ;
+
+ if ( m_nMapNum > 1) {
+
+ vtLs[1].x = vtLs[0].y ; vtLs[1].y = vtLs[0].z ; vtLs[1].z = vtLs[0].x ;
+ vtLs[2].x = vtLs[0].z ; vtLs[2].y = vtLs[0].x ; vtLs[2].z = vtLs[0].y ;
+
+ vtLe[1].x = vtLe[0].y ; vtLe[1].y = vtLe[0].z ; vtLe[1].z = vtLe[0].x ;
+ vtLe[2].x = vtLe[0].z ; vtLe[2].y = vtLe[0].x ; vtLe[2].z = vtLe[0].y ;
+ }
+ else {
+
+ vtLs[1].x = 0 ; vtLs[1].y = 0 ; vtLs[1].z = 0 ;
+ vtLs[2].x = 0 ; vtLs[2].y = 0 ; vtLs[2].z = 0 ;
+
+ vtLe[1].x = 0 ; vtLe[1].y = 0 ; vtLe[1].z = 0 ;
+ vtLe[2].x = 0 ; vtLe[2].y = 0 ; vtLe[2].z = 0 ;
+ }
+
+
+ // Ciclo sulle mappe
+ for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) {
+ // Normalizzo i vettori
+ vtLs[i].Normalize() ;
+ vtLe[i].Normalize() ;
+
+ // Direzione utensile costante: pura traslazione
+ if ( AreSameVectorApprox( vtLs[i], vtLe[i])) {
+
+ // Proiezione dei vettori sulle rispettive griglie
+ Vector3d vtLsXY( vtLs[i].x, vtLs[i].y, 0) ;
+
+ // Versore utensile parallelo all'asse Z
+ if ( vtLsXY.SqLen() < EPS_SMALL * EPS_SMALL) {
+
+ Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ;
+
+ // Foratura
+ if ( vtMove.SqLenXY() < EPS_SMALL) {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica o sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa conica
+ else if ( m_nToolType == 4)
+ Conus_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ // Fresatura con vettore movimento perpendicolare all'utensile
+ else if ( abs( vtMove.z) < EPS_SMALL) {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica o sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa conica
+ else if ( m_nToolType == 4)
+ Conus_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ // Fresatura con vettore movimento generico rispetto all'utensile
+ else {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica o sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa conica
+ else
+ Conus_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ }
+ // Versore utensile nel piano
+ else if ( abs( vtLs[i].z) < EPS_SMALL) {
+
+ Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ;
+ Vector3d vtMLong = ( vtMove * vtLs[i]) * vtLs[i] ;
+ Vector3d vtMOrt = vtMove - vtMLong ;
+
+ double dSqLOrt = vtMOrt.SqLen() ;
+
+ // Foratura
+ if ( dSqLOrt < EPS_SMALL * EPS_SMALL) {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica o sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa conica
+ else
+ Conus_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ // Fresatura con vettore movimento perpendicolare all'utensile
+ else if ( 1 - dSqLOrt < EPS_SMALL * EPS_SMALL) {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica o sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa conica
+ else if ( m_nToolType == 4)
+ Conus_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ // Fresatura con vettore movimento generico rispetto all'utensile
+ else {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica o sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Altri utensili
+ else if ( m_nToolType == 4)
+ Conus_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ }
+ // Versore utensile con direzione generica
+ else {
+
+ Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ;
+ Vector3d vtMLong = ( vtMove * vtLs[i]) * vtLs[i] ;
+ Vector3d vtMOrt = vtMove - vtMLong ;
+
+ double dSqLOrt = vtMOrt.SqLen() ;
+
+ // Foratura
+ if ( dSqLOrt < EPS_SMALL * EPS_SMALL) {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica e sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ else if ( m_nToolType == 4)
+ Conus_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ else {
+ // Utensile generico
+ if ( m_nToolType == 0)
+ GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ // Fresa cilindrica e sferica
+ else if ( m_nToolType == 1 || m_nToolType == 2)
+ CylBall_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ else if ( m_nToolType == 4)
+ Conus_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ;
+ }
+ }
+ }
+ else ;
+ // Altri casi al momento non gestiti
+ // return false ;
+ }
+ return true ;
+}
+
+
+
+// ---------- VERSORE UTENSILE DERETTO COME Z --------------------------------
+
+
+// ---------- Cilindro e sfera -----------------------------------------------
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Proiezione dei punti sul piano
+ Point3d ptSxy( ptS.x, ptS.y, 0) ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dSqRad = m_dRadius * m_dRadius ;
+
+ // Punte del gambo
+ Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ;
+ Point3d ptTStemE = ptE - vtToolDir * dStemHeigth ;
+
+ // Quote estreme del gambo
+ double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ;
+ double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptE.z, ptTStemE.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 - ptSxy ;
+
+ double dSqLen = vtC.SqLen() ;
+
+ // Se il punto si trova dentro il cerchio taglio
+ if ( dSqLen < dSqRad)
+ // utensile cilindrico
+ if ( m_nToolType == CylindricalMill)
+ SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ;
+ // utensile sferico
+ else if ( m_nToolType == BallEndMill) {
+
+ double dH = sqrt( dSqRad - dSqLen) ;
+
+ if ( vtToolDir.z > 0)
+ SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ;
+ else
+ SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ;
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_ZPerp( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ //Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dSqRad = m_dRadius * m_dRadius ;
+
+ // Punte del gambo
+ Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ;
+ Point3d ptTStemE = ptE - vtToolDir * dStemHeigth ;
+
+ // Quote estreme del gambo
+ double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ;
+ double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptS.z, ptTStemS.z)) ;
+
+ // Vettore movimento e sua lunghezza
+ Vector3d vtMove = ptE - ptS ; double dLen = vtMove.LenXY() ;
+
+ // Definizione di un sistema di riferimento ad hoc
+ Point3d ptSxy( ptS.x, ptS.y, 0) ;
+ Vector3d vtV1 = vtMove ; vtV1.Normalize() ; // se |vtMove| < EPS è un buco con dz = 0
+ 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 vtC = ptC - ptSxy ;
+
+ double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ;
+
+ // Utensile cilindrico
+ if ( m_nToolType == CylindricalMill) {
+ // Se il punto cade nella zona di interesse taglio
+ if ( ( dP1 * dP1 + dP2 * dP2 < dSqRad) ||
+ ( ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2) < dSqRad ||
+ ( dP1 > 0 && dP1 < dLen && abs( dP2) < m_dRadius))
+
+ SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ;
+ }
+ // Utensile sferico
+ else if ( m_nToolType == BallEndMill) {
+
+ if ( dP1 < 0 && dP1 * dP1 + dP2 * dP2 < m_dRadius * m_dRadius) {
+
+ double dH = sqrt( dSqRad - dP1 * dP1 - dP2 * dP2) ;
+
+ if ( vtToolDir.z > 0)
+ SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ;
+ else
+ SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ;
+ }
+ else if ( dP1 > dLen && ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2 < dSqRad) {
+
+ double dH = sqrt( dSqRad - ( dP1 - dLen) * ( dP1 - dLen) - dP2 * dP2) ;
+
+ if ( vtToolDir.z > 0)
+ SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ;
+ else
+ SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ;
+ }
+ else if ( dP1 > - EPS_SMALL && dP1 < dLen + EPS_SMALL && abs( dP2) < m_dRadius) {
+
+ double dH = sqrt( dSqRad - dP2 * dP2) ;
+
+ if ( vtToolDir.z > 0)
+ SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ;
+ else
+ SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dSqRad = m_dRadius * m_dRadius ;
+
+ // Studio delle simmetrie
+ Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ;
+ Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ;
+ Point3d ptIT = ptI - vtToolDir * dStemHeigth ;
+ Point3d ptFT = ptF - vtToolDir * dStemHeigth ;
+ Point3d ptIxy( ptI.x, ptI.y, 0) ;
+
+ // Quote iniziali e finali massime e
+ // minime del gambo dell'utensile e DeltaZ
+ double dZMaxI = max( ptI.z, ptIT.z) ;
+ double dZMaxF = max( ptF.z, ptFT.z) ;
+ double dZMinI = dZMaxI - dStemHeigth ;
+ double dZMinF = dZMaxF - dStemHeigth ;
+ double dDeltaZ = dZMaxF - dZMaxI ;
+
+ // Vettori caratterizzanti il moto
+ Vector3d vtMove = ptF - ptI ;
+ Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ;
+ double dLen = vtMove.Len() ;
+ double dLenXY = vtMoveXY.LenXY() ;
+ vtMove.Normalize() ;
+
+ // Parametri per determinare l'ellisse proiettata
+ double dCos = vtToolDir * vtMove ;
+ double dSin = ( abs( dCos) < 1 ? 1 - dCos * dCos : 0) ;
+ double dSemiAxMin = m_dRadius * dCos ; // x1^2 = a^2 - (a / b)^2 x2^2 ; a = r dCos e b = r;
+ double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; // da cui si ottiene x1^2 = a^2 - dCos^2 x2^2
+ double dSqRatio = dSqSemiAxMin / dSqRad ;
+
+ // Definizione di un sistema di riferimento ad hoc
+ Vector3d vtV1, vtV2 ;
+
+ // Se la lunghezza è troppo piccola lo allungo
+ if ( dLenXY < EPS_SMALL)
+ vtV1 = ( 1 / dLenXY) * vtMoveXY ;
+ else
+ vtV1 = vtMoveXY ;
+
+ // Normalizzo vtV1
+ vtV1.Normalize() ;
+ // Definisco vtV2
+ vtV2 = vtV1 ;
+ vtV2.Rotate( Z_AX, 90) ;
+
+ double dMin, dMax ;
+
+ 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 dX1 = vtC * vtV1 ;
+ double dX2 = vtC * vtV2 ;
+
+ // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo
+ if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < m_dRadius) ||
+ ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad ||
+ dX1 * dX1 + dX2 * dX2 < dSqRad) {
+
+ if ( m_nToolType == CylindricalMill) {
+
+ double dX1_0 = sqrt( dSqRad - dX2 * dX2) ;
+ // Massimo
+ if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad)
+
+ dMax = dZMaxF ;
+ else
+ dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ;
+ // Minimo
+ if ( dX1 * dX1 + dX2 * dX2 < dSqRad)
+
+ dMin = dZMinI ;
+ else
+ dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( m_nToolType == BallEndMill) {
+
+ double dCylX1_0 = sqrt( dSqRad - dX2 * dX2) ;
+ double dSqRoot = sqrt( dSqRad - dX2 * dX2) ;
+ double dX1_0 = dCos * dSqRoot ;
+ double dH0 = dSin * dSqRoot ;
+
+ if ( vtToolDir.z > 0) {
+ // Massimo
+ if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad)
+
+ dMax = dZMaxF ;
+ else
+ dMax = dZMaxI + dDeltaZ * ( dX1 + dCylX1_0) / dLenXY ;
+
+ // Minimo
+ if ( dX1 < dX1_0)
+
+ dMin = dZMinI - sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ;
+
+ else if ( dX1 < dLenXY + dX1_0)
+
+ dMin = dZMinI - dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ;
+ else
+ dMin = dZMinF - sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ else {
+ // Massimo
+ if ( dX1 < - dX1_0)
+
+ dMax = dZMaxI + sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ;
+
+ else if ( dX1 < dLenXY - dX1_0)
+
+ dMax = dZMaxI + dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ;
+ else
+ dMax = dZMaxF + sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ;
+
+ // Minimo
+ if ( dX1 * dX1 + dX2 * dX2 < dSqRad)
+
+ dMin = dZMinI ;
+ else
+ dMin = dZMinI + dDeltaZ * ( dX2 - dCylX1_0) / dLenXY ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+
+// ---------- Coni -----------------------------------------------------------
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dMinRad = min( m_dRadius, m_dTipRadius) ;
+ double dMaxRad = max( m_dRadius, m_dTipRadius) ;
+ double dDeltaRad = dMaxRad - dMinRad ;
+ double dSqMinRad = dMinRad * dMinRad ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+ // Proiezione delle posizioni sul piano
+ Point3d ptO( ptS.x, ptS.y, 0) ;
+
+ // Quote massime e minime dell'utensile durante il moto
+ double dZMax = max( max( ptS.z, ptS.z - vtToolDir.z * m_dHeight), max( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ;
+ double dZMin = min( min( ptS.z, ptS.z - vtToolDir.z * m_dHeight), min( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ;
+
+ // Trapano
+ if ( m_dTipRadius < m_dRadius) {
+ // Ciclo sui punti
+ 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.SqLenXY() ;
+
+ if ( dSqDist < dSqMinRad)
+
+ SubtractIntervals( nGrid, i, j, dZMin, dZMax) ;
+
+ else if ( dSqDist < dSqMaxRad) {
+
+ double dr = sqrt( dSqDist) ;
+
+ if ( vtToolDir.z > 0)
+
+ SubtractIntervals( nGrid, i, j, dZMin + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax) ;
+ else
+ SubtractIntervals( nGrid, i, j, dZMin, dZMax - m_dTipHeight * ( dr - dMinRad) / dDeltaRad) ;
+ }
+ }
+ }
+ }
+ // Coda di rondine
+ else {
+ // Ciclo sui punti
+ 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.SqLenXY() ;
+
+ if ( dSqDist < dSqMinRad)
+
+ SubtractIntervals( nGrid, i, j, dZMin, dZMax) ;
+
+ else if ( dSqDist < dSqMaxRad) {
+
+ double dr = sqrt( dSqDist) ;
+
+ if ( vtToolDir.z > 0)
+
+ SubtractIntervals( nGrid, i, j, dZMin, dZMax - dStemHeigth - m_dTipHeight * ( dr - dMinRad) / dDeltaRad) ;
+ else
+ SubtractIntervals( nGrid, i, j, dZMin + dStemHeigth + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dMinRad = min( m_dRadius, m_dTipRadius) ;
+ double dMaxRad = max( m_dRadius, m_dTipRadius) ;
+ double dDeltaRad = dMaxRad - dMinRad ;
+ double dSqMinRad = dMinRad * dMinRad ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+ // Quote fondo, punta e fine gambo
+ double dBaseZ = ptS.z ;
+ double dTipZ = ptS.z - m_dHeight * vtToolDir.z ;
+ double dStemZ = ptS.z - dStemHeigth * vtToolDir.z ;
+ double dZ1 = ( m_dRadius > m_dTipRadius ? dBaseZ : dTipZ) ;
+ double dZ2 = ( m_dRadius > m_dTipRadius ? dTipZ : dStemZ) ;
+ double dZ3 = ( m_dRadius > m_dTipRadius ? dStemZ : dTipZ) ;
+
+
+ // Sistemi di riferimento sul piano
+ Point3d ptIxy( ptS.x, ptS.y, 0) ;
+ Point3d ptFxy( ptE.x, ptE.y, 0) ;
+ Vector3d vtV1 = ptFxy - ptIxy ;
+ double dLenXY = vtV1.LenXY() ;
+ vtV1.Normalize() ;
+ Vector3d vtV2 = vtV1 ;
+ vtV2.Rotate( Z_AX, 90) ;
+
+
+ // Ciclo sui punti
+ 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 dSqDistI = vtCI.SqLenXY() ;
+ double dSqDistF = vtCF.SqLenXY() ;
+
+ double dX1 = vtCI * vtV1 ;
+ double dX2 = vtCI * vtV2 ;
+
+
+ if ( dSqDistI < dSqMinRad || dSqDistF < dSqMinRad ||
+ ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dMinRad))
+
+ SubtractIntervals( nGrid, i, j, min( dBaseZ, dTipZ), max( dBaseZ, dTipZ)) ;
+
+ else if ( dSqDistI < dSqMaxRad && dX1 < 0) {
+
+ double dr = sqrt( dSqDistI) ;
+
+ SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad),
+ max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ;
+ }
+ else if ( dX1 <= dLenXY && abs( dX2) < dMaxRad) {
+
+ double dr = abs( dX2) ;
+
+ SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad),
+ max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ;
+ }
+ else if ( dSqDistF < dSqMaxRad) {
+
+ double dr = sqrt( dSqDistF) ;
+
+ SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad),
+ max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ;
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ if ( m_dTipRadius < m_dRadius)
+ Dr_ZMilling( nGrid, ptS, ptE, vtToolDir) ;
+ else
+ Sw_ZMilling( nGrid, ptS, ptE, vtToolDir) ;
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Dr_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza dell'utensile con lo Zmap
+ bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ 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) ;
+ }
+
+ // Raggio minimo e massimo
+ double dMaxRad = max( m_dRadius, m_dTipRadius) ;
+ double dMinRad = min( m_dRadius, m_dTipRadius) ;
+
+ // 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 ;
+
+
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Sw_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza dell'utensile con lo Zmap
+ bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ 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 dMaxRad = max( m_dRadius, m_dTipRadius) ;
+ double dMinRad = min( m_dRadius, m_dTipRadius) ;
+ 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 ;
+
+ // Ciclo sui punti
+ 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+
+ }
+ }
+ }
+ return true ;
+}
+
+// --------- Utensile generico ------------------------------------------------
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::GenTool_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ // Posizioni iniziale e finale dell'utensile
+ Point3d ptI = ptS ;
+ Point3d ptF = ptE ;
+
+ // vettore movimento
+ Vector3d vtMove = ptE - ptS ;
+
+ // Settaggio profilo
+ CurveComposite* pToolProfile ;
+ if ( m_ToolArcLineApprox.GetCurveCount() == 0)
+ // Se l'utensile non è stato approssimato uso l'originale
+ pToolProfile = &m_ToolOutline ;
+ else
+ // altrimenti usi l'approssimazione
+ pToolProfile = &m_ToolArcLineApprox ;
+
+ // Ciclo sulle curve
+ const ICurve* pCurve = pToolProfile->GetFirstCurve() ;
+ 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 ;
+
+ CompCyl_ZDrilling( nGrid, ptS, ptE, 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 ;
+
+ CompConus_ZDrilling( nGrid, ptS, ptE, 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 ;
+
+ CompConus_ZDrilling( nGrid, 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
+ CompBall_Milling( nGrid, 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 = pToolProfile->GetNextCurve() ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ // Posizioni iniziale e finale dell'utensile
+ Point3d ptI = ptS ;
+ Point3d ptF = ptE ;
+
+ // vettore movimento
+ Vector3d vtMove = ptE - ptS ;
+
+ // Settaggio profilo
+ CurveComposite* pToolProfile ;
+ if ( m_ToolArcLineApprox.GetCurveCount() == 0)
+ // Se l'utensile non è stato approssimato uso l'originale
+ pToolProfile = &m_ToolOutline ;
+ else
+ // altrimenti usi l'approssimazione
+ pToolProfile = &m_ToolArcLineApprox ;
+
+ // Ciclo sulle curve
+ const ICurve* pCurve = pToolProfile->GetFirstCurve() ;
+ 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 ;
+
+ CompCyl_ZMilling( nGrid, 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 ;
+
+ CompConus_ZMilling( nGrid, 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 ;
+
+ CompConus_ZMilling( nGrid, 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
+ CompBall_Milling( nGrid, 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 = pToolProfile->GetNextCurve() ;
+ }
+ return true ;
+
+}
+
+
+// ---------- VERSORE UTENSILE NEL PIANO XY ----------------------------------
+
+// --------- Cilindro e sfera ------------------------------------------------
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile e quota Z del movimento
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dSqRad = m_dRadius * m_dRadius ;
+ double dZ = ptS.z ;
+
+ // Vettore movimento e sua lunghezza
+ Vector3d vtMove = ptE - ptS ; double dLen = vtMove.LenXY() ;
+
+ // Definizione di un sistema di riferimento ad hoc
+ Point3d ptI = ( vtMove * vtToolDir > 0 ? ptE : ptS) ;
+ Point3d ptF = ( vtMove * vtToolDir > 0 ? ptS - dStemHeigth * vtToolDir : ptE - dStemHeigth * vtToolDir) ;
+ Point3d ptIxy( ptI.x, ptI.y, 0) ;
+ Point3d ptFxy( ptF.x, ptF.y, 0) ;
+
+ Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; 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 vtC = ptC - ptIxy ;
+
+ double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ;
+
+ Vector3d vtBall = ptC - ptFxy ; double dSqLen = vtBall.SqLenXY() ;
+
+ // Zona lavorata dalla parte cilindrica
+ if ( dP1 > 0 && dP1 < dStemHeigth + dLen &&
+ abs( dP2) < m_dRadius ) {
+
+ double dH = sqrt( dSqRad - dP2 * dP2) ;
+
+ SubtractIntervals( nGrid, i, j, dZ - dH , dZ + dH) ;
+ }
+
+ // Se l'utensile è sferico sottraggo anche la punta
+ if ( m_nToolType == BallEndMill)
+ if ( dSqLen < dSqRad) { // LA SOLUZIONE MOMENTANEA è CREARE UTENSILE GENERICO SE LO STELO è PIù CORTO DEL RAGGIO
+
+ double dH = sqrt( dSqRad - dSqLen) ;
+
+ SubtractIntervals( nGrid, i, j, dZ - dH, dZ + dH) ;
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dSqRad = m_dRadius * m_dRadius ;
+
+ // Studio simmetrie del problema
+ Point3d ptI = ( ptS.z <= ptE.z ? ptS : ptE) ;
+ Point3d ptF = ( ptS.z <= ptE.z ? ptE : ptS) ;
+ Point3d ptIxy( ptI.x, ptI.y, 0) ;
+
+ // Quote punti iniziale e finale
+ double dZI = ptI.z ;
+ double dZF = ptF.z ;
+ double dDeltaZ = ptF.z - ptI.z ;
+
+ // Vettori caratterizzanti il moto
+ Vector3d vtMove = ptF - ptI ;
+ double dLen = vtMove.Len() ;
+ Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ;
+ double dLenXY = vtMoveXY.LenXY() ;
+ vtMove.Normalize() ;
+
+ // Sistema di riferimento ad hoc
+ Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; vtV1.Normalize() ;
+ Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ;
+ if ( vtV2 * vtMove < 0)
+ vtV2 = - vtV2 ;
+
+ // Vettori e punti determinanti i piani
+ Vector3d vtP = vtMove ; // Se dLen < EPS_SMALL non si usa
+ vtP.Rotate( vtToolDir, 90) ;
+ Point3d ptUp = ptI + m_dRadius * ( vtP.z > 0 ? vtP : - vtP) ;
+ Point3d ptDw = ptI + m_dRadius * ( vtP.z > 0 ? - vtP : vtP) ;
+
+ Vector3d vtPXY( vtP.x, vtP.y, 0) ;
+
+ Vector3d vtUp = ptUp - ORIG ; double dDotUp = vtUp * vtP ;
+ Vector3d vtDw = ptDw - ORIG ; double dDotDw = vtDw * vtP ;
+
+ double dSmall = m_dRadius * vtPXY.LenXY() ;
+
+ // Parte sferica
+ double dCos = vtMove.z ; // vtMove.z > 0 : ptF.z >= ptI.z
+ double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ;
+ double dSemiAxMin = m_dRadius * dCos ;
+
+ double dInfZ, dSupZ ;
+
+
+ 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 ;
+
+ // Parte cilindrica
+ if ( dP1 > 0 && dP1 < dStemHeigth) {
+
+ if ( dP2 > - m_dRadius && dP2 < dLenXY + m_dRadius) {
+ // Massimi
+ if ( dP2 < - dSmall + EPS_SMALL) {
+ double dHsq = dSqRad - dP2 * dP2 ;
+ double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ;
+ dSupZ = dZI + dH ;
+ }
+ else if ( dP2 < dLenXY - dSmall - EPS_SMALL) {
+
+ dSupZ = ( dDotUp - dX * vtP.x - dY * vtP.y) / vtP.z ;
+ }
+ else {
+
+ double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ;
+ dSupZ = dZF + dH ;
+ }
+ // Minimi
+ if ( dP2 < dSmall + EPS_SMALL) {
+ double dHsq = dSqRad - dP2 * dP2 ;
+ double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ;
+ dInfZ = dZI - dH ;
+ }
+ else if ( dP2 < dLenXY + dSmall - EPS_SMALL) {
+
+ dInfZ = ( dDotDw - dX * vtP.x - dY * vtP.y) / vtP.z ;
+ }
+ else {
+
+ double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ;
+ dInfZ = dZF - dH ;
+ }
+
+ SubtractIntervals( nGrid, i, j, dInfZ, dSupZ) ;
+ }
+ }
+ // Se l'utensile è ball-end sottraggo la punta
+ if ( m_nToolType == BallEndMill) {
+
+ if ( ( ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSqRad ||
+ ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + ( dP2 - dLenXY) * ( dP2 - dLenXY) < dSqRad ||
+ ( dP2 > 0 && dP2 < dLenXY && dP1 < m_dHeight)) && ( dP1 >= dStemHeigth)) {
+
+ double dSqRoot = sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth)) ;
+ double dP2_0 = dCos * dSqRoot ;
+ double dH0 = dSin * dSqRoot ;
+
+ double dMin, dMax ;
+
+ // Massimo
+ if ( dP2 < - dP2_0)
+
+ dMax = dZI + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ;
+
+ else if ( dP2 < dLenXY - dP2_0)
+
+ dMax = dZI + dH0 + dDeltaZ * ( dP2 + dP2_0) / dLenXY ;
+ else
+ dMax = dZF + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ;
+
+ // Minimo
+ if ( dP2 < dP2_0)
+
+ dMin = dZI - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ;
+
+ else if ( dP2 < dLenXY + dP2_0)
+
+ dMin = dZI - dH0 + dDeltaZ * ( dP2 - dP2_0) / dLenXY ;
+ else
+ dMin = dZF - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ if ( m_nToolType == CylindricalMill)
+
+ return CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, m_dHeight, m_dRadius) ;
+
+ else if ( m_nToolType == BallEndMill) {
+
+ double dHei = m_dHeight - m_dTipHeight ;
+
+ CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dHei, m_dRadius) ;
+
+ CompBall_Milling( nGrid, ptS - dHei * vtToolDir, ptE - dHei * vtToolDir, m_dRadius) ;
+
+ return true ;
+ }
+ else
+ return false ;
+}
+
+
+// --------- Coni ------------------------------------------------------------
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dMinRad = min( m_dRadius, m_dTipRadius) ;
+ double dMaxRad = max( m_dRadius, m_dTipRadius) ;
+ double dDeltaRad = dMaxRad - dMinRad ;
+ double dSqMinRad = dMinRad * dMinRad ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+ // Geometria del moto
+ double dLenXY = ( ptE - ptS).LenXY() ;
+ Point3d ptI = ( vtToolDir * ( ptE - ptS) < 0 ? ptS : ptE) ;
+ double dMatStemLen = ( m_dRadius > m_dTipRadius ? dStemHeigth + dLenXY : dStemHeigth) ;
+ double dSqTipRad = m_dTipRadius * m_dTipRadius ;
+ double dSqRad = m_dRadius * m_dRadius ;
+
+ // Sistema di riferimento sul piano
+ Vector3d vtV1 = - vtToolDir ;
+ Vector3d vtV2 = vtV1 ;
+ vtV2.Rotate( Z_AX, 90) ;
+
+ // Proiezione di ptI sul piano
+ Point3d ptIxy( ptI.x, ptI.y, 0) ;
+
+
+ // Ciclo sui punti
+ 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 dX1 = vtC * vtV1 ;
+ double dX2 = vtC * vtV2 ;
+
+ double dr = m_dRadius + ( dX1 - dMatStemLen) * ( m_dTipRadius - m_dRadius) / m_dTipHeight ;
+
+ if ( dX1 > 0 && dX1 < dMatStemLen &&
+ abs( dX2) < m_dRadius) {
+
+ double dH = sqrt( dSqRad - dX2 * dX2) ;
+ SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ;
+ }
+ else if ( dX1 >= dMatStemLen &&
+ dX1 < dMatStemLen + m_dTipHeight &&
+ abs( dX2) < dr) {
+
+ double dH = sqrt( dr * dr - dX2 * dX2) ;
+ SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ;
+ }
+
+ if ( m_dTipRadius >= m_dRadius) {
+
+ if ( dX1 >= dMatStemLen + m_dTipHeight &&
+ dX1 < dMatStemLen + m_dTipHeight + dLenXY &&
+ abs( dX2) < dSqTipRad) {
+
+ double dH = sqrt( dSqTipRad - dX2 * dX2) ;
+ SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dMinRad = min( m_dRadius, m_dTipRadius) ;
+ double dMaxRad = max( m_dRadius, m_dTipRadius) ;
+ double dSqTipRad = m_dTipRadius * m_dTipRadius ;
+ double dSqRad = m_dRadius * m_dRadius ;
+ double dDeltaRad = dMaxRad - dMinRad ;
+ double dSqMinRad = dMinRad * dMinRad ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+ // Studio delle simmetrie
+ Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ;
+ Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ;
+
+ // Vettori caratterizzanti il moto
+ Vector3d vtMove = ptF - ptI ;
+ Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ;
+ double dLen = vtMove.Len() ;
+ double dLenXY = vtMoveXY.LenXY() ;
+
+ // Quote iniziale e finale
+ double dZI = ptI.z ;
+ double dZF = ptF.z ;
+
+ // Sistema di riferimento sul piano
+ Point3d ptIxy( ptI.x, ptI.y, 0) ;
+ Point3d ptFxy( ptF.x, ptF.y, 0) ;
+ // Primo vettore del riferimento
+ Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ;
+ vtV1.Normalize() ;
+ Vector3d vtV2 ;
+
+ // Movimento verticale
+ if ( dLenXY / dLen < EPS_SMALL) {
+
+ // Secondo vettore del riferimento
+ vtV2 = vtV1 ;
+ vtV2.Rotate( Z_AX, 90) ;
+
+ // Ciclo sui punti
+ 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 dX1 = vtC * vtV1 ;
+ double dX2 = vtC * vtV2 ;
+
+ double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ;
+ // Parte cilindrica
+ if ( dX1 > 0 && dX1 < dStemHeigth && abs( dX2) < m_dRadius) {
+
+ double dH = sqrt( dSqRad - dX2 * dX2) ;
+ SubtractIntervals( nGrid, i, j, dZI - dH, dZF + dH) ;
+ }
+ // Parte conica
+ else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && abs( dX2) < dr) {
+
+ double dH = sqrt( dr * dr - dX2 * dX2) ;
+ SubtractIntervals ( nGrid, i, j, dZI - dH, dZF + dH) ;
+ }
+ }
+ }
+ }
+ else {
+
+ // Secondo vettore del riferimento
+ Vector3d vtV2 = vtMoveXY ;
+ vtV2.Normalize() ;
+
+ // Sistema di riferimento per determinare i piani
+ Vector3d vtW1 = ( m_dHeight > m_dTipHeight ? vtV1 : - vtV1) ;
+ Vector3d vtW2 = vtMove ;
+ vtW2.Normalize() ;// Se vtMove non è suff ort a vtW1 vtMove = vtMoveOrt + vtMoveLong e via
+ Vector3d vtW3 = vtW1 ^ vtW2 ;
+
+ // Altezza cono
+ double dL = dMaxRad * m_dTipHeight / dDeltaRad ;
+
+ // Vertice del cono iniziale
+ Point3d ptV = ptI - ( m_dHeight > m_dTipHeight ? ( dStemHeigth + dL) * vtW1 : ( dL - m_dHeight) * vtW1) ;
+
+ //
+ double dCos = vtW2.z ;
+ double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ;
+
+ double dLimXY = dCos * m_dRadius ;
+ double dLimH = dSin * m_dRadius ;
+ double dDeltaZ = ptF.z - ptI.z ;
+
+ double dMin, dMax ;
+
+ // Ciclo sui punti
+ 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 dX1 = vtC * vtV1 ;
+ double dX2 = vtC * vtV2 ;
+
+ double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ;
+
+ // Parte cilindrica
+ if ( dX1 > 0 && dX1 < dStemHeigth &&
+ dX2 > - m_dRadius && dX2 < dLenXY + m_dRadius) {
+ // Massimi
+ if ( dX2 < - dLimXY)
+ dMax = dZI + sqrt( dSqRad - dX2 * dX2) ;
+ else if ( dX2 < dLenXY - dLimXY)
+ dMax = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ;
+ else
+ dMax = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ // Minimi
+ if ( dX2 < dLimXY)
+ dMin = dZI + sqrt( dSqRad - dX2 * dX2) ;
+ else if ( dX2 < dLenXY + dLimXY)
+ dMin = dZI - dLimH + dDeltaZ * ( dX2 - dLimXY) / dLenXY ;
+ else
+ dMin = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ // Parte conica
+ else if ( dX1 >= dStemHeigth && dX1 < m_dHeight &&
+ dX2 > - dr && dX2 < dLenXY + dr) {
+
+ double dRadLimXY = dr * dCos ;
+ double dRadLimH = dr * dSin ;
+
+ // Massimi
+ if ( dX2 < - dRadLimXY)
+ dMax = dZI + sqrt( dr * dr - dX2 * dX2) ;
+ else if ( dX2 < dLenXY - dRadLimXY)
+ dMax = dZI + dRadLimH + dDeltaZ * ( dX2 + dRadLimXY) / dLenXY ;
+ else
+ dMax = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ // Minimi
+ if ( dX2 < dRadLimXY)
+ dMin = dZI + sqrt( dr * dr - dX2 * dX2) ;
+ else if ( dX2 < dLenXY + dRadLimXY)
+ dMin = dZI - dRadLimH + dDeltaZ * ( dX2 - dRadLimXY) / dLenXY ;
+ else
+ dMin = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) {
+
+ double dStemHeigth = m_dHeight - m_dTipRadius ;
+
+ CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ;
+
+ if ( m_dTipRadius < m_dRadius) {
+
+ Point3d ptSTip = ptS - dStemHeigth * vtToolDir ;
+ Point3d ptETip = ptE - dStemHeigth * vtToolDir ;
+
+ CompConus_Milling( nGrid, ptSTip, ptETip, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ;
+ }
+ else {
+
+ Point3d ptSTip = ptS - m_dHeight * vtToolDir ;
+ Point3d ptETip = ptE - m_dHeight * vtToolDir ;
+
+ CompConus_Milling( nGrid, ptSTip, ptETip, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ;
+ }
+
+ return true ;
+}
+
+// ---------- VERSORE UTENSILE CON ORIENTAZIONE GENERICA ---------------------
+
+// ---------- Cilindro e sfera -----------------------------------------------
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) {
+
+ double dStemHeigth = m_dHeight - m_dRadius ;
+
+ CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ;
+ // Sfera
+ if ( m_nToolType == 2) {
+
+ Point3d ptSBall = ptS - dStemHeigth * vtToolDir ;
+ Point3d ptEBall = ptE - dStemHeigth * vtToolDir ;
+
+ CompBall_Milling( nGrid, ptSBall, ptEBall, m_dRadius) ;
+ }
+
+ return true ;
+}
+//----------------------------------------------------------------------------
+bool
+VolZmap::CylBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) {
+
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+
+ CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ;
+ // Sfera
+ if ( m_nToolType == 2) {
+
+ Point3d ptSBall = ptS - dStemHeigth * vtToolDir ;
+ Point3d ptEBall = ptE - dStemHeigth * vtToolDir ;
+
+ CompBall_Milling( nGrid, ptSBall, ptEBall, m_dRadius) ;
+ }
+
+ return true ;
+}
+
+// ---------- Coni -----------------------------------------------------------
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) {
+
+ double dStemHeigth = m_dHeight - m_dRadius ;
+
+ CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ;
+ // Trapano
+ if ( m_dTipRadius < m_dRadius) {
+
+ Point3d ptSBall = ptS - dStemHeigth * vtToolDir ;
+ Point3d ptEBall = ptE - dStemHeigth * vtToolDir ;
+
+ CompConus_Drilling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ;
+ }
+ else {
+
+ Point3d ptSBall = ptS - m_dHeight * vtToolDir ;
+ Point3d ptEBall = ptE - m_dHeight * vtToolDir ;
+
+ CompConus_Drilling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::Conus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) {
+
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+
+ CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ;
+ // Trapano
+ if ( m_dTipRadius < m_dRadius) {
+
+ Point3d ptSBall = ptS - dStemHeigth * vtToolDir ;
+ Point3d ptEBall = ptE - dStemHeigth * vtToolDir ;
+
+ CompConus_Milling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ;
+ }
+ else {
+
+ Point3d ptSBall = ptS - m_dHeight * vtToolDir ;
+ Point3d ptEBall = ptE - m_dHeight * vtToolDir ;
+
+ CompConus_Milling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ;
+ }
+
+ return true ;
+}
+
+// ---------- Utensile generico ----------------------------------------------
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ // Posizioni iniziale e finale dell'utensile
+ Point3d ptI = ptS ;
+ Point3d ptF = ptE ;
+
+ // vettore movimento
+ Vector3d vtMove = ptE - ptS ;
+
+ // Settaggio profilo
+ CurveComposite* pToolProfile ;
+ if ( m_ToolArcLineApprox.GetCurveCount() == 0)
+ // Se l'utensile non è stato approssimato uso l'originale
+ pToolProfile = & m_ToolOutline ;
+ else
+ // altrimenti usi l'approssimazione
+ pToolProfile = &m_ToolArcLineApprox ;
+
+ // Ciclo sulle curve
+ const ICurve* pCurve = pToolProfile->GetFirstCurve() ;
+ 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 ;
+
+ CompCyl_Drilling( nGrid, 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 ;
+
+ CompConus_Drilling( nGrid, 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 ;
+
+ CompConus_Drilling( nGrid, 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
+ CompBall_Milling( nGrid, 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 = pToolProfile->GetNextCurve() ;
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir)
+{
+ // Posizioni iniziale e finale dell'utensile
+ Point3d ptI = ptS ;
+ Point3d ptF = ptE ;
+
+ // vettore movimento
+ Vector3d vtMove = ptE - ptS ;
+
+ // Settaggio profilo
+ CurveComposite* pToolProfile ;
+ if ( m_ToolArcLineApprox.GetCurveCount() == 0)
+ // Se l'utensile non è stato approssimato uso l'originale
+ pToolProfile = &m_ToolOutline ;
+ else
+ // altrimenti usi l'approssimazione
+ pToolProfile = &m_ToolArcLineApprox ;
+
+ // Ciclo sulle curve
+ const ICurve* pCurve = pToolProfile->GetFirstCurve() ;
+ 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 ;
+
+ CompCyl_Milling( nGrid, 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 ;
+
+ CompConus_Milling( nGrid, 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 ;
+
+ CompConus_Milling( nGrid, 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
+ CompBall_Milling( nGrid, 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 = pToolProfile->GetNextCurve() ;
+ }
+
+ return true ;
+}
+
+
+// ------------------------- COMPONENTI ELEMENTARI -----------------------------------------------------------------------------
+
+// Asse di simmetria diretto come l'asse Z: FORATURA
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza con lo Zmap
+ bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ,
+ dRad, dRad, dHei) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Proiezione dei punti sul piano
+ Point3d ptSxy( ptS.x, ptS.y, 0) ;
+
+ // Parametri geometrici dell'utensile
+ double dSqRad = dRad * dRad ;
+
+ // Punte del gambo
+ Point3d ptTStemS = ptS - vtToolDir * dHei ;
+ Point3d ptTStemE = ptE - vtToolDir * dHei ;
+
+ // Quote estreme del gambo
+ double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ;
+ double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptS.z, ptTStemS.z)) ;
+
+ // Ciclo sui punti
+ 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 - ptSxy ;
+
+ double dSqLen = vtC.SqLen() ;
+
+ // Se il punto si trova dentro il cerchio taglio
+ if ( dSqLen < dSqRad)
+ SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ;
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza con lo Zmap
+ bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
+
+ if ( ! Control)
+ return true ;
+
+ Point3d ptO( ptS.x, ptS.y, 0) ;
+
+ double dZMin, dZMax ;
+ double dAngC = dHei / ( dMaxRad - dMinRad) ;
+ double dSqMinRad = dMinRad * dMinRad ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+ // Studio delle simmetrie
+ if ( vtToolDir.z > 0) {
+
+ dZMin = ( ptS.z < ptE.z ? ptS.z - dHei : ptE.z - dHei) ;
+ dZMax = ( ptS.z < ptE.z ? ptE.z : ptS.z) ;
+ }
+ else {
+
+ dZMin = ( ptS.z < ptE.z ? ptS.z : ptE.z) ;
+ dZMax = ( ptS.z < ptE.z ? ptE.z + dHei : ptS.z + dHei) ;
+ }
+
+ // Ciclo sui punti
+ 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 < dSqMinRad)
+
+ SubtractIntervals( nGrid, i, j, dZMin, dZMax) ;
+
+ else if ( dSqDist < dSqMaxRad) {
+
+ double dr = sqrt( dSqDist) ;
+
+ if ( vtToolDir.z > 0)
+
+ SubtractIntervals( nGrid, i, j, dZMin + dAngC * ( dr - dMinRad), dZMax) ;
+ else
+ SubtractIntervals( nGrid, i, j, dZMin, dZMax - dAngC * ( dr - dMinRad)) ;
+ }
+ }
+
+ return true ;
+}
+
+// Asse di simmetria diretto come l'asse Z: FRESATURA
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza con lo Zmap
+ bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici
+ double dSqRad = dRad * dRad ;
+
+ // Studio delle simmetrie
+ Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ;
+ Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ;
+ Point3d ptIT = ptI - vtToolDir * dHei ;
+ Point3d ptFT = ptF - vtToolDir * dHei ;
+ Point3d ptIxy( ptI.x, ptI.y, 0) ;
+
+ // Quote iniziali e finali massime e
+ // minime del gambo dell'utensile e DeltaZ
+ double dZMaxI = max( ptI.z, ptIT.z) ;
+ double dZMaxF = max( ptF.z, ptFT.z) ;
+ double dZMinI = dZMaxI - dHei ;
+ double dZMinF = dZMaxF - dHei ;
+ double dDeltaZ = dZMaxF - dZMaxI ;
+
+ // Vettori caratterizzanti il moto
+ Vector3d vtMove = ptF - ptI ;
+ Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ;
+ double dLen = vtMove.Len() ;
+ double dLenXY = vtMoveXY.LenXY() ;
+ vtMove.Normalize() ;
+
+ // Parametri per determinare l'ellisse proiettata
+ double dCos = vtToolDir * vtMove ;
+ double dSin = ( abs( dCos) < 1 ? 1 - dCos * dCos : 0) ;
+ double dSemiAxMin = dRad * dCos ; // x1^2 = a^2 - (a / b)^2 x2^2 ; a = r dCos e b = r;
+ double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; // da cui si ottiene x1^2 = a^2 - dCos^2 x2^2
+ double dSqRatio = dSqSemiAxMin / dSqRad ;
+
+ // Definizione di un sistema di riferimento ad hoc
+ Vector3d vtV1, vtV2 ;
+
+ // Se la lunghezza è troppo piccola lo allungo
+ if ( dLenXY < EPS_SMALL)
+ vtV1 = ( 1 / dLenXY) * vtMoveXY ;
+ else
+ vtV1 = vtMoveXY ;
+
+ // Normalizzo vtV1
+ vtV1.Normalize() ;
+ // Definisco vtV2
+ vtV2 = vtV1 ;
+ vtV2.Rotate( Z_AX, 90) ;
+
+ double dMin, dMax ;
+
+ 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 dX1 = vtC * vtV1 ;
+ double dX2 = vtC * vtV2 ;
+
+ // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo
+ if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dRad) ||
+ ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad ||
+ dX1 * dX1 + dX2 * dX2 < dSqRad) {
+
+ double dX1_0 = sqrt( dSqRad - dX2 * dX2) ;
+ // Massimo
+ if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad)
+
+ dMax = dZMaxF ;
+ else
+ dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ;
+ // Minimo
+ if ( dX1 * dX1 + dX2 * dX2 < dSqRad)
+
+ dMin = dZMinI ;
+ else
+ dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad)
+{
+ double dMin, dMax, dPLim, dMLim ;
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
+
+ if ( ! Control)
+ return true ;
+
+ Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ;
+ Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ return true ;
+}
+
+
+
+// Asse di simmetria con orientazione generica: FORATURA
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad)
+{
+ double dMin, dMax;
+ unsigned int nStartI, nEndI, nStartJ, nEndJ ;
+
+ bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ;
+
+ if ( ! Control)
+ return true ;
+
+ // Studio delle simmetrie
+ Vector3d vtMove = ptE - ptS ;
+
+ Point3d ptI = ( vtMove * vtToolDir > 0 ? ptE : ptS) ;
+ Point3d ptF = ( vtMove * vtToolDir > 0 ? ptS - dHei * vtToolDir : ptE - 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 ;
+ double dSqRad = dRad * dRad ;
+
+ // 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( dSqRad - dProjI2 * dProjI2) &&
+ dProjI1 < dLOri + dCos * sqrt( dSqRad - dProjI2 * dProjI2) &&
+ dProjI2 * dProjI2 < dSqRad) {
+
+ // Massimi
+ if ( dProjI1 < dLOri - dCos * sqrt( dSqRad - dProjI2 * dProjI2)) {
+
+ double dZ0 = dSin * sqrt( dSqRad - dProjI2 * dProjI2) ;
+ double dI10 = - dCos * sqrt( dSqRad - 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( dSqRad - dProjI2 * dProjI2))
+
+ dMin = ( dDotI - vtV.x * dX - vtV.y *dY) / vtV.z ;
+
+ else {
+
+ double dZ0 = - dSin * sqrt( dSqRad - dProjI2 * dProjI2) ;
+ double dI10 = dCos * sqrt( dSqRad - dProjI2 * dProjI2) ;
+
+ dMin = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ;
+ }
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE,
+ const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad)
+{
+ double dMin, dMax ;
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
+
+ if ( ! Control)
+ return true ;
+
+ Vector3d vtMove = ptE - ptS ; 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 ;
+
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+ // 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 ? ptS : ptE) ;
+ 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 = ( ptS.z < ptE.z ? ptS : ptE) ;
+ Point3d ptCylF = ( ptS.z < ptE.z ? ptE : ptS) ;
+
+ 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) ;
+ Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ;
+
+
+ // 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 < dSqMaxRad &&
+ dPCyl1 > - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) &&
+ dPCyl1 < dLOri + dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) {
+
+ // Massimi
+ if ( dPCyl1 < dLOri - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) {
+
+ double dZ0 = dSin * sqrt( dSqMaxRad - dPCyl2 * dPCyl2) ;
+ double dP0 = - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) ;
+
+ 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) / dSqMaxRad))
+
+ dMin = ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z ;
+
+ else {
+
+ double dZ0 = - dSin * sqrt( dSqMaxRad - dPCyl2 * dPCyl2) ;
+ double dP0 = dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) ;
+
+ dMin = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ;
+ }
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ // Parte conica
+ Vector3d vtD = Z_AX ;
+
+ ptC.LocToLoc( GridFrame, ConusFrame) ;
+
+ vtD.LocToLoc( GridFrame, 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, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( ConusFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( ConusFrame, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
+
+ ptR1.LocToLoc( ConusFrame, GridFrame) ;
+ ptR2.LocToLoc( ConusFrame, GridFrame) ;
+
+ dMin = min( ptR1.z, ptR2.z) ;
+ dMax = max( ptR1.z, ptR2.z) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
+
+ ptR1.LocToLoc( ConusFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+// Asse di simmetria con orientazione generica: FRESATURA
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad)
+{
+ double dMin, dMax ;
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool Control = BBoxComponent( nGrid, ptS, ptE, 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 * ( ptE - ptS) > 0 ? ptS + dHei * vtV1 : ptE + dHei * vtV1) ;
+ ptF = ( vtV1 * ( ptE - ptS) > 0 ? ptE + dHei * vtV1 : ptS + dHei * vtV1) ;
+ }
+ else {
+
+ vtV1 = vtToolDir ;
+ ptI = ( vtV1 * ( ptE - ptS) > 0 ? ptS : ptE) ;
+ ptF = ( vtV1 * ( ptE - ptS) > 0 ? ptE : ptS) ;
+ }
+
+ Point3d ptIT = ptI - vtV1 * dHei ;
+ Point3d ptFT = ptF - vtV1 * dHei ;
+
+ // Definizione di un sintema di riferimento nel piano
+ // Ocio che |V1| sia maggiore di EPS_SMALL
+ Vector3d vtU1( - vtV1.x, - vtV1.y, 0) ;
+ vtU1.Normalize() ;
+ Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ;
+
+ Vector3d vtMove = ptF - ptI ;
+ Vector3d vtMLong = ( vtMove * vtV1) * vtV1 ;
+ Vector3d vtMOrt = vtMove - vtMLong ;
+
+ // Parametri geometrici dell'utensile
+ // e della traiettoria
+ double dCos = vtV1.z ;
+ double dSin = vtV1.LenXY() ;
+
+ double dZI = ptI.z ;
+ double dZF = ptF.z ;
+ double dDeltaZ = ptIT.z - ptI.z ;
+ double dL = dSin * dHei ;
+
+ double dLen = vtMove.Len() ;
+ double dLLong = vtMLong.Len() ;
+ double dLOrt = vtMOrt.Len() ;
+
+ double dCoef = dLOrt / dLLong ;
+ double dAng = atan( 1 / dCoef) ;
+
+ double dSqRad = dRad * dRad ;
+ double dSemiAxMin = dCos * dRad ;
+
+ // vtV1, vtV2 e vtV3 definiscono gli assi dei sistemi di riferimento intrinseci
+ Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ;
+ Vector3d vtV3 = vtV1 ^ vtV2 ;
+
+ Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ;
+ 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
+ double dSqRootI = sqrt( dSqRad - dPI2 * dPI2) ;
+ double dPI1_0 = dCos * dSqRootI ;
+
+
+ if ( dPI1 >= - dPI1_0 && dPI1 <= dL + dPI1_0 &&
+ dPI2 * dPI2 < dSqRad) {
+
+ // Minimi
+ if ( dPI1 <= dL - dPI1_0) {
+
+ double dZ0 = - dSin * dSqRootI ;
+ // da ( dPI1 - dPI1_0) è stato cambiato in ( dPI1 + dPI1_0)
+ dMin = dZI + dZ0 + ( dPI1 + dPI1_0) * dDeltaZ / dL ;
+ }
+ else
+
+ dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+
+ // Massimi
+ if ( dPI1 < dPI1_0)
+
+ dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+
+ else {
+
+ double dZ0 = dSin * dSqRootI ;
+
+ dMax = dZI + dZ0 + ( dPI1 - dPI1_0) * dDeltaZ / dL ;
+ }
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ // Parte cilindrica F
+ double dSqRootF = sqrt( dSqRad - dPF2 * dPF2) ;
+ double dPF1_0 = dCos * dSqRootF ;
+
+ if ( dPF1 >= - dPF1_0 && dPF1 <= dL + dPF1_0 && dPF2 * dPF2 < dSqRad) { // Baubaubau
+
+ // Minimi
+ if ( dPF1 <= dL - dPF1_0) {
+
+ double dZ0 = - dSin * dSqRootF ;
+ // da ( dPI1 - dPI1_0) è stato cambiato in ( dPI1 + dPI1_0)
+ dMin = dZF + dZ0 + ( dPF1 + dPF1_0) * dDeltaZ / dL ;
+ }
+ else
+
+ dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+
+ // Massimi
+ if ( dPF1 < dPF1_0)
+
+ dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+
+ else {
+
+ double dZ0 = dSin * dSqRootF ;
+
+ dMax = dZF + dZ0 + ( dPF1 - dPF1_0) * dDeltaZ / dL ;
+ }
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ } */
+
+ if ( IntersZLineCylinder( ptC, ptI, ptIT, vtToolDir, dRad, dMin, dMax)) {
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ if ( IntersZLineCylinder( ptC, ptF, ptFT, vtToolDir, dRad, dMin, dMax)) {
+
+ SubtractIntervals( nGrid, 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( GridFrame, CylFrame) ;
+ ptInt2.LocToLoc( GridFrame, CylFrame) ;
+ ptInt3.LocToLoc( GridFrame, CylFrame) ;
+ ptInt4.LocToLoc( GridFrame, RotFrame) ;
+ ptInt5.LocToLoc( GridFrame, CylFrame) ;
+ ptInt6.LocToLoc( GridFrame, 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, GridFrame) ;
+
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ dLim1 = ptInt6.z ;
+
+ bFlag = true ;
+ }
+ else
+
+ dLim2 = ptInt6.z ;
+ }
+
+
+ if ( bFlag) { // Una linea non confinata se entra in un volume chiuso ci deve uscire
+
+ dMin = min( dLim1, dLim2) ;
+ dMax = max( dLim1, dLim2) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ // Traslazione dell'ellisse
+
+ Vector3d vtK = Z_AX ;
+
+ vtK.LocToLoc( GridFrame, CylFrame) ;
+ ptC.LocToLoc( GridFrame, 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 - dSqRad ;
+ 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( GridFrame, CylFrame) ;
+ ptPf.LocToLoc( GridFrame, FCylFrame) ;
+
+ if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqRad &&
+ ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqRad) {
+
+ ptPi.LocToLoc( CylFrame, GridFrame) ;
+ ptPf.LocToLoc( FCylFrame, GridFrame) ;
+
+ dMin = min( ptPi.z, ptPf.z) ;
+ dMax = max( ptPi.z, ptPf.z) ;
+
+ SubtractIntervals( nGrid, 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, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptInter1.x > 0 && ptInter2.x < dLLong) {
+
+ ptInter1.LocToLoc( CylFrame, GridFrame) ;
+ ptInter2.LocToLoc( CylFrame, GridFrame) ;
+
+ dMin = min( ptInter1.z, ptInter2.z) ;
+ dMax = max( ptInter1.z, ptInter2.z) ;
+
+ SubtractIntervals( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) {
+
+ ptInter2.LocToLoc( CylFrame, GridFrame) ;
+
+ 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( nGrid, 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 - dSqRad ;
+ 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( GridFrame, TCylFrame) ;
+ ptPf.LocToLoc( GridFrame, FTCylFrame) ;
+
+ if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqRad &&
+ ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqRad) {
+
+ ptPi.LocToLoc( TCylFrame, GridFrame) ;
+ ptPf.LocToLoc( FTCylFrame, GridFrame) ;
+
+ dMin = min( ptPi.z, ptPf.z) ;
+ dMax = max( ptPi.z, ptPf.z) ;
+
+ SubtractIntervals( nGrid, 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, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) {
+
+ ptTInter1.LocToLoc( TCylFrame, GridFrame) ;
+ ptTInter2.LocToLoc( TCylFrame, GridFrame) ;
+
+ dMin = min( ptTInter1.z, ptTInter2.z) ;
+ dMax = max( ptTInter1.z, ptTInter2.z) ;
+
+ SubtractIntervals( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) {
+
+ ptTInter2.LocToLoc( TCylFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad)
+{
+ double dMin, dMax ;
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ;
+
+ if ( ! Control)
+ return true ;
+
+ double dDeltaR = dMaxRad - dMinRad ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+ double dSqMinRad = dMinRad * dMinRad ;
+
+ Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ;
+ Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ;
+
+ 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 CompConusAux_Milling( nGrid, 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 ptSloc = 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 - ptSloc ;
+
+ 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 GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ;
+ Frame3d IConeFrame ; IConeFrame.Set( ptIV, vtV1, vtV2, vtV3) ;
+ Frame3d FConeFrame ; FConeFrame.Set( ptFV, vtV1, vtV2, vtV3) ;
+ Frame3d PlSFrame ; PlSFrame.Set( ptSloc, 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 ;
+
+ Point3d ptIntLC1, ptIntLC2 ;
+ double dPMax, dPMin ;
+
+ // Cono iniziale
+ if ( IntersLineConus( ptC, vtK, IConeFrame, dTan, dl, dL, ptIntLC1, ptIntLC2)) {
+
+ dPMin = min( ptIntLC1.z, ptIntLC2.z) ;
+ dPMax = max( ptIntLC1.z, ptIntLC2.z) ;
+
+ SubtractIntervals( nGrid, i, j, dPMin, dPMax) ;
+ }
+
+ // Cono finale
+ if ( IntersLineConus( ptC, vtK, FConeFrame, dTan, dl, dL, ptIntLC1, ptIntLC2)) {
+
+ dPMin = min( ptIntLC1.z, ptIntLC2.z) ;
+ dPMax = max( ptIntLC1.z, ptIntLC2.z) ;
+
+ SubtractIntervals( nGrid, i, j, dPMin, dPMax) ;
+ }
+ /*
+ // Cono I
+ ptC.LocToLoc( GridFrame, IConeFrame) ;
+ vtK.LocToLoc( GridFrame, 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, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( IConeFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( IConeFrame, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
+
+ ptR1.LocToLoc( IConeFrame, GridFrame) ;
+ ptR2.LocToLoc( IConeFrame, GridFrame) ;
+
+ dMin = min( ptR1.z, ptR2.z) ;
+ dMax = max( ptR1.z, ptR2.z) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
+
+ ptR1.LocToLoc( IConeFrame, GridFrame) ;
+
+ 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( nGrid, 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, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( FConeFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( FConeFrame, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
+
+ ptR1.LocToLoc( FConeFrame, GridFrame) ;
+ ptR2.LocToLoc( FConeFrame, GridFrame) ;
+
+ dMin = min( ptR1.z, ptR2.z) ;
+ dMax = max( ptR1.z, ptR2.z) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
+
+ ptR1.LocToLoc( FConeFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ } */
+
+
+
+ // Solido interno
+
+ // ptC.LocToLoc( FConeFrame, GridFrame) ;
+ // vtK.LocToLoc( FConeFrame, GridFrame) ;
+
+ 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( GridFrame, PlSFrame) ;
+ ptInt2.LocToLoc( GridFrame, PlDFrame) ;
+ ptInt3.LocToLoc( GridFrame, PlBFrame) ;
+ ptInt4.LocToLoc( GridFrame, PlTFrame) ;
+ ptInt5.LocToLoc( GridFrame, PlIFrame) ;
+ ptInt6.LocToLoc( GridFrame, 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, GridFrame) ;
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ 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, GridFrame) ;
+
+ if ( ! bFlag) {
+
+ dLim1 = ptInt6.z ;
+ bFlag = true ;
+ }
+ else
+
+ dLim2 = ptInt6.z ;
+ }
+
+ if( bFlag) {
+
+ dMin = min( dLim1, dLim2) ;
+ dMax = max( dLim1, dLim2) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ // Traslazioni ellissi
+
+ ptC.LocToLoc( GridFrame, LargeEllipse) ;
+ vtK.LocToLoc( GridFrame, 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 - dSqMaxRad ;
+ 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( GridFrame, LargeEllipse) ;
+ ptPf.LocToLoc( GridFrame, FLargeEllipse) ;
+
+ if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMaxRad &&
+ ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMaxRad) {
+
+ ptPi.LocToLoc( LargeEllipse, GridFrame) ;
+ ptPf.LocToLoc( FLargeEllipse, GridFrame) ;
+
+ dMin = min( ptPi.z, ptPf.z) ;
+ dMax = max( ptPi.z, ptPf.z) ;
+
+ SubtractIntervals( nGrid, 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, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptInter1.x > 0 && ptInter2.x < dLLong) {
+
+ ptInter1.LocToLoc( LargeEllipse, GridFrame) ;
+ ptInter2.LocToLoc( LargeEllipse, GridFrame) ;
+
+ dMin = min( ptInter1.z, ptInter2.z) ;
+ dMax = max( ptInter1.z, ptInter2.z) ;
+
+ SubtractIntervals( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) {
+
+ ptInter2.LocToLoc( LargeEllipse, GridFrame) ;
+
+ 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( nGrid, 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 - dSqMinRad ;
+ 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( GridFrame, SmallEllipse) ;
+ ptPf.LocToLoc( GridFrame, FSmallEllipse) ;
+
+ if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMinRad &&
+ ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMinRad) {
+
+ ptPi.LocToLoc( SmallEllipse, GridFrame) ;
+ ptPf.LocToLoc( FSmallEllipse, GridFrame) ;
+
+ dMin = min( ptPi.z, ptPf.z) ;
+ dMax = max( ptPi.z, ptPf.z) ;
+
+ SubtractIntervals( nGrid, 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, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) {
+
+ ptTInter1.LocToLoc( SmallEllipse, GridFrame) ;
+ ptTInter2.LocToLoc( SmallEllipse, GridFrame) ;
+
+ dMin = min( ptTInter1.z, ptTInter2.z) ;
+ dMax = max( ptTInter1.z, ptTInter2.z) ;
+
+ SubtractIntervals( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) {
+
+ ptTInter2.LocToLoc( SmallEllipse, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompConusAux_Milling( unsigned int nGrid, 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) ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+
+ Point3d ptV = ptI - vtV1 * dL ;
+ Point3d ptT = ptI - vtV1 * dHei ;
+
+ Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ;
+ 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( GridFrame, ConeFrame) ;
+ Vector3d vtKE = vtK ; vtKE.LocToLoc( GridFrame, 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( GridFrame, 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, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( ConeFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) {
+
+ ptR2.LocToLoc( ConeFrame, GridFrame) ;
+
+ 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) {
+
+ ptR1.LocToLoc( ConeFrame, GridFrame) ;
+ ptR2.LocToLoc( ConeFrame, GridFrame) ;
+
+ dMin = min( ptR1.z, ptR2.z) ;
+ dMax = max( ptR1.z, ptR2.z) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) {
+
+ ptR1.LocToLoc( ConeFrame, GridFrame) ;
+
+ 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( nGrid, 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 - dSqMaxRad ;
+ 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( GridFrame, IEllipseFrame) ;
+ ptPf.LocToLoc( GridFrame, FEllipseFrame) ;
+
+ if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMaxRad &&
+ ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMaxRad) {
+
+ ptPi.LocToLoc( IEllipseFrame, GridFrame) ;
+ ptPf.LocToLoc( FEllipseFrame, GridFrame) ;
+
+ dMin = min( ptPi.z, ptPf.z) ;
+ dMax = max( ptPi.z, ptPf.z) ;
+
+ SubtractIntervals( nGrid, 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, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptInter1.x > 0 && ptInter2.x < dLLong) {
+
+ ptInter1.LocToLoc( IEllipseFrame, GridFrame) ;
+ ptInter2.LocToLoc( IEllipseFrame, GridFrame) ;
+
+ dMin = min( ptInter1.z, ptInter2.z) ;
+ dMax = max( ptInter1.z, ptInter2.z) ;
+
+ SubtractIntervals( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) {
+
+ ptInter2.LocToLoc( IEllipseFrame, GridFrame) ;
+
+ 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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+ return true ;
+}
+
+// ---------- SFERA ----------------------------------------------------------
+//----------------------------------------------------------------------------
+bool
+VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, double dRad)
+{
+ double dMin, dMax ;
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ bool Control = BBoxComponent( nGrid, 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 ;
+ double dSqRad = dRad * dRad ;
+
+
+ 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 < dSqRad) {
+
+ double dH = sqrt( dSqRad - dSqLen) ;
+
+ dMin = dZI - dH ;
+ dMax = dZI + dDeltaZ + dH ;
+
+ SubtractIntervals( nGrid, 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 < dSqRad || dFSqDist < dSqRad ||
+ ( dX1 > 0 && dX1 < dPLen && dX2 * dX2 < dSqRad)) {
+
+ // Massimi
+ if ( dX1 < - dR1 * sqrt( dSqRad - ( dX2 * dX2)))
+
+ dMax = dZI + sqrt( dSqRad - dISqDist) ;
+
+ else if ( dX1 < dPLen - dR1 * sqrt( dSqRad - ( dX2 * dX2)))
+
+ dMax = dZI + dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 + dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ;
+
+ else
+
+ dMax = dZI + dDeltaZ + sqrt( dSqRad - dFSqDist) ;
+
+ // Minimi
+ if ( dX1 < dR1 * sqrt( dSqRad - ( dX2 * dX2)))
+
+ dMin = dZI - sqrt( dSqRad - dISqDist) ;
+
+ else if ( dX1 < dPLen + dR1 * sqrt( dSqRad - ( dX2 * dX2)))
+
+ dMin = dZI - dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 - dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ;
+
+ else
+
+ dMin = dZI + dDeltaZ - sqrt( dSqRad - dFSqDist) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+
+ return true ;
+}
+
+// ------------------------- BOUNDING BOX --------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+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.
+
+ // Controllo sull'ammissibilità del numero di griglia
+ if ( nGrid < 0 || nGrid > 2)
+ return false ;
+
+ unsigned int nMaxNx, nMaxNy ;
+
+ double dMaxXValue, dMaxYValue ;
+ double dMinZValue, dMaxZValue ;
+
+ nMaxNx = m_nVNx[nGrid] ; nMaxNy = m_nVNy[nGrid] ;
+
+ dMaxXValue = nMaxNx * m_dStep ; dMaxYValue = nMaxNy * m_dStep ;
+
+ dMinZValue = m_dVMinZ[nGrid] ; dMaxZValue = m_dVMaxZ[nGrid] ;
+
+
+ // 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::BBoxComponent( unsigned int nGrid, const Point3d & ptP1, const Point3d & ptP2, const Vector3d & vtV1, const Vector3d & vtV2,
+ unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ,
+ double dRad, double dTipRad, double dHei)
+{
+ // NB: E' vitale che vengano passati i punti e i vettori nel sistema di riferimento
+ // di riferimento opportuno.
+
+ // Controllo sull'ammissibilità del numero di griglia
+ if ( nGrid < 0 || nGrid > 2)
+ return false ;
+
+ unsigned int nMaxNx, nMaxNy ;
+
+ double dMaxXValue, dMaxYValue ;
+ double dMinZValue, dMaxZValue ;
+
+ nMaxNx = m_nVNx[nGrid] ; nMaxNy = m_nVNy[nGrid] ;
+
+ dMaxXValue = nMaxNx * m_dStep ; dMaxYValue = nMaxNy * m_dStep ;
+
+ dMinZValue = m_dVMinZ[nGrid] ; dMaxZValue = m_dVMaxZ[nGrid] ;
+
+ // Determinazione del raggio massimo del componente
+ double dMaxRad = max( dRad, dTipRad) ;
+
+ // Determinazione delle posizioni della punta del componente 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 > 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 ;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+ /*
+
+ // VERSIONE NUOVA DA TESTARE
+bool
+VolZmap::Cyl_Milling( unsigned int nGrid, 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( nGrid, ptLs, ptLe, vtToolDir, vtToolDir,
+ nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ;
+
+ if ( ! Control)
+ return true ;
+
+
+ Point3d ptI, ptF ;
+ Vector3d vtV1, vtV2, vtV3 ;
+ // Studio delle simmetrie
+ //vtV1 = ( vtToolDir.z < 0 ? - vtToolDir : vtToolDir) ;
+ //Point3d ptI = ptLs + ( vtToolDir.z < 0 ? dHei * vtV1 : vtNUll) ;
+ //Point3d ptF + ( vtToolDir.z < 0 ? dHei * vtV1 : vtNUll) ;
+ 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() ;
+ double dSemiAxMin = m_dRadius * dCos ;
+ double dSqRad = m_dRadius * m_dRadius ;
+ double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ;
+ 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 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
+ vtV2 = vtMOrt ; vtV2.Normalize() ;
+ 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 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 vtRIT = ptIT - ORIG ;
+ double dDotIT = vtV1 * vtRIT ;
+ Vector3d vtRF = ptF - ORIG ;
+ double dDotF = vtV1 * vtRF ;
+ Vector3d vtRFT = ptFT - ORIG ;
+ double dDotFT = vtV1 * vtRFT ;
+
+ Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ;
+ Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ;
+
+ double dFrCos = cos( dAng) ;
+ double dFrSin = sin( dAng) ;
+
+ Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtV3) ;
+ Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtV3) ;
+
+ // Versore Z nel sistema di riferimento CylFrame
+ Vector3d vtKCyl = Z_AX ; vtKCyl.LocToLoc( m_LocalFrame, CylFrame) ;
+ // Versore Z nel sistema di riferimento RotFrame
+ Vector3d vtKRot = Z_AX ; vtKRot.LocToLoc( m_LocalFrame, RotFrame) ;
+
+
+ // Ciclo sui dexel
+ 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) ;
+ Point3d ptCCyl( dX, dY, 0) ;
+ Point3d ptCRot( dX, dY, 0) ;
+ Point3d ptCTCyl( dX, dY, 0) ;
+ ptCCyl.LocToLoc( m_LocalFrame, CylFrame) ;
+ ptCRot.LocToLoc( m_LocalFrame, RotFrame) ;
+ ptCTCyl.LocToLoc( m_LocalFrame, TCylFrame) ;
+
+
+ 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 ;
+
+ // Cilindro iniziale
+ if ( dPI1 * dPI1 / dSqSemiAxMin + dPI2 * dPI2 / dSqRad < 1 ||
+ ( dPI1 - dL) * ( dPI1 - dL) / dSqSemiAxMin + dPI2 * dPI2 / dSqRad < 1 ||
+ ( dPI1 > 0 && dPI1 < dL && abs( dPI2) < m_dRadius)) {
+
+ double dSqRoot = sqrt( dSqRad - dPI2 * dPI2) ;
+ double dPI1_0 = dCos * dSqRoot ;
+ double dH = dSin * dSqRoot ;
+
+ // Massimo
+ if ( dPI1 < dPI1_0)
+ // Se vtV1.z -> 0 allora dCos -> 0 e con essi l'area ove vi
+ // è la proiezione su XY del piano, quindi la divisione non da
+ // problemi, data la dimensione del passo della griglia
+ dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+ else
+ // Se vtV1.z -> 1 dCos -> 1 3 dSin -> 0 e con esso dL -> 0,
+ // ma anche l'area della regione interessata tende a zero,
+ // quindi la divisione non da problemi, data la dimensione del passo della griglia
+ dMax = dZI + dH + dDeltaZ * ( dPI1 - dPI1_0) / dL ;
+
+ // Minimo
+ if ( dPI1 < - dPI1_0)
+ // Analoga osservazione
+ dMin = dZI - dH + dDeltaZ * ( dPI1 + dPI1_0) / dL ;
+ else
+ // Analoga osservazione
+ dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ // Cilindro finale
+ if ( dPF1 * dPF1 + dPF2 * dPF2 < 1 ||
+ ( dPF1 - dL) * ( dPF1 - dL) + dPF2 * dPF2 < 1 ||
+ ( dPF1 > 0 && dPF1 < dL && abs( dPF2) < EPS_SMALL)) {
+
+ double dSqRoot = sqrt( dSqRad - ( dPF2 - dL) * ( dPF2 - dL)) ;
+ double dPF1_0 = dCos * dSqRoot ;
+ double dH = dSin * dSqRoot ;
+
+ // Massimo
+ if ( dPF1 < dPF1_0)
+ // Se vtV1.z -> 0 allora dCos -> 0 e con essi l'area ove vi
+ // è la proiezione su XY del piano, quindi la divisione non da
+ // problemi, data la dimensione del passo della griglia
+ dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+ else
+ // Se vtV1.z -> 1 dCos -> 1 3 dSin -> 0 e con esso dL -> 0,
+ // ma anche l'area della regione interessata tende a zero,
+ // quindi la divisione non da problemi, data la dimensione del passo della griglia
+ dMax = dZF + dH + dDeltaZ * ( dPF1 - dPF1_0) / dL ;
+
+ // Minimo
+ if ( dPF1 < - dPF1_0)
+ // Analoga osservazione
+ dMin = dZF - dH + dDeltaZ * ( dPF1 + dPF1_0) / dL ;
+ else
+ // Analoga osservazione
+ dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ // Parallelepipedo
+ unsigned int nInt = 0 ;
+ double dt ;
+
+ Point3d ptInt1, ptInt2 ;
+ // Piani paralleli a XY nel sistema CylFrame
+ if ( abs( vtKCyl.z) > EPS_ZERO ||
+ abs( ptCCyl.z - m_dRadius) < EPS_SMALL ||
+ abs( ptCCyl.z + m_dRadius) < EPS_SMALL) {
+
+ dt = ( m_dRadius - ptCCyl.z) / vtKCyl.z ;
+ Point3d ptInt = ptCCyl + dt * vtKCyl ;
+
+ if ( ptInt.y > 0 && ptInt.y < dLOrt &&
+ dLOrt * ptCCyl.x - dLLong * ptCCyl.y < 0 &&
+ dLOrt * ptCCyl.x + dLOrt * dHei - dLLong * ptCCyl.y > 0) {
+
+ ptInt.LocToLoc( CylFrame, m_LocalFrame) ;
+
+ ptInt1 = ptInt ;
+ nInt = 1 ;
+ }
+
+ dt = ( - m_dRadius - ptCCyl.z) / vtKCyl.z ;
+ ptInt = ptCCyl + dt * vtKCyl ;
+
+ if ( ptInt.y > 0 && ptInt.y < dLOrt &&
+ dLOrt * ptCCyl.x - dLLong * ptCCyl.y < 0 &&
+ dLOrt * ptCCyl.x + dLOrt * dHei - dLLong * ptCCyl.y > 0) {
+
+ ptInt.LocToLoc( CylFrame, m_LocalFrame) ;
+
+ if ( nInt == 0) {
+ ptInt1 = ptInt ;
+ nInt = 1 ;
+ }
+ else if ( nInt == 1) {
+ ptInt2 = ptInt ;
+ nInt = 2 ;
+ }
+ }
+ }
+ // Piani paralleli a XZ nel sistema CylFrame
+ if ( abs( vtKCyl.y) > EPS_ZERO ||
+ abs( ptCCyl.y) < EPS_SMALL ||
+ abs( ptCCyl.y - dLOrt) < EPS_SMALL) {
+
+ dt = - ptCCyl.y / vtKCyl.y ;
+ Point3d ptInt = ptCCyl + dt * vtKCyl ;
+
+ if ( ptInt.x > - dHei && ptInt.x < 0 &&
+ ptInt.z > - m_dRadius && ptInt.z < m_dRadius) {
+
+ ptInt.LocToLoc( CylFrame, m_LocalFrame) ;
+
+ if ( nInt == 0) {
+ ptInt1 = ptInt ;
+ nInt = 1 ;
+ }
+ else if ( nInt == 1) {
+ ptInt2 = ptInt ;
+ nInt = 2 ;
+ }
+ }
+
+ dt = ( dLOrt - ptCCyl.y) / vtKCyl.y ;
+ ptInt = ptCCyl + dt * vtKCyl ;
+
+ if ( ptInt.x > - dHei && ptInt.x < 0 &&
+ ptInt.z > - m_dRadius && ptInt.z < m_dRadius) {
+
+ ptInt.LocToLoc( CylFrame, m_LocalFrame) ;
+
+ if ( nInt == 0) {
+ ptInt1 = ptInt ;
+ nInt = 1 ;
+ }
+ else if ( nInt == 1) {
+ ptInt2 = ptInt ;
+ nInt = 2 ;
+ }
+ }
+ }
+ // Piani paralleli a YZ nel sistema RotFrame
+ if ( abs( vtKRot.x) > EPS_ZERO ||
+ abs( ptCRot.x) < EPS_SMALL ||
+ abs( ptCRot.x + dHei * dFrCos) < EPS_SMALL) {
+
+ dt = - ptCRot.x / vtKRot.x ;
+ Point3d ptInt = ptCCyl + dt * vtKRot ;
+
+ if ( ptInt.y > 0 && ptInt.y < dLen &&
+ ptInt.z > - m_dRadius && ptInt.z < m_dRadius) {
+
+ ptInt.LocToLoc( RotFrame, m_LocalFrame) ;
+
+ if ( nInt == 0) {
+ ptInt1 = ptInt ;
+ nInt = 1 ;
+ }
+ else if ( nInt == 1) {
+ ptInt2 = ptInt ;
+ nInt = 2 ;
+ }
+ }
+
+ dt = ( - dHei * dFrSin - ptCRot.x) / vtKRot.x ;
+ ptInt = ptCCyl + dt * vtKRot ;
+
+ if ( ptInt.y > - dHei * dFrSin && ptInt.y < dLen - dHei * dFrSin &&
+ ptInt.z > - m_dRadius && ptInt.z < m_dRadius) {
+
+ ptInt.LocToLoc( RotFrame, m_LocalFrame) ;
+
+ if ( nInt == 0) {
+ ptInt1 = ptInt ;
+ nInt = 1 ;
+ }
+ else if ( nInt == 1) {
+ ptInt2 = ptInt ;
+ nInt = 2 ;
+ }
+ }
+ }
+
+ if ( nInt == 2) {
+
+ dMin = min( ptInt1.z, ptInt2.z) ;
+ dMax = max( ptInt1.z, ptInt2.z) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+
+ // Traslazione ellisse di fondo
+ std::vector vdCoef(3);
+ std::vector vdRoots;
+
+ vdCoef[0] = dCoef * dCoef * ptCCyl.x * ptCCyl.x + ptCCyl.y * ptCCyl.y + ptCCyl.z * ptCCyl.z - 2 * dCoef * ptCCyl.x * ptCCyl.y - dRad * dRad ;
+ vdCoef[1] = 2 * ( dCoef * dCoef * vtKCyl.x * ptCCyl.x + vtKCyl.y * ptCCyl.y + vtKCyl.z * ptCCyl.z - dCoef * ( vtKCyl.x * ptCCyl.y + vtKCyl.y * ptCCyl.x)) ;
+ vdCoef[2] = dCoef * dCoef * vtKCyl.x * vtKCyl.x + vtKCyl.y * vtKCyl.y + vtKCyl.z * vtKCyl.z - 2 * dCoef * vtKCyl.x * vtKCyl.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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ else if ( nRoot == 2) {
+
+ Point3d ptInter1 = ptCCyl + vdRoots[0] * vtKCyl ;
+ Point3d ptInter2 = ptCCyl + vdRoots[1] * vtKCyl ;
+
+
+ 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( nGrid, 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( nGrid, 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( nGrid, 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( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+
+ // Traslazione ellisse di punta
+ std::vector vdTCoef(3);
+ std::vector vdTRoots;
+
+ vdTCoef[0] = dCoef * dCoef * ptCTCyl.x * ptCTCyl.x + ptCTCyl.y * ptCTCyl.y + ptCTCyl.z * ptCTCyl.z - 2 * dCoef * ptCTCyl.x * ptCTCyl.y - dRad * dRad ;
+ vdTCoef[1] = 2 * ( dCoef * dCoef * vtKCyl.x * ptCTCyl.x + vtKCyl.y * ptCTCyl.y + vtKCyl.z * ptCTCyl.z - dCoef * ( vtKCyl.x * ptCTCyl.y + vtKCyl.y * ptCTCyl.x)) ;
+ vdTCoef[2] = dCoef * dCoef * vtKCyl.x * vtKCyl.x + vtKCyl.y * vtKCyl.y + vtKCyl.z * vtKCyl.z - 2 * dCoef * vtKCyl.x * vtKCyl.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( nGrid, i, j, dMin, dMax) ;
+ }
+
+ }
+ else if ( nTRoot == 2) {
+
+ Point3d ptTInter1 = ptCTCyl + vdTRoots[0] * vtKCyl ;
+ Point3d ptTInter2 = ptCTCyl + vdTRoots[1] * vtKCyl ;
+
+ 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( nGrid, 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( nGrid, 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( nGrid, 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( nGrid, 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::Conus_XYPerp( unsigned int nGrid, const Point3d ptS, const Point3d ptE, const Vector3d vtToolDir)
+{
+ unsigned int nStartI, nStartJ, nEndI, nEndJ ;
+
+ // Verifica sull'interferenza utensile Zmap
+ bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ;
+
+ if ( ! bTest)
+ return true ;
+
+ // Parametri geometrici dell'utensile
+ double dStemHeigth = m_dHeight - m_dTipHeight ;
+ double dMinRad = min( m_dRadius, m_dTipRadius) ;
+ double dMaxRad = max( m_dRadius, m_dTipRadius) ;
+ double dSqTipRad = m_dTipRadius * m_dTipRadius ;
+ double dSqRad = m_dRadius * m_dRadius ;
+ double dDeltaRad = dMaxRad - dMinRad ;
+ double dSqMinRad = dMinRad * dMinRad ;
+ double dSqMaxRad = dMaxRad * dMaxRad ;
+
+ // Studio delle simmetrie
+ Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ;
+ Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ;
+
+ // Vettori caratterizzanti il moto
+ Vector3d vtMove = ptF - ptI ;
+ Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ;
+ double dLen = vtMove.Len() ;
+ double dLenXY = vtMoveXY.LenXY() ;
+
+ // Quote iniziale e finale
+ double dZI = ptI.z ;
+ double dZF = ptF.z ;
+
+ // Sistema di riferimento sul piano
+ Point3d ptIxy( ptI.x, ptI.y, 0) ;
+ Point3d ptFxy( ptF.x, ptF.y, 0) ;
+ // Primo vettore del riferimento
+ Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ;
+ vtV1.Normalize() ;
+ Vector3d vtV2 ;
+
+ // Movimento verticale
+ if ( dLenXY / dLen < EPS_SMALL) {
+ // Secondo vettore del riferimento
+ vtV2 = vtV1 ;
+ vtV2.Rotate( Z_AX, 90) ;
+
+ // Ciclo sui punti
+ 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 dX1 = vtC * vtV1 ;
+ double dX2 = vtC * vtV2 ;
+
+ double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ;
+ // Parte cilindrica
+ if ( dX1 > 0 && dX1 < dStemHeigth && abs( dX2) < m_dRadius) {
+
+ double dH = sqrt( dSqRad - dX2 * dX2) ;
+ SubtractIntervals( nGrid, i, j, dZI - dH, dZF + dH) ;
+ }
+ // Parte conica
+ else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && abs( dX2) < dr) {
+
+ double dH = sqrt( dr * dr - dX2 * dX2) ;
+ SubtractIntervals ( nGrid, i, j, dZI - dH, dZF + dH) ;
+ }
+ }
+ }
+ }
+ else {
+ // Secondo vettore del riferimento
+ Vector3d vtV2 = vtMoveXY ;
+ vtV2.Normalize() ;
+
+ // Sistema di riferimento per determinare i piani
+ Vector3d vtW1 = ( m_dHeight > m_dTipHeight ? vtV1 : - vtV1) ;
+ Vector3d vtW2 = vtMove ;
+ vtW2.Normalize() ;// Se vtMove non è suff ort a vtW1 vtMove = vtMoveOrt + vtMoveLong e via
+ Vector3d vtW3 = vtW1 ^ vtW2 ;
+
+ // Altezza cono
+ double dL = dMaxRad * m_dTipHeight / dDeltaRad ;
+
+ // Vertice del cono iniziale
+ Point3d ptV = ptI - ( m_dHeight > m_dTipHeight ? ( dStemHeigth + dL) * vtW1 : ( dL - m_dHeight) * vtW1) ;
+
+ //
+ double dCos = vtW2.z ;
+ double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ;
+
+ double dLimXY = dCos * m_dRadius ;
+ double dLimH = dSin * m_dRadius ;
+ double dDeltaZ = ptF.z - ptI.z ;
+
+ double dMin, dMax ;
+
+
+ // Ciclo sui punti
+ 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 dX1 = vtC * vtV1 ;
+ double dX2 = vtC * vtV2 ;
+
+ double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ;
+
+ // Parte cilindrica
+ if ( dX1 > 0 && dX1 < dStemHeigth &&
+ dX2 > - m_dRadius && dX2 < dLenXY + m_dRadius)
+ {
+ // Massimi
+ if ( dX2 < - dLimXY)
+ dMax = dZI + sqrt( dSqRad - dX2 * dX2) ;
+ else if ( dX2 < dLenXY - dLimXY)
+ dMax = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ;
+ else
+ dMax = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ // Minimi
+ if ( dX2 < dLimXY)
+ dMin = dZI + sqrt( dSqRad - dX2 * dX2) ;
+ else if ( dX2 < dLenXY + dLimXY)
+ dMin = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ;
+ else
+ dMin = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ // Parte conica
+ else if ( dX1 >= dStemHeigth && dX1 < m_dHeight &&
+ dX2 > - dr && dX2 < dLenXY + dr) {
+
+ double dRadLimXY = dr * dCos ;
+ double dRadLimH = dr * dSin ;
+
+ // Massimi
+ if ( dX2 < - dRadLimXY)
+ dMax = dZI + sqrt( dr * dr - dX2 * dX2) ;
+ else if ( dX2 < dLenXY - dRadLimXY)
+ dMax = dZI + dRadLimH + dDeltaZ * ( dX2 + dRadLimXY) / dLenXY ;
+ else
+ dMax = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ // Minimi
+ if ( dX2 < dRadLimXY)
+ dMin = dZI + sqrt( dr * dr - dX2 * dX2) ;
+ else if ( dX2 < dLenXY + dRadLimXY)
+ dMin = dZI - dRadLimH + dDeltaZ * ( dX2 - dRadLimXY) / dLenXY ;
+ else
+ dMin = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ;
+
+ SubtractIntervals( nGrid, i, j, dMin, dMax) ;
+ }
+ }
+ }
+ }
+ return true ;
+}*/
+
+
+// Massimi
+ //if ( dX1 < - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dSqRad * dR2 * dR2)))/* &&
+ // dISqDist < dRad * dRad) */
+
+ //dMax = dZI + sqrt( dSqRad - dISqDist) ;
+
+ //else if ( /*dX1 >= - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && */
+ // dX1 < dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad))
+
+ //dMax = dZI + dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) * dVLen / dPLen ;
+
+ //else /*if ( dX1 >= dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) &&
+ // dFSqDist < dRad * dRad)*/
+
+ //dMax = dZI + dDeltaZ + sqrt( dSqRad - dFSqDist) ;
+
+ // Minimi
+ // if ( dX1 < dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad))/* &&
+ // dISqDist < dRad * dRad) */
+
+ // dMin = dZI - sqrt( dSqRad - dISqDist) ;
+
+ //else if ( /*dX1 >= dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && */
+ // dX1 < dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad))
+
+ // dMin = dZI - dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) * dVLen / dPLen ;
+
+ //else /*if ( dX1 >= dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) &&
+ // dFSqDist < dRad * dRad) */
+
+ //dMin = dZI + dDeltaZ - sqrt( dSqRad - dFSqDist) ;
+
+
+
\ No newline at end of file
diff --git a/VolZmap.cpp b/VolZmap.cpp
index f1a946e..71cf1ed 100644
--- a/VolZmap.cpp
+++ b/VolZmap.cpp
@@ -28,12 +28,16 @@ GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ;
//----------------------------------------------------------------------------
VolZmap::VolZmap(void)
- : m_nStatus( TO_VERIFY), m_nTempProp(), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG)
+ : m_nStatus( TO_VERIFY), m_dStep( EPS_SMALL), m_nTempProp( 0), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG)
{
- m_dStep = 0 ;
- m_nNx = 0 ;
- m_nNy = 0 ;
- m_nDim = 0 ;
+ m_nMapNum = 0 ;
+ for ( int i = 0 ; i < 3 ; ++ i) {
+ m_nVNx[i] = 0 ;
+ m_nVNy[i] = 0 ;
+ m_nVDim[i] = 0 ;
+ m_dVMinZ[i] = 0 ;
+ m_dVMaxZ[i] = 0 ;
+ }
}
//----------------------------------------------------------------------------
@@ -74,12 +78,24 @@ VolZmap::CopyFrom( const VolZmap& vzmSrc)
if ( &vzmSrc == this)
return true ;
m_OGrMgr.Reset() ;
- m_LocalFrame = vzmSrc.m_LocalFrame ;
+
+ m_nMapNum = vzmSrc.m_nMapNum ;
+
+ for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) {
+
+ m_MapFrame[i] = vzmSrc.m_MapFrame[i] ;
+
+ m_nVNx[i] = vzmSrc.m_nVNx[i] ;
+ m_nVNy[i] = vzmSrc.m_nVNy[i] ;
+ m_nVDim[i] = vzmSrc.m_nVDim[i] ;
+
+ m_dVMinZ[i] = vzmSrc.m_dVMinZ[i] ;
+ m_dVMaxZ[i] = vzmSrc.m_dVMaxZ[i] ;
+
+ m_TriZValues[i] = vzmSrc.m_TriZValues[i] ;
+ }
+
m_dStep = vzmSrc.m_dStep ;
- m_nDim = vzmSrc.m_nDim ;
- m_nNx = vzmSrc.m_nNx ;
- m_nNy = vzmSrc.m_nNy ;
- m_ZValues = vzmSrc.m_ZValues ;
m_nStatus = vzmSrc.m_nStatus ;
m_nTempProp = vzmSrc.m_nTempProp ;
return true ;
@@ -118,38 +134,44 @@ VolZmap::GetNgeId( void) const
bool
VolZmap::Save( NgeWriter& ngeOut) const
{
- // parametri di scrittura: sistema di riferimento, minimo incremento, numero di passi
- // in direzione x e y, e per ogni casella, numero di valori e valori
- if ( ! ngeOut.WriteFrame( m_LocalFrame, ";", true))
- return false ;
- if ( ! ngeOut.WriteDouble( m_dStep, ",", false))
- return false ;
- if ( ! ngeOut.WriteInt( m_nNx, ",", false))
- return false ;
- if ( ! ngeOut.WriteInt( m_nNy, ";", true))
- return false ;
- // ciclo sui dexel
- for ( unsigned int i = 0 ; i < m_nDim ; ++ i) {
- // numero di estremi
- int nDim = int( m_ZValues[i].size()) ;
- if ( ! ngeOut.WriteInt( nDim, ",", false))
+ // parametri di scrittura: sistema di riferimento, numero di passi
+ // in direzione x e y, minimo incremento e per ogni casella, numero di valori e valori
+ for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) {
+ if ( ! ngeOut.WriteFrame( m_MapFrame[i], ",", true))
+ return false ;
+ if ( ! ngeOut.WriteInt( m_nVNx[i], ",", false))
return false ;
- // se dexel nullo
- if ( nDim == 0) {
+ if ( ! ngeOut.WriteInt( m_nVNy[i], ",", true))
+ return false ;
+ }
+
+ if ( ! ngeOut.WriteDouble( m_dStep, ";", false))
+ return false ;
+
+ // ciclo sulle mappe
+ for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) {
+ // ciclo sui dexel
+ for ( unsigned int j = 0 ; j < m_nVDim[i] ; ++ j) {
+ // numero di estremi
+ int nDim = int( m_TriZValues[i][j].size()) ;
+ if ( ! ngeOut.WriteInt( nDim, ",", false))
+ return false ;
+ // se dexel nullo
+ if ( nDim == 0) {
// scrivo un valore dummy
if ( ! ngeOut.WriteDouble( 0, ";", true))
return false ;
- }
- // altrimenti
- else {
- for ( unsigned int k = 0 ; k < m_ZValues[i].size() ; ++ k) {
- bool bEndL = ( k == m_ZValues[i].size() - 1) ;
- if ( ! ngeOut.WriteDouble( m_ZValues[i][k], ( bEndL ? ";" : ","), bEndL))
- return false ;
}
- }
- }
-
+ // altrimenti
+ else {
+ for ( unsigned int k = 0 ; k < m_TriZValues[i][j].size() ; ++ k) {
+ bool bEndL = ( k == m_TriZValues[i][j].size() - 1) ;
+ if ( ! ngeOut.WriteDouble( m_TriZValues[i][j][k], ( bEndL ? ";" : ","), bEndL))
+ return false ;
+ }
+ }
+ }
+ }
return true ;
}
@@ -158,49 +180,61 @@ bool
VolZmap::Load( NgeReader& ngeIn)
{
m_nStatus = TO_VERIFY ;
- // parametri di lettura: sistema di riferimento, minimo incremento, numero di passi
- // in direzione x e y, e per ogni casella, numero di valori e valori
- if ( ! ngeIn.ReadFrame( m_LocalFrame, ";", true))
- return false ;
- if ( ! ngeIn.ReadDouble( m_dStep, ",", false))
- return false ;
+ // parametri di lettura: sistema di riferimento, numero di passi
+ // in direzione x e y, minimo incremento e per ogni casella, numero di valori e valori
+
int nTemp ;
- if ( ! ngeIn.ReadInt( nTemp, ",", false))
- return false ;
- m_nNx = nTemp ;
- if ( ! ngeIn.ReadInt( nTemp, ";", true))
- return false ;
- m_nNy = nTemp ;
- // dimensione del vettore di dexel
- m_nDim = m_nNx * m_nNy ;
- m_ZValues.resize(m_nDim) ;
+ for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) {
- // ciclo sui dexel
- for ( unsigned int i = 0 ; i < m_nDim ; ++ i) {
- // leggo il numero di estremi nel dexel
+ if ( ! ngeIn.ReadFrame( m_MapFrame[i], ";", true))
+ return false ;
if ( ! ngeIn.ReadInt( nTemp, ",", false))
return false ;
- // devono essere pari
- if ( ( nTemp % 2) != 0)
+ m_nVNx[i] = nTemp ;
+ if ( ! ngeIn.ReadInt( nTemp, ";", true))
return false ;
- // se dexel nullo
- if ( nTemp == 0) {
- // leggo un valore dummy
- double dDummy ;
- if ( ! ngeIn.ReadDouble( dDummy, ",", true))
+ m_nVNy[i] = nTemp ;
+ }
+
+ if ( ! ngeIn.ReadDouble( m_dStep, ",", false))
+ return false ;
+
+ // dimensione dei vettori di dexel
+ for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) {
+
+ m_nVDim[i] = m_nVNx[i] * m_nVNy[i] ;
+ m_TriZValues[i].resize(m_nVDim[i]) ;
+ }
+
+ // ciclo sulle mappe
+ for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) {
+ // ciclo sui dexel
+ for ( unsigned int j = 0 ; j < m_nVDim[i] ; ++ j) {
+ // leggo il numero di estremi nel dexel
+ if ( ! ngeIn.ReadInt( nTemp, ",", false))
return false ;
- }
- // altrimenti
- else {
- // dimensiono l'array
- m_ZValues[i].resize(nTemp) ;
- // leggo i valori
- for ( unsigned int k = 0 ; k < m_ZValues[i].size() ; ++ k) {
- bool bEndL = ( k == m_ZValues[i].size() - 1) ;
- if ( ! ngeIn.ReadDouble( m_ZValues[i][k], ( bEndL ? ";" : ","), bEndL))
+ // devono essere pari
+ if ( ( nTemp % 2) != 0)
+ return false ;
+ // se dexel nullo
+ if ( nTemp == 0) {
+ // leggo un valore dummy
+ double dDummy ;
+ if ( ! ngeIn.ReadDouble( dDummy, ",", true))
return false ;
}
+ // altrimenti
+ else {
+ // dimensiono l'array
+ m_TriZValues[i][j].resize(nTemp) ;
+ // leggo i valori
+ for ( unsigned int k = 0 ; k < m_TriZValues[i][j].size() ; ++ k) {
+ bool bEndL = ( k == m_TriZValues[i][j].size() - 1) ;
+ if ( ! ngeIn.ReadDouble( m_TriZValues[i][j][k], ( bEndL ? ";" : ","), bEndL))
+ return false ;
+ }
+ }
}
}
@@ -220,24 +254,24 @@ VolZmap::GetLocalBBox( BBox3d& b3Loc, int nFlag) const
// 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) ;
+ b3Loc.Add( Point3d( m_nVNx[0] * m_dStep, m_nVNy[0] * m_dStep, m_dVMaxZ[0])) ;
+ b3Loc.ToGlob( m_MapFrame[0]) ;
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) ;
+ for ( size_t j = 0 ; j <= m_nVNy[0] ; ++ j) {
+ size_t jc = ( ( j != m_nVNy[0]) ? j : m_nVNy[0] -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()) ;
+ for ( size_t i = 0 ; i <= m_nVNx[0] ; ++ i) {
+ size_t ic = ( ( i != m_nVNx[0]) ? i : m_nVNx[0] -1) ;
+ size_t nPos = ic + jc * m_nVNx[0] ;
+ if ( m_TriZValues[0][nPos].size() > 0) {
+ Point3d ptP = m_MapFrame[0].Orig() + dX * m_MapFrame[0].VersX() + dY * m_MapFrame[0].VersY() ;
+ b3Loc.Add( ptP + m_TriZValues[0][nPos][0] * m_MapFrame[0].VersZ()) ;
+ b3Loc.Add( ptP + m_TriZValues[0][nPos][m_TriZValues[0][nPos].size()-1] * m_MapFrame[0].VersZ()) ;
}
// passo al punto successivo
dX += m_dStep ;
@@ -259,29 +293,29 @@ VolZmap::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
// reset box
b3Ref.Reset() ;
// trasformo il riferimento locale tramite quello passato
- Frame3d frUse = m_LocalFrame ;
+ Frame3d frUse = m_MapFrame[0] ;
frUse.ToGlob( frRef) ;
// 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.Add( Point3d( m_nVNx[0] * m_dStep, m_nVNy[0] * m_dStep, m_dVMaxZ[0])) ;
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) ;
+ for ( size_t j = 0 ; j <= m_nVNy[0] ; ++ j) {
+ size_t jc = ( ( j != m_nVNy[0]) ? j : m_nVNy[0] -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) {
+ for ( size_t i = 0 ; i <= m_nVNx[0] ; ++ i) {
+ size_t ic = ( ( i != m_nVNx[0]) ? i : m_nVNx[0] -1) ;
+ size_t nPos = ic + jc * m_nVNx[0] ;
+ if ( m_TriZValues[0][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()) ;
+ b3Ref.Add( ptP + m_TriZValues[0][nPos][0] * frUse.VersZ()) ;
+ b3Ref.Add( ptP + m_TriZValues[0][nPos][m_TriZValues[0][nPos].size()-1] * frUse.VersZ()) ;
}
// passo al punto successivo
dX += m_dStep ;
@@ -291,7 +325,7 @@ VolZmap::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const
}
return true ;
-}
+}
//----------------------------------------------------------------------------
bool
@@ -302,8 +336,9 @@ VolZmap::Translate( const Vector3d& vtMove)
return false ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
- // traslo il riferimento
- m_LocalFrame.Translate( vtMove) ;
+ // traslo i riferimenti
+ for ( int i = 0 ; i < int( m_nMapNum) ; ++ i)
+ m_MapFrame[i].Translate( vtMove) ;
return true ;
}
@@ -316,8 +351,10 @@ VolZmap::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub
return false ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
- // ruoto il riferimento
- return m_LocalFrame.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
+ // ruoto i riferimenti
+ for ( int i = 0 ; i < int( m_nMapNum) ; ++ i)
+ m_MapFrame[i].Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
+ return true ;
}
//----------------------------------------------------------------------------
@@ -360,7 +397,9 @@ VolZmap::ToGlob( const Frame3d& frRef)
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
// trasformo il riferimento
- return m_LocalFrame.ToGlob( frRef) ;
+ for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i)
+ m_MapFrame[i].ToGlob( frRef) ;
+ return true ;
}
//----------------------------------------------------------------------------
@@ -373,7 +412,9 @@ VolZmap::ToLoc( const Frame3d& frRef)
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
// trasformo il riferimento
- return m_LocalFrame.ToLoc( frRef) ;
+ for ( int i = 0 ; i < int( m_nMapNum) ; ++ i)
+ m_MapFrame[i].ToLoc( frRef) ;
+ return true ;
}
//----------------------------------------------------------------------------
@@ -386,7 +427,9 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
// trasformo il riferimento
- return m_LocalFrame.LocToLoc( frOri, frDest) ;
+ for ( int i = 0 ; i < int( m_nMapNum) ; ++ i)
+ m_MapFrame[i].LocToLoc( frOri, frDest) ;
+ return true ;
}
diff --git a/VolZmap.h b/VolZmap.h
index a605194..dbca216 100644
--- a/VolZmap.h
+++ b/VolZmap.h
@@ -60,9 +60,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW
public : // IVolZmap
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
- 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 Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dPrec, bool bTriDex) override ;
+ bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec, bool bTriDex) override ;
+ bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex) 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 ;
@@ -70,10 +70,12 @@ class VolZmap : public IVolZmap, public IGeoObjRW
bool SetAdvTool( const std::string& pToolName,
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 GetDepth( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) override ;
bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) override ;
+
+ bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) override ;
+
public : // IGeoObjRW
virtual int GetNgeId( void) const ;
virtual bool Save( NgeWriter& ngeOut) const ;
@@ -103,144 +105,110 @@ 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
- // Fori
- bool DrillingZ( const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) ;
-
- bool CBTDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ;
-
- // Tagli orizzontali
- bool MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- bool CBTMillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ;
-
- inline bool GetMinMaxZSw( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ;
- inline bool GetMinMaxZDr( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ;
- inline bool GetMinMaxZ( unsigned int nI, unsigned int nJ, double dZCutBase, double dDeltaZ, double dSqDist, const Vector3d& vtToolDir) ;
-
- // generico 3 assi
- bool MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- bool CBMillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ;
- bool ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ;
-
- inline bool GetMinMaxZGen( unsigned int nI, unsigned int nJ, double dProj, double dSqd, double dLenPath, double dZheight, double dDelta, const Vector3d& vtToolDir) ;
-
+ bool MarchingCubes( TRIA3DLIST& lstTria) const ;
+ bool IsThereMat( int nI, int nJ, int nK) const ;
+ bool IsThereMat( const int nMatr[][3], int nNum, double & dHx, double & dHy, double & dHz) const ;
+ bool IntersPos( int nVec1[], int nVec2[], Point3d & ptInt) const ;
- // Versore utensile nel piano XY
- // DeltaZ = 0
- bool DrillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
+ // OPERAZIONI SU INTERVALLI
+ bool SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) ;
+ bool SubtractIntervals( unsigned int nGrid, const Point3d& ptP, double dMin, double dMax) ;
+ bool AddIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) ;
+ bool AddIntervals( unsigned int nGrid, const Point3d& ptP, double dMin, double dMax) ;
- bool CBTDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool ConusDrillingXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ;
-
- bool MillingPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
+ // SOTTRAZIONI
+ // UTENSILI
+ // Asse di simmetria parallelo a Z
+ bool CylBall_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool CylBall_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- bool CBTPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool ConusPerpXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ;
-
- bool MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool PlaneGenCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool ConusPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
+ bool Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool Conus_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool Conus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- inline bool GetMinMaxXY( unsigned int nI, unsigned int nJ, double dProj, double dZheight, double dSqD, double dPathPerp, double dPathPar, double dScProd) ;
- inline bool GetMMPlaneGenCyl( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, double dProj1, double dProj2) ;
- inline bool GetMMPlaneGenBall( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, Point3d ptIxy, Vector3d vtMove, Vector3d vtV1, Vector3d vtV2) ;
-
- // DeltaZ != 0
- bool MillingXYVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
+ bool Dr_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) ;
+ bool Sw_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) ;
- bool MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
+ bool GenTool_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- bool XYLongVertCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- bool MillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- bool MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool MillingXYConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- bool MillingXYPlus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- bool MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool MillingXYPlusConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
+ // Asse di simmetria nel piano
+ bool CylBall_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool CylBall_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool CylBall_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- // Virtual milling per componenti elementari
+ bool Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool Conus_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- // Versore utensile parallelo all'asse Z
- // Movimento parallelo al versore utensile
- bool DrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- // Componenti
- bool LongCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ;
- bool LongConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
+ // Asse di simmetria con orientazione generica
+ bool CylBall_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool CylBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- // Angolo generico fra movimento e versore utensile
- bool MillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- // Componenti
- bool MillCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ;
- bool MillConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
+ bool Conus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool Conus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- // Direzione generica del versore utensile
- // Movimento parallelo al versore utensile
- bool Drilling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool DrillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
+ bool GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ bool GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
- // Componenti elementari degli untensili
- bool LongBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) ;
- bool LongCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ;
- bool LongConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
+ // COMPONENTI
+ // Asse di simmetria diretto come l'asse Z
- // Angolo generico fra movimento e versore utensile
- bool Milling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
- bool MillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ;
-
- // Componenti elementari degli utensili
- bool MillCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ;
- bool MillCyl2( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ;
- bool MillBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) ;
- bool MillConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
- bool MillConusAux( const Point3d& ptI, const Point3d& ptF, const Vector3d& vtV1, const Vector3d& vtV2, const Vector3d& vtV3,
- unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ,
- double dHei, double dMaxRad, double dMinRad, double dCoef) ;
+ // Drilling
+ bool CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir, double dHei, double dRad) ;
+ bool CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
- // Traslazioni
- bool Ball( const Point3d& ptLs, const Point3d& ptLe, double dRad) ;
+ // Milling
+ bool CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) ;
+ bool CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
- // Sottrazione per tridexel
- bool ZDrillingCB( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ;
+ // Asse di simmetria con orientazione generica
- // 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) ;
+ // Drilling
+ bool CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) ;
+ bool CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
+
+ // Milling
+ bool CompCyl_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) ;
+ bool CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ;
+ bool CompConusAux_Milling( unsigned int nGrid, 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) ;
+
+ // Generica traslazione sfera
+ bool CompBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, double dRad) ;
+
+ // BBox per utensili e solidi semplici
inline bool BoundingBox( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2,
- unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) ;
- inline bool BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2) ;
- inline bool BBoxComponent( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2,
- unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ,
- double dRad, double dTipRad, double dHei) ;
+ unsigned int& nStI, unsigned int& nStJ, unsigned int& nEnI, unsigned int& nEnJ) ;
inline bool BBoxComponent( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2,
- unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ,
+ unsigned int& nStI, unsigned int& nStJ, unsigned int& nEnI, unsigned int& nEnJ,
double dRad, double dTipRad, double dHei) ;
-
+
+ // Intersezioni
bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV,
const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ;
+ bool IntersLineZMapBBox( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) ;
+ bool IntersLineDexel( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, unsigned int nI, unsigned int nJ,
+ 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) ;
+ double& dU1, double& dU2) ;
+ bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
+ const Frame3d& CylFrame, double dL, double dR,
+ Point3d& ptInt1, Point3d& ptInt2) ;
+ bool IntersZLineCylinder( const Point3d& ptLine,
+ const Point3d& ptBase, const Point3d& ptTop, const Vector3d& vtDir, double dCylR,
+ double& dInfZ, double& dSupZ) ;
+ bool IntersLineEllipticalCylinder( const Frame3d& CircFrame, const Vector3d& vtLineDir, const Point3d& ptLineSt,
+ PNTVECTOR& ptInters, double dObCoef, double dSqRad, double dL) ;
+ bool IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir,
+ const Frame3d& ConusFrame, double dTan, double dl, double dL,
+ Point3d& ptInt1, Point3d& ptInt2) ;
+ bool IntersLineSphere( const Point3d& ptLineSt, const Vector3d& vtLineDir,
+ const Point3d& ptCenter, double dRad,
+ Point3d& ptInt1, Point3d& ptInt2) ;
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
@@ -248,47 +216,27 @@ class VolZmap : public IVolZmap, public IGeoObjRW
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Status m_nStatus ; // stato
- int m_nTempProp ; // proprietà temporanea
-
- Frame3d m_LocalFrame ;
- Frame3d m_LocalFrame2 ;
- Frame3d m_LocalFrame3 ;
- double m_dStep ;
-
- unsigned int m_nNx ; // i = 0, 1, ..., m_nNx - 1
- unsigned int m_nNy ; // j = 0, 1, ..., m_nNy - 1
- unsigned int m_nNx2 ;
- unsigned int m_nNy2 ;
- unsigned int m_nNx3 ;
- unsigned int m_nNy3 ;
- unsigned int m_nDim ;
- unsigned int m_nDim2 ;
- unsigned int m_nDim3 ;
-
- double m_dMinZ ;
- double m_dMaxZ ;
-
- double m_dMinZ2 ;
- double m_dMaxZ2 ;
-
- double m_dMinZ3 ;
- double m_dMaxZ3 ;
-
- std::vector > m_ZValues ;
- std::vector > m_ZValues2 ;
- std::vector > m_ZValues3 ;
-
- double m_dLinTol ;
- double m_dAngTolDeg ;
- std::string m_sToolName ;
- unsigned int m_nToolType ;
+ int m_nTempProp ; // proprietà temporanea
+ double m_dStep ; // passo delle griglie
+ unsigned int m_nMapNum ; // numero di griglie ( 1 o 3)
+ Frame3d m_MapFrame[3] ; // riferimenti delle griglie
+ unsigned int m_nVNx[3] ; // dimensione di ciascuna griglia in X
+ unsigned int m_nVNy[3] ; // dimensione di ciascuna griglia in Y
+ unsigned int m_nVDim[3] ; // dimensione di ciascuna griglia ( X * Y)
+ double m_dVMinZ[3] ; // minimo in Zlocale di ciascuna griglia
+ double m_dVMaxZ[3] ; // massimo in Zlocale di ciascuna griglia
+ std::vector> m_TriZValues[3] ; // dexel delle 3 griglie
+ double m_dLinTol ; // dati per utensile
+ double m_dAngTolDeg ;
+ std::string m_sToolName ;
+ unsigned int m_nToolType ;
CurveComposite m_ToolOutline ;
CurveComposite m_ToolArcLineApprox ;
- double m_dHeight ;
- double m_dTipHeight ;
- double m_dRadius ;
- double m_dRCorner ;
- double m_dTipRadius ;
+ double m_dHeight ;
+ double m_dTipHeight ;
+ double m_dRadius ;
+ double m_dRCorner ;
+ double m_dTipRadius ;
} ;
//-----------------------------------------------------------------------------
diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp
deleted file mode 100644
index ae88760..0000000
--- a/VolZmapCalculus.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-//----------------------------------------------------------------------------
-// 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
deleted file mode 100644
index 7b25667..0000000
--- a/VolZmapCreation.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-//----------------------------------------------------------------------------
-// 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
deleted file mode 100644
index 9d8bf66..0000000
--- a/VolZmapGraphics.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/VolZmapVolume.cpp b/VolZmapVolume.cpp
deleted file mode 100644
index 4ff5fd9..0000000
--- a/VolZmapVolume.cpp
+++ /dev/null
@@ -1,8524 +0,0 @@
-//----------------------------------------------------------------------------
-// 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.IsSmall()) {
- if ( m_nToolType == 0)
- return DrillingGT( ptLs, ptLe, vtDir) ;
- else
- return DrillingXY( ptLs, ptLe, vtDir) ;
- }
-
- // Movimento perpendicolare alla direzione dell'utensile
- if ( vtTLong.IsSmall()) {
- 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 ( AreSamePointXYApprox( ptLs, ptLe))
- 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.IsSmallXY())
- return MillingXYLongVert( ptLs, ptLe, vtDir) ;
-
- // Movimento perpendicolare alla direzione dell'utensile
- if ( vtTLong.IsSmallXY())
- 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.IsSmall()) {
- 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)
-{
- unsigned int nStartI, nStartJ, nEndI, nEndJ ;
- bool bControl = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ;
- if ( ! bControl)
- 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 vtV1( vtMove.x, vtMove.y, 0) ; 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() ;
-
- double dMin, dMax ;
- 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