From 7ee899b0a26b58cdbfa41874c05534692ded6b9b Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 19 Dec 2016 14:35:10 +0000 Subject: [PATCH] EgtGeomKernel 1.6x2 : - modifiche a Zmap per tridexel. --- EgtGeomKernel.rc | Bin 11718 -> 11718 bytes EgtGeomKernel.vcxproj | 8 +- EgtGeomKernel.vcxproj.filters | 20 +- GdbExecutor.cpp | 69 +- MC_Tables.h | 298 ++ VolTriZmapCalculus.cpp | 736 +++ VolTriZmapCreation.cpp | 595 +++ VolTriZmapGraphics.cpp | 1026 ++++ VolTriZmapVolume.cpp | 6204 ++++++++++++++++++++++++ VolZmap.cpp | 243 +- VolZmap.h | 266 +- VolZmapCalculus.cpp | 313 -- VolZmapCreation.cpp | 258 - VolZmapGraphics.cpp | 255 - VolZmapVolume.cpp | 8524 --------------------------------- 15 files changed, 9168 insertions(+), 9647 deletions(-) create mode 100644 MC_Tables.h create mode 100644 VolTriZmapCalculus.cpp create mode 100644 VolTriZmapCreation.cpp create mode 100644 VolTriZmapGraphics.cpp create mode 100644 VolTriZmapVolume.cpp delete mode 100644 VolZmapCalculus.cpp delete mode 100644 VolZmapCreation.cpp delete mode 100644 VolZmapGraphics.cpp delete mode 100644 VolZmapVolume.cpp diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 55956b31824a130688771b7c996e70f83e3d0005..a677cd963c5ba4ddefa9b5dca188f5171f105f88 100644 GIT binary patch delta 110 zcmX>WeJpyzA2vp#&G-4vGfl1&(wY2&Q;pGRvZAo=W*@FeEMOU1X1ItOWeJpyzA2vqA&G-4vGfl1&(wY2&Q;pGZvZAo=W*@FeEMOU1X1ItO + + + + - - - - 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