diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 55956b3..a677cd9 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 7d9fc3f..e39d247 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -357,12 +357,12 @@ copy $(TargetPath) \EgtProg\Dll64 + + + + - - - - diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index a3a03b3..4d4b58d 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -339,19 +339,19 @@ File di origine\GeoCollision - - File di origine\Geo - - - File di origine\Geo - - - File di origine\Geo - File di origine\Geo - + + File di origine\Geo + + + File di origine\Geo + + + File di origine\Geo + + File di origine\Geo diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 4ba35b8..2c496aa 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -2610,8 +2610,8 @@ GdbExecutor::ExecuteVolZmap(const string& sCmd2, const STRVECTOR& vsParams) bool GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams) { - // parametri : Id, IdParent, ptO, dPrec, dLengthX, dLengthY, dLengthZ - if ( vsParams.size() != 7) + // parametri : Id, IdParent, ptO, dLengthX, dLengthY, dLengthZ, dPrec [, bTriDexel] + if ( vsParams.size() < 7) return false ; // recupero il riferimento in cui è immerso Frame3d frRef ; @@ -2621,27 +2621,32 @@ GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams) Point3d ptO ; if ( ! GetPointParam( vsParams[2], frRef, ptO)) return false ; - // recupero precisione - double dPrec ; - if ( ! FromString( vsParams[3], dPrec)) - return false ; // recupero LunghezzaX double dLengthX ; - if ( ! FromString( vsParams[4], dLengthX)) + if ( ! FromString( vsParams[3], dLengthX)) return false ; // recupero LunghezzaY double dLengthY ; - if ( ! FromString( vsParams[5], dLengthY)) + if ( ! FromString( vsParams[4], dLengthY)) return false ; // recupero LunghezzaZ double dLengthZ ; - if ( ! FromString( vsParams[6], dLengthZ)) + if ( ! FromString( vsParams[5], dLengthZ)) return false ; + // recupero precisione + double dPrec ; + if ( ! FromString( vsParams[6], dPrec)) + return false ; + // recupero flag tipo Zmap + bool bTriDexel = false ; + if ( vsParams.size() >= 8 && vsParams[7] != "0") + bTriDexel = true ; + // creo Zmap PtrOwner pZprova( new VolZmap) ; - pZprova->Create( ptO, dLengthX, dLengthY, dLengthZ, dPrec); + pZprova->Create( ptO, dLengthX, dLengthY, dLengthZ, dPrec, bTriDexel) ; - // inserisco nel DB + // inserisco nel DB return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; } @@ -2649,8 +2654,8 @@ GdbExecutor::VolZmapCreate( const STRVECTOR& vsParams) bool GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams) { - // parametri : Id, IdParent, idCurv, dPrec, dLengthZ - if ( vsParams.size() != 5) + // parametri : Id, IdParent, idCurv, dPrec, dLengthZ [, bTriDexel] + if ( vsParams.size() < 5) return false ; // recupero il riferimento in cui è immerso Frame3d frRef ; @@ -2658,21 +2663,26 @@ GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams) return false ; // recupero id flatregion int nIdFlat = GetIdParam( vsParams[2]) ; - // recupero precisione - double dPrec ; - if ( ! FromString( vsParams[4], dPrec)) - return false ; // recupero dimensioneZ double dLengthZ ; if ( ! FromString( vsParams[3], dLengthZ)) return false ; + // recupero precisione + double dPrec ; + if ( ! FromString( vsParams[4], dPrec)) + return false ; // recupero puntatore a FlatRegion ISurfFlatRegion* pRegion = GetSurfFlatRegion( m_pGDB->GetGeoObj( nIdFlat)) ; if ( pRegion == nullptr) return false ; + // Flag tipo di mappa + bool bTriDexel = false ; + if ( vsParams.size() >= 6 && vsParams[5] != "0") + bTriDexel = true ; + // creo Zmap PtrOwner pZprova( new VolZmap) ; - pZprova->CreateFromFlatRegion( *pRegion, dLengthZ, dPrec); + pZprova->CreateFromFlatRegion( *pRegion, dLengthZ, dPrec, bTriDexel) ; // inserisco nel DB return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; @@ -2682,8 +2692,8 @@ GdbExecutor::VolZmapCreateFromFlatRegion( const STRVECTOR& vsParams) bool GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams) { - // parametri : Id, IdParent, idSurf, dPrec - if ( vsParams.size() != 4) + // parametri : Id, IdParent, idSurf, dPrec, bFlag + if ( vsParams.size() != 5) return false ; // recupero il riferimento in cui è immerso Frame3d frRef ; @@ -2695,13 +2705,17 @@ GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams) double dPrec ; if ( ! FromString( vsParams[3], dPrec)) return false ; + // Flag tipo di mappa + bool bType= false ; + if ( vsParams.size() >= 5 && vsParams[4] != "0") + bType = true ; // recupero puntatore a Trimesh SurfTriMesh* pSurf = GetBasicSurfTriMesh( m_pGDB->GetGeoObj( nIdSurf)) ; if ( pSurf == nullptr) return false ; // creo Zmap PtrOwner pZprova( new VolZmap) ; - pZprova->CreateFromTriMesh( * pSurf, dPrec); + pZprova->CreateFromTriMesh( * pSurf, dPrec, bType) ; // inserisco nel DB return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; @@ -2711,8 +2725,8 @@ GdbExecutor::VolZmapCreateFromTriMesh( const STRVECTOR& vsParams) bool GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams) { - // parametri : Id, IdParent, ptPs, ptPe, vtVs, vtVe, dLinTol, dAngTolDeg (gli ultimi due servono per lavorazione con utensile generico) - if ( vsParams.size() != 8) + // parametri : Id, IdParent, ptPs, ptPe, vtVs, vtVe, dLinTol, dAngTolDeg (dLinTol e dAngTol sono per lavo con gen tool), bType + if ( vsParams.size() != 9) return false ; // recupero il riferimento in cui è immerso Frame3d frRef ; @@ -2741,6 +2755,10 @@ GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams) double dAngTolDeg ; if ( ! FromString( vsParams[7], dAngTolDeg)) return false ; + bool bType = false ; + if ( vsParams.size() >= 9 && vsParams[2] != "0") + bType = true ; + // recupero lo Zmap int nIdZmap = GetIdParam( vsParams[0]) ; VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nIdZmap)) ; @@ -2748,7 +2766,10 @@ GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams) return false ; // eseguo la lavorazione pZmap->SetTolerances( dLinTol, dAngTolDeg) ; - return pZmap->MillingStep( ptPs, vtDs, ptPe, vtDe) ; + //if ( bType) + return pZmap->MillingStep( ptPs, vtDs, ptPe, vtDe) ; + //else + // return pZmap->MillingStep( ptPs, vtDs, ptPe, vtDe) ; } //---------------------------------------------------------------------------- diff --git a/MC_Tables.h b/MC_Tables.h new file mode 100644 index 0000000..0869577 --- /dev/null +++ b/MC_Tables.h @@ -0,0 +1,298 @@ + +// Tabella segmenti +static int EdgeTable[256] = { + + 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, + 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, + 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, + 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, + 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, + 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, + 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, + 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, + 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, + 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, + 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, + 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, + 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, + 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, + 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , + 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, + 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, + 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, + 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, + 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, + 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, + 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, + 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, + 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, + 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, + 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, + 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, + 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, + 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, + 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, + 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, + 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 +} ; + +// Tabella triangoli +static int TriangleTable[256][16] = { + + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1}, + {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1}, + {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1}, + {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1}, + {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1}, + {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1}, + {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, + {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, + {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, + {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1}, + {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, + {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}, + {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1}, + {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, + {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1}, + {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, + {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1}, + {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, + {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1}, + {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1}, + {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, + {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1}, + {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}, + {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1}, + {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1}, + {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1}, + {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, + {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1}, + {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1}, + {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, + {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1}, + {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1}, + {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, + {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1}, + {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, + {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, + {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1}, + {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1}, + {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1}, + {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, + {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, + {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1}, + {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1}, + {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, + {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1}, + {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, + {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, + {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, + {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1}, + {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1}, + {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, + {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1}, + {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1}, + {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, + {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1}, + {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, + {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1}, + {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, + {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1}, + {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1}, + {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, + {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, + {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1}, + {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, + {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1}, + {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, + {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, + {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, + {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1}, + {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}, + {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1}, + {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1}, + {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, + {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1}, + {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, + {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1}, + {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, + {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1}, + {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, + {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1}, + {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, + {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, + {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, + {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, + {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1}, + {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, + {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1}, + {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, + {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1}, + {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1}, + {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, + {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1}, + {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, + {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1}, + {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1}, + {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, + {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +} ; \ No newline at end of file diff --git a/VolTriZmapCalculus.cpp b/VolTriZmapCalculus.cpp new file mode 100644 index 0000000..36d58ce --- /dev/null +++ b/VolTriZmapCalculus.cpp @@ -0,0 +1,736 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (tre griglie) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- + +#include "stdafx.h" +#include "CurveLine.h" +#include "VolZmap.h" +#include "GeoConst.h" +#include "IntersLineSurfTm.h" +#include "\EgtDev\Include\EgtNumUtils.h" + + +using namespace std ; + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, + const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) +{ + // Il box è allineato agli assi + + dU1 = - INFINITO ; + dU2 = INFINITO ; + + // confronto con piani YZ (perpendicolari ad asse X) + if ( vtV.x > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ; + dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ; + } + else if ( vtV.x < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ; + dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ; + } + else if ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL) + return false ; + + // confronto con piani ZX (perpendicolari ad asse Y) + if ( vtV.y > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ; + dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ; + } + else if ( vtV.y < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ; + dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ; + } + else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL) + return false ; + + // confronto con piani XZ (perpendicolari ad asse Z) + if ( vtV.z > EPS_ZERO) { + dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ; + dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ; + } + else if ( vtV.z < - EPS_ZERO) { + dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ; + dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ; + } + else if ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL) + return false ; + + return ( dU2 >= dU1) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineZMapBBox( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) +{ + // Punti estremi del box dello Zmap + Point3d ptMin = ORIG ; + Point3d ptMax = ptMin + Vector3d( m_nVNx[nGrid] * m_dStep, m_nVNy[nGrid] * m_dStep, m_dVMaxZ[nGrid]) ; + + return ( IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) && ( dU1 > 0 || dU2 > 0)) ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineDexel( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, unsigned int nI, + unsigned int nJ, double& dU1, double& dU2) +{ + // Determino l'indice del dexel e il doppio del numero di suo intervalli + unsigned int nDexelPos = nJ * m_nVNx[nGrid] + nI ; + unsigned int nDexelSize = unsigned int( m_TriZValues[nGrid][nDexelPos].size()) ; + + // Se non c'è materiale non devo fare alcunché + if ( nDexelSize == 0) + return false ; + + // Determino estremi nel piano XY intrinseco del dexel + double dXmin = nI * m_dStep ; + double dYmin = nJ * m_dStep ; + double dXmax = ( nI + 1) * m_dStep ; + double dYmax = ( nJ + 1) * m_dStep ; + + // ciclo sugli intervalli + dU1 = INFINITO ; + dU2 = - INFINITO ; + bool bInters = false ; + for ( unsigned int nIndex = 0 ; nIndex < nDexelSize ; nIndex += 2) { + // estremi del box del singolo intervallo + Point3d ptE1( dXmin, dYmin, m_TriZValues[nGrid][nDexelPos][nIndex]) ; + Point3d ptE2( dXmax, dYmax, m_TriZValues[nGrid][nDexelPos][nIndex+1]) ; + double dt1, dt2 ; + if ( IntersLineBox( ptP, vtV, ptE1, ptE2, dt1, dt2)) { + bInters = true ; + dU1 = min( dU1, dt1) ; + dU2 = max( dU2, dt2) ; + } + } + + return bInters ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLength, double& dOutLength) +{ + // Porto il raggio nel riferimento intrinseco + Point3d ptP = ptPGlob ; + ptP.ToLoc( m_MapFrame[0]) ; + Vector3d vtV = vtDir ; + vtV.ToLoc( m_MapFrame[0]) ; + vtV.Normalize() ; + + // Studio dell'intersezione fra semiretta e BBox dello Zmap + double dU1, dU2 ; + bool bTest = IntersLineZMapBBox( 0, ptP, vtV, dU1, dU2) ; + + // Semiretta esterna al box dello Zmap + if ( ! bTest) { + dInLength = - 2 ; + dOutLength = - 2 ; + return true ; + } + + Point3d ptI, ptF ; + // Una sola intersezione valida ( punto interno, intersezione valida 2) + if ( dU1 < 0 && dU2 > 0) { + ptI = ptP ; + ptF = ptP + dU2 * vtV ; + } + // due soluzioni valide ( punto esterno) + else { + ptI = ptP + dU1 * vtV ; + ptF = ptP + dU2 * vtV ; + } + + // Determinazione degli indici i j dei punti ptI e ptF + int nIi = Clamp( int( floor( ptI.x / m_dStep)), 0, m_nVNx[0] - 1) ; + int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nVNy[0] - 1) ; + int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nVNx[0] - 1) ; + int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nVNy[0] - 1) ; + + // Inizializzo distanze + dInLength = INFINITO ; + dOutLength = - INFINITO ; + + // Variazioni + double dDeltaX = ptF.x - ptI.x ; + double dDeltaY = ptF.y - ptI.y ; + + // se inclinazione da asse X minore di 45 gradi (in assoluto) + if ( abs( dDeltaY) <= abs( dDeltaX)) { + // mi muovo lungo X (i) + int nIncrI = ( nFi >= nIi ? 1 : - 1) ; + for ( int i = nIi, j = nIj ; + i != nFi + nIncrI ; + i += nIncrI) { + + // Controllo con nuovo i e j corrente (considero il bordo sinistro del dexel) + double dU1, dU2 ; + if ( IntersLineDexel( 0, ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + + // Mi sposto sul bordo destro del dexel + double dMoveX = ( ( i + max( nIncrI, 0)) * m_dStep - ptI.x) ; + double dMoveY = dMoveX * dDeltaY / dDeltaX ; + double dY = ptI.y + dMoveY ; + int OldJ = j ; + j = Clamp( int( floor( dY / m_dStep)), 0, m_nVNy[0] - 1) ; + + // Analisi del dexel + if ( j != OldJ) { + double dU1, dU2 ; + if ( IntersLineDexel( 0, ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + } + } + } + + // altrimenti + else { + // mi muovo lungo Y (j) + int nIncrJ = ( nFj >= nIj ? 1 : - 1) ; + for ( int i = nIi, j = nIj ; + j != nFj + nIncrJ ; + j += nIncrJ) { + + // Controllo con nuovo j e i corrente (considero il bordo sotto del dexel) + double dU1, dU2 ; + if ( IntersLineDexel( 0, ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + + // Mi sposto sul bordo sopra del dexel + double dMoveY = ( ( j + max( nIncrJ, 0)) * m_dStep - ptI.y) ; + double dMoveX = dMoveY * dDeltaX / dDeltaY ; + double dX = ptI.x + dMoveX ; + int OldI = i ; + i = Clamp( int( floor( dX / m_dStep)), 0, m_nVNx[0] - 1) ; + + // Analisi del dexel + if ( i != OldI) { + double dU1, dU2 ; + if ( IntersLineDexel( 0, ptP, vtV, i, j, dU1, dU2)) { + dInLength = min( dInLength, dU1) ; + dOutLength = max( dOutLength, dU2) ; + } + } + } + } + + // Se non abbiamo incontrato materiale + if ( dInLength > dOutLength - EPS_SMALL) { + dInLength = - 2 ; + dOutLength = - 2 ; + return true ; + } + + // Se parto dall'interno + if ( dInLength < - EPS_SMALL) + dInLength = - 1 ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) +{ + // BBox + BBox3d b3Box( ORIG, ORIG + vtDiag) ; + + // lo porto nel riferimento intrinseco dello Zmap + b3Box.LocToLoc( frBox, m_MapFrame[0]) ; + + // BBox dello Zmap nel suo riferimento intrinseco + BBox3d b3Zmap( ORIG, Point3d( m_nVNx[0] * m_dStep, m_nVNy[0] * m_dStep, m_dVMaxZ[0])) ; + + // Se non interferiscono, posso uscire + BBox3d b3Int ; + if ( ! b3Zmap.FindIntersection( b3Box, b3Int)) + return true ; + + // Limiti su indici + int nStI = Clamp( int( b3Int.GetMin().x / m_dStep), 0, m_nVNx[0] -1) ; + int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nVNx[0] -1) ; + int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nVNy[0] -1) ; + int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nVNy[0] -1) ; + + // Vettore direzione dei dexel nel riferimento del Box + Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame[0], frBox) ; + + // Riferimento intrinseco dei dexel nel riferimento del box + Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame[0], frBox) ; + Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame[0], frBox) ; + Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame[0], frBox) ; + + // Ciclo di intersezione dei dexel con il BBox + for ( int i = nStI ; i <= nEnI ; ++ i) { + + for ( int j = nStJ ; j <= nEnJ ; ++ j) { + + int nPos = j * m_nVNx[0] + i ; + int nSize = int( m_TriZValues[0][nPos].size()) ; + if ( nSize == 0) + continue ; + + Point3d ptC = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ; + + double dZmin, dZmax ; + if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) { + + for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 2) { + if ( ! ( dZmax < m_TriZValues[0][nPos][nIndex] - EPS_SMALL || + dZmin > m_TriZValues[0][nPos][nIndex + 1] + EPS_SMALL)) + return false ; + } + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, + const Frame3d& CylFrame, double dL, double dR, + Point3d& ptInt1, Point3d& ptInt2) +{ + // NB: L'origine del sistema di riferimento deve essere + // nel centro della circonferenza di base e l'asse di simmetria + // deve coincidere con l'asse x. + // La funzione restituisce true in caso di intersezione, + // false altrimenti. + + Point3d ptP = ptLineSt ; + Vector3d vtV = vtLineDir ; + + // Trasformazione delle coordinate + ptP.ToLoc( CylFrame) ; + vtV.ToLoc( CylFrame) ; + + DBLVECTOR vdCoef(3) ; + DBLVECTOR vdRoots ; + + double dSqRad = dR * dR ; + + vdCoef[0] = ptP.y * ptP.y + ptP.z * ptP.z - dSqRad ; + vdCoef[1] = 2 * ( ptP.y * vtV.y + ptP.z * vtV.z) ; + vdCoef[2] = vtV.y * vtV.y + vtV.z * vtV.z ; + + // Computo radici + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // Nessuna soluzione + if ( nRoot == 0) { + + if ( abs( vtV.x) > EPS_ZERO) { + + ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + if ( ptInt1.y * ptInt1.y + ptInt1.z * ptInt1.z <= dSqRad && + ptInt2.y * ptInt2.y + ptInt2.z * ptInt2.z <= dSqRad) { + + ptInt1.ToGlob( CylFrame) ; + ptInt2.ToGlob( CylFrame) ; + + return true ; + } + // Nessuna intersezione + else + return false ; + } + // Nessuna intersezione + else + return false ; + } + + // L'equazione ammette o due soluzioni (eventualmente + // coincidenti) oppure nessuna o infinite se la la retta + // appartiene alla superficie + + if ( nRoot == 2) { + + ptInt1 = ptP + vdRoots[0] * vtV ; + ptInt2 = ptP + vdRoots[1] * vtV ; + + if ( ptInt1.x > ptInt2.x) + swap( ptInt1, ptInt2) ; + + if ( ptInt1.x < 0 && ptInt2.x >= 0 && ptInt2.x <= dL) { + + ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; + } + else if ( ptInt1.x < 0 && ptInt2.x > dL) { + + ptInt1 = ptP - ( ptP.x / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + else if ( ptInt1.x >= 0 && ptInt2.x <= dL) { + + ; + } + else if ( ptInt1.x >= 0 && ptInt1.x < dL && ptInt2.x >= dL) { + + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + // Intersezioni esterne alla regione di interesse + // (quella compresa fra 0 e dL) + else + return false ; + + // Riporto le coordinate nel sistema di riferimento griglia + ptInt1.ToGlob( CylFrame) ; + ptInt2.ToGlob( CylFrame) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersZLineCylinder( const Point3d& ptLine, + const Point3d& ptBase, const Point3d& ptTop, const Vector3d& vtDir, double dCylR, + double& dInfZ, double& dSupZ) +{ + // NB: Le coordinate sono espresse nel sistema griglia + // La funzione restituisce true in caso di intersezione, + // false altrimenti. + + double dSqRad = dCylR * dCylR ; + + // Cilindro verticale + if ( AreSamePointXYApprox( ptBase, ptTop)) { + + // Intersezione + if ( SqDistXY( ptLine, ptBase) <= dSqRad) { + dInfZ = min( ptBase.z, ptTop.z) ; + dSupZ = max( ptBase.z, ptTop.z) ; + return true ; + } + + // Non vi è intersezione + else + return false ; + } + + // Cilindro non verticale + else { + + // Studio delle simmetrie + Point3d ptS = ( ptBase.z < ptTop.z ? ptBase : ptTop) ; + Point3d ptE = ( ptBase.z < ptTop.z ? ptTop : ptBase) ; + + Vector3d vtV1 = ptE - ptS ; vtV1.z = 0 ; + + double dLenXY = vtV1.LenXY() ; + double dSZ = ptS.z ; + double dEZ = ptE.z ; + double dDeltaZ = dEZ - dSZ ; + + Vector3d vtL( ptLine.x - ptS.x, ptLine.y - ptS.y, 0) ; + + // vtV1 e vtV2 formano un sistema ortonormale + // sul piano e insieme a ptSxy formano un sistema + // di riferimento bidimensionale + vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; + vtV2.Rotate( Z_AX, 90) ; + + double dLen = ( ptE - ptS).Len() ; + + // Sono seno e coseno dell'angolo complementare + // rispetto a quello formato dal vettore movimento + // con il piano, per questo motivo si ha dCos con + // dDeltaZ e dSin con dLenXY + double dCos = dDeltaZ / dLen ; + double dSin = dLenXY / dLen ; + + // Nuove coordinate piane del punto + double dLocX1 = vtL * vtV1 ; + double dLocX2 = vtL * vtV2 ; + + double dSqRoot = sqrt( dSqRad - dLocX2 * dLocX2) ; + double dX1_0 = dCos * dSqRoot ; + + if ( dLocX1 >= - dX1_0 && dLocX1 <= dLenXY + dX1_0 && + abs( dLocX2) < dCylR) { + + // Minimi + if ( dLocX1 < dX1_0) { + + double dDotS = vtDir * ( ptS - ORIG) ; + // Qui usiamo ptLine perché servono coordinate griglia + dInfZ = ( dDotS - vtDir.x * ptLine.x - vtDir.y * ptLine.y) / vtDir.z ; + } + else { + + double dZ0 = - dSin * dSqRoot ; + + dInfZ = dSZ + dZ0 + ( dLocX1 - dX1_0) * dDeltaZ / dLenXY ; + } + + // Massimi + if ( dLocX1 < dLenXY - dX1_0) { + + double dZ0 = dSin * dSqRoot ; + + dSupZ = dSZ + dZ0 + ( dLocX1 - dX1_0) * dDeltaZ / dLenXY ; + } + else { + + double dDotE = vtDir * ( ptE - ORIG) ; + // Qui usiamo ptLine perché servono coordinate griglia + dSupZ = ( dDotE - vtDir.x * ptLine.x - vtDir.y * ptLine.y) / vtDir.z ; + } + + return true ; + } + + return false ; + } +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, + const Frame3d& ConusFrame, double dTan, double dl, double dL, + Point3d& ptInt1, Point3d& ptInt2) +{ + // NB: L'origine del sistema di riferimento deve essere + // nel vertice del cono e l'asse di simmetria deve coincidere + // con l'asse x. + // La funzione restituisce true in caso di intersezione, + // false altrimenti. + + Point3d ptP = ptLineSt ; + Vector3d vtV = vtLineDir ; + + // Trasformazione delle coordinate + ptP.ToLoc( ConusFrame) ; + vtV.ToLoc( ConusFrame) ; + + DBLVECTOR vdCoef(3) ; + DBLVECTOR vdRoots ; + + double dSqTan = dTan * dTan ; + + vdCoef[0] = dSqTan * ptP.x * ptP.x - ptP.y * ptP.y - ptP.z * ptP.z ; + vdCoef[1] = 2 * ( dSqTan * ptP.x * vtV.x - ptP.y * vtV.y - ptP.z * vtV.z) ; + vdCoef[2] = dSqTan * vtV.x * vtV.x - vtV.y * vtV.y - vtV.z * vtV.z ; + + // Computo radici + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + // Nessuna soluzione + if ( nRoot == 0) + return false ; + + // Una soluzione: la retta iterseca superficie + // laterale e un piano + if ( nRoot == 1) { + + ptInt1 = ptP + vdRoots[0] * vtV ; + + if ( ptInt1.x >= dl && ptInt1.x < dL) { + + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + else if ( ptInt1.x >= 0 && ptInt1.x < dl) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + + // Riporto le coordinate nel sistema di riferimento + // griglia + ptInt1.ToGlob( ConusFrame) ; + ptInt2.ToGlob( ConusFrame) ; + } + // Due soluzioni: la retta interseca due volte la + // superficie laterale + else if ( nRoot == 2) { + + ptInt1 = ptP + vdRoots[0] * vtV ; + ptInt2 = ptP + vdRoots[1] * vtV ; + + if ( ptInt1.x > ptInt2.x) { + swap( ptInt1, ptInt2) ; + } + + if ( ptInt1.x < 0 && ptInt2.x > 0 && ptInt2.x < dl) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + else if ( ptInt1.x < 0 && ptInt2.x >= dl && ptInt2.x < dL) { + + ptInt1 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + else if ( ptInt1.x > 0 && ptInt1.x < dl && ptInt2.x >= dl && ptInt2.x < dL) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + } + else if ( ptInt1.x > 0 && ptInt1.x < dl && ptInt2.x >= dL) { + + ptInt1 = ptP + ( ( dl - ptP.x) / vtV.x) * vtV ; + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + else if ( ptInt1.x >= dl && ptInt1.x < dL && ptInt2.x < dL) { + + ; + } + else if ( ptInt1.x >= dl && ptInt1.x < dL && ptInt2.x >= dL) { + + ptInt2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + // Intersezioni esterne alla regione di interesse + // (quella compresa fra dl e dL) + else + return false ; + + // Riporto le coordinate nel sistema di riferimento + // griglia + ptInt1.ToGlob( ConusFrame) ; + ptInt2.ToGlob( ConusFrame) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersLineEllipticalCylinder( const Frame3d & CircFrame, const Vector3d & vtLineDir, const Point3d & ptLineSt, + std::vector & ptInters, double dObCoef, double dSqRad, double dL) +{ + // NB: L'origine del sistema di riferimento deve essere + // nel centro della circonferenza di base, la cui tralsazione obliqua + // genera il cilindro ellittico, e l'asse x deve essere l'asse + // di simmetria di tale circonferenza. + // La funzione restituisce true in caso di intersezione, + // false altrimenti. + // NB: Il Parametro dObCoef è il coeffociente angolare della retta movimento + // rispetto all'asse x, e dSqRad è il quadrato del raggio della circonferenza. + + double dSqCoef = dObCoef * dObCoef ; + + Point3d ptP = ptLineSt ; + Vector3d vtV = vtLineDir ; + + // Sistema di riferimanto grigia + Frame3d GridFrame ; + GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; + + // Trasformazione delle coordinate + ptP.LocToLoc( GridFrame, CircFrame) ; + vtV.LocToLoc( GridFrame, CircFrame) ; + + std::vector vdCoef(3) ; + std::vector vdRoots ; + + vdCoef[0] = dSqCoef * ptP.x * ptP.x + ptP.y * ptP.y + ptP.z * ptP.z - 2 * dObCoef * ptP.x * ptP.y - dSqRad ; + vdCoef[1] = 2 * ( dSqCoef * vtV.x * ptP.x + vtV.y * ptP.y + vtV.z * ptP.z - dObCoef * ( vtV.x * ptP.y + vtV.y * ptP.x)) ; + vdCoef[2] = dSqCoef * vtV.x * vtV.x + vtV.y * vtV.y + vtV.z * vtV.z - 2 * dObCoef * vtV.x * vtV.y ; + + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + Point3d ptR1, ptR2 ; + + // Nessuna soluzione + if ( nRoot == 0) { + + if ( abs( vtV.x) > EPS_ZERO) { + + ptR1 = ptP - ( ptP.x / vtV.x) * vtV ; + ptR2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + + if ( ptR1.y * ptR1.y + ptR1.z * ptR1.z < dSqRad && + ptR1.y * ptR1.y + ptR1.z * ptR1.z < dSqRad) { + + ptR1.LocToLoc( CircFrame, GridFrame) ; + ptR2.LocToLoc( CircFrame, GridFrame) ; + + ptInters.resize(2) ; + + ptInters[0] = ptR1 ; + ptInters[0] = ptR2 ; + + return true ; + } + // Nessuna intersezione + else + return false ; + } + // Nessuna intersezione + else + return false ; + } + + // L'equazione ammette o due soluzioni (eventualmente + // coincidenti) oppure nessuna o infinite se la la retta + // appartiene alla superficie + + ptInters.resize(2) ; + + if ( nRoot == 2) { + + ptR1 = ptP + vdRoots[0] * vtV ; + ptR2 = ptP + vdRoots[1] * vtV ; + + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x >= 0 && ptR1.x < dL && + ptR2.x > dL) { + + ptR1 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + else if ( ptR1.x >= 0 && ptR2.x <= dL) { + + ; + } + else if ( ptR1.x < 0 && ptR2.x > dL) { + + ptR1 = ptP - ( ptP.x / vtV.x) * vtV ; + ptR2 = ptP + ( ( dL - ptP.x) / vtV.x) * vtV ; + } + else if ( ptR1.x < 0 && ptR2.x >= 0 && ptR2.x <= dL) { + + ptR1 = ptP - ( ptP.x / vtV.x) * vtV ; + } + + // Riporto le coordinate nel sistema di riferimento + // griglia + ptR1.LocToLoc( CircFrame, GridFrame) ; + ptR2.LocToLoc( CircFrame, GridFrame) ; + + ptInters[0] = ptR1 ; + ptInters[1] = ptR2 ; + } + + return true ; +} \ No newline at end of file diff --git a/VolTriZmapCreation.cpp b/VolTriZmapCreation.cpp new file mode 100644 index 0000000..2936b89 --- /dev/null +++ b/VolTriZmapCreation.cpp @@ -0,0 +1,595 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (tre griglie) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- + +#include "stdafx.h" +#include "CurveLine.h" +#include "VolZmap.h" +#include "GeoConst.h" +#include "IntersLineSurfTm.h" +#include "\EgtDev\Include\EgtNumUtils.h" + + +using namespace std ; + +// ------------------------- CREAZIONE MAPPA -------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec, bool bFlag) +{ + + // Controlli l'ammissibilità delle dimensioni lineari del grezzo e del passo + if ( dPrec < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) + return false ; + + // Aggiorno il passo + m_dStep = dPrec ; + + // Aggiorno la dimensione della mappa 1 o 3 + m_nMapNum = ( bFlag ? 3 : 1) ; + + // Disponendo i sistemi di riferimento in una successione, le coordinate x,y,z + // di uno si ottengono da una permutazione ciclica di quelle del precedente sistema. + // es: X(n) = Z(n-1), Y(n) = X(n-1), Z(n) = Y(n-1) + + // Definisco i sistemi di riferimento + m_MapFrame[0].Set( ptO, X_AX, Y_AX, Z_AX) ; + + // Definisco i vettori dei limiti su indici + m_nVNx[0] = static_cast ( ceil( dLengthX / m_dStep)) ; + m_nVNy[0] = static_cast ( ceil( dLengthY / m_dStep)) ; + + if ( m_nMapNum > 1) { + + m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ; + m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ; + + m_nVNx[1] = static_cast ( ceil( dLengthY / m_dStep)) ; + m_nVNy[1] = static_cast ( ceil( dLengthZ / m_dStep)) ; + + m_nVNx[2] = static_cast ( ceil( dLengthZ / m_dStep)) ; + m_nVNy[2] = static_cast ( ceil( dLengthX / m_dStep)) ; + } + else { + + m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ; + m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ; + + m_nVNx[1] = 0 ; + m_nVNy[1] = 0 ; + + m_nVNx[2] = 0 ; + m_nVNy[2] = 0 ; + } + + // Definizione della mappa + + // Creazione delle mappe + // Calcolo del numero di celle per ogni mappa + for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) + + m_nVDim[i] = m_nVNx[i] * m_nVNy[i] ; + + // Creazione delle celle per ogni mappa + for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) + + m_TriZValues[i].resize( m_nVDim[i]) ; + + // Riempimento delle celle + for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) + for ( unsigned int j = 0 ; j < m_nVDim[i] ; ++ j) { + + m_TriZValues[i][j].resize(2) ; + + m_TriZValues[i][j][0] = 0 ; + + if ( i == 0) + m_TriZValues[i][j][1] = dLengthZ ; + else if ( i == 1) + m_TriZValues[i][j][1] = dLengthX ; + else if ( i == 2) + m_TriZValues[i][j][1] = dLengthY ; + } + + // Definizione delle limitazioni iniziali in Z per ogni mappa + for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) { + + m_dVMinZ[i] = 0 ; + + if ( i == 0) + m_dVMaxZ[i] = dLengthZ ; + else if ( i == 1) + m_dVMaxZ[i] = dLengthX ; + else if ( i == 2) + m_dVMaxZ[i] = dLengthY ; + } + + // Aggiornamento dello stato + m_nStatus = OK ; + + return true ; +} + +bool +VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec, bool bFlag) +{ + + Point3d ptMapOrig, ptMapEnd ; + + // Aggiorno la dimensione della mappa 1 o 3 + m_nMapNum = ( bFlag ? 3 : 1) ; + + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + m_dStep = max( dPrec, 100 * EPS_SMALL) ; + + // Determino il bounding box della flat region + BBox3d SurfBBox ; + Surf.GetLocalBBox( SurfBBox, BBF_EXACT) ; + + // Determino i punti estremi del bounding box + SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; + + // Sistema di riferimento mappa + m_MapFrame[0].Set( ptMapOrig, X_AX, Y_AX, Z_AX) ; + + + // Determino le dimensioni lineari X Y della griglia + double dLengthX = ptMapEnd.x - ptMapOrig.x ; + double dLengthY = ptMapEnd.y - ptMapOrig.y ; + + // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe + // della griglia Zmap e da questi la dimensione del vettore di dexel + m_nVNx[0] = static_cast ( ceil( dLengthX / m_dStep)) ; + m_nVNy[0] = static_cast ( ceil( dLengthY / m_dStep)) ; + + m_nVDim[0] = m_nVNx[0] * m_nVNy[0] ; + + // Ridimensiono il vettore di dexel e creo lo Zmap + m_TriZValues[0].resize( m_nVDim[0]) ; + + // Se Tridexel ridimensiono anche gli altri vettori + if ( bFlag) { + + m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ; + m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ; + + m_nVNx[1] = static_cast ( ceil( dLengthY / m_dStep)) ; + m_nVNy[1] = static_cast ( ceil( dDimZ / m_dStep)) ; + + m_nVDim[1] = m_nVNx[1] * m_nVNy[1] ; + + m_nVNx[2] = static_cast ( ceil( dDimZ / m_dStep)) ; + m_nVNy[2] = static_cast ( ceil( dLengthX / m_dStep)) ; + + m_nVDim[2] = m_nVNx[2] * m_nVNy[2] ; + + m_TriZValues[1].resize( m_nVDim[1]) ; + m_TriZValues[2].resize( m_nVDim[2]) ; + } + else { + + m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ; + m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ; + + m_nVNx[1] = 0 ; + m_nVNy[1] = 0 ; + + m_nVDim[1] = 0 ; + + m_nVNx[2] = 0 ; + m_nVNy[2] = 0 ; + + m_nVDim[2] = 0 ; + } + + // Determinazione e ridimensionamento dei dexel + // interni alla regione + + // Griglia 0 + for ( unsigned int i = 0 ; i < m_nVNx[0] ; ++ i) { + + // Definisco la retta da intersecare con la regione + double dX = ( i + 0.5) * m_dStep ; + Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; + CurveLine GridLine ; + GridLine.SetPVL( ptP0, Y_AX, dLengthY) ; + + // Determino le intersezioni della retta con la regione + CRVCVECTOR IntersectionResults ; + Surf.GetCurveClassification( GridLine, IntersectionResults) ; + // Parti di cui la retta analizzata è composta + int nPart = int( IntersectionResults.size()) ; + + // Analizzo le parti + for ( int k = 0 ; k < nPart ; ++ k) { + + // Tipo di curva + int nType = IntersectionResults[k].nClass ; + + // Parametri iniziale e finale + double dt1 = IntersectionResults[k].dParS ; + double dt2 = IntersectionResults[k].dParE ; + + // Se la retta è interna alla regione o coincidente con parte della sua frontiera + if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { + + // Indici corrispondenti alle coordinate dei punti + int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep + 0.5)), 0, m_nVNy[0] - 1) ; + int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep - 0.5)), 0, m_nVNy[0] - 1) ; + + // Ridimensiono e riempio i dexel + for ( int j = nStartJ ; j <= nEndJ ; ++ j) { + // Determino il dexel + int nPos0 = j * m_nVNx[0] + i ; + + m_TriZValues[0][nPos0].resize( 2) ; + // Aggiorno le quote estreme del segmento + m_TriZValues[0][nPos0][0] = 0 ; + m_TriZValues[0][nPos0][1] = dDimZ ; + } + + // Se tridexel riempio i singoli dexel della + // griglia 2 con gli intervalli + if ( bFlag) { + + for ( size_t a = 0 ; a < m_nVNx[2] ; ++ a) { + + size_t nPos2 = i * m_nVNx[2] + a ; + + size_t nCurrentSize = m_TriZValues[2][nPos2].size( ) ; + + m_TriZValues[2][nPos2].resize( nCurrentSize + 2) ; + + m_TriZValues[2][nPos2][nCurrentSize] = dt1 * dLengthY ; + m_TriZValues[2][nPos2][nCurrentSize + 1] = dt2 * dLengthY ; + } + } + } + } + } + + // Se tridexel resta la griglia 1 + if ( bFlag) { + + for ( unsigned int i = 0 ; i < m_nVNx[1] ; ++ i) { + + // Definisco la retta da intersecare con la regione + double dX = ( i + 0.5) * m_dStep ; + Point3d ptP0 = ptMapOrig + Vector3d( 0, dX, 0) ; + CurveLine GridLine ; + GridLine.SetPVL( ptP0, X_AX, dLengthX) ; + + // Determino le intersezioni della retta con la regione + CRVCVECTOR IntersectionResults ; + Surf.GetCurveClassification( GridLine, IntersectionResults) ; + // Parti di cui la retta analizzata è composta + int nPart = int( IntersectionResults.size()) ; + + // Analizzo le parti + for ( int k = 0 ; k < nPart ; ++ k) { + + // Tipo di curva + int nType = IntersectionResults[k].nClass ; + + // Se la retta è interna alla regione o coincidente con parte della sua frontiera + if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { + + // Parametri iniziale e finale + double dt1 = IntersectionResults[k].dParS ; + double dt2 = IntersectionResults[k].dParE ; + + for ( size_t j = 0 ; j < m_nVNy[1] ; ++ j) { + + size_t nPos1 = j * m_nVNx[1] + i ; + + size_t nCurrentSize = m_TriZValues[1][nPos1].size( ) ; + + m_TriZValues[1][nPos1].resize( nCurrentSize + 2) ; + + m_TriZValues[1][nPos1][nCurrentSize] = dt1 * dLengthX ; + m_TriZValues[1][nPos1][nCurrentSize + 1] = dt2 * dLengthX ; + } + } + } + } + } + + + m_dVMinZ[0] = 0 ; + m_dVMaxZ[0] = dDimZ ; + + if ( bFlag) { + + m_dVMinZ[1] = 0 ; + m_dVMaxZ[1] = dLengthX ; + m_dVMinZ[2] = 0 ; + m_dVMaxZ[2] = dLengthY ; + } + else { + + m_dVMinZ[1] = 0 ; + m_dVMaxZ[1] = 0 ; + m_dVMinZ[2] = 0 ; + m_dVMaxZ[2] = 0 ; + } + + // Aggiornamento dello stato + m_nStatus = OK ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bFlag) +{ + // Se la superficie non è chiusa non ha senso continuare + if ( ! Surf.IsClosed()) + return false ; + + // Aggiorno la dimensione della mappa 1 o 3 + m_nMapNum = ( bFlag ? 3 : 1) ; + + // Determino il bounding box della TriMesh + BBox3d SurfBBox ; + Surf.GetLocalBBox( SurfBBox) ; + + // Determino i punti estremi del bounding box + Point3d ptMapOrig, ptMapEnd ; + SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; + + // Sistema di riferimento mappa + m_MapFrame[0].Set( ptMapOrig, Frame3d::TOP) ; + + // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL + m_dStep = max( dPrec, 100 * EPS_SMALL) ; + + // Determino le dimensioni lineari del BBox + double dLengthX = ptMapEnd.x - ptMapOrig.x ; + double dLengthY = ptMapEnd.y - ptMapOrig.y ; + double dLengthZ = ptMapEnd.z - ptMapOrig.z ; + + + // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe + // della griglia Zmap e da questi la dimensione del vettore di dexel + m_nVNx[0] = static_cast ( ceil( dLengthX / m_dStep)) ; + m_nVNy[0] = static_cast ( ceil( dLengthY / m_dStep)) ; + + m_nVDim[0] = m_nVNx[0] * m_nVNy[0] ; + + // Ridimensiono il vettore di dexel e creo lo Zmap + m_TriZValues[0].resize( m_nVDim[0]) ; + + // Se Tridexel ridimensiono anche gli altri vettori + if ( bFlag) { + + m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ; // Sarà Front Left + m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ; + + m_nVNx[1] = static_cast ( ceil( dLengthY / m_dStep)) ; + m_nVNy[1] = static_cast ( ceil( dLengthZ / m_dStep)) ; + + m_nVDim[1] = m_nVNx[1] * m_nVNy[1] ; + + m_nVNx[2] = static_cast ( ceil( dLengthZ / m_dStep)) ; + m_nVNy[2] = static_cast ( ceil( dLengthX / m_dStep)) ; + + m_nVDim[2] = m_nVNx[2] * m_nVNy[2] ; + + m_TriZValues[1].resize( m_nVDim[1]) ; + m_TriZValues[2].resize( m_nVDim[2]) ; + } + + + // Oggetto per calcolo massivo intersezioni + IntersParLinesSurfTm intPLSTM( m_MapFrame[0], Surf) ; + + // Determinazione e ridimensionamento dei dexel interni alla trimesh + for ( unsigned int i = 0 ; i < m_nVNx[0] ; ++ i) { + for ( unsigned int j = 0 ; j < m_nVNy[0] ; ++ j) { + + // Definisco la retta da intersecare con la trimesh + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + Point3d ptP0( dX, dY, 0) ; + + // Determino le intersezioni della retta con la TriMesh + ILSIVECTOR IntersectionResults ; + intPLSTM.GetInters( ptP0, dLengthZ, IntersectionResults) ; + + int nInt = int( IntersectionResults.size()) ; + + unsigned int nPos = j * m_nVNx[0] + i ; + + bool bInside = false ; + Point3d ptIn ; + for ( int k = 0 ; k < nInt ; ++ k) { + + int nIntType = IntersectionResults[k].nILTT ; + + // Se c'è intersezione + if ( nIntType != ILTT_NO) { + + double dCos = IntersectionResults[k].dCosDN ; + + // entro nella superficie trimesh + if ( dCos < - EPS_SMALL) { + + ptIn = IntersectionResults[k].ptI ; + + bInside = true ; + } + + // esco dalla superficie trimesh + else if ( dCos > EPS_SMALL && bInside) { + + Point3d ptOut = IntersectionResults[k].ptI ; + + unsigned int nCurrentSize = unsigned int( m_TriZValues[0][nPos].size()) ; + + m_TriZValues[0][nPos].resize( nCurrentSize + 2) ; + + m_TriZValues[0][nPos][nCurrentSize] = ptIn.z - ptMapOrig.z ; + m_TriZValues[0][nPos][nCurrentSize + 1] = ptOut.z - ptMapOrig.z ; + + bInside = false ; + } + } + } + } + } + + if ( bFlag) { + + IntersParLinesSurfTm intPLSTM1( m_MapFrame[1], Surf) ; + + // Determinazione e ridimensionamento dei dexel interni alla trimesh + for ( unsigned int i = 0 ; i < m_nVNx[1] ; ++ i) { + for ( unsigned int j = 0 ; j < m_nVNy[1] ; ++ j) { + + // Definisco la retta da intersecare con la trimesh + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + Point3d ptP0( dX, dY, 0) ; + + // Determino le intersezioni della retta con la TriMesh + ILSIVECTOR IntersectionResults ; + intPLSTM1.GetInters( ptP0, dLengthX, IntersectionResults) ; + + int nInt = int( IntersectionResults.size()) ; + + unsigned int nPos = j * m_nVNx[1] + i ; + + bool bInside = false ; + Point3d ptIn ; + for ( int k = 0 ; k < nInt ; ++ k) { + + int nIntType = IntersectionResults[k].nILTT ; + + // Se c'è intersezione + if ( nIntType != ILTT_NO) { + + double dCos = IntersectionResults[k].dCosDN ; + + // entro nella superficie trimesh + if ( dCos < - EPS_SMALL) { + + ptIn = IntersectionResults[k].ptI ; + + bInside = true ; + } + + // esco dalla superficie trimesh + else if ( dCos > EPS_SMALL && bInside) { + + Point3d ptOut = IntersectionResults[k].ptI ; + + unsigned int nCurrentSize = unsigned int( m_TriZValues[1][nPos].size()) ; + + m_TriZValues[1][nPos].resize( nCurrentSize + 2) ; + + m_TriZValues[1][nPos][nCurrentSize] = ptIn.x - ptMapOrig.x ; + m_TriZValues[1][nPos][nCurrentSize + 1] = ptOut.x - ptMapOrig.x ; + + bInside = false ; + } + } + } + } + } + + IntersParLinesSurfTm intPLSTM2( m_MapFrame[2], Surf) ; + + // Determinazione e ridimensionamento dei dexel interni alla trimesh + for ( unsigned int i = 0 ; i < m_nVNx[2] ; ++ i) { + for ( unsigned int j = 0 ; j < m_nVNy[2] ; ++ j) { + + // Definisco la retta da intersecare con la trimesh + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + Point3d ptP0( dX, dY, 0) ; + + // Determino le intersezioni della retta con la TriMesh + ILSIVECTOR IntersectionResults ; + intPLSTM2.GetInters( ptP0, dLengthY, IntersectionResults) ; + + int nInt = int( IntersectionResults.size()) ; + + unsigned int nPos = j * m_nVNx[2] + i ; + + bool bInside = false ; + Point3d ptIn ; + for ( int k = 0 ; k < nInt ; ++ k) { + + int nIntType = IntersectionResults[k].nILTT ; + + // Se c'è intersezione + if ( nIntType != ILTT_NO) { + + double dCos = IntersectionResults[k].dCosDN ; + + // entro nella superficie trimesh + if ( dCos < - EPS_SMALL) { + + ptIn = IntersectionResults[k].ptI ; + + bInside = true ; + } + + // esco dalla superficie trimesh + else if ( dCos > EPS_SMALL && bInside) { + + Point3d ptOut = IntersectionResults[k].ptI ; + + unsigned int nCurrentSize = unsigned int( m_TriZValues[2][nPos].size()) ; + + m_TriZValues[2][nPos].resize( nCurrentSize + 2) ; + + m_TriZValues[2][nPos][nCurrentSize] = ptIn.y - ptMapOrig.y ; + m_TriZValues[2][nPos][nCurrentSize + 1] = ptOut.y - ptMapOrig.y ; + + bInside = false ; + } + } + } + } + } + } + + // Assegno il minimo e massimo valore di Z della mappa + m_dVMinZ[0] = 0 ; + m_dVMaxZ[0] = dLengthZ ; + + if ( bFlag) { + + m_dVMinZ[1] = 0 ; + m_dVMaxZ[1] = dLengthX ; + m_dVMinZ[2] = 0 ; + m_dVMaxZ[2] = dLengthY ; + } + else { + + m_dVMinZ[1] = 0 ; + m_dVMaxZ[1] = 0 ; + m_dVMinZ[2] = 0 ; + m_dVMaxZ[2] = 0 ; + } + + + + m_nStatus = OK ; + + return true ; +} \ No newline at end of file diff --git a/VolTriZmapGraphics.cpp b/VolTriZmapGraphics.cpp new file mode 100644 index 0000000..4e816a1 --- /dev/null +++ b/VolTriZmapGraphics.cpp @@ -0,0 +1,1026 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (tre griglie) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- + +#include "stdafx.h" +#include "CurveLine.h" +#include "VolZmap.h" +#include "GeoConst.h" +#include "IntersLineSurfTm.h" +#include "\EgtDev\Include\EGkIntervals.h" +#include "\EgtDev\Include\EgtNumUtils.h" +#include "MC_Tables.h" + + +using namespace std ; + +// ------------------------- VISUALIZZAZIONE -------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const +{ + // Controllo l'ammissibilità della griglia + if ( nDir < 0 || nDir > 2) + return false ; + + // Verifiche sugli indici + if ( nPos1 < 0 || nPos1 >= int( m_nVNx[nDir]) || nPos2 < 0 || nPos2 >= int( m_nVNy[nDir])) + return false ; + + int nPos = nPos1 + nPos2 * m_nVNx[nDir] ; + + if ( nPos < 0 || nPos >= int( m_TriZValues[nDir].size())) + return false ; + + // Calcolo coordinate punto + double dX = m_dStep * ( 0.5 + nPos1) ; + double dY = m_dStep * ( 0.5 + nPos2) ; + + // Determino il punto di partensa sulla griglia + Point3d ptP = m_MapFrame[nDir].Orig() + dX * m_MapFrame[nDir].VersX() + dY * m_MapFrame[nDir].VersY() ; + + // Creo le polilinee + for ( int j = 1 ; j < int( m_TriZValues[nDir][nPos].size()) ; j += 2) { + // aggiungo polilinea a lista + lstPL.emplace_back() ; + // inserisco punti estremi + lstPL.back().AddUPoint( 0, ptP + m_TriZValues[nDir][nPos][j-1] * m_MapFrame[nDir].VersZ()) ; + lstPL.back().AddUPoint( 1, ptP + m_TriZValues[nDir][nPos][j] * m_MapFrame[nDir].VersZ()) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const +{ + if ( m_nMapNum == 1) { + const int MAX_DIM_CHUNK = 128 ; + for ( int i = 0 ; i < int( m_nVNx[0]) ; i += MAX_DIM_CHUNK) { + int nDimChunkX = min( MAX_DIM_CHUNK, int( m_nVNx[0]) - i) ; + for ( int j = 0 ; j < int( m_nVNy[0]) ; j += MAX_DIM_CHUNK) { + int nDimChunkY = min( MAX_DIM_CHUNK, int( m_nVNy[0]) - j) ; + GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, MAX_DIM_CHUNK, lstTria) ; + } + } + } + else + MarchingCubes( lstTria) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk, TRIA3DLIST& lstTria) const +{ + // determino se è un semplice parallelepipedo + bool bIsSimple = true ; + double dBotZ ; + double dTopZ ; + for ( int i = 0 ; i < nDim1 && bIsSimple ; ++ i) { + for ( int j = 0 ; j < nDim2 && bIsSimple ; ++ j) { + int nPos = ( nPos1 + i) + ( nPos2 + j) * m_nVNx[0] ; + if ( nPos > int( m_nVDim[0]) || + int( m_TriZValues[0][nPos].size()) != 2) + bIsSimple = false ; + else if ( i == 0 && j == 0) { + dBotZ = m_TriZValues[0][nPos][0] ; + dTopZ = m_TriZValues[0][nPos][1] ; + } + else if ( abs( m_TriZValues[0][nPos][0] - dBotZ) > EPS_SMALL || + abs( m_TriZValues[0][nPos][1] - dTopZ) > EPS_SMALL) + bIsSimple = false ; + } + } + + // se semplice parallelepipedo + if ( bIsSimple) { + CalcChunkPrisms( nPos1, nPos2, nDim1, nDim2, lstTria) ; + } + // se chunk di dimensioni accettabili + else if ( nDimChk >= 4) { + int nNewDimChk = nDimChk / 2 ; + for ( int i = nPos1 ; i < int( nPos1 + nDim1) ; i += nNewDimChk) { + int nDimChunkX = min( nNewDimChk, int( nPos1 + nDim1) - i) ; + for ( int j = nPos2 ; j < int( nPos2 + nDim2) ; j += nNewDimChk) { + int nDimChunkY = min( nNewDimChk, int( nPos2 + nDim2) - j) ; + GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, nNewDimChk, lstTria) ; + } + } + } + // altrimenti + else { + // elaboro ogni singolo dexel + for ( int i = 0 ; i < nDim1 ; ++ i) { + for ( int j = 0 ; j < nDim2 ; ++ j) { + CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const +{ + // verifiche sugli indici + if ( nPos1 < 0 || nPos1 + nDim1 > int( m_nVNx[0]) || nPos2 < 0 || nPos2 + nDim2 > int( m_nVNy[0])) + return false ; + int nPos = nPos1 + nPos2 * m_nVNx[0] ; + if ( nPos < 0 || nPos >= int( m_nVDim[0])) + return false ; + + // calcolo coordinate punti + double dX = m_dStep * nPos1 ; + double dY = m_dStep * nPos2 ; + Point3d ptP1 = m_MapFrame[0].Orig() + dX * m_MapFrame[0].VersX() + dY * m_MapFrame[0].VersY() ; + Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_MapFrame[0].VersX() ; + Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_MapFrame[0].VersY() ; + Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_MapFrame[0].VersY() ; + + // creo le facce sopra e sotto + Vector3d vtDZt = m_TriZValues[0][nPos][1] * m_MapFrame[0].VersZ() ; + Vector3d vtDZb = m_TriZValues[0][nPos][0] * m_MapFrame[0].VersZ() ; + // faccia superiore P1t->P2t->P3t->P4t : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_MapFrame[0].VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_MapFrame[0].VersZ()) ; + // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_MapFrame[0].VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_MapFrame[0].VersZ()) ; + + // creo le facce laterali + for ( int j = 0 ; j < nDim2 ; ++ j) { + int nPosD = nPos + nDim1 - 1 + j * m_nVNx[0] ; + int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nVNx[0] - 1) ? nPosD + 1 : - 1) ; + Point3d ptP2D = ptP2 + j * m_dStep * m_MapFrame[0].VersY() ; + Point3d ptP3D = ptP2D + m_dStep * m_MapFrame[0].VersY() ; + AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_MapFrame[0].VersZ(), m_MapFrame[0].VersX(), lstTria) ; + } + for ( int i = 0 ; i < nDim1 ; ++ i) { + int nPosD = nPos + ( nDim2 - 1) * m_nVNx[0] + i ; + int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nVNy[0] - 1) ? nPosD + m_nVNx[0] : - 1) ; + Point3d ptP4D = ptP4 + i * m_dStep * m_MapFrame[0].VersX() ; + Point3d ptP3D = ptP4D + m_dStep * m_MapFrame[0].VersX() ; + AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_MapFrame[0].VersZ(), m_MapFrame[0].VersY(), lstTria) ; + } + for ( int j = 0 ; j < nDim2 ; ++ j) { + int nPosD = nPos + j * m_nVNx[0] ; + int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ; + Point3d ptP1D = ptP1 + j * m_dStep * m_MapFrame[0].VersY() ; + Point3d ptP4D = ptP1D + m_dStep * m_MapFrame[0].VersY() ; + AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_MapFrame[0].VersZ(), - m_MapFrame[0].VersX(), lstTria) ; + } + for ( int i = 0 ; i < nDim1 ; ++ i) { + int nPosD = nPos + i ; + int nPosSud = ( nPos2 > 0 ? nPosD - m_nVNx[0] : - 1) ; + Point3d ptP1D = ptP1 + i * m_dStep * m_MapFrame[0].VersX() ; + Point3d ptP2D = ptP1D + m_dStep * m_MapFrame[0].VersX() ; + AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_MapFrame[0].VersZ(), - m_MapFrame[0].VersY(), lstTria) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const +{ + // verifiche sugli indici + if ( nPos1 < 0 || nPos1 >= int( m_nVNx[0]) || nPos2 < 0 || nPos2 >= int( m_nVNy[0])) + return false ; + int nPos = nPos1 + nPos2 * m_nVNx[0] ; + if ( nPos < 0 || nPos >= int( m_nVDim[0])) + return false ; + + // calcolo coordinate punto + double dX = m_dStep * nPos1 ; + double dY = m_dStep * nPos2 ; + Point3d ptP1 = m_MapFrame[0].Orig() + dX * m_MapFrame[0].VersX() + dY * m_MapFrame[0].VersY() ; + Point3d ptP2 = ptP1 + m_dStep * m_MapFrame[0].VersX() ; + Point3d ptP3 = ptP2 + m_dStep * m_MapFrame[0].VersY() ; + Point3d ptP4 = ptP1 + m_dStep * m_MapFrame[0].VersY() ; + + // creo le facce sopra e sotto di ogni intervallo (sempre visibili) + for ( int i = 1 ; i < int( m_TriZValues[0][nPos].size()) ; i += 2) { + Vector3d vtDZt = m_TriZValues[0][nPos][i] * m_MapFrame[0].VersZ() ; + Vector3d vtDZb = m_TriZValues[0][nPos][i-1] * m_MapFrame[0].VersZ() ; + // faccia superiore P1t->P2t->P3t->P4t : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_MapFrame[0].VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_MapFrame[0].VersZ()) ; + // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_MapFrame[0].VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_MapFrame[0].VersZ()) ; + } + + // creo le facce laterali + int nPosEst = ( nPos1 < int( m_nVNx[0] - 1) ? nPos + 1 : - 1) ; + AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_MapFrame[0].VersZ(), m_MapFrame[0].VersX(), lstTria) ; + int nPosNord = ( nPos2 < int( m_nVNy[0] - 1) ? nPos + m_nVNx[0] : - 1) ; + AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_MapFrame[0].VersZ(), m_MapFrame[0].VersY(), lstTria) ; + int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ; + AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_MapFrame[0].VersZ(), - m_MapFrame[0].VersX(), lstTria) ; + int nPosSud = ( nPos2 > 0 ? nPos - m_nVNx[0] : - 1) ; + AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_MapFrame[0].VersZ(), - m_MapFrame[0].VersY(), lstTria) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, + const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const +{ + Intervals intFace ; + for ( int i = 1 ; i < int( m_TriZValues[0][nPos].size()) ; i += 2) + intFace.Add( m_TriZValues[0][nPos][i-1], m_TriZValues[0][nPos][i]) ; + if ( nPosAdj > 0) { + for ( int i = 1 ; i < int( m_TriZValues[0][nPosAdj].size()) ; i += 2) + intFace.Subtract( m_TriZValues[0][nPosAdj][i-1], m_TriZValues[0][nPosAdj][i]) ; + } + double dMin, dMax ; + bool bFound = intFace.GetFirst( dMin, dMax) ; + while ( bFound) { + Vector3d vtDZt = dMax * vtZ ; + Vector3d vtDZb = dMin * vtZ ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP + vtDZb, ptQ + vtDZb, ptQ + vtDZt, vtNorm) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptQ + vtDZt, ptP + vtDZt, ptP + vtDZb, vtNorm) ; + bFound = intFace.GetNext( dMin, dMax) ; + } + return true ; +} + + +/* +//---------------------------------------------------------------------------- +bool +VolZmap::MarchingCubes( TRIA3DLIST& lstTria) +{ + // Limiti superiori sui tre indici + unsigned int nLimI = m_nVNx[0] ; + unsigned int nLimJ = m_nVNy[0] ; + unsigned int nLimK = m_nVNy[1] ; + + struct Corner { + + int nCornerNumber ; + unsigned int nI, nJ, nK ; + } ; + + // Ciclo su tutti i voxel dello Zmap + for ( unsigned int k = 0 ; k < nLimK ; ++ k) { + for ( unsigned int i = 0 ; i < nLimI ; ++ i) { + for ( unsigned int j = 0 ; j < nLimJ ; ++ j) { + } + } + } + return true ; +} +*/ + +/* +//---------------------------------------------------------------------------- +bool +VolZmap::MarchingCubes( TRIA3DLIST& lstTria) +{ + unsigned int nLimI = m_nVNx[0] ; + unsigned int nLimJ = m_nVNy[0] ; + unsigned int nLimK = m_nVNy[1] ; + + + // Ciclo su tutti i voxel dello Zmap + for ( unsigned int k = 0 ; k < nLimK ; ++ k) { + for ( unsigned int i = 0 ; i < nLimI ; ++ i) { + for ( unsigned int j = 0 ; j < nLimJ ; ++ j) { + + // Indici i,j,k dei vertici + int IndexCorner[8][3] = { + + { i, j, k}, + { i + 1, j, k}, + { i + 1, j + 1, k}, + { i, j + 1, k}, + { i, j, k + 1}, + { i + 1, j, k + 1}, + { i + 1, j + 1, k + 1}, + { i, j + 1, k + 1} + } ; + + int nIndex = 0 ; + + bool CornerTF[8] = { false, false, false, false, + false, false, false, false,} ; + + // Classificazione dei vertici: interni o esterni al materiale + if ( IsThereMat( i, j, k)) { + nIndex |= ( 1 << 0) ; + CornerTF[0] = true ; + } + if ( IsThereMat( i + 1, j, k)) { + nIndex |= ( 1 << 1) ; + CornerTF[1] = true ; + } + if ( IsThereMat( i + 1, j + 1, k)) { + nIndex |= ( 1 << 2) ; + CornerTF[2] = true ; + } + if ( IsThereMat( i, j + 1, k)) { + nIndex |= ( 1 << 3) ; + CornerTF[3] = true ; + } + if ( IsThereMat( i, j, k + 1)) { + nIndex |= ( 1 << 4) ; + CornerTF[4] = true ; + } + if ( IsThereMat( i + 1, j, k + 1)) { + nIndex |= ( 1 << 5) ; + CornerTF[5] = true ; + } + if ( IsThereMat( i + 1, j + 1, k + 1)) { + nIndex |= ( 1 << 6) ; + CornerTF[6] = true ; + } + if ( IsThereMat( i, j + 1, k + 1)) { + nIndex |= ( 1 << 7) ; + CornerTF[7] = true ; + } + + // Se vi è qualche intersezione fra segmenti e superficie + // continuo altrimenti passo al prossimo voxel + if ( EdgeTable[nIndex] != 0) { + + static int intersections[12][2] = { + + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, + { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } + } ; + + Point3d ptIntPoint[12] ; + + // Ciclo sui segmenti + for ( int i = 0 ; i < 12 ; ++ i) { + // Se il segmento non attraversa la superficie + // passo al successivo + if ( ! ( EdgeTable[nIndex] & ( 1 << i))) + continue ; + + int n1 = intersections[i][0]; + int n2 = intersections[i][1]; + + // Determino con precisione il punto di intersezione sullo spigolo + IntersPos( IndexCorner[n1], IndexCorner[n2], ptIntPoint[i]) ; + } + + // Costruzione dei triangoli + for ( int i = 0 ; TriangleTable[nIndex][i] != - 1 ; ++ i) { + + // Costruzione triangolo + int i0 = TriangleTable[nIndex][i] ; + int i1 = TriangleTable[nIndex][i+1] ; + int i2 = TriangleTable[nIndex][i+2] ; + + Triangle3d CurrentTriangle ; + + Vector3d vtV1 = ptIntPoint[i1] - ptIntPoint[i0] ; + Vector3d vtV2 = ptIntPoint[i2] - ptIntPoint[i0] ; + Vector3d vtN = vtV1 ^ vtV2 ; + + vtN.Normalize() ; + + int nCorner = intersections[i0][0] ; + + Point3d ptCorner( IndexCorner[nCorner][0] * m_dStep, + IndexCorner[nCorner][1] * m_dStep, + IndexCorner[nCorner][2] * m_dStep) ; + + Vector3d vtT = ptCorner - ptIntPoint[i0] ; + + vtT.Normalize() ; + + if ( CornerTF[nCorner]) { + if ( vtN * vtT < 0) + vtN = - vtN ; + } + else { + if ( vtN * vtT > 0) + vtN = - vtN ; + }*/ + + /* + oppure: + if( nIndex & ( 1 << nCorner)) { + if( vtN * vtT < 0) + } + else { + if ( vtN * vtT > 0) + vtN = - vtN ; + } + */ /* + + CurrentTriangle.Set( ptIntPoint[i0], ptIntPoint[i1], ptIntPoint[i2], vtN) ; + + // Aggiungo triangolo + lstTria.emplace_back( CurrentTriangle) ; + } + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IsThereMat( unsigned int nI, unsigned int nJ, unsigned int nK) +{ + double dZ[3] ; + + dZ[0] = ( nI + 0.5) * m_dStep ; + dZ[1] = ( nK + 0.5) * m_dStep ; + dZ[2] = ( nJ + 0.5) * m_dStep ; + + int nCount = 0 ; + + for ( int nGrid = 0 ; nGrid < int ( m_nMapNum) ; ++ nGrid) { + + unsigned int nGrI, nGrJ ; + + if ( nGrid == 0) { + nGrI = nI ; + nGrJ = nJ ; + } + else if ( nGrid == 1) { + nGrI = nJ ; + nGrJ = nK ; + } + else { + nGrI = nK ; + nGrJ = nI ; + } + + unsigned int nPos = nGrJ * m_nVNx[nGrid] + nGrI ; + unsigned int nDexSize = m_TriZValues[nGrid][nPos].size() ; + unsigned int nIndex = 0 ; + + while ( nIndex < nDexSize) { + + if ( dZ[nGrid] > m_TriZValues[nGrid][nPos][nIndex] + EPS_SMALL || + dZ[nGrid] < m_TriZValues[nGrid][nPos][nIndex + 1] - EPS_SMALL) { + + ++ nCount ; + break ; + } + ++ nIndex ; + } + } + + if ( nCount > 1) + return true ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d & ptInt) { + + if ( nVec1[0] != nVec2[0]) { + + int nMinI = min( nVec1[0], nVec2[0]) ; + int nMaxI = max( nVec1[0], nVec2[0]) ; + + double dMinX = nMinI * m_dStep ; + double dMaxX = nMaxI * m_dStep ; + + unsigned int nDexel = nVec1[2] * m_nVNx[1] + nVec1[1] ; + unsigned int nSize = m_TriZValues[1][nDexel].size() ; + + ptInt.y = nVec1[1] * m_dStep ; + ptInt.z = nVec1[2] * m_dStep ; + + for ( unsigned int i = 0 ; i < nSize ; i += 2) { + + double dx1 = m_TriZValues[1][nDexel][i] ; + double dx2 = m_TriZValues[1][nDexel][i+1] ; + + if ( dx1 < dMinX && dx2 > dMinX && dx2 < dMaxX) { + + ptInt.x = dx2 ; + break ; + } + else if ( dx1 > dMinX && dx1 < dMaxX && dx2 > dMaxX) { + + ptInt.x = dx1 ; + break ; + } + } + } + else if ( nVec1[1] != nVec2[1]) { + + int nMinJ = min( nVec1[1], nVec2[1]) ; + int nMaxJ = max( nVec1[1], nVec2[1]) ; + + double dMinY = nMinJ * m_dStep ; + double dMaxY = nMaxJ * m_dStep ; + + unsigned int nDexel = nVec1[2] * m_nVNx[2] + nVec1[0] ; + unsigned int nSize = m_TriZValues[2][nDexel].size() ; + + ptInt.x = nVec1[0] * m_dStep ; + ptInt.z = nVec1[2] * m_dStep ; + + for ( unsigned int j = 0 ; j < nSize ; j += 2) { + + double dy1 = m_TriZValues[2][nDexel][j] ; + double dy2 = m_TriZValues[2][nDexel][j+1] ; + + if ( dy1 < dMinY && dy2 > dMinY && dy2 < dMaxY) { + + ptInt.y = dy2 ; + break ; + } + else if ( dy1 > dMinY && dy1 < dMaxY && dy2 > dMaxY) { + + ptInt.y = dy1 ; + break ; + } + } + } + else if ( nVec1[2] != nVec2[2]) { + + int nMinK = min( nVec1[2], nVec2[2]) ; + int nMaxK = max( nVec1[2], nVec2[2]) ; + + double dMinZ = nMinK * m_dStep ; + double dMaxZ = nMaxK * m_dStep ; + + unsigned int nDexel = nVec1[1] * m_nVNx[0] + nVec1[0] ; + unsigned int nSize = m_TriZValues[0][nDexel].size() ; + + ptInt.x = nVec1[0] * m_dStep ; + ptInt.y = nVec1[1] * m_dStep ; + + for ( unsigned int k = 0 ; k < nSize ; k += 2) { + + double dz1 = m_TriZValues[0][nDexel][k] ; + double dz2 = m_TriZValues[0][nDexel][k+1] ; + + if ( dz1 < dMinZ && dz2 > dMinZ && dz2 < dMaxZ) { + + ptInt.z = dz2 ; + break ; + } + else if ( dz1 > dMinZ && dz1 < dMaxZ && dz2 > dMaxZ) { + + ptInt.z = dz1 ; + break ; + } + } + } + return true ; +} */ + +// Prova + +bool function( const Vector3d & vtV) +{ + if ( 100 - vtV * vtV < 0) + return true ; + return false ; +} + +bool midpoint( int nVec1[], int nVec2[], Point3d & ptInt, double dStep) +{ + Point3d pt1( ( nVec1[0] + 0.5) * dStep, + ( nVec1[1] + 0.5) * dStep, + ( nVec1[2] + 0.5) * dStep) ; + + Point3d pt2( ( nVec2[0] + 0.5) * dStep, + ( nVec2[1] + 0.5) * dStep, + ( nVec2[2] + 0.5) * dStep) ; + + + ptInt = pt1 + 0.5 * ( pt2 - pt1) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MarchingCubes( TRIA3DLIST& lstTria) const +{ + + Point3d ptMapOrig = m_MapFrame[0].Orig() ; + + int nLimI = int( m_nVNx[0]) ; + int nLimJ = int( m_nVNy[0]) ; + int nLimK = int( m_nVNy[1]) ; + + + // Ciclo su tutti i voxel dello Zmap + for ( int i = - 1 ; i < nLimI ; ++ i) { + for ( int j = - 1 ; j < nLimJ ; ++ j) { + for ( int k = - 1 ; k < nLimK ; ++ k) { + + if ( i == 0 && j == 6 && k == 8) { + + double bau = 1 ; + } + + // Indici i,j,k dei vertici + int IndexCorner[8][3] = { + + { i, j, k}, + { i + 1, j, k}, + { i + 1, j + 1, k}, + { i, j + 1, k}, + { i, j, k + 1}, + { i + 1, j, k + 1}, + { i + 1, j + 1, k + 1}, + { i, j + 1, k + 1} + } ; + + + int nIndex = 0 ; + + // Classificazione dei vertici: interni o esterni al materiale + if ( IsThereMat( i, j, k)) + nIndex |= ( 1 << 0) ; + + if ( IsThereMat( i + 1, j, k)) + nIndex |= ( 1 << 1) ; + + if ( IsThereMat( i + 1, j + 1, k)) + nIndex |= ( 1 << 2) ; + + if ( IsThereMat( i, j + 1, k)) + nIndex |= ( 1 << 3) ; + + if ( IsThereMat( i, j, k + 1)) + nIndex |= ( 1 << 4) ; + + if ( IsThereMat( i + 1, j, k + 1)) + nIndex |= ( 1 << 5) ; + + if ( IsThereMat( i + 1, j + 1, k + 1)) + nIndex |= ( 1 << 6) ; + + if ( IsThereMat( i, j + 1, k + 1)) + nIndex |= ( 1 << 7) ; + + + // Se vi è qualche intersezione fra segmenti e superficie + // continuo altrimenti passo al prossimo voxel + if ( EdgeTable[nIndex] == 0) + continue ; + + static int intersections[12][2] = { + + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 0 }, { 4, 5 }, { 5, 6 }, + { 6, 7 }, { 7, 4 }, { 0, 4 }, { 1, 5 }, { 2, 6 }, { 3, 7 } + } ; + + Point3d ptIntPoint[12] ; + + // Ciclo sui segmenti + for ( int EdgeIndex = 0 ; EdgeIndex < 12 ; ++ EdgeIndex) { + // Se il segmento non attraversa la superficie + // passo al successivo + if ( ! ( EdgeTable[nIndex] & ( 1 << EdgeIndex))) + continue ; + + int n1 = intersections[EdgeIndex][0] ; + int n2 = intersections[EdgeIndex][1] ; + + // Determino con precisione il punto di intersezione sullo spigolo + IntersPos( IndexCorner[n1], IndexCorner[n2], ptIntPoint[EdgeIndex]) ; + // midpoint( IndexCorner[n1], IndexCorner[n2], ptIntPoint[EdgeIndex], m_dStep) ; + + ptIntPoint[EdgeIndex] = ptIntPoint[EdgeIndex] ; + + ptIntPoint[EdgeIndex].ToGlob( m_MapFrame[0]) ; + } + + // Costruzione dei triangoli + for ( int TriIndex = 0 ; TriangleTable[nIndex][TriIndex] != - 1 ; TriIndex += 3) { + + // Costruzione triangolo + int i0 = TriangleTable[nIndex][TriIndex + 2] ; + int i1 = TriangleTable[nIndex][TriIndex + 1] ; + int i2 = TriangleTable[nIndex][TriIndex] ; + + Triangle3d CurrentTriangle ; + + Vector3d vtN = ( ptIntPoint[i1] - ptIntPoint[i0]) ^ ( ptIntPoint[i2] - ptIntPoint[i1]) ; + + vtN.Normalize() ; + + vtN.ToGlob( m_MapFrame[0]) ; + + // Il triangolo è pronto + CurrentTriangle.Set( ptIntPoint[i0], ptIntPoint[i1], ptIntPoint[i2], vtN) ; + + // Aggiungo triangolo + lstTria.emplace_back( CurrentTriangle) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IsThereMat( int nI, int nJ, int nK) const +{ + + if ( nI == - 1 || nI == m_nVNx[0] || + nJ == - 1 || nJ == m_nVNy[0] || + nK == - 1 || nK == m_nVNy[1]) + + return false ; + + double dZ[3] ; + + dZ[0] = ( nK + 0.5) * m_dStep ; + dZ[1] = ( nI + 0.5) * m_dStep ; + dZ[2] = ( nJ + 0.5) * m_dStep ; + + int nCount = 0 ; + + for ( int nGrid = 0 ; nGrid < int ( m_nMapNum) ; ++ nGrid) { + + unsigned int nGrI, nGrJ ; + + if ( nGrid == 0) { + nGrI = nI ; + nGrJ = nJ ; + } + else if ( nGrid == 1) { + nGrI = nJ ; + nGrJ = nK ; + } + else { + nGrI = nK ; + nGrJ = nI ; + } + + unsigned int nPos = nGrJ * m_nVNx[nGrid] + nGrI ; + size_t nDexSize = m_TriZValues[nGrid][nPos].size() ; + unsigned int nIndex = 0 ; + + while ( nIndex < nDexSize) { + + if ( dZ[nGrid] > m_TriZValues[nGrid][nPos][nIndex] && + dZ[nGrid] < m_TriZValues[nGrid][nPos][nIndex + 1]) { + + ++ nCount ; + break ; + } + nIndex += 2 ; + } + } + //if ( nCount > 0) + if ( nCount == 3) + return true ; + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IsThereMat( const int nMatr[][3], int nNum, double & dHx, double & dHy, double & dHz) const +{ + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::IntersPos( int nVec1[], int nVec2[], Point3d & ptInt) const +{ + + if ( nVec1[0] != nVec2[0]) { + + int nMinI = min( nVec1[0], nVec2[0]) ; + int nMaxI = max( nVec1[0], nVec2[0]) ; + + double dMinX = ( nMinI + 0.5) * m_dStep ; + double dMaxX = ( nMaxI + 0.5) * m_dStep ; + + unsigned int nDexel = nVec1[2] * m_nVNx[1] + nVec1[1] ; + size_t nSize = m_TriZValues[1][nDexel].size() ; + + ptInt.y = ( nVec1[1] + 0.5) * m_dStep ; + ptInt.z = ( nVec1[2] + 0.5) * m_dStep ; + + unsigned int i ; + + for ( i = 0 ; i < nSize ; i += 2) { + + double dx1 = m_TriZValues[1][nDexel][i] ; + double dx2 = m_TriZValues[1][nDexel][i+1] ; + + if ( dx1 <= dMinX && dx2 >= dMinX && dx2 <= dMaxX) { + + ptInt.x = dx2 ; + break ; + } + else if ( dx1 >= dMinX && dx1 <= dMaxX && dx2 >= dMaxX) { + + ptInt.x = dx1 ; + break ; + } + } + + if ( i == nSize) + ptInt.x = 0.5 * ( dMinX + dMaxX) ; + } + else if ( nVec1[1] != nVec2[1]) { + + int nMinJ = min( nVec1[1], nVec2[1]) ; + int nMaxJ = max( nVec1[1], nVec2[1]) ; + + double dMinY = ( nMinJ + 0.5) * m_dStep ; + double dMaxY = ( nMaxJ + 0.5) * m_dStep ; + // 2 0 + unsigned int nDexel = nVec1[0] * m_nVNx[2] + nVec1[2] ; + size_t nSize = m_TriZValues[2][nDexel].size() ; + + ptInt.x = ( nVec1[0] + 0.5) * m_dStep ; + ptInt.z = ( nVec1[2] + 0.5) * m_dStep ; + + unsigned int j ; + + for ( j = 0 ; j < nSize ; j += 2) { + + double dy1 = m_TriZValues[2][nDexel][j] ; + double dy2 = m_TriZValues[2][nDexel][j+1] ; + + if ( dy1 <= dMinY && dy2 >= dMinY && dy2 <= dMaxY) { + + ptInt.y = dy2 ; + break ; + } + else if ( dy1 >= dMinY && dy1 <= dMaxY && dy2 >= dMaxY) { + + ptInt.y = dy1 ; + break ; + } + } + + if ( j == nSize) + ptInt.y = 0.5 * ( dMinY + dMaxY) ; + } + else if ( nVec1[2] != nVec2[2]) { + + int nMinK = min( nVec1[2], nVec2[2]) ; + int nMaxK = max( nVec1[2], nVec2[2]) ; + + double dMinZ = ( nMinK + 0.5) * m_dStep ; + double dMaxZ = ( nMaxK + 0.5) * m_dStep ; + + unsigned int nDexel = nVec1[1] * m_nVNx[0] + nVec1[0] ; + size_t nSize = m_TriZValues[0][nDexel].size() ; + + ptInt.x = ( nVec1[0] + 0.5) * m_dStep ; + ptInt.y = ( nVec1[1] + 0.5) * m_dStep ; + + unsigned int k ; + + for ( k = 0 ; k < nSize ; k += 2) { + + double dz1 = m_TriZValues[0][nDexel][k] ; + double dz2 = m_TriZValues[0][nDexel][k+1] ; + + if ( dz1 <= dMinZ && dz2 >= dMinZ && dz2 <= dMaxZ) { + + ptInt.z = dz2 ; + break ; + } + else if ( dz1 >= dMinZ && dz1 <= dMaxZ && dz2 >= dMaxZ) { + + ptInt.z = dz1 ; + break ; + } + } + + if ( k == nSize) + ptInt.z = 0.5 * ( dMinZ + dMaxZ) ; + } + return true ; +} + +/* + Point3d ptProva[8] ; + Vector3d vtProva[8] ; + + ptProva[0].x = ( i + 0.5) * m_dStep ; + ptProva[0].y = ( j + 0.5) * m_dStep ; + ptProva[0].z = ( k + 0.5) * m_dStep ; + ptProva[1].x = ( i + 1.5) * m_dStep ; + ptProva[1].y = ( j + 0.5) * m_dStep ; + ptProva[1].z = ( k + 0.5) * m_dStep ; + ptProva[2].x = ( i + 1.5) * m_dStep ; + ptProva[2].y = ( j + 1.5) * m_dStep ; + ptProva[2].z = ( k + 0.5) * m_dStep ; + ptProva[3].x = ( i + 0.5) * m_dStep ; + ptProva[3].y = ( j + 1.5) * m_dStep ; + ptProva[3].z = ( k + 0.5) * m_dStep ; + ptProva[4].x = ( i + 0.5) * m_dStep ; + ptProva[4].y = ( j + 0.5) * m_dStep ; + ptProva[4].z = ( k + 1.5) * m_dStep ; + ptProva[5].x = ( i + 1.5) * m_dStep ; + ptProva[5].y = ( j + 0.5) * m_dStep ; + ptProva[5].z = ( k + 1.5) * m_dStep ; + ptProva[6].x = ( i + 1.5) * m_dStep ; + ptProva[6].y = ( j + 1.5) * m_dStep ; + ptProva[6].z = ( k + 1.5) * m_dStep ; + ptProva[7].x = ( i + 0.5) * m_dStep ; + ptProva[7].y = ( j + 1.5) * m_dStep ; + ptProva[7].z = ( k + 1.5) * m_dStep ; + + Point3d ptC( 10, 10, 10) ; + + for ( int boh = 0 ; boh < 8 ; ++ boh) + + vtProva[boh] = ptProva[boh] - ptC ; */ + +/* + if ( function( vtProva[0])) + nIndex |= ( 1 << 0) ; + + if ( function( vtProva[1])) + nIndex |= ( 1 << 1) ; + + if ( function( vtProva[2])) + nIndex |= ( 1 << 2) ; + + if ( function( vtProva[3])) + nIndex |= ( 1 << 3) ; + + if ( function( vtProva[4])) + nIndex |= ( 1 << 4) ; + + if ( function( vtProva[5])) + nIndex |= ( 1 << 5) ; + + if ( function( vtProva[6])) + nIndex |= ( 1 << 6) ; + + if ( function( vtProva[7])) + nIndex |= ( 1 << 7) ; */ + +/* + Vector3d vtV1 = ptIntPoint[i1] - ptIntPoint[i0] ; + Vector3d vtV2 = ptIntPoint[i2] - ptIntPoint[i0] ; + Vector3d vtN = vtV1 ^ vtV2 ; + + vtN.Normalize() ; + + int nCorner = intersections[i0][0] ; + + Point3d ptCorner( IndexCorner[nCorner][0] * m_dStep, + IndexCorner[nCorner][1] * m_dStep, + IndexCorner[nCorner][2] * m_dStep) ; + + Vector3d vtT = ptCorner - ptIntPoint[i0] ; + + vtT.Normalize() ; + + + if( nIndex & ( 1 << nCorner)) { + if( vtN * vtT < 0) + vtN = - vtN ; + } + else { + if ( vtN * vtT > 0) + vtN = - vtN ; + }*/ + + + + + + + \ No newline at end of file diff --git a/VolTriZmapVolume.cpp b/VolTriZmapVolume.cpp new file mode 100644 index 0000000..24bd458 --- /dev/null +++ b/VolTriZmapVolume.cpp @@ -0,0 +1,6204 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2016 +//---------------------------------------------------------------------------- +// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 +// Contenuto : Implementazione della classe Volume Zmap (tre griglie) +// +// +// +// Modifiche : 22.01.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- + +#include "stdafx.h" +#include "CurveLine.h" +#include "VolZmap.h" +#include "GeoConst.h" +#include "IntersLineSurfTm.h" +#include "\EgtDev\Include\EgtNumUtils.h" + + +using namespace std ; + + + + + +// ------------------------- OPERAZIONI SU INTERVALLI -------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + return true ; + + // Controllo che il numero di griglia sia entro i limiti + if ( nGrid < 0 || nGrid > 2) + return false ; + + // Controllo che dMin < dMax + if ( dMin > dMax) + swap( dMin, dMax) ; + + // Controllo che indici nI, nJ siano entro i limiti + if ( nI < 0 && nI >= m_nVNx[nGrid] && + nJ < 0 && nJ >= m_nVNy[nGrid]) + return false ; + + // Calcolo nPos + unsigned int nPos = nJ * m_nVNx[nGrid] + nI ; // O nJ*m_Nx + nI + 1 ? + + /* Non serve: se size == 0 non entra nel ciclo + // Se il dexel è vuoto non succede niente + if ( m_TriZValues[nGrid][nPos].size() == 0) + return true ; */ + + // Ciclo sugli intervalli del singolo dexel + bool bModified = false ; + unsigned int i = 0 ; + + while ( i + 1 < m_TriZValues[nGrid][nPos].size()) { + + // Casi: + // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione + if ( m_TriZValues[nGrid][nPos][i] > dMax - EPS_SMALL) { + ; + } + // Intersezione + else if ( m_TriZValues[nGrid][nPos][i + 1] > dMax + EPS_SMALL) { + // L'intervallo corrente corrente viene limitato a sinistra + if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) { + bModified = true ; + m_TriZValues[nGrid][nPos][i] = dMax ; + } + // L'intervallo si divide in due intervalli + else { + bModified = true ; + m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ; + + for ( size_t j = m_TriZValues[nGrid][nPos].size() - 1 ; j >= i + 3 ; -- j) + + m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j - 2] ; + + m_TriZValues[nGrid][nPos][i + 1] = dMin ; + m_TriZValues[nGrid][nPos][i + 2] = dMax ; + + i = i + 2 ; + } + } + else { + // L'intervallo corrente viene eliminato + if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) { + bModified = true ; + for ( unsigned int j = i ; j < m_TriZValues[nGrid][nPos].size() - 2 ; ++ j) + + m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j + 2] ; + + m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() - 2) ; + + i = i - 2 ; + } + // L'intervallo corrente viene limitato a destra + else if ( m_TriZValues[nGrid][nPos][i + 1] > dMin + EPS_SMALL) { + bModified = true ; + m_TriZValues[nGrid][nPos][i + 1] = dMin ; + } + // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione + else { + ; + } + } + + i = i + 2 ; + } + + // Se eseguita modifica, imposto ricalcolo della grafica + if ( bModified) + m_OGrMgr.Reset() ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SubtractIntervals( unsigned int nGrid, const Point3d & ptP, double dMin, double dMax) +{ + // Controllo che il numero di griglia sia entro i limiti. + if ( nGrid < 0 || nGrid > 2) + return false ; + + // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) + Point3d ptPL = ptP ; + ptPL.ToLoc( m_MapFrame[nGrid]) ; + + double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco + double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) + + dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; + dhMin = dZ + dMin ; dhMax = dZ + dMax ; + + // Cerco il punto della griglia più vicino + double integerPartX = floor( dX / m_dStep) ; + double integerPartY = floor( dY / m_dStep) ; + + unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. + unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 ; + + // Controllo che gli indici ottenuti siano nella griglia: + // se sono dentro la griglia chiamo l'altra subtract + if ( i >= 0 && i < m_nVNx[nGrid] && + j >= 0 && j < m_nVNy[nGrid]) + + return SubtractIntervals( nGrid, i, j, dhMin, dhMax) ; + // altrimenti non succede niente + else + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + return true ; + + // Controllo che il numero di griglia sia entro i limiti + if ( nGrid < 0 || nGrid > 2) + return false ; + + // Controllo che indici nI, nJ siano entro i limiti + if ( nI < 0 && nI >= m_nVNx[nGrid] && + nJ < 0 && nJ >= m_nVNy[nGrid]) + return false ; + + // Calcolo nPos + unsigned int nPos = nJ * m_nVNx[nGrid] + nI ; + + // Controllo che dMin < dMax + swap( dMin, dMax) ; + + // Se spillone vuoto + if ( m_TriZValues[nGrid][nPos].size() == 0) { + + m_TriZValues[nGrid][nPos].resize( 2) ; + + m_TriZValues[nGrid][nPos][0] = dMin ; + m_TriZValues[nGrid][nPos][1] = dMax ; + + if ( dMax > m_dVMaxZ[nGrid]) + m_dVMinZ[nGrid] = dMax ; + + if ( dMin < m_dVMinZ[nGrid]) + m_dVMinZ[nGrid] = dMin ; + + m_OGrMgr.Reset() ; + + return true ; + } + + // Ciclo sugli intervalli dello spillone + bool bModified = false ; + unsigned int i = 0 ; + while ( i + 1 < m_TriZValues[nGrid][nPos].size()) { + + // Eventuale aggiustamento di intervalli sovrapposti + if ( i > 0) { + if ( m_TriZValues[nGrid][nPos][i] < m_TriZValues[nGrid][nPos][i - 1] + EPS_SMALL) { + // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva + if ( m_TriZValues[nGrid][nPos][i - 1] < m_TriZValues[nGrid][nPos][i + 1] + EPS_SMALL) + + m_TriZValues[nGrid][nPos][i - 1] = m_TriZValues[nGrid][nPos][i + 1] ; + + for ( unsigned int j = i ; j < m_TriZValues[nGrid][nPos].size() - 2 ; ++ j) + m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j + 2] ; + + m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() - 2) ; + + i = i - 2 ; + } + } + + // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente + if ( m_TriZValues[nGrid][nPos][i] > dMax + EPS_SMALL) { + bModified = true ; + + m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ; + + for ( size_t j = m_TriZValues[nGrid][nPos].size() - 1 ; j >= i + 2 ; -- j) + m_TriZValues[nGrid][nPos][j] = m_TriZValues[nGrid][nPos][j - 2] ; + + m_TriZValues[nGrid][nPos][i] = dMin ; + m_TriZValues[nGrid][nPos][i + 1] = dMax ; + + i = i + 2 ; + } + + // Casi d'intersezione: + else if ( m_TriZValues[nGrid][nPos][i + 1] > dMax - EPS_SMALL) { + // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente + if ( m_TriZValues[nGrid][nPos][i] > dMin - EPS_SMALL) { + bModified = true ; + m_TriZValues[nGrid][nPos][i] = dMin ; + } + } + + else { + // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi + if ( m_TriZValues[nGrid][nPos][i] > dMin + EPS_SMALL) { + bModified = true ; + m_TriZValues[nGrid][nPos][i] = dMin ; + m_TriZValues[nGrid][nPos][i + 1] = dMax ; + } + // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente + else if ( m_TriZValues[nGrid][nPos][i + 1] > dMin - EPS_SMALL) { + bModified = true ; + m_TriZValues[nGrid][nPos][i + 1] = dMax ; + } + else { + // Aggiungo intervallo a destra dell'ultimo intervallo + if ( i == m_TriZValues[nGrid][nPos].size() - 2) { + bModified = true ; + m_TriZValues[nGrid][nPos].resize( m_TriZValues[nGrid][nPos].size() + 2) ; + + m_TriZValues[nGrid][nPos][i + 2] = dMin ; + m_TriZValues[nGrid][nPos][i + 3] = dMax ; + + i = i + 2 ; + } + } + } + + i = i + 2 ; + } + + // se eseguita modifica, imposto ricalcolo della grafica + if ( bModified) { + + m_OGrMgr.Reset() ; + + if ( dMax > m_dVMaxZ[nGrid]) + m_dVMinZ[nGrid] = dMax ; + + if ( dMin < m_dVMinZ[nGrid]) + m_dVMinZ[nGrid] = dMin ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddIntervals( unsigned int nGrid, const Point3d & ptP, double dMin, double dMax) +{ + // Controllo che il numero di griglia sia entro i limiti. + if ( nGrid < 0 || nGrid > 2) + return false ; + + // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) + Point3d ptPL = ptP ; + ptPL.ToLoc( m_MapFrame[nGrid]) ; + + double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco + double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) + + dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; + dhMin = dZ + dMin ; dhMax = dZ + dMax ; + + // Cerco il punto della griglia più vicino + double integerPartX = floor( dX / m_dStep) ; + double integerPartY = floor( dY / m_dStep) ; + + unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. + unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 + + // Controllo che gli indici ottenuti siano nella griglia: + // se sono dentro la griglia chiamo l'altra add + if ( i >= 0 && i < m_nVNx[nGrid] && + j >= 0 && j < m_nVNy[nGrid]) + + return AddIntervals( nGrid, i, j, dhMin, dhMax) ; + else + // altrimenti non succede niente + return false ; +} + +// ------------------------- LAVORAZIONI -------------------------------------------------------------------------------------- + + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) +{ + + // Controllo sull'effettiva esisenza del movimento + if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe)) + return true ; + + // Punti nei sistemi di riferimento intrinseci dello Zmap + Point3d ptLs[3] ; + Point3d ptLe[3] ; + + ptLs[0] = ptPs ; + ptLs[0].ToLoc( m_MapFrame[0]) ; + + ptLe[0] = ptPe ; + ptLe[0].ToLoc( m_MapFrame[0]) ; + + if ( m_nMapNum > 1) { + + ptLs[1].x = ptLs[0].y ; ptLs[1].y = ptLs[0].z ; ptLs[1].z = ptLs[0].x ; + ptLs[2].x = ptLs[0].z ; ptLs[2].y = ptLs[0].x ; ptLs[2].z = ptLs[0].y ; + + ptLe[1].x = ptLe[0].y ; ptLe[1].y = ptLe[0].z ; ptLe[1].z = ptLe[0].x ; + ptLe[2].x = ptLe[0].z ; ptLe[2].y = ptLe[0].x ; ptLe[2].z = ptLe[0].y ; + } + else { + + ptLs[1].x = 0 ; ptLs[1].y = 0 ; ptLs[1].z = 0 ; + ptLs[2].x = 0 ; ptLs[2].y = 0 ; ptLs[2].z = 0 ; + + ptLe[1].x = 0 ; ptLe[1].y = 0 ; ptLe[1].z = 0 ; + ptLe[2].x = 0 ; ptLe[2].y = 0 ; ptLe[2].z = 0 ; + } + + + // Vettori nei sistemi di riferimento intrinseci dello Zmap + Vector3d vtLs [3] ; + Vector3d vtLe [3] ; + + vtLs[0] = vtDs ; + vtLs[0].ToLoc( m_MapFrame[0]) ; + + vtLe[0] = vtDe ; + vtLe[0].ToLoc( m_MapFrame[0]) ; + + if ( m_nMapNum > 1) { + + vtLs[1].x = vtLs[0].y ; vtLs[1].y = vtLs[0].z ; vtLs[1].z = vtLs[0].x ; + vtLs[2].x = vtLs[0].z ; vtLs[2].y = vtLs[0].x ; vtLs[2].z = vtLs[0].y ; + + vtLe[1].x = vtLe[0].y ; vtLe[1].y = vtLe[0].z ; vtLe[1].z = vtLe[0].x ; + vtLe[2].x = vtLe[0].z ; vtLe[2].y = vtLe[0].x ; vtLe[2].z = vtLe[0].y ; + } + else { + + vtLs[1].x = 0 ; vtLs[1].y = 0 ; vtLs[1].z = 0 ; + vtLs[2].x = 0 ; vtLs[2].y = 0 ; vtLs[2].z = 0 ; + + vtLe[1].x = 0 ; vtLe[1].y = 0 ; vtLe[1].z = 0 ; + vtLe[2].x = 0 ; vtLe[2].y = 0 ; vtLe[2].z = 0 ; + } + + + // Ciclo sulle mappe + for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) { + // Normalizzo i vettori + vtLs[i].Normalize() ; + vtLe[i].Normalize() ; + + // Direzione utensile costante: pura traslazione + if ( AreSameVectorApprox( vtLs[i], vtLe[i])) { + + // Proiezione dei vettori sulle rispettive griglie + Vector3d vtLsXY( vtLs[i].x, vtLs[i].y, 0) ; + + // Versore utensile parallelo all'asse Z + if ( vtLsXY.SqLen() < EPS_SMALL * EPS_SMALL) { + + Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ; + + // Foratura + if ( vtMove.SqLenXY() < EPS_SMALL) { + // Utensile generico + if ( m_nToolType == 0) + GenTool_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica o sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa conica + else if ( m_nToolType == 4) + Conus_ZDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + // Fresatura con vettore movimento perpendicolare all'utensile + else if ( abs( vtMove.z) < EPS_SMALL) { + // Utensile generico + if ( m_nToolType == 0) + GenTool_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica o sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa conica + else if ( m_nToolType == 4) + Conus_ZPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + // Fresatura con vettore movimento generico rispetto all'utensile + else { + // Utensile generico + if ( m_nToolType == 0) + GenTool_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica o sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa conica + else + Conus_ZMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + } + // Versore utensile nel piano + else if ( abs( vtLs[i].z) < EPS_SMALL) { + + Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ; + Vector3d vtMLong = ( vtMove * vtLs[i]) * vtLs[i] ; + Vector3d vtMOrt = vtMove - vtMLong ; + + double dSqLOrt = vtMOrt.SqLen() ; + + // Foratura + if ( dSqLOrt < EPS_SMALL * EPS_SMALL) { + // Utensile generico + if ( m_nToolType == 0) + GenTool_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica o sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa conica + else + Conus_XYDrilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + // Fresatura con vettore movimento perpendicolare all'utensile + else if ( 1 - dSqLOrt < EPS_SMALL * EPS_SMALL) { + // Utensile generico + if ( m_nToolType == 0) + GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica o sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa conica + else if ( m_nToolType == 4) + Conus_XYPerp( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + // Fresatura con vettore movimento generico rispetto all'utensile + else { + // Utensile generico + if ( m_nToolType == 0) + GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica o sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Altri utensili + else if ( m_nToolType == 4) + Conus_XYMilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + } + // Versore utensile con direzione generica + else { + + Vector3d vtMove = ptLe[i] - ptLs[i] ; vtMove.Normalize() ; + Vector3d vtMLong = ( vtMove * vtLs[i]) * vtLs[i] ; + Vector3d vtMOrt = vtMove - vtMLong ; + + double dSqLOrt = vtMOrt.SqLen() ; + + // Foratura + if ( dSqLOrt < EPS_SMALL * EPS_SMALL) { + // Utensile generico + if ( m_nToolType == 0) + GenTool_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica e sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + else if ( m_nToolType == 4) + Conus_Drilling( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + else { + // Utensile generico + if ( m_nToolType == 0) + GenTool_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; + // Fresa cilindrica e sferica + else if ( m_nToolType == 1 || m_nToolType == 2) + CylBall_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; + else if ( m_nToolType == 4) + Conus_Milling( i, ptLs[i], ptLe[i], vtLs[i]) ; + } + } + } + else ; + // Altri casi al momento non gestiti + // return false ; + } + return true ; +} + + + +// ---------- VERSORE UTENSILE DERETTO COME Z -------------------------------- + + +// ---------- Cilindro e sfera ----------------------------------------------- +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Proiezione dei punti sul piano + Point3d ptSxy( ptS.x, ptS.y, 0) ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dSqRad = m_dRadius * m_dRadius ; + + // Punte del gambo + Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ; + Point3d ptTStemE = ptE - vtToolDir * dStemHeigth ; + + // Quote estreme del gambo + double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; + double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptE.z, ptTStemE.z)) ; + + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; + + double dSqLen = vtC.SqLen() ; + + // Se il punto si trova dentro il cerchio taglio + if ( dSqLen < dSqRad) + // utensile cilindrico + if ( m_nToolType == CylindricalMill) + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ; + // utensile sferico + else if ( m_nToolType == BallEndMill) { + + double dH = sqrt( dSqRad - dSqLen) ; + + if ( vtToolDir.z > 0) + SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; + else + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_ZPerp( unsigned int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + //Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dSqRad = m_dRadius * m_dRadius ; + + // Punte del gambo + Point3d ptTStemS = ptS - vtToolDir * dStemHeigth ; + Point3d ptTStemE = ptE - vtToolDir * dStemHeigth ; + + // Quote estreme del gambo + double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; + double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptS.z, ptTStemS.z)) ; + + // Vettore movimento e sua lunghezza + Vector3d vtMove = ptE - ptS ; double dLen = vtMove.LenXY() ; + + // Definizione di un sistema di riferimento ad hoc + Point3d ptSxy( ptS.x, ptS.y, 0) ; + Vector3d vtV1 = vtMove ; vtV1.Normalize() ; // se |vtMove| < EPS è un buco con dz = 0 + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; + + double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; + + // Utensile cilindrico + if ( m_nToolType == CylindricalMill) { + // Se il punto cade nella zona di interesse taglio + if ( ( dP1 * dP1 + dP2 * dP2 < dSqRad) || + ( ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2) < dSqRad || + ( dP1 > 0 && dP1 < dLen && abs( dP2) < m_dRadius)) + + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ; + } + // Utensile sferico + else if ( m_nToolType == BallEndMill) { + + if ( dP1 < 0 && dP1 * dP1 + dP2 * dP2 < m_dRadius * m_dRadius) { + + double dH = sqrt( dSqRad - dP1 * dP1 - dP2 * dP2) ; + + if ( vtToolDir.z > 0) + SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; + else + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; + } + else if ( dP1 > dLen && ( dP1 - dLen) * ( dP1 - dLen) + dP2 * dP2 < dSqRad) { + + double dH = sqrt( dSqRad - ( dP1 - dLen) * ( dP1 - dLen) - dP2 * dP2) ; + + if ( vtToolDir.z > 0) + SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; + else + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; + } + else if ( dP1 > - EPS_SMALL && dP1 < dLen + EPS_SMALL && abs( dP2) < m_dRadius) { + + double dH = sqrt( dSqRad - dP2 * dP2) ; + + if ( vtToolDir.z > 0) + SubtractIntervals( nGrid, i, j, dMinStemZ - dH, dMaxStemZ) ; + else + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ + dH) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dSqRad = m_dRadius * m_dRadius ; + + // Studio delle simmetrie + Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; + Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; + Point3d ptIT = ptI - vtToolDir * dStemHeigth ; + Point3d ptFT = ptF - vtToolDir * dStemHeigth ; + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + // Quote iniziali e finali massime e + // minime del gambo dell'utensile e DeltaZ + double dZMaxI = max( ptI.z, ptIT.z) ; + double dZMaxF = max( ptF.z, ptFT.z) ; + double dZMinI = dZMaxI - dStemHeigth ; + double dZMinF = dZMaxF - dStemHeigth ; + double dDeltaZ = dZMaxF - dZMaxI ; + + // Vettori caratterizzanti il moto + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + double dLen = vtMove.Len() ; + double dLenXY = vtMoveXY.LenXY() ; + vtMove.Normalize() ; + + // Parametri per determinare l'ellisse proiettata + double dCos = vtToolDir * vtMove ; + double dSin = ( abs( dCos) < 1 ? 1 - dCos * dCos : 0) ; + double dSemiAxMin = m_dRadius * dCos ; // x1^2 = a^2 - (a / b)^2 x2^2 ; a = r dCos e b = r; + double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; // da cui si ottiene x1^2 = a^2 - dCos^2 x2^2 + double dSqRatio = dSqSemiAxMin / dSqRad ; + + // Definizione di un sistema di riferimento ad hoc + Vector3d vtV1, vtV2 ; + + // Se la lunghezza è troppo piccola lo allungo + if ( dLenXY < EPS_SMALL) + vtV1 = ( 1 / dLenXY) * vtMoveXY ; + else + vtV1 = vtMoveXY ; + + // Normalizzo vtV1 + vtV1.Normalize() ; + // Definisco vtV2 + vtV2 = vtV1 ; + vtV2.Rotate( Z_AX, 90) ; + + double dMin, dMax ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo + if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < m_dRadius) || + ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad || + dX1 * dX1 + dX2 * dX2 < dSqRad) { + + if ( m_nToolType == CylindricalMill) { + + double dX1_0 = sqrt( dSqRad - dX2 * dX2) ; + // Massimo + if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) + + dMax = dZMaxF ; + else + dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ; + // Minimo + if ( dX1 * dX1 + dX2 * dX2 < dSqRad) + + dMin = dZMinI ; + else + dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( m_nToolType == BallEndMill) { + + double dCylX1_0 = sqrt( dSqRad - dX2 * dX2) ; + double dSqRoot = sqrt( dSqRad - dX2 * dX2) ; + double dX1_0 = dCos * dSqRoot ; + double dH0 = dSin * dSqRoot ; + + if ( vtToolDir.z > 0) { + // Massimo + if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) + + dMax = dZMaxF ; + else + dMax = dZMaxI + dDeltaZ * ( dX1 + dCylX1_0) / dLenXY ; + + // Minimo + if ( dX1 < dX1_0) + + dMin = dZMinI - sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ; + + else if ( dX1 < dLenXY + dX1_0) + + dMin = dZMinI - dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; + else + dMin = dZMinF - sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else { + // Massimo + if ( dX1 < - dX1_0) + + dMax = dZMaxI + sqrt( dSqRad - dX1 * dX1 - dX2 * dX2) ; + + else if ( dX1 < dLenXY - dX1_0) + + dMax = dZMaxI + dH0 + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; + else + dMax = dZMaxF + sqrt( dSqRad - ( dX1 - dLenXY) * ( dX1 - dLenXY) - dX2 * dX2) ; + + // Minimo + if ( dX1 * dX1 + dX2 * dX2 < dSqRad) + + dMin = dZMinI ; + else + dMin = dZMinI + dDeltaZ * ( dX2 - dCylX1_0) / dLenXY ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + } + return true ; +} + + +// ---------- Coni ----------------------------------------------------------- +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dDeltaRad = dMaxRad - dMinRad ; + double dSqMinRad = dMinRad * dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Proiezione delle posizioni sul piano + Point3d ptO( ptS.x, ptS.y, 0) ; + + // Quote massime e minime dell'utensile durante il moto + double dZMax = max( max( ptS.z, ptS.z - vtToolDir.z * m_dHeight), max( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ; + double dZMin = min( min( ptS.z, ptS.z - vtToolDir.z * m_dHeight), min( ptE.z, ptE.z - vtToolDir.z * m_dHeight)) ; + + // Trapano + if ( m_dTipRadius < m_dRadius) { + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptO ; + + double dSqDist = vtC.SqLenXY() ; + + if ( dSqDist < dSqMinRad) + + SubtractIntervals( nGrid, i, j, dZMin, dZMax) ; + + else if ( dSqDist < dSqMaxRad) { + + double dr = sqrt( dSqDist) ; + + if ( vtToolDir.z > 0) + + SubtractIntervals( nGrid, i, j, dZMin + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax) ; + else + SubtractIntervals( nGrid, i, j, dZMin, dZMax - m_dTipHeight * ( dr - dMinRad) / dDeltaRad) ; + } + } + } + } + // Coda di rondine + else { + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptO ; + + double dSqDist = vtC.SqLenXY() ; + + if ( dSqDist < dSqMinRad) + + SubtractIntervals( nGrid, i, j, dZMin, dZMax) ; + + else if ( dSqDist < dSqMaxRad) { + + double dr = sqrt( dSqDist) ; + + if ( vtToolDir.z > 0) + + SubtractIntervals( nGrid, i, j, dZMin, dZMax - dStemHeigth - m_dTipHeight * ( dr - dMinRad) / dDeltaRad) ; + else + SubtractIntervals( nGrid, i, j, dZMin + dStemHeigth + m_dTipHeight * ( dr - dMinRad) / dDeltaRad, dZMax) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dDeltaRad = dMaxRad - dMinRad ; + double dSqMinRad = dMinRad * dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Quote fondo, punta e fine gambo + double dBaseZ = ptS.z ; + double dTipZ = ptS.z - m_dHeight * vtToolDir.z ; + double dStemZ = ptS.z - dStemHeigth * vtToolDir.z ; + double dZ1 = ( m_dRadius > m_dTipRadius ? dBaseZ : dTipZ) ; + double dZ2 = ( m_dRadius > m_dTipRadius ? dTipZ : dStemZ) ; + double dZ3 = ( m_dRadius > m_dTipRadius ? dStemZ : dTipZ) ; + + + // Sistemi di riferimento sul piano + Point3d ptIxy( ptS.x, ptS.y, 0) ; + Point3d ptFxy( ptE.x, ptE.y, 0) ; + Vector3d vtV1 = ptFxy - ptIxy ; + double dLenXY = vtV1.LenXY() ; + vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; + vtV2.Rotate( Z_AX, 90) ; + + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtCI = ptC - ptIxy ; + Vector3d vtCF = ptC - ptFxy ; + + double dSqDistI = vtCI.SqLenXY() ; + double dSqDistF = vtCF.SqLenXY() ; + + double dX1 = vtCI * vtV1 ; + double dX2 = vtCI * vtV2 ; + + + if ( dSqDistI < dSqMinRad || dSqDistF < dSqMinRad || + ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dMinRad)) + + SubtractIntervals( nGrid, i, j, min( dBaseZ, dTipZ), max( dBaseZ, dTipZ)) ; + + else if ( dSqDistI < dSqMaxRad && dX1 < 0) { + + double dr = sqrt( dSqDistI) ; + + SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), + max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ; + } + else if ( dX1 <= dLenXY && abs( dX2) < dMaxRad) { + + double dr = abs( dX2) ; + + SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), + max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ; + } + else if ( dSqDistF < dSqMaxRad) { + + double dr = sqrt( dSqDistF) ; + + SubtractIntervals( nGrid, i, j, min( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad), + max( dZ1, dZ2 + ( dr - dMinRad) * ( dZ3 - dZ2) / dDeltaRad)) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + if ( m_dTipRadius < m_dRadius) + Dr_ZMilling( nGrid, ptS, ptE, vtToolDir) ; + else + Sw_ZMilling( nGrid, ptS, ptE, vtToolDir) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Dr_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza dell'utensile con lo Zmap + bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Punti iniziale e finale e proiezione sul piano del punto iniziale + Point3d ptI, ptF, ptO ; + + if ( vtToolDir.z > 0) { + ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + } + else { + ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + } + + // Raggio minimo e massimo + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + + // Quote iniziale e finale della base dell'utensile e DeltaZ + double dZI = ptI.z ; + double dZF = ptF.z ; + double dDeltaZ = dZF - dZI ; + + + // Vettori di movimento + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; + + // Sistema di riferimento sul cono e vertice del cono + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + Point3d ptV = ptI - ( m_dHeight + m_dTipHeight * dMinRad / ( dMaxRad - dMinRad)) * vtV1 ; + + // Apertura del cono e parametri per determinare i piani + double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + + double dCos = dTanAlpha * dRatio ; + double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 + + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 - + ( dSin / dDen) * vtV3 ; + + Vector3d vtR0 = ptV - ORIG ; + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + // Grandezze per determinare la configurazione geometrica dell'utensile + double dMin, dMax ; + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptO ; + Vector3d vtCf = vtC - vtMoveXY ; + + Vector3d vtUC = vtC ; vtUC.Normalize() ; + Vector3d vtUCf = vtCf ; vtUCf.Normalize() ; + + double dCCos = vtUC * vtV2 ; + double dCCosf = vtUCf * vtV2 ; + + double dProj = vtC * vtV2 ; + Vector3d vtOrt = vtC - dProj * vtV2 ; + + double dSqDistI = vtC * vtC ; + double dSqDistM = vtOrt * vtOrt ; + double dSqDistF = vtCf * vtCf ; + + // Se dentro la zona interessata dalla lavorazione valuto + // la tipologia di tale zona + if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || + ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || + ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { + + // Caso vettore utensile equiverso all'asse Z + if ( vtToolDir.z > 0) { + // Massimi + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + if ( dProj < dLen - dPMaxI) + + dMax = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxI) ; + else + dMax = dZF ; + + // Minimi + if ( dSqDistI < dMinRad * dMinRad) + + dMin = dZI - m_dHeight ; + + else { + + if ( ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMin = dZI - m_dHeight + ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; + else + dMin = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMin = dZF - m_dHeight + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + + dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + else { + + if ( dSqDistI < dMaxRad * dMaxRad) + + dMin = dZI - m_dHeight + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) + + dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + } + // Caso vettore utensile opposto all'asse Z + else { + // Massimi + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + if ( dSqDistI < dMinRad * dMinRad) + + dMax = dZI + m_dHeight ; + + else { + + if ( - ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMax = dZI + m_dHeight - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMax = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; + else + dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMax = dZF + m_dHeight - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + + dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + + } + else { + + if ( dSqDistI < dMaxRad * dMaxRad) + + dMax = dZI + m_dHeight - ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + + else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) + + dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + + } + } + // Minimi + double dPMaxCirc = sqrt( dMaxRad * dMaxRad - dSqDistM) ; + + if ( dProj > dLen - dPMaxCirc) + dMin = dZF ; + else + dMin = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxCirc) ; + } + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Sw_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza dell'utensile con lo Zmap + bool bTest = BoundingBox( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Punti iniziale e finale e proiezione sul piano del punto iniziale + Point3d ptI, ptF, ptO ; + + if ( vtToolDir.z > 0) { + + ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + } + + else { + ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; + ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + } + + Point3d ptICyl = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dDeltaH = m_dHeight - m_dTipHeight ; + double dMinZCyl = min( ptICyl.z, ptICyl.z - vtToolDir.z * dDeltaH) ; + + // Punti contatto cono cilindro + Point3d ptIS = ptI - ( m_dHeight - m_dTipHeight) * vtToolDir ; + Point3d ptFS = ptF - ( m_dHeight - m_dTipHeight) * vtToolDir ; + + // Quote iniziali e finali e DeltaZ + double dZI = ptI.z ; double dZF = ptF.z ; + double dDeltaZ = dZF - dZI ; double dADeltaZ = abs( dDeltaZ) ; + double dZIS = ptIS.z ; double dZFS = ptFS.z ; + + // Vettori di movimento + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; + + // Sistema di riferimento sul cono e vertice del cono + Vector3d vtV1 = - vtToolDir ; + Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + Point3d ptV = ptI + ( m_dHeight - m_dTipHeight * ( 1 + dMinRad / ( dMaxRad - dMinRad))) * vtV1 ; + + // Apertura del cono e parametri per determinare i piani + double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + + double dCos = dTanAlpha * dRatio ; + double dSin = ( abs( dCos) < 1 ? sqrt( 1- dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; + + // Versori normali e prodotti scalari per per determinare i piani + Vector3d vtNp = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 + + ( dSin / dDen) * vtV3 ; + Vector3d vtNm = - ( dTanAlpha / dDen) * vtV1 + + ( dCos / dDen) * vtV2 - + ( dSin / dDen) * vtV3 ; + + Vector3d vtR0 = ptV - ORIG ; + double dDotp = vtR0 * vtNp ; + double dDotm = vtR0 * vtNm ; + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++j) { + + double dMin, dMax ; + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; Vector3d vtCf = vtC - vtMoveXY ; + + Vector3d vtUC = vtC ; Vector3d vtUCf = vtCf ; vtUC.Normalize() ; vtUCf.Normalize() ; + + double dCCos = vtUC * vtV2 ; double dCCosf = vtUCf * vtV2 ; + + double dProj = vtC * vtV2 ; + Vector3d vtOrt = vtC - dProj * vtV2 ; + + double dSqDistI = vtC * vtC ; + double dSqDistM = vtOrt * vtOrt ; + double dSqDistF = vtCf * vtCf ; + + if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || + ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || + ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { + // Caso vettore utensile equiverso all'asse Z + if ( vtV1.z < 0) { + + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + // Massimi + if ( dRatio <= 1 / dTanAlpha) { + + if ( dSqDistI < dMinRad * dMinRad) + + dMax = dZIS ; + + else { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMax = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; + else + dMax = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMax = dZFS - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + else { + + if ( dSqDistI < dMinRad * dMinRad) + + dMax = dZIS ; + + else if ( dSqDistI < dMaxRad * dMaxRad) + + dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else { + + if ( dProj >= dPMaxI) + + dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + // Minimi + + if ( dSqDistF < dMaxRad * dMaxRad) + + dMin = dZFS - m_dTipHeight ; + + else if ( dProj <= dLen - dPMaxI) + + dMin = dZIS - m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; + + } + // Caso vettore utensile opposto all'asse Z + else { + + double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; + + // Massimi + if ( dSqDistF < dMaxRad * dMaxRad) + + dMax = dZFS + m_dTipHeight ; + + else if ( dProj <= dLen - dPMaxI) + + dMax = dZIS + m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; + + // Minimi + if ( dRatio <= 1 / dTanAlpha) { + + if ( dSqDistI < dMinRad * dMinRad) + + dMin = dZIS ; + + else { + + if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) + + dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { + + double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; + double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistM <= dMinSql) + + dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + + else if ( dSqDistM < dMaxSql) { + + if ( vtC * vtV3 > 0) + + dMin = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; + else + dMin = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; + } + } + else if ( dCCosf >= dCos) { + + double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; + + if ( dSqDistF < dMinRad * dMinRad) + + dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; + else + dMin = dZFS + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; + } + else + dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + } + } + else { + + if ( dSqDistI < dMinRad * dMinRad) + + dMin = dZIS ; + + else if ( dSqDistI < dMaxRad * dMaxRad) + + dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; + + else + + dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; + + } + } + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Parte cilindrica + Vector3d vtCyl = ( vtV1.z < 0 ? vtCf : vtC) ; + Vector3d vtCylf = ( vtV1.z < 0 ? vtC : vtCf) ; + Vector3d vtMot = ( vtV1.z < 0 ? - vtV2 : vtV2) ; + + double dCylProj = vtCyl * vtMot ; + double dCylSqDistI = vtCyl * vtCyl ; + double dCylSqDistF = vtCylf * vtCylf ; + double dCylSqDistM = ( vtCyl - dCylProj * vtMot) * ( vtCyl - dCylProj * vtMot) ; + + + if ( dCylSqDistI < dMinRad * dMinRad + || dCylSqDistF < dMinRad * dMinRad + || ( dCylProj > 0 && dCylProj < dLen && dCylSqDistM < dMinRad * dMinRad)) { + + double dSt = sqrt( dMinRad * dMinRad - dCylSqDistM) ; + + // Minimi + if ( dCylSqDistI < dMinRad * dMinRad ) + + dMin = dMinZCyl ; + + else if ( dCylProj >= dSt) + + dMin = dMinZCyl + ( dCylProj - dSt) * dADeltaZ / dLen ; + + // Massimi + if ( dCylSqDistF < dMinRad * dMinRad) + + dMax = dMinZCyl + dDeltaH + dADeltaZ ; + + else if ( dCylProj <= dLen - dSt) + + dMax = dMinZCyl + dDeltaH + ( dCylProj + dSt) * dADeltaZ / dLen ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + + } + } + } + return true ; +} + +// --------- Utensile generico ------------------------------------------------ + +//---------------------------------------------------------------------------- +bool +VolZmap::GenTool_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptS ; + Point3d ptF = ptE ; + + // vettore movimento + Vector3d vtMove = ptE - ptS ; + + // Settaggio profilo + CurveComposite* pToolProfile ; + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + pToolProfile = &m_ToolOutline ; + else + // altrimenti usi l'approssimazione + pToolProfile = &m_ToolArcLineApprox ; + + // Ciclo sulle curve + const ICurve* pCurve = pToolProfile->GetFirstCurve() ; + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso segmento + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + CompCyl_ZDrilling( nGrid, ptS, ptE, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + CompConus_ZDrilling( nGrid, ptS, ptE, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utesile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + CompConus_ZDrilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = pToolProfile->GetNextCurve() ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptS ; + Point3d ptF = ptE ; + + // vettore movimento + Vector3d vtMove = ptE - ptS ; + + // Settaggio profilo + CurveComposite* pToolProfile ; + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + pToolProfile = &m_ToolOutline ; + else + // altrimenti usi l'approssimazione + pToolProfile = &m_ToolArcLineApprox ; + + // Ciclo sulle curve + const ICurve* pCurve = pToolProfile->GetFirstCurve() ; + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso segmento + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + CompCyl_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + CompConus_ZMilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + CompConus_ZMilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = pToolProfile->GetNextCurve() ; + } + return true ; + +} + + +// ---------- VERSORE UTENSILE NEL PIANO XY ---------------------------------- + +// --------- Cilindro e sfera ------------------------------------------------ +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile e quota Z del movimento + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dSqRad = m_dRadius * m_dRadius ; + double dZ = ptS.z ; + + // Vettore movimento e sua lunghezza + Vector3d vtMove = ptE - ptS ; double dLen = vtMove.LenXY() ; + + // Definizione di un sistema di riferimento ad hoc + Point3d ptI = ( vtMove * vtToolDir > 0 ? ptE : ptS) ; + Point3d ptF = ( vtMove * vtToolDir > 0 ? ptS - dStemHeigth * vtToolDir : ptE - dStemHeigth * vtToolDir) ; + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; + + Vector3d vtBall = ptC - ptFxy ; double dSqLen = vtBall.SqLenXY() ; + + // Zona lavorata dalla parte cilindrica + if ( dP1 > 0 && dP1 < dStemHeigth + dLen && + abs( dP2) < m_dRadius ) { + + double dH = sqrt( dSqRad - dP2 * dP2) ; + + SubtractIntervals( nGrid, i, j, dZ - dH , dZ + dH) ; + } + + // Se l'utensile è sferico sottraggo anche la punta + if ( m_nToolType == BallEndMill) + if ( dSqLen < dSqRad) { // LA SOLUZIONE MOMENTANEA è CREARE UTENSILE GENERICO SE LO STELO è PIù CORTO DEL RAGGIO + + double dH = sqrt( dSqRad - dSqLen) ; + + SubtractIntervals( nGrid, i, j, dZ - dH, dZ + dH) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dSqRad = m_dRadius * m_dRadius ; + + // Studio simmetrie del problema + Point3d ptI = ( ptS.z <= ptE.z ? ptS : ptE) ; + Point3d ptF = ( ptS.z <= ptE.z ? ptE : ptS) ; + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + // Quote punti iniziale e finale + double dZI = ptI.z ; + double dZF = ptF.z ; + double dDeltaZ = ptF.z - ptI.z ; + + // Vettori caratterizzanti il moto + Vector3d vtMove = ptF - ptI ; + double dLen = vtMove.Len() ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + double dLenXY = vtMoveXY.LenXY() ; + vtMove.Normalize() ; + + // Sistema di riferimento ad hoc + Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + if ( vtV2 * vtMove < 0) + vtV2 = - vtV2 ; + + // Vettori e punti determinanti i piani + Vector3d vtP = vtMove ; // Se dLen < EPS_SMALL non si usa + vtP.Rotate( vtToolDir, 90) ; + Point3d ptUp = ptI + m_dRadius * ( vtP.z > 0 ? vtP : - vtP) ; + Point3d ptDw = ptI + m_dRadius * ( vtP.z > 0 ? - vtP : vtP) ; + + Vector3d vtPXY( vtP.x, vtP.y, 0) ; + + Vector3d vtUp = ptUp - ORIG ; double dDotUp = vtUp * vtP ; + Vector3d vtDw = ptDw - ORIG ; double dDotDw = vtDw * vtP ; + + double dSmall = m_dRadius * vtPXY.LenXY() ; + + // Parte sferica + double dCos = vtMove.z ; // vtMove.z > 0 : ptF.z >= ptI.z + double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ; + double dSemiAxMin = m_dRadius * dCos ; + + double dInfZ, dSupZ ; + + + for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dP1 = vtC * vtV1 ; + double dP2 = vtC * vtV2 ; + + // Parte cilindrica + if ( dP1 > 0 && dP1 < dStemHeigth) { + + if ( dP2 > - m_dRadius && dP2 < dLenXY + m_dRadius) { + // Massimi + if ( dP2 < - dSmall + EPS_SMALL) { + double dHsq = dSqRad - dP2 * dP2 ; + double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; + dSupZ = dZI + dH ; + } + else if ( dP2 < dLenXY - dSmall - EPS_SMALL) { + + dSupZ = ( dDotUp - dX * vtP.x - dY * vtP.y) / vtP.z ; + } + else { + + double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + dSupZ = dZF + dH ; + } + // Minimi + if ( dP2 < dSmall + EPS_SMALL) { + double dHsq = dSqRad - dP2 * dP2 ; + double dH = ( dHsq > 0 ? sqrt( dHsq) : 0) ; + dInfZ = dZI - dH ; + } + else if ( dP2 < dLenXY + dSmall - EPS_SMALL) { + + dInfZ = ( dDotDw - dX * vtP.x - dY * vtP.y) / vtP.z ; + } + else { + + double dH = sqrt( dSqRad - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + dInfZ = dZF - dH ; + } + + SubtractIntervals( nGrid, i, j, dInfZ, dSupZ) ; + } + } + // Se l'utensile è ball-end sottraggo la punta + if ( m_nToolType == BallEndMill) { + + if ( ( ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + dP2 * dP2 < dSqRad || + ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) + ( dP2 - dLenXY) * ( dP2 - dLenXY) < dSqRad || + ( dP2 > 0 && dP2 < dLenXY && dP1 < m_dHeight)) && ( dP1 >= dStemHeigth)) { + + double dSqRoot = sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth)) ; + double dP2_0 = dCos * dSqRoot ; + double dH0 = dSin * dSqRoot ; + + double dMin, dMax ; + + // Massimo + if ( dP2 < - dP2_0) + + dMax = dZI + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; + + else if ( dP2 < dLenXY - dP2_0) + + dMax = dZI + dH0 + dDeltaZ * ( dP2 + dP2_0) / dLenXY ; + else + dMax = dZF + sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + + // Minimo + if ( dP2 < dP2_0) + + dMin = dZI - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - dP2 * dP2) ; + + else if ( dP2 < dLenXY + dP2_0) + + dMin = dZI - dH0 + dDeltaZ * ( dP2 - dP2_0) / dLenXY ; + else + dMin = dZF - sqrt( dSqRad - ( dP1 - dStemHeigth) * ( dP1 - dStemHeigth) - ( dP2 - dLenXY) * ( dP2 - dLenXY)) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + if ( m_nToolType == CylindricalMill) + + return CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, m_dHeight, m_dRadius) ; + + else if ( m_nToolType == BallEndMill) { + + double dHei = m_dHeight - m_dTipHeight ; + + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dHei, m_dRadius) ; + + CompBall_Milling( nGrid, ptS - dHei * vtToolDir, ptE - dHei * vtToolDir, m_dRadius) ; + + return true ; + } + else + return false ; +} + + +// --------- Coni ------------------------------------------------------------ +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dDeltaRad = dMaxRad - dMinRad ; + double dSqMinRad = dMinRad * dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Geometria del moto + double dLenXY = ( ptE - ptS).LenXY() ; + Point3d ptI = ( vtToolDir * ( ptE - ptS) < 0 ? ptS : ptE) ; + double dMatStemLen = ( m_dRadius > m_dTipRadius ? dStemHeigth + dLenXY : dStemHeigth) ; + double dSqTipRad = m_dTipRadius * m_dTipRadius ; + double dSqRad = m_dRadius * m_dRadius ; + + // Sistema di riferimento sul piano + Vector3d vtV1 = - vtToolDir ; + Vector3d vtV2 = vtV1 ; + vtV2.Rotate( Z_AX, 90) ; + + // Proiezione di ptI sul piano + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC ( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + double dr = m_dRadius + ( dX1 - dMatStemLen) * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; + + if ( dX1 > 0 && dX1 < dMatStemLen && + abs( dX2) < m_dRadius) { + + double dH = sqrt( dSqRad - dX2 * dX2) ; + SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ; + } + else if ( dX1 >= dMatStemLen && + dX1 < dMatStemLen + m_dTipHeight && + abs( dX2) < dr) { + + double dH = sqrt( dr * dr - dX2 * dX2) ; + SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ; + } + + if ( m_dTipRadius >= m_dRadius) { + + if ( dX1 >= dMatStemLen + m_dTipHeight && + dX1 < dMatStemLen + m_dTipHeight + dLenXY && + abs( dX2) < dSqTipRad) { + + double dH = sqrt( dSqTipRad - dX2 * dX2) ; + SubtractIntervals( nGrid, i, j, ptI.z - dH, ptI.z + dH) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dSqTipRad = m_dTipRadius * m_dTipRadius ; + double dSqRad = m_dRadius * m_dRadius ; + double dDeltaRad = dMaxRad - dMinRad ; + double dSqMinRad = dMinRad * dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Studio delle simmetrie + Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; + Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; + + // Vettori caratterizzanti il moto + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + double dLen = vtMove.Len() ; + double dLenXY = vtMoveXY.LenXY() ; + + // Quote iniziale e finale + double dZI = ptI.z ; + double dZF = ptF.z ; + + // Sistema di riferimento sul piano + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + // Primo vettore del riferimento + Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; + vtV1.Normalize() ; + Vector3d vtV2 ; + + // Movimento verticale + if ( dLenXY / dLen < EPS_SMALL) { + + // Secondo vettore del riferimento + vtV2 = vtV1 ; + vtV2.Rotate( Z_AX, 90) ; + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; + // Parte cilindrica + if ( dX1 > 0 && dX1 < dStemHeigth && abs( dX2) < m_dRadius) { + + double dH = sqrt( dSqRad - dX2 * dX2) ; + SubtractIntervals( nGrid, i, j, dZI - dH, dZF + dH) ; + } + // Parte conica + else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && abs( dX2) < dr) { + + double dH = sqrt( dr * dr - dX2 * dX2) ; + SubtractIntervals ( nGrid, i, j, dZI - dH, dZF + dH) ; + } + } + } + } + else { + + // Secondo vettore del riferimento + Vector3d vtV2 = vtMoveXY ; + vtV2.Normalize() ; + + // Sistema di riferimento per determinare i piani + Vector3d vtW1 = ( m_dHeight > m_dTipHeight ? vtV1 : - vtV1) ; + Vector3d vtW2 = vtMove ; + vtW2.Normalize() ;// Se vtMove non è suff ort a vtW1 vtMove = vtMoveOrt + vtMoveLong e via + Vector3d vtW3 = vtW1 ^ vtW2 ; + + // Altezza cono + double dL = dMaxRad * m_dTipHeight / dDeltaRad ; + + // Vertice del cono iniziale + Point3d ptV = ptI - ( m_dHeight > m_dTipHeight ? ( dStemHeigth + dL) * vtW1 : ( dL - m_dHeight) * vtW1) ; + + // + double dCos = vtW2.z ; + double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dLimXY = dCos * m_dRadius ; + double dLimH = dSin * m_dRadius ; + double dDeltaZ = ptF.z - ptI.z ; + + double dMin, dMax ; + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; + + // Parte cilindrica + if ( dX1 > 0 && dX1 < dStemHeigth && + dX2 > - m_dRadius && dX2 < dLenXY + m_dRadius) { + // Massimi + if ( dX2 < - dLimXY) + dMax = dZI + sqrt( dSqRad - dX2 * dX2) ; + else if ( dX2 < dLenXY - dLimXY) + dMax = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ; + else + dMax = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + // Minimi + if ( dX2 < dLimXY) + dMin = dZI + sqrt( dSqRad - dX2 * dX2) ; + else if ( dX2 < dLenXY + dLimXY) + dMin = dZI - dLimH + dDeltaZ * ( dX2 - dLimXY) / dLenXY ; + else + dMin = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + // Parte conica + else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && + dX2 > - dr && dX2 < dLenXY + dr) { + + double dRadLimXY = dr * dCos ; + double dRadLimH = dr * dSin ; + + // Massimi + if ( dX2 < - dRadLimXY) + dMax = dZI + sqrt( dr * dr - dX2 * dX2) ; + else if ( dX2 < dLenXY - dRadLimXY) + dMax = dZI + dRadLimH + dDeltaZ * ( dX2 + dRadLimXY) / dLenXY ; + else + dMax = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + // Minimi + if ( dX2 < dRadLimXY) + dMin = dZI + sqrt( dr * dr - dX2 * dX2) ; + else if ( dX2 < dLenXY + dRadLimXY) + dMin = dZI - dRadLimH + dDeltaZ * ( dX2 - dRadLimXY) / dLenXY ; + else + dMin = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { + + double dStemHeigth = m_dHeight - m_dTipRadius ; + + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + + if ( m_dTipRadius < m_dRadius) { + + Point3d ptSTip = ptS - dStemHeigth * vtToolDir ; + Point3d ptETip = ptE - dStemHeigth * vtToolDir ; + + CompConus_Milling( nGrid, ptSTip, ptETip, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; + } + else { + + Point3d ptSTip = ptS - m_dHeight * vtToolDir ; + Point3d ptETip = ptE - m_dHeight * vtToolDir ; + + CompConus_Milling( nGrid, ptSTip, ptETip, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; + } + + return true ; +} + +// ---------- VERSORE UTENSILE CON ORIENTAZIONE GENERICA --------------------- + +// ---------- Cilindro e sfera ----------------------------------------------- +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { + + double dStemHeigth = m_dHeight - m_dRadius ; + + CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + // Sfera + if ( m_nToolType == 2) { + + Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; + Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; + + CompBall_Milling( nGrid, ptSBall, ptEBall, m_dRadius) ; + } + + return true ; +} +//---------------------------------------------------------------------------- +bool +VolZmap::CylBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { + + double dStemHeigth = m_dHeight - m_dTipHeight ; + + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + // Sfera + if ( m_nToolType == 2) { + + Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; + Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; + + CompBall_Milling( nGrid, ptSBall, ptEBall, m_dRadius) ; + } + + return true ; +} + +// ---------- Coni ----------------------------------------------------------- +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { + + double dStemHeigth = m_dHeight - m_dRadius ; + + CompCyl_Drilling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + // Trapano + if ( m_dTipRadius < m_dRadius) { + + Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; + Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; + + CompConus_Drilling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; + } + else { + + Point3d ptSBall = ptS - m_dHeight * vtToolDir ; + Point3d ptEBall = ptE - m_dHeight * vtToolDir ; + + CompConus_Drilling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) { + + double dStemHeigth = m_dHeight - m_dTipHeight ; + + CompCyl_Milling( nGrid, ptS, ptE, vtToolDir, dStemHeigth, m_dRadius) ; + // Trapano + if ( m_dTipRadius < m_dRadius) { + + Point3d ptSBall = ptS - dStemHeigth * vtToolDir ; + Point3d ptEBall = ptE - dStemHeigth * vtToolDir ; + + CompConus_Milling( nGrid, ptSBall, ptEBall, vtToolDir, m_dTipHeight, m_dRadius, m_dTipRadius) ; + } + else { + + Point3d ptSBall = ptS - m_dHeight * vtToolDir ; + Point3d ptEBall = ptE - m_dHeight * vtToolDir ; + + CompConus_Milling( nGrid, ptSBall, ptEBall, - vtToolDir, m_dTipHeight, m_dTipRadius, m_dRadius) ; + } + + return true ; +} + +// ---------- Utensile generico ---------------------------------------------- + +//---------------------------------------------------------------------------- +bool +VolZmap::GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptS ; + Point3d ptF = ptE ; + + // vettore movimento + Vector3d vtMove = ptE - ptS ; + + // Settaggio profilo + CurveComposite* pToolProfile ; + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + pToolProfile = & m_ToolOutline ; + else + // altrimenti usi l'approssimazione + pToolProfile = &m_ToolArcLineApprox ; + + // Ciclo sulle curve + const ICurve* pCurve = pToolProfile->GetFirstCurve() ; + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso di semento + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + CompCyl_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + CompConus_Drilling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + CompConus_Drilling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = pToolProfile->GetNextCurve() ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) +{ + // Posizioni iniziale e finale dell'utensile + Point3d ptI = ptS ; + Point3d ptF = ptE ; + + // vettore movimento + Vector3d vtMove = ptE - ptS ; + + // Settaggio profilo + CurveComposite* pToolProfile ; + if ( m_ToolArcLineApprox.GetCurveCount() == 0) + // Se l'utensile non è stato approssimato uso l'originale + pToolProfile = &m_ToolOutline ; + else + // altrimenti usi l'approssimazione + pToolProfile = &m_ToolArcLineApprox ; + + // Ciclo sulle curve + const ICurve* pCurve = pToolProfile->GetFirstCurve() ; + while ( pCurve != nullptr) { + + double dHeight ; + + int nCurveType = pCurve -> GetType() ; + + // Caso di semento + if ( nCurveType == CRV_LINE) { + + Point3d ptStart, ptEnd ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + + if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { + + dHeight = abs( ptStart.y - ptEnd.y) ; + + // Il componente è un cilindro + if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { + + double dRadius = ptStart.x ; + + CompCyl_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dRadius) ; + } + // Il componente è un cono con vettore equiverso a quello dell'utensile + else if ( ptStart.x > ptEnd.x) { + + double dMaxRad = ptStart.x ; + double dMinRad = ptEnd.x ; + + CompConus_Milling( nGrid, ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + // Il componente è un cono con vettore opposto a quello dell'utensile + else if ( ptStart.x < ptEnd.x) { + + double dMaxRad = ptEnd.x ; + double dMinRad = ptStart.x ; + + Point3d ptIn = ptI - vtToolDir * dHeight ; + Point3d ptFn = ptIn + vtMove ; + + CompConus_Milling( nGrid, ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; + } + } + else + dHeight = 0 ; + } + // Caso arco + else if ( nCurveType == CRV_ARC) { + + // Centro e Punti iniziale e finale del cerchio + Point3d ptStart, ptEnd, ptO ; + + pCurve -> GetStartPoint( ptStart) ; + pCurve -> GetEndPoint( ptEnd) ; + pCurve -> GetCenterPoint( ptO) ; + + // Determino il raggio + Vector3d vtStRad = ptStart - ptO ; + Vector3d vtEnRad = ptEnd - ptO ; + + double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; + + // Determino le posizioni iniziale e finale del centrodella sfera + Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; + Point3d ptOEn = ptOSt + vtMove ; + + // Eseguo l'asportazione del materiale + CompBall_Milling( nGrid, ptOSt, ptOEn, dRadius) ; + + + // aggiorno l'altezza + dHeight = abs( ptStart.y - ptEnd.y) ; + } + + // Determino le posizioni iniziale e finale del componente successivo + ptI = ptI - vtToolDir * dHeight ; + ptF = ptI + vtMove ; + + // Aggiorno il puntatore + pCurve = pToolProfile->GetNextCurve() ; + } + + return true ; +} + + +// ------------------------- COMPONENTI ELEMENTARI ----------------------------------------------------------------------------- + +// Asse di simmetria diretto come l'asse Z: FORATURA + +//---------------------------------------------------------------------------- +bool +VolZmap::CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza con lo Zmap + bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, + dRad, dRad, dHei) ; + + if ( ! bTest) + return true ; + + // Proiezione dei punti sul piano + Point3d ptSxy( ptS.x, ptS.y, 0) ; + + // Parametri geometrici dell'utensile + double dSqRad = dRad * dRad ; + + // Punte del gambo + Point3d ptTStemS = ptS - vtToolDir * dHei ; + Point3d ptTStemE = ptE - vtToolDir * dHei ; + + // Quote estreme del gambo + double dMinStemZ = min( min( ptS.z, ptTStemS.z), min( ptE.z, ptTStemE.z)) ; + double dMaxStemZ = max( max( ptS.z, ptTStemS.z), max( ptS.z, ptTStemS.z)) ; + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptSxy ; + + double dSqLen = vtC.SqLen() ; + + // Se il punto si trova dentro il cerchio taglio + if ( dSqLen < dSqRad) + SubtractIntervals( nGrid, i, j, dMinStemZ, dMaxStemZ) ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza con lo Zmap + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( ! Control) + return true ; + + Point3d ptO( ptS.x, ptS.y, 0) ; + + double dZMin, dZMax ; + double dAngC = dHei / ( dMaxRad - dMinRad) ; + double dSqMinRad = dMinRad * dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Studio delle simmetrie + if ( vtToolDir.z > 0) { + + dZMin = ( ptS.z < ptE.z ? ptS.z - dHei : ptE.z - dHei) ; + dZMax = ( ptS.z < ptE.z ? ptE.z : ptS.z) ; + } + else { + + dZMin = ( ptS.z < ptE.z ? ptS.z : ptE.z) ; + dZMax = ( ptS.z < ptE.z ? ptE.z + dHei : ptS.z + dHei) ; + } + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; + + double dSqDist = vtC * vtC ; + + if ( dSqDist < dSqMinRad) + + SubtractIntervals( nGrid, i, j, dZMin, dZMax) ; + + else if ( dSqDist < dSqMaxRad) { + + double dr = sqrt( dSqDist) ; + + if ( vtToolDir.z > 0) + + SubtractIntervals( nGrid, i, j, dZMin + dAngC * ( dr - dMinRad), dZMax) ; + else + SubtractIntervals( nGrid, i, j, dZMin, dZMax - dAngC * ( dr - dMinRad)) ; + } + } + + return true ; +} + +// Asse di simmetria diretto come l'asse Z: FRESATURA + +//---------------------------------------------------------------------------- +bool +VolZmap::CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza con lo Zmap + bool bTest = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici + double dSqRad = dRad * dRad ; + + // Studio delle simmetrie + Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; + Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; + Point3d ptIT = ptI - vtToolDir * dHei ; + Point3d ptFT = ptF - vtToolDir * dHei ; + Point3d ptIxy( ptI.x, ptI.y, 0) ; + + // Quote iniziali e finali massime e + // minime del gambo dell'utensile e DeltaZ + double dZMaxI = max( ptI.z, ptIT.z) ; + double dZMaxF = max( ptF.z, ptFT.z) ; + double dZMinI = dZMaxI - dHei ; + double dZMinF = dZMaxF - dHei ; + double dDeltaZ = dZMaxF - dZMaxI ; + + // Vettori caratterizzanti il moto + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + double dLen = vtMove.Len() ; + double dLenXY = vtMoveXY.LenXY() ; + vtMove.Normalize() ; + + // Parametri per determinare l'ellisse proiettata + double dCos = vtToolDir * vtMove ; + double dSin = ( abs( dCos) < 1 ? 1 - dCos * dCos : 0) ; + double dSemiAxMin = dRad * dCos ; // x1^2 = a^2 - (a / b)^2 x2^2 ; a = r dCos e b = r; + double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; // da cui si ottiene x1^2 = a^2 - dCos^2 x2^2 + double dSqRatio = dSqSemiAxMin / dSqRad ; + + // Definizione di un sistema di riferimento ad hoc + Vector3d vtV1, vtV2 ; + + // Se la lunghezza è troppo piccola lo allungo + if ( dLenXY < EPS_SMALL) + vtV1 = ( 1 / dLenXY) * vtMoveXY ; + else + vtV1 = vtMoveXY ; + + // Normalizzo vtV1 + vtV1.Normalize() ; + // Definisco vtV2 + vtV2 = vtV1 ; + vtV2.Rotate( Z_AX, 90) ; + + double dMin, dMax ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + // Se il punto appartiene alla proiezione del volume spazzato valuto massimo e minimo + if ( ( dX1 > 0 && dX1 < dLenXY && abs( dX2) < dRad) || + ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad || + dX1 * dX1 + dX2 * dX2 < dSqRad) { + + double dX1_0 = sqrt( dSqRad - dX2 * dX2) ; + // Massimo + if ( ( dX1 - dLenXY) * ( dX1 - dLenXY) + dX2 * dX2 < dSqRad) + + dMax = dZMaxF ; + else + dMax = dZMaxI + dDeltaZ * ( dX1 + dX1_0) / dLenXY ; + // Minimo + if ( dX1 * dX1 + dX2 * dX2 < dSqRad) + + dMin = dZMinI ; + else + dMin = dZMinI + dDeltaZ * ( dX1 - dX1_0) / dLenXY ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) +{ + double dMin, dMax, dPLim, dMLim ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( ! Control) + return true ; + + Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; + Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + double dZI = ptI.z ; + double dZTI = ptI.z - vtV1.z * dHei ; + double dDeltaZ = ptF.z - ptI.z ; + double dDeltaR = dMaxRad - dMinRad ; + + double dTan = dDeltaR / dHei ; + double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; + + double dCos = dTan * dRatio ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + + Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; + + Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; + Vector3d vtR0 = ptV - ORIG ; + + double dDots = vtR0 * vtNs ; + double dDotd = vtR0 * vtNd ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCI = ptC - ptIxy ; double dSqDI = vtCI.SqLenXY() ; + Vector3d vtCF = ptC - ptFxy ; double dSqDF = vtCF.SqLenXY() ; + + double dIDO = vtCI * vtV3 ; + double dIDL = vtCI * vtV2 ; + double dIVarCos = dIDL / sqrt( dSqDI) ; + + double dFDL = vtCF * vtV2 ; + double dFVarCos = dFDL / sqrt( dSqDF) ; + + if ( dSqDI < dMaxRad * dMaxRad || dSqDF < dMaxRad * dMaxRad || + (abs( dIDO) < dMaxRad && dIDL > 0 && dIDL < dLOrt)) { + + // Caso dTan > 1 / dRatio + if ( dRatio > 1 / dTan) { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) + + dPLim = dZI + dDeltaZ ; + + else + + dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) + + dMLim = dZTI ; + + else if ( dSqDI < dMaxRad * dMaxRad) + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + else + + dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + } + else { + + // Limiti nella direzione positiva di vtV1 + if ( dSqDF < dMaxRad * dMaxRad) + + dPLim = dZI + dDeltaZ ; + + else + + dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + // Limiti nella direzione negativa di vtV1 + if ( dSqDI < dMinRad * dMinRad) + + dMLim = dZTI ; + + else if ( dSqDI >= dMinRad * dMinRad && dSqDI < dMaxRad * dMaxRad && dIVarCos < dCos) + + dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + + else if ( dSqDI >= dMinRad * dMinRad && dIVarCos >= dCos && dFVarCos < dCos && abs( dIDO) < dMaxRad * dSin) { // da qui + + if ( dIDO > - dMaxRad * dSin && dIDO <= - dMinRad * dSin) + + dMLim = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; + + else if ( dIDO > - dMinRad * dSin && dIDO < dMinRad * dSin) + + dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + else if ( dIDO >= dMinRad * dSin && dIDO < dMaxRad * dSin) + + dMLim = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; // a qui + } + else if ( dFVarCos >= dCos) { + + if ( dSqDF < dMinRad * dMinRad) + + dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + + else + + dMLim = dZTI + dDeltaZ + ( sqrt( dSqDF) - dMinRad) * ( dZI - dZTI) / dDeltaR ; + } + else + + dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; + } + + dMin = min( dPLim, dMLim) ; + dMax = max( dPLim, dMLim) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + return true ; +} + + + +// Asse di simmetria con orientazione generica: FORATURA + +//---------------------------------------------------------------------------- +bool +VolZmap::CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) +{ + double dMin, dMax; + unsigned int nStartI, nEndI, nStartJ, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( ! Control) + return true ; + + // Studio delle simmetrie + Vector3d vtMove = ptE - ptS ; + + Point3d ptI = ( vtMove * vtToolDir > 0 ? ptE : ptS) ; + Point3d ptF = ( vtMove * vtToolDir > 0 ? ptS - dHei * vtToolDir : ptE - dHei * vtToolDir) ; + + if ( ptI.z > ptF.z) { + + Point3d ptTemp = ptI ; + ptI = ptF ; + ptF = ptTemp ; + } + + double dDeltaZ = ptF.z - ptI.z ; + double dZI = ptI.z ; + + // Definizione + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtCyl = ptF - ptI ; double dLen = sqrt( vtCyl * vtCyl) ; + Vector3d vtCylVer( 0, 0, vtCyl.z) ; double dLVer = abs( vtCyl.z) ; + Vector3d vtCylOri( vtCyl.x, vtCyl.y, 0) ; double dLOri = vtCylOri.LenXY() ; + + double dCos = dLVer / dLen ; // Coseno dell'angolo formato da vtCyl con l'asse Z. + double dSin = dLOri / dLen ; // Seno dell'angolo formato da vtCyl con l'asse Z. + + double dSemiMin = dRad * dCos ; + double dSqRad = dRad * dRad ; + + // Definizione del sistema di riferimento nel piano + Vector3d vtU1 = vtCylOri ; + + if ( vtU1.LenXY() < EPS_SMALL) { + + double dLenVector = sqrt(vtCyl.x * vtCyl.x + vtCyl.y * vtCyl.y) ; + + vtU1 = ( 1 + dLenVector) / dLenVector * vtU1 ; + } + + vtU1.Normalize() ; + + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + // Definizione piani + Vector3d vtV = vtMove ; vtV.Normalize() ; + Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV ; + Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; + + double dProjI1 = vtCI * vtU1 ; double dProjI2 = vtCI * vtU2 ; + double dProjF1 = vtCF * vtU1 ; double dProjF2 = vtCF * vtU2 ; + + if ( dProjI1 > - dCos * sqrt( dSqRad - dProjI2 * dProjI2) && + dProjI1 < dLOri + dCos * sqrt( dSqRad - dProjI2 * dProjI2) && + dProjI2 * dProjI2 < dSqRad) { + + // Massimi + if ( dProjI1 < dLOri - dCos * sqrt( dSqRad - dProjI2 * dProjI2)) { + + double dZ0 = dSin * sqrt( dSqRad - dProjI2 * dProjI2) ; + double dI10 = - dCos * sqrt( dSqRad - dProjI2 * dProjI2) ; + + dMax = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; + } + else + + dMax = ( dDotF - vtV.x * dX - vtV.y *dY) / vtV.z ; + + // Minimi + if ( dProjI1 < dCos * sqrt( dSqRad - dProjI2 * dProjI2)) + + dMin = ( dDotI - vtV.x * dX - vtV.y *dY) / vtV.z ; + + else { + + double dZ0 = - dSin * sqrt( dSqRad - dProjI2 * dProjI2) ; + double dI10 = dCos * sqrt( dSqRad - dProjI2 * dProjI2) ; + + dMin = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, + const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) +{ + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( ! Control) + return true ; + + Vector3d vtMove = ptE - ptS ; double dLen = vtMove.Len() ; + Vector3d vtMZ( 0, 0, vtMove.z) ; double dLVer = abs( vtMove.z) ; + Vector3d vtMXY( vtMove.x, vtMove.y, 0) ; double dLOri = vtMXY.LenXY() ; + + double dSin = dLOri / dLen ; + double dCos = dLVer / dLen ; + + double dSemiMinR = dMaxRad * dCos ; + double dSemiMinr = dMinRad * dCos ; + + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Sistema di riferimento sul cono + Vector3d vtV1 = vtToolDir ; // controllare qui e negli altri coni che le proiezioni non siano troppo piccole FORSE CONVIENE FARE I CONTI CON VTMOVE NORMALIZZATO (QUESTO IN TUTTI I MOVIMENTI) + + double dCoef23 = ( vtV1.z > 0 ? 1 : - 1) ; + double dCoef21 = - dCoef23 * vtV1.z ; // vtV1.z := vtV1 * Z_AX + + Vector3d vtV2 = dCoef21 * vtV1 + dCoef23 * Z_AX ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Simmetrie del problema riguardanti il cono + Point3d ptCBot = ( vtV1 * vtMove > 0 ? ptS : ptE) ; + Point3d ptCTip = ptCBot - dHei * vtV1 ; + + double dDeltaR = dMaxRad - dMinRad ; + double dTan = dDeltaR / dHei ; + double dL = ( ( dMaxRad * dHei) / dDeltaR) ; + double dl = dL - dHei ; + + Point3d ptV = ptCBot - vtV1 * dL ; + + // Simmetrie del problema riguardanti il cilinidro + Point3d ptCylI = ( ptS.z < ptE.z ? ptS : ptE) ; + Point3d ptCylF = ( ptS.z < ptE.z ? ptE : ptS) ; + + double dDeltaZ = ptCylF.z - ptCylI.z ; + double dZCylI = ptCylI.z ; + + // Piani cono + Vector3d vtR0B = ptCBot - ORIG ; double dDotB = vtR0B * vtV1 ; + Vector3d vtR0T = ptCTip - ORIG ; double dDotT = vtR0T * vtV1 ; + + + // Piani cilindro + Vector3d vtR0I = ptCylI - ORIG ; double dDotI = vtR0I * vtV1 ; + Vector3d vtR0F = ptCylF - ORIG ; double dDotF = vtR0F * vtV1 ; + + + // Punti sul piano + Point3d ptCylIxy( ptCylI.x, ptCylI.y, 0) ; + Point3d ptCBotxy( ptCBot.x, ptCBot.y, 0) ; + + + // Riferimenti sul piano + Vector3d vtU1( ptCylF.x - ptCylI.x, ptCylF.y - ptCylI.y, 0) ; vtU1.Normalize() ; + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + Vector3d vtW1( vtV1.x, vtV1.y, 0) ; vtW1.Normalize() ; + Vector3d vtW2 = vtW1 ; vtW2.Rotate( Z_AX, 90) ; + + // Sistema di riferimento del cono + Frame3d ConusFrame ; ConusFrame.Set( ptV, vtV1, vtV2, vtV3) ; + Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; + + + // Ciclo + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptCylIxy ; + + double dPCyl1 = vtC * vtU1 ; double dPCyl2 = vtC * vtU2 ; + + // Parte cilindrica + if ( dPCyl2 * dPCyl2 < dSqMaxRad && + dPCyl1 > - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) && + dPCyl1 < dLOri + dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) { + + // Massimi + if ( dPCyl1 < dLOri - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) { + + double dZ0 = dSin * sqrt( dSqMaxRad - dPCyl2 * dPCyl2) ; + double dP0 = - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) ; + + dMax = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; + } + else + + dMax = ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; + + // Minimi + if ( dPCyl1 < dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad)) + + dMin = ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; + + else { + + double dZ0 = - dSin * sqrt( dSqMaxRad - dPCyl2 * dPCyl2) ; + double dP0 = dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / dSqMaxRad) ; + + dMin = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Parte conica + Vector3d vtD = Z_AX ; + + ptC.LocToLoc( GridFrame, ConusFrame) ; + + vtD.LocToLoc( GridFrame, ConusFrame) ; + + std::vector vdCoef(3); + std::vector vdRoots; + + vdCoef[0] = ( dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z) ; + vdCoef[1] = 2 * ( dTan * dTan * ptC.x * vtD.x - ptC.y * vtD.y - ptC.z * vtD.z) ; + vdCoef[2] = dTan * dTan * vtD.x * vtD.x - vtD.y * vtD.y - vtD.z * vtD.z ; + + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + if ( nRoot == 1) { + + Point3d ptR1 = ptC + vdRoots[0] * vtD ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( ConusFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nRoot == 2) { + + Point3d ptR1 = ptC + vdRoots[0] * vtD ; + Point3d ptR2 = ptC + vdRoots[1] * vtD ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConusFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConusFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( ConusFrame, GridFrame) ; + ptR2.LocToLoc( ConusFrame, GridFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( ConusFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + return true ; +} + +// Asse di simmetria con orientazione generica: FRESATURA + +//---------------------------------------------------------------------------- +bool +VolZmap::CompCyl_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) +{ + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, + nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( ! Control) + return true ; + + Point3d ptI ; + Point3d ptF ; + Vector3d vtV1 ; + + // Studio delle simmetrie + if ( vtToolDir.z < 0) { + + vtV1 = - vtToolDir ; + ptI = ( vtV1 * ( ptE - ptS) > 0 ? ptS + dHei * vtV1 : ptE + dHei * vtV1) ; + ptF = ( vtV1 * ( ptE - ptS) > 0 ? ptE + dHei * vtV1 : ptS + dHei * vtV1) ; + } + else { + + vtV1 = vtToolDir ; + ptI = ( vtV1 * ( ptE - ptS) > 0 ? ptS : ptE) ; + ptF = ( vtV1 * ( ptE - ptS) > 0 ? ptE : ptS) ; + } + + Point3d ptIT = ptI - vtV1 * dHei ; + Point3d ptFT = ptF - vtV1 * dHei ; + + // Definizione di un sintema di riferimento nel piano + // Ocio che |V1| sia maggiore di EPS_SMALL + Vector3d vtU1( - vtV1.x, - vtV1.y, 0) ; + vtU1.Normalize() ; + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtMLong = ( vtMove * vtV1) * vtV1 ; + Vector3d vtMOrt = vtMove - vtMLong ; + + // Parametri geometrici dell'utensile + // e della traiettoria + double dCos = vtV1.z ; + double dSin = vtV1.LenXY() ; + + double dZI = ptI.z ; + double dZF = ptF.z ; + double dDeltaZ = ptIT.z - ptI.z ; + double dL = dSin * dHei ; + + double dLen = vtMove.Len() ; + double dLLong = vtMLong.Len() ; + double dLOrt = vtMOrt.Len() ; + + double dCoef = dLOrt / dLLong ; + double dAng = atan( 1 / dCoef) ; + + double dSqRad = dRad * dRad ; + double dSemiAxMin = dCos * dRad ; + + // vtV1, vtV2 e vtV3 definiscono gli assi dei sistemi di riferimento intrinseci + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; + Frame3d CylFrame ; CylFrame.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; + Frame3d TCylFrame ; TCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; + Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; + + // Altri punti notevoli + Point3d ptIPlus = ptI + dRad * vtV3 ; + Point3d ptIMinus = ptI - dRad * vtV3 ; + Point3d ptFPlus = ptIPlus + vtMove ; + Point3d ptFMinus = ptIMinus + vtMove ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + // Grandezze per la definizione dei piani + Vector3d vtRI = ptI - ORIG ; double dDotI = vtV1 * vtRI ; + Vector3d vtRF = ptF - ORIG ; double dDotF = vtV1 * vtRF ; + + Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtV1 * vtRIT ; + Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtV1 * vtRFT ; + + Vector3d vtRIPlus = ptIPlus - ORIG ; + Vector3d vtRIMinus = ptIMinus - ORIG ; + Vector3d vtRFPlus = ptFPlus - ORIG ; + + Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + + Vector3d vtRITPlus = ptIPlus - ORIG - vtV1 * dHei ; + + Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtV3) ; + Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtV3) ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + + Vector3d vtCI = ptC - ptIxy ; + Vector3d vtCF = ptC - ptFxy ; + Vector3d vtC = ptC - ORIG ; + /* + double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; + double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; + + // Forse queste parti cilindriche andrebbero fatte per + // intersezione se il versoreutensile è molto verticale + // Parte cilindrica I + double dSqRootI = sqrt( dSqRad - dPI2 * dPI2) ; + double dPI1_0 = dCos * dSqRootI ; + + + if ( dPI1 >= - dPI1_0 && dPI1 <= dL + dPI1_0 && + dPI2 * dPI2 < dSqRad) { + + // Minimi + if ( dPI1 <= dL - dPI1_0) { + + double dZ0 = - dSin * dSqRootI ; + // da ( dPI1 - dPI1_0) è stato cambiato in ( dPI1 + dPI1_0) + dMin = dZI + dZ0 + ( dPI1 + dPI1_0) * dDeltaZ / dL ; + } + else + + dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + // Massimi + if ( dPI1 < dPI1_0) + + dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + else { + + double dZ0 = dSin * dSqRootI ; + + dMax = dZI + dZ0 + ( dPI1 - dPI1_0) * dDeltaZ / dL ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Parte cilindrica F + double dSqRootF = sqrt( dSqRad - dPF2 * dPF2) ; + double dPF1_0 = dCos * dSqRootF ; + + if ( dPF1 >= - dPF1_0 && dPF1 <= dL + dPF1_0 && dPF2 * dPF2 < dSqRad) { // Baubaubau + + // Minimi + if ( dPF1 <= dL - dPF1_0) { + + double dZ0 = - dSin * dSqRootF ; + // da ( dPI1 - dPI1_0) è stato cambiato in ( dPI1 + dPI1_0) + dMin = dZF + dZ0 + ( dPF1 + dPF1_0) * dDeltaZ / dL ; + } + else + + dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + // Massimi + if ( dPF1 < dPF1_0) + + dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + else { + + double dZ0 = dSin * dSqRootF ; + + dMax = dZF + dZ0 + ( dPF1 - dPF1_0) * dDeltaZ / dL ; + } + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } */ + + if ( IntersZLineCylinder( ptC, ptI, ptIT, vtToolDir, dRad, dMin, dMax)) { + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + if ( IntersZLineCylinder( ptC, ptF, ptFT, vtToolDir, dRad, dMin, dMax)) { + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + + // Parallelepipedo + Point3d ptInt1 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + Point3d ptInt2 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + Point3d ptInt3 = ptC + ( ( ( vtRIPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt4 = ptC + ( ( ( vtRIPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + Point3d ptInt5 = ptC + ( ( ( vtRFPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt6 = ptC + ( ( ( vtRITPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + + + ptInt1.LocToLoc( GridFrame, CylFrame) ; + ptInt2.LocToLoc( GridFrame, CylFrame) ; + ptInt3.LocToLoc( GridFrame, CylFrame) ; + ptInt4.LocToLoc( GridFrame, RotFrame) ; + ptInt5.LocToLoc( GridFrame, CylFrame) ; + ptInt6.LocToLoc( GridFrame, TRotFrame) ; + + bool bFlag = false ; + double dLim1, dLim2 ; + + if ( ptInt1.y >= 0 && ptInt1.y <= dLOrt && + ptInt1.x >= - dHei + ptInt1.y * ( dLLong / dLOrt) && + ptInt1.x <= ptInt1.y * ( dLLong / dLOrt)) { + + ptInt1.LocToLoc( CylFrame, GridFrame) ; + + + dLim1 = ptInt1.z ; + bFlag = true ; + } + + if ( ptInt2.y >= 0 && ptInt2.y <= dLOrt && + ptInt2.x >= - dHei + ptInt2.y * ( dLLong / dLOrt) && + ptInt2.x <= ptInt2.y * ( dLLong / dLOrt)) { + + ptInt2.LocToLoc( CylFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt2.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt2.z ; + } + + if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && + ptInt3.x >= - dHei && ptInt3.x <= 0) { + + ptInt3.LocToLoc( CylFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt3.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt3.z ; + } + + if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && + ptInt4.y >= 0 && ptInt4.y <= dLen) { + + ptInt4.LocToLoc( RotFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt4.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt4.z ; + } + + if ( ptInt5.z >= - dRad && ptInt5.z <= dRad && + ptInt5.x >= dLLong- dHei && ptInt5.x <= dLLong) { + + ptInt5.LocToLoc( CylFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt5.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt5.z ; + } + + if ( ptInt6.z >= - dRad && ptInt6.z <= dRad && + ptInt6.y >= 0 && ptInt6.y <= dLen) { + + ptInt6.LocToLoc( TRotFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt6.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt6.z ; + } + + + if ( bFlag) { // Una linea non confinata se entra in un volume chiuso ci deve uscire + + dMin = min( dLim1, dLim2) ; + dMax = max( dLim1, dLim2) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Traslazione dell'ellisse + + Vector3d vtK = Z_AX ; + + vtK.LocToLoc( GridFrame, CylFrame) ; + ptC.LocToLoc( GridFrame, CylFrame) ; + + std::vector vdCoef(3); + std::vector vdRoots; + + vdCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqRad ; + vdCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + if ( nRoot == 0 || nRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( GridFrame, CylFrame) ; + ptPf.LocToLoc( GridFrame, FCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqRad) { + + ptPi.LocToLoc( CylFrame, GridFrame) ; + ptPf.LocToLoc( FCylFrame, GridFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nRoot == 2) { + + Point3d ptInter1 = ptC + vdRoots[0] * vtK ; + Point3d ptInter2 = ptC + vdRoots[1] * vtK ; + + + if ( ptInter1.x > ptInter2.x) { + + Point3d ptTemp = ptInter1 ; + ptInter1 = ptInter2 ; + ptInter2 = ptTemp ; + } + + if ( ptInter1.x > 0 && ptInter1.x < dLLong && + ptInter2.x > dLLong) { + + ptInter1.LocToLoc( CylFrame, GridFrame) ; + + dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { + + ptInter1.LocToLoc( CylFrame, GridFrame) ; + ptInter2.LocToLoc( CylFrame, GridFrame) ; + + dMin = min( ptInter1.z, ptInter2.z) ; + dMax = max( ptInter1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { + + ptInter2.LocToLoc( CylFrame, GridFrame) ; + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + + ptC.LocToLoc( CylFrame, TCylFrame) ; + vtK.LocToLoc( CylFrame, TCylFrame) ; + + std::vector vdTCoef(3); + std::vector vdTRoots; + + vdTCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqRad ; + vdTCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdTCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + int nTRoot = PolynomialRoots( 2, vdTCoef, vdTRoots) ; + + if ( nTRoot == 0 || nTRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( GridFrame, TCylFrame) ; + ptPf.LocToLoc( GridFrame, FTCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqRad) { + + ptPi.LocToLoc( TCylFrame, GridFrame) ; + ptPf.LocToLoc( FTCylFrame, GridFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + } + else if ( nTRoot == 2) { + + Point3d ptTInter1 = ptC + vdTRoots[0] * vtK ; + Point3d ptTInter2 = ptC + vdTRoots[1] * vtK ; + + if ( ptTInter1.x > ptTInter2.x) { + + Point3d ptTemp = ptTInter1 ; + ptTInter1 = ptTInter2 ; + ptTInter2 = ptTemp ; + } + + if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && + ptTInter2.x > dLLong) { + + ptTInter1.LocToLoc( TCylFrame, GridFrame) ; + + dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { + + ptTInter1.LocToLoc( TCylFrame, GridFrame) ; + ptTInter2.LocToLoc( TCylFrame, GridFrame) ; + + dMin = min( ptTInter1.z, ptTInter2.z) ; + dMax = max( ptTInter1.z, ptTInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { + + dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { + + ptTInter2.LocToLoc( TCylFrame, GridFrame) ; + + dMin = min( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + dMax = max( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) +{ + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; + + if ( ! Control) + return true ; + + double dDeltaR = dMaxRad - dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + double dSqMinRad = dMinRad * dMinRad ; + + Point3d ptI = ( vtToolDir * ( ptE - ptS) > 0 ? ptS : ptE) ; + Point3d ptF = ( vtToolDir * ( ptE - ptS) > 0 ? ptE : ptS) ; + + Point3d ptIT = ptI - vtToolDir * dHei ; + Point3d ptFT = ptF - vtToolDir * dHei ; + + double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; + double dl = dL - dHei ; + + Point3d ptIV = ptI - vtToolDir * dL ; + Point3d ptFV = ptF - vtToolDir * dL ; + + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + + Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Apertura del cono e parametri per determinare i piani + double dTan = dDeltaR / dHei ; + double dRatio = dLLong / dLOrt ; + + double dCos = dTan * dRatio ; + double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dDen = sqrt( 1 + dTan * dTan) ; + double dCoef = dLOrt / dLLong ; // Per traslazione ellissi + + if ( dRatio > 1 / dTan) + + return CompConusAux_Milling( nGrid, ptI, ptF, vtV1, vtV2, vtV3, nStartI, nStartJ, nEndI, nEndJ, dHei, dMaxRad, dMinRad, dCoef) ; + + + // Versori normali e prodotti scalari per per determinare i piani + // Piani laterali: + Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; + Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; + Vector3d vtRIV = ptIV - ORIG ; + // double dDots = vtRIV * vtNs ; // forse qui è meglio due punti ptIT + vtV3 * dMinRad e ptIT - vtV3 * dMinRad + // double dDotd = vtRIV * vtNd ; + + Vector3d vtS1 = vtNs ; + Vector3d vtS2 = vtMove ; vtS2.Normalize() ; // double dDotTestqs = vtS1 * vtS2 ; + Vector3d vtS3 = vtS1 ^ vtS2 ; + + Vector3d vtD1 = vtNd ; + Vector3d vtD2 = vtS2 ; // double dDotTestD = vtD1 * vtD2 ; + Vector3d vtD3 = vtD1 ^ vtD2 ; + + Point3d ptSloc = ptI + vtV2 * ( dMaxRad * dCos) + vtV3 * ( dMaxRad * dSin) ; + Point3d ptD = ptI + vtV2 * ( dMaxRad * dCos) - vtV3 * ( dMaxRad * dSin) ; + Point3d ptST = ptIT + vtV2 * ( dMinRad * dCos) + vtV3 * ( dMinRad * dSin) ; + + Vector3d vtLen = ptST - ptSloc ; + + double dPLong = abs( vtLen * vtS3) ; + double dPOrt = abs( vtLen * vtS2) ; + // Vector3d vtLTr = vtLen - dPLong * vtS3 ; + + // double dPOrt = vtLTr.Len() ; + + // Piani di fondo e punta: + Vector3d vtU1 = - dLOrt * vtV1 + dLLong * vtV2 ; vtU1.Normalize() ; + Vector3d vtU2 = vtMove ; vtU2.Normalize() ; // double dDotTest = vtU1 * vtU2 ; + Vector3d vtU3 = vtU1 ^ vtU2 ; + + Point3d ptU = ptI + vtV2 * ( dMaxRad * dCos) ; + Point3d ptTU = ptIT + vtV2 * ( dMinRad * dCos) ; + + Vector3d vtRU = ptU - ORIG ; // double dDotB = vtRU * vtU1 ; + Vector3d vtRUT = ptTU - ORIG ; // double dDotT = vtRUT * vtU1 ; + + // Piani finale e iniziale: + Vector3d vtVAux = ptTU - ptU ; + + double dAuxOrt = vtVAux * vtV2 ; + double dAuxLong = vtVAux * vtV1 ; // Tenere in considerazione per tronchi con dimensioni tali da poter approssimare tori + + Vector3d vtW1 = - dAuxOrt * vtV1 + dAuxLong * vtV2 ; double dLAux1 = vtW1.Len() ; vtW1.Normalize() ; + Vector3d vtW2 = vtVAux ; double dLAux2 = vtW2.Len() ; vtW2.Normalize() ; // double dDottest = vtW1 * vtW2 ; + Vector3d vtW3 = vtW1 ^ vtW2 ; + + double dPr2 = vtLen * vtW2 ; double prova1 = vtLen * vtW3 ; double prova2 = dSin * dDeltaR ; + + Point3d ptFU = ptU + vtMove ; + + Vector3d vtRFU = ptFU - ORIG ; // double dDotPF = vtRFU * vtW1 ; + + // Piani cono: + Vector3d vtRCI = ptI - ORIG ; double dDotCI = vtRCI * vtV1 ; + Vector3d vtRCIT = ptIT - ORIG ; double dDotCIT = vtRCIT * vtV1 ; + + Vector3d vtRCF = ptF - ORIG ; double dDotCF = vtRCF * vtV1 ; + Vector3d vtRCFT = ptFT - ORIG ; double dDotCFT = vtRCFT * vtV1 ; + + + // Sistemi di riferimento + Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; + Frame3d IConeFrame ; IConeFrame.Set( ptIV, vtV1, vtV2, vtV3) ; + Frame3d FConeFrame ; FConeFrame.Set( ptFV, vtV1, vtV2, vtV3) ; + Frame3d PlSFrame ; PlSFrame.Set( ptSloc, vtS1, vtS2, vtS3) ; + Frame3d PlDFrame ; PlDFrame.Set( ptD, vtD1, vtD2, vtD3) ; + Frame3d PlBFrame ; PlBFrame.Set( ptU, vtU1, vtU2, vtU3) ; + Frame3d PlTFrame ; PlTFrame.Set( ptTU, vtU1, vtU2, vtU3) ; + Frame3d PlIFrame ; PlIFrame.Set( ptU, vtW1, vtW2, vtW3) ; + Frame3d PlFFrame ; PlFFrame.Set( ptFU, vtW1, vtW2, vtW3) ; + Frame3d LargeEllipse ; LargeEllipse.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FLargeEllipse ; FLargeEllipse.Set( ptF, vtV1, vtV2, vtV3) ; + Frame3d SmallEllipse ; SmallEllipse.Set( ptIT, vtV1, vtV2, vtV3) ; + Frame3d FSmallEllipse ; FSmallEllipse.Set( ptFT, vtV1, vtV2, vtV3) ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ORIG ; + Vector3d vtK = Z_AX ; + + Point3d ptIntLC1, ptIntLC2 ; + double dPMax, dPMin ; + + // Cono iniziale + if ( IntersLineConus( ptC, vtK, IConeFrame, dTan, dl, dL, ptIntLC1, ptIntLC2)) { + + dPMin = min( ptIntLC1.z, ptIntLC2.z) ; + dPMax = max( ptIntLC1.z, ptIntLC2.z) ; + + SubtractIntervals( nGrid, i, j, dPMin, dPMax) ; + } + + // Cono finale + if ( IntersLineConus( ptC, vtK, FConeFrame, dTan, dl, dL, ptIntLC1, ptIntLC2)) { + + dPMin = min( ptIntLC1.z, ptIntLC2.z) ; + dPMax = max( ptIntLC1.z, ptIntLC2.z) ; + + SubtractIntervals( nGrid, i, j, dPMin, dPMax) ; + } + /* + // Cono I + ptC.LocToLoc( GridFrame, IConeFrame) ; + vtK.LocToLoc( GridFrame, IConeFrame) ; + + std::vector vdIConeCoef(3); + std::vector vdIConeRoots; + + vdIConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; + vdIConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; + vdIConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; + + int nIConeRoot = PolynomialRoots( 2, vdIConeCoef, vdIConeRoots) ; + + if ( nIConeRoot == 1) { + + Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( IConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nIConeRoot == 2) { + + Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; + Point3d ptR2 = ptC + vdIConeRoots[1] * vtK ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( IConeFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( IConeFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( IConeFrame, GridFrame) ; + ptR2.LocToLoc( IConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( IConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + + // Cono F + ptC.LocToLoc( IConeFrame, FConeFrame) ; + vtK.LocToLoc( IConeFrame, FConeFrame) ; + + std::vector vdFConeCoef(3); + std::vector vdFConeRoots; + + vdFConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; + vdFConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; + vdFConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; + + int nFConeRoot = PolynomialRoots( 2, vdFConeCoef, vdFConeRoots) ; + + if ( nFConeRoot == 1) { + + Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( FConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nFConeRoot == 2) { + + Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; + Point3d ptR2 = ptC + vdFConeRoots[1] * vtK ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( FConeFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( FConeFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( FConeFrame, GridFrame) ; + ptR2.LocToLoc( FConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( FConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } */ + + + + // Solido interno + + // ptC.LocToLoc( FConeFrame, GridFrame) ; + // vtK.LocToLoc( FConeFrame, GridFrame) ; + + Point3d ptInt1 = ptC + ( ( ( vtRIV - vtC) * vtS1) / ( vtK * vtS1)) * vtK ; + Point3d ptInt2 = ptC + ( ( ( vtRIV - vtC) * vtD1) / ( vtK * vtD1)) * vtK ; + Point3d ptInt3 = ptC + ( ( ( vtRU - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; + Point3d ptInt4 = ptC + ( ( ( vtRUT - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; + Point3d ptInt5 = ptC + ( ( ( vtRU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; + Point3d ptInt6 = ptC + ( ( ( vtRFU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; + + ptInt1.LocToLoc( GridFrame, PlSFrame) ; + ptInt2.LocToLoc( GridFrame, PlDFrame) ; + ptInt3.LocToLoc( GridFrame, PlBFrame) ; + ptInt4.LocToLoc( GridFrame, PlTFrame) ; + ptInt5.LocToLoc( GridFrame, PlIFrame) ; + ptInt6.LocToLoc( GridFrame, PlFFrame) ; + + double dLim1, dLim2 ; + bool bFlag = false ; + + if ( ptInt1.z >= 0 && ptInt1.z <= dPLong && + ptInt1.y >= - ptInt1.z * dPOrt / dPLong && + ptInt1.y <= dLen - ptInt1.z * dPOrt / dPLong ) { + + ptInt1.LocToLoc( PlSFrame, GridFrame) ; + + dLim1 = ptInt1.z ; + bFlag = true ; + } + + if ( ptInt2.z >= - dPLong && ptInt2.z <= 0 && + ptInt2.y >= ptInt2.z * dPOrt / dPLong && + ptInt2.y <= dLen + ptInt2.z * dPOrt / dPLong) { + + ptInt2.LocToLoc( PlDFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt2.z ; + bFlag = true ; + } + else + + dLim2 = ptInt2.z ; + } + + if ( ptInt3.y >= 0 && ptInt3.y <= dLen && + ptInt3.z > - dMaxRad * dSin && + ptInt3.z < dMaxRad * dSin) { + + ptInt3.LocToLoc( PlBFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt3.z ; + bFlag = true ; + } + else + + dLim2 = ptInt3.z ; + } + + if ( ptInt4.y >= 0 && ptInt4.y <= dLen && + ptInt4.z > - dMinRad * dSin && + ptInt4.z < dMinRad * dSin) { + + ptInt4.LocToLoc( PlTFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt4.z ; + bFlag = true ; + } + else + + dLim2 = ptInt4.z ; + } + + if ( ptInt5.y >= 0 && ptInt5.y <= dPr2 && + ptInt5.z > - dSin * dMaxRad + ptInt5.y * prova1 / dPr2 && + ptInt5.z < dSin * dMaxRad - ptInt5.y * prova1 / dPr2) { + + ptInt5.LocToLoc( PlIFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt5.z ; + bFlag = true ; + } + else + + dLim2 = ptInt5.z ; + } + + if ( ptInt6.y >= 0 && ptInt6.y <= dPr2 && + ptInt6.z > - dSin * dMaxRad + ptInt6.y * prova1 / dPr2 && + ptInt6.z < dSin * dMaxRad - ptInt6.y * prova1 / dPr2) { + + ptInt6.LocToLoc( PlFFrame, GridFrame) ; + + if ( ! bFlag) { + + dLim1 = ptInt6.z ; + bFlag = true ; + } + else + + dLim2 = ptInt6.z ; + } + + if( bFlag) { + + dMin = min( dLim1, dLim2) ; + dMax = max( dLim1, dLim2) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Traslazioni ellissi + + ptC.LocToLoc( GridFrame, LargeEllipse) ; + vtK.LocToLoc( GridFrame, LargeEllipse) ; + + std::vector vdLargeCoef(3); + std::vector vdLargeRoots; + + vdLargeCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqMaxRad ; + vdLargeCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdLargeCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + + int nLRoot = PolynomialRoots( 2, vdLargeCoef, vdLargeRoots) ; + + if ( nLRoot == 0) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( GridFrame, LargeEllipse) ; + ptPf.LocToLoc( GridFrame, FLargeEllipse) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMaxRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMaxRad) { + + ptPi.LocToLoc( LargeEllipse, GridFrame) ; + ptPf.LocToLoc( FLargeEllipse, GridFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nLRoot == 2) { + + Point3d ptInter1 = ptC + vdLargeRoots[0] * vtK ; + Point3d ptInter2 = ptC + vdLargeRoots[1] * vtK ; + + + if ( ptInter1.x > ptInter2.x) { + + Point3d ptTemp = ptInter1 ; + ptInter1 = ptInter2 ; + ptInter2 = ptTemp ; + } + + if ( ptInter1.x > 0 && ptInter1.x < dLLong && + ptInter2.x > dLLong) { + + ptInter1.LocToLoc( LargeEllipse, GridFrame) ; + + dMin = min( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + dMax = max( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { + + ptInter1.LocToLoc( LargeEllipse, GridFrame) ; + ptInter2.LocToLoc( LargeEllipse, GridFrame) ; + + dMin = min( ptInter1.z, ptInter2.z) ; + dMax = max( ptInter1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { + + dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { + + ptInter2.LocToLoc( LargeEllipse, GridFrame) ; + + dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + + ptC.LocToLoc( LargeEllipse, SmallEllipse) ; + vtK.LocToLoc( LargeEllipse, SmallEllipse) ; + + std::vector vdSmallCoef(3); + std::vector vdSmallRoots; + + vdSmallCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqMinRad ; + vdSmallCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; + vdSmallCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; + + int nSRoot = PolynomialRoots( 2, vdSmallCoef, vdSmallRoots) ; + + if ( nSRoot == 0) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( GridFrame, SmallEllipse) ; + ptPf.LocToLoc( GridFrame, FSmallEllipse) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMinRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMinRad) { + + ptPi.LocToLoc( SmallEllipse, GridFrame) ; + ptPf.LocToLoc( FSmallEllipse, GridFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nSRoot == 2) { + + Point3d ptTInter1 = ptC + vdSmallRoots[0] * vtK ; + Point3d ptTInter2 = ptC + vdSmallRoots[1] * vtK ; + + if ( ptTInter1.x > ptTInter2.x) { + + Point3d ptTemp = ptTInter1 ; + ptTInter1 = ptTInter2 ; + ptTInter2 = ptTemp ; + } + + if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && + ptTInter2.x > dLLong) { + + ptTInter1.LocToLoc( SmallEllipse, GridFrame) ; + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { + + ptTInter1.LocToLoc( SmallEllipse, GridFrame) ; + ptTInter2.LocToLoc( SmallEllipse, GridFrame) ; + + dMin = min( ptTInter1.z, ptTInter2.z) ; + dMax = max( ptTInter1.z, ptTInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { + + dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { + + ptTInter2.LocToLoc( SmallEllipse, GridFrame) ; + + dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CompConusAux_Milling( unsigned int nGrid, const Point3d & ptI, const Point3d & ptF, const Vector3d & vtV1, const Vector3d & vtV2, const Vector3d & vtV3, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dHei, double dMaxRad, double dMinRad, double dCoef) +{ + + double dDeltaR = dMaxRad - dMinRad ; + double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; + double dTan = dDeltaR / dHei ; + double dl = dL - dHei ; + + double dLLong = abs( ( ptF - ptI) * vtV1) ; + double dLOrt = abs( ( ptF - ptI) * vtV2) ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + + Point3d ptV = ptI - vtV1 * dL ; + Point3d ptT = ptI - vtV1 * dHei ; + + Frame3d GridFrame ; GridFrame.Set( ORIG, X_AX, Y_AX, Z_AX) ; + Frame3d ConeFrame ; ConeFrame.Set( ptV, vtV1, vtV2, vtV3) ; + Frame3d IEllipseFrame ; IEllipseFrame.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FEllipseFrame ; FEllipseFrame.Set( ptF, vtV1, vtV2, vtV3) ; + + Vector3d vtI = ptI - ORIG ; double dDotI = vtI * vtV1 ; + Vector3d vtT = ptT - ORIG ; double dDotT = vtT * vtV1 ; + Vector3d vtF = ptF - ORIG ; double dDotF = vtF * vtV1 ; + + Vector3d vtK = Z_AX ; + Vector3d vtKC = vtK ; vtKC.LocToLoc( GridFrame, ConeFrame) ; + Vector3d vtKE = vtK ; vtKE.LocToLoc( GridFrame, IEllipseFrame) ; + + double dMin, dMax ; + + for ( unsigned int i = nStI ; i <= nEnI ; ++ i) { + + for ( unsigned int j = nStJ ; j <= nEnJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; + + // Cono + ptC.LocToLoc( GridFrame, ConeFrame) ; + + std::vector vdConeCoef(3); + std::vector vdConeRoots; + + vdConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; + vdConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtKC.x - ptC.y * vtKC.y - ptC.z * vtKC.z) ; + vdConeCoef[2] = dTan * dTan * vtKC.x * vtKC.x - vtKC.y * vtKC.y - vtKC.z * vtKC.z ; + + int nConeRoot = PolynomialRoots( 2, vdConeCoef, vdConeRoots) ; + + + if ( nConeRoot == 1) { + + Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; + + if ( ptR1.x >= dl && ptR1.x < dL) { + + ptR1.LocToLoc( ConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dl) { + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nConeRoot == 2) { + + Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdConeRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConeFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { + + ptR2.LocToLoc( ConeFrame, GridFrame) ; + + dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { + + dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { + + ptR1.LocToLoc( ConeFrame, GridFrame) ; + ptR2.LocToLoc( ConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { + + ptR1.LocToLoc( ConeFrame, GridFrame) ; + + dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + + // Tralsazione dell'ellisse + + ptC.LocToLoc( ConeFrame, IEllipseFrame) ; + + std::vector vdEllipseCoef(3); + std::vector vdEllipseRoots; + + vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dSqMaxRad ; + vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKE.x * ptC.x + vtKE.y * ptC.y + vtKE.z * ptC.z - dCoef * ( vtKE.x * ptC.y + vtKE.y * ptC.x)) ; + vdEllipseCoef[2] = dCoef * dCoef * vtKE.x * vtKE.x + vtKE.y * vtKE.y + vtKE.z * vtKE.z - 2 * dCoef * vtKE.x * vtKE.y ; + + + int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; + + + if ( nEllipseRoot == 0 || nEllipseRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( GridFrame, IEllipseFrame) ; + ptPf.LocToLoc( GridFrame, FEllipseFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dSqMaxRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dSqMaxRad) { + + ptPi.LocToLoc( IEllipseFrame, GridFrame) ; + ptPf.LocToLoc( FEllipseFrame, GridFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + if ( nEllipseRoot == 2) { + + Point3d ptInter1 = ptC + vdEllipseRoots[0] * vtKE ; + Point3d ptInter2 = ptC + vdEllipseRoots[1] * vtKE ; + + + if ( ptInter1.x > ptInter2.x) { + + Point3d ptTemp = ptInter1 ; + ptInter1 = ptInter2 ; + ptInter2 = ptTemp ; + } + + if ( ptInter1.x > 0 && ptInter1.x < dLLong && + ptInter2.x > dLLong) { + + ptInter1.LocToLoc( IEllipseFrame, GridFrame) ; + + dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { + + ptInter1.LocToLoc( IEllipseFrame, GridFrame) ; + ptInter2.LocToLoc( IEllipseFrame, GridFrame) ; + + dMin = min( ptInter1.z, ptInter2.z) ; + dMax = max( ptInter1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { + + ptInter2.LocToLoc( IEllipseFrame, GridFrame) ; + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + return true ; +} + +// ---------- SFERA ---------------------------------------------------------- +//---------------------------------------------------------------------------- +bool +VolZmap::CompBall_Milling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, double dRad) +{ + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptLs, ptLe, V_NULL, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; + + if ( ! Control) + return true ; + + Point3d ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; + Point3d ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + + double dVLen = abs( vtMove.z) ; // Verticale e planare rispetto ai dexel + double dPLen = vtMoveXY.LenXY() ; + double dLen = vtMove.Len() ; + + double dR1 = dVLen / dLen ; + double dR2 = dPLen / dLen ; + + double dZI = ptI.z ; + double dDeltaZ = ptF.z - ptI.z ; + double dSqRad = dRad * dRad ; + + + if ( dPLen < EPS_SMALL) { + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; + + double dSqLen = vtC.SqLen() ; + + if ( dSqLen < dSqRad) { + + double dH = sqrt( dSqRad - dSqLen) ; + + dMin = dZI - dH ; + dMax = dZI + dDeltaZ + dH ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + else { + + Vector3d vtV1 = vtMoveXY ; vtV1.Normalize() ; + Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; + + double dX1 = vtCI * vtV1 ; double dX2 = vtCI * vtV2 ; + + double dISqDist = vtCI * vtCI ; double dFSqDist = vtCF * vtCF ; + + if ( dISqDist < dSqRad || dFSqDist < dSqRad || + ( dX1 > 0 && dX1 < dPLen && dX2 * dX2 < dSqRad)) { + + // Massimi + if ( dX1 < - dR1 * sqrt( dSqRad - ( dX2 * dX2))) + + dMax = dZI + sqrt( dSqRad - dISqDist) ; + + else if ( dX1 < dPLen - dR1 * sqrt( dSqRad - ( dX2 * dX2))) + + dMax = dZI + dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 + dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ; + + else + + dMax = dZI + dDeltaZ + sqrt( dSqRad - dFSqDist) ; + + // Minimi + if ( dX1 < dR1 * sqrt( dSqRad - ( dX2 * dX2))) + + dMin = dZI - sqrt( dSqRad - dISqDist) ; + + else if ( dX1 < dPLen + dR1 * sqrt( dSqRad - ( dX2 * dX2))) + + dMin = dZI - dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 - dR1 * sqrt( dSqRad - ( dX2 * dX2))) * dVLen / dPLen ; + + else + + dMin = dZI + dDeltaZ - sqrt( dSqRad - dFSqDist) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + + return true ; +} + +// ------------------------- BOUNDING BOX -------------------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +inline bool +VolZmap::BoundingBox( unsigned int nGrid, const Point3d & ptP1, const Point3d & ptP2, const Vector3d & vtV1, const Vector3d & vtV2, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) +{ + // NB: E' vitale che vengano passati i punti e i vettori nel sistema di riferimento + // di riferimento opportuno. + + // Controllo sull'ammissibilità del numero di griglia + if ( nGrid < 0 || nGrid > 2) + return false ; + + unsigned int nMaxNx, nMaxNy ; + + double dMaxXValue, dMaxYValue ; + double dMinZValue, dMaxZValue ; + + nMaxNx = m_nVNx[nGrid] ; nMaxNy = m_nVNy[nGrid] ; + + dMaxXValue = nMaxNx * m_dStep ; dMaxYValue = nMaxNy * m_dStep ; + + dMinZValue = m_dVMinZ[nGrid] ; dMaxZValue = m_dVMaxZ[nGrid] ; + + + // Determinazione del raggio massimo dell'utensile + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + + // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale + Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; + Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; + + // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad ; + double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad ; + double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad ; + double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad ; + double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad ; + double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad ; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL) + return false ; + if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL) + return false ; + if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL) + return false ; + + // Limiti su indici + nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : static_cast ( dMaxX / m_dStep)) ; + nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + return true ; +} + +//---------------------------------------------------------------------------- +inline bool +VolZmap::BBoxComponent( unsigned int nGrid, const Point3d & ptP1, const Point3d & ptP2, const Vector3d & vtV1, const Vector3d & vtV2, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dRad, double dTipRad, double dHei) +{ + // NB: E' vitale che vengano passati i punti e i vettori nel sistema di riferimento + // di riferimento opportuno. + + // Controllo sull'ammissibilità del numero di griglia + if ( nGrid < 0 || nGrid > 2) + return false ; + + unsigned int nMaxNx, nMaxNy ; + + double dMaxXValue, dMaxYValue ; + double dMinZValue, dMaxZValue ; + + nMaxNx = m_nVNx[nGrid] ; nMaxNy = m_nVNy[nGrid] ; + + dMaxXValue = nMaxNx * m_dStep ; dMaxYValue = nMaxNy * m_dStep ; + + dMinZValue = m_dVMinZ[nGrid] ; dMaxZValue = m_dVMaxZ[nGrid] ; + + // Determinazione del raggio massimo del componente + double dMaxRad = max( dRad, dTipRad) ; + + // Determinazione delle posizioni della punta del componente nelle posizioni iniziale e finale + Point3d ptP1T = ptP1 - dHei * vtV1 ; + Point3d ptP2T = ptP2 - dHei * vtV2 ; + + // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento + double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad; + double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad; + double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad; + double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad; + double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad; + double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad; + + // Verifica dell'interferenza dell'utensile con lo Zmap + if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL) + return false ; + if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL) + return false ; + if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL) + return false ; + + // Limiti su indici + nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; + nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : static_cast ( dMaxX / m_dStep)) ; + nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; + nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : static_cast ( dMaxY / m_dStep)) ; + + return true ; +} + + + + + + + + + + + + + + + + + + + + + + +/* + /* + + // VERSIONE NUOVA DA TESTARE +bool +VolZmap::Cyl_Milling( unsigned int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) +{ + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( nGrid, ptLs, ptLe, vtToolDir, vtToolDir, + nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( ! Control) + return true ; + + + Point3d ptI, ptF ; + Vector3d vtV1, vtV2, vtV3 ; + // Studio delle simmetrie + //vtV1 = ( vtToolDir.z < 0 ? - vtToolDir : vtToolDir) ; + //Point3d ptI = ptLs + ( vtToolDir.z < 0 ? dHei * vtV1 : vtNUll) ; + //Point3d ptF + ( vtToolDir.z < 0 ? dHei * vtV1 : vtNUll) ; + if ( vtToolDir.z < 0) { + vtV1 = - vtToolDir ; + ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs + dHei * vtV1 : ptLe + dHei * vtV1) ; + ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe + dHei * vtV1 : ptLs + dHei * vtV1) ; + } + else { + vtV1 = vtToolDir ; + ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; + ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; + } + + Point3d ptIT = ptI - vtV1 * dHei ; + Point3d ptFT = ptF - vtV1 * dHei ; + + // Definizione di un sintema di riferimento nel piano + Vector3d vtU1( - vtV1.x, - vtV1.y, 0) ; + double dCos = vtV1.z ; + double dSin = vtU1.LenXY() ; + double dSemiAxMin = m_dRadius * dCos ; + double dSqRad = m_dRadius * m_dRadius ; + double dSqSemiAxMin = dSemiAxMin * dSemiAxMin ; + vtU1.Normalize() ; // Ocio che la sua lunghezza sia maggiore di EPS_SMALL + Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; + + double dZI = ptI.z ; + double dZF = ptF.z ; + double dDeltaZ = ptIT.z - ptI.z ; + + double dL = dSin * dHei ; + + Vector3d vtMove = ptF - ptI ; + double dLen = vtMove.Len() ; + Vector3d vtMLong = ( vtMove * vtV1) * vtV1 ; + double dLLong = vtMLong.Len() ; + Vector3d vtMOrt = vtMove - vtMLong ; + double dLOrt = vtMOrt.Len() ; + + double dCoef = dLOrt / dLLong ; + double dAng = atan( 1 / dCoef) ; + + // vtV1, vtV2 e vtV3 definiscono gli assi dei sistemi di riferimento intrinseci + vtV2 = vtMOrt ; vtV2.Normalize() ; + vtV3 = vtV1 ^ vtV2 ; + + Frame3d CylFrame ; CylFrame.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; + Frame3d TCylFrame ; TCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; + Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; + + // Altri punti notevoli + Point3d ptIPlus = ptI + dRad * vtV3 ; + Point3d ptIMinus = ptI - dRad * vtV3 ; + + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + + // Grandezze per la definizione dei piani + Vector3d vtRI = ptI - ORIG ; + double dDotI = vtV1 * vtRI ; + Vector3d vtRIT = ptIT - ORIG ; + double dDotIT = vtV1 * vtRIT ; + Vector3d vtRF = ptF - ORIG ; + double dDotF = vtV1 * vtRF ; + Vector3d vtRFT = ptFT - ORIG ; + double dDotFT = vtV1 * vtRFT ; + + Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + + double dFrCos = cos( dAng) ; + double dFrSin = sin( dAng) ; + + Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtV3) ; + Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtV3) ; + + // Versore Z nel sistema di riferimento CylFrame + Vector3d vtKCyl = Z_AX ; vtKCyl.LocToLoc( m_LocalFrame, CylFrame) ; + // Versore Z nel sistema di riferimento RotFrame + Vector3d vtKRot = Z_AX ; vtKRot.LocToLoc( m_LocalFrame, RotFrame) ; + + + // Ciclo sui dexel + for( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Point3d ptCCyl( dX, dY, 0) ; + Point3d ptCRot( dX, dY, 0) ; + Point3d ptCTCyl( dX, dY, 0) ; + ptCCyl.LocToLoc( m_LocalFrame, CylFrame) ; + ptCRot.LocToLoc( m_LocalFrame, RotFrame) ; + ptCTCyl.LocToLoc( m_LocalFrame, TCylFrame) ; + + + Vector3d vtCI = ptC - ptIxy ; + Vector3d vtCF = ptC - ptFxy ; + //Vector3d vtC = ptC - ORIG ; + + double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; + double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; + + // Cilindro iniziale + if ( dPI1 * dPI1 / dSqSemiAxMin + dPI2 * dPI2 / dSqRad < 1 || + ( dPI1 - dL) * ( dPI1 - dL) / dSqSemiAxMin + dPI2 * dPI2 / dSqRad < 1 || + ( dPI1 > 0 && dPI1 < dL && abs( dPI2) < m_dRadius)) { + + double dSqRoot = sqrt( dSqRad - dPI2 * dPI2) ; + double dPI1_0 = dCos * dSqRoot ; + double dH = dSin * dSqRoot ; + + // Massimo + if ( dPI1 < dPI1_0) + // Se vtV1.z -> 0 allora dCos -> 0 e con essi l'area ove vi + // è la proiezione su XY del piano, quindi la divisione non da + // problemi, data la dimensione del passo della griglia + dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + else + // Se vtV1.z -> 1 dCos -> 1 3 dSin -> 0 e con esso dL -> 0, + // ma anche l'area della regione interessata tende a zero, + // quindi la divisione non da problemi, data la dimensione del passo della griglia + dMax = dZI + dH + dDeltaZ * ( dPI1 - dPI1_0) / dL ; + + // Minimo + if ( dPI1 < - dPI1_0) + // Analoga osservazione + dMin = dZI - dH + dDeltaZ * ( dPI1 + dPI1_0) / dL ; + else + // Analoga osservazione + dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Cilindro finale + if ( dPF1 * dPF1 + dPF2 * dPF2 < 1 || + ( dPF1 - dL) * ( dPF1 - dL) + dPF2 * dPF2 < 1 || + ( dPF1 > 0 && dPF1 < dL && abs( dPF2) < EPS_SMALL)) { + + double dSqRoot = sqrt( dSqRad - ( dPF2 - dL) * ( dPF2 - dL)) ; + double dPF1_0 = dCos * dSqRoot ; + double dH = dSin * dSqRoot ; + + // Massimo + if ( dPF1 < dPF1_0) + // Se vtV1.z -> 0 allora dCos -> 0 e con essi l'area ove vi + // è la proiezione su XY del piano, quindi la divisione non da + // problemi, data la dimensione del passo della griglia + dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + else + // Se vtV1.z -> 1 dCos -> 1 3 dSin -> 0 e con esso dL -> 0, + // ma anche l'area della regione interessata tende a zero, + // quindi la divisione non da problemi, data la dimensione del passo della griglia + dMax = dZF + dH + dDeltaZ * ( dPF1 - dPF1_0) / dL ; + + // Minimo + if ( dPF1 < - dPF1_0) + // Analoga osservazione + dMin = dZF - dH + dDeltaZ * ( dPF1 + dPF1_0) / dL ; + else + // Analoga osservazione + dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Parallelepipedo + unsigned int nInt = 0 ; + double dt ; + + Point3d ptInt1, ptInt2 ; + // Piani paralleli a XY nel sistema CylFrame + if ( abs( vtKCyl.z) > EPS_ZERO || + abs( ptCCyl.z - m_dRadius) < EPS_SMALL || + abs( ptCCyl.z + m_dRadius) < EPS_SMALL) { + + dt = ( m_dRadius - ptCCyl.z) / vtKCyl.z ; + Point3d ptInt = ptCCyl + dt * vtKCyl ; + + if ( ptInt.y > 0 && ptInt.y < dLOrt && + dLOrt * ptCCyl.x - dLLong * ptCCyl.y < 0 && + dLOrt * ptCCyl.x + dLOrt * dHei - dLLong * ptCCyl.y > 0) { + + ptInt.LocToLoc( CylFrame, m_LocalFrame) ; + + ptInt1 = ptInt ; + nInt = 1 ; + } + + dt = ( - m_dRadius - ptCCyl.z) / vtKCyl.z ; + ptInt = ptCCyl + dt * vtKCyl ; + + if ( ptInt.y > 0 && ptInt.y < dLOrt && + dLOrt * ptCCyl.x - dLLong * ptCCyl.y < 0 && + dLOrt * ptCCyl.x + dLOrt * dHei - dLLong * ptCCyl.y > 0) { + + ptInt.LocToLoc( CylFrame, m_LocalFrame) ; + + if ( nInt == 0) { + ptInt1 = ptInt ; + nInt = 1 ; + } + else if ( nInt == 1) { + ptInt2 = ptInt ; + nInt = 2 ; + } + } + } + // Piani paralleli a XZ nel sistema CylFrame + if ( abs( vtKCyl.y) > EPS_ZERO || + abs( ptCCyl.y) < EPS_SMALL || + abs( ptCCyl.y - dLOrt) < EPS_SMALL) { + + dt = - ptCCyl.y / vtKCyl.y ; + Point3d ptInt = ptCCyl + dt * vtKCyl ; + + if ( ptInt.x > - dHei && ptInt.x < 0 && + ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { + + ptInt.LocToLoc( CylFrame, m_LocalFrame) ; + + if ( nInt == 0) { + ptInt1 = ptInt ; + nInt = 1 ; + } + else if ( nInt == 1) { + ptInt2 = ptInt ; + nInt = 2 ; + } + } + + dt = ( dLOrt - ptCCyl.y) / vtKCyl.y ; + ptInt = ptCCyl + dt * vtKCyl ; + + if ( ptInt.x > - dHei && ptInt.x < 0 && + ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { + + ptInt.LocToLoc( CylFrame, m_LocalFrame) ; + + if ( nInt == 0) { + ptInt1 = ptInt ; + nInt = 1 ; + } + else if ( nInt == 1) { + ptInt2 = ptInt ; + nInt = 2 ; + } + } + } + // Piani paralleli a YZ nel sistema RotFrame + if ( abs( vtKRot.x) > EPS_ZERO || + abs( ptCRot.x) < EPS_SMALL || + abs( ptCRot.x + dHei * dFrCos) < EPS_SMALL) { + + dt = - ptCRot.x / vtKRot.x ; + Point3d ptInt = ptCCyl + dt * vtKRot ; + + if ( ptInt.y > 0 && ptInt.y < dLen && + ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { + + ptInt.LocToLoc( RotFrame, m_LocalFrame) ; + + if ( nInt == 0) { + ptInt1 = ptInt ; + nInt = 1 ; + } + else if ( nInt == 1) { + ptInt2 = ptInt ; + nInt = 2 ; + } + } + + dt = ( - dHei * dFrSin - ptCRot.x) / vtKRot.x ; + ptInt = ptCCyl + dt * vtKRot ; + + if ( ptInt.y > - dHei * dFrSin && ptInt.y < dLen - dHei * dFrSin && + ptInt.z > - m_dRadius && ptInt.z < m_dRadius) { + + ptInt.LocToLoc( RotFrame, m_LocalFrame) ; + + if ( nInt == 0) { + ptInt1 = ptInt ; + nInt = 1 ; + } + else if ( nInt == 1) { + ptInt2 = ptInt ; + nInt = 2 ; + } + } + } + + if ( nInt == 2) { + + dMin = min( ptInt1.z, ptInt2.z) ; + dMax = max( ptInt1.z, ptInt2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + // Traslazione ellisse di fondo + std::vector vdCoef(3); + std::vector vdRoots; + + vdCoef[0] = dCoef * dCoef * ptCCyl.x * ptCCyl.x + ptCCyl.y * ptCCyl.y + ptCCyl.z * ptCCyl.z - 2 * dCoef * ptCCyl.x * ptCCyl.y - dRad * dRad ; + vdCoef[1] = 2 * ( dCoef * dCoef * vtKCyl.x * ptCCyl.x + vtKCyl.y * ptCCyl.y + vtKCyl.z * ptCCyl.z - dCoef * ( vtKCyl.x * ptCCyl.y + vtKCyl.y * ptCCyl.x)) ; + vdCoef[2] = dCoef * dCoef * vtKCyl.x * vtKCyl.x + vtKCyl.y * vtKCyl.y + vtKCyl.z * vtKCyl.z - 2 * dCoef * vtKCyl.x * vtKCyl.y ; + + + int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; + + if ( nRoot == 0 || nRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, CylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( CylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + else if ( nRoot == 2) { + + Point3d ptInter1 = ptCCyl + vdRoots[0] * vtKCyl ; + Point3d ptInter2 = ptCCyl + vdRoots[1] * vtKCyl ; + + + if ( ptInter1.x > ptInter2.x) { + + Point3d ptTemp = ptInter1 ; + ptInter1 = ptInter2 ; + ptInter2 = ptTemp ; + } + + if ( ptInter1.x > 0 && ptInter1.x < dLLong && + ptInter2.x > dLLong) { + + ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; + + dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { + + ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; + ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; + + dMin = min( ptInter1.z, ptInter2.z) ; + dMax = max( ptInter1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { + + ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; + + dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + + // Traslazione ellisse di punta + std::vector vdTCoef(3); + std::vector vdTRoots; + + vdTCoef[0] = dCoef * dCoef * ptCTCyl.x * ptCTCyl.x + ptCTCyl.y * ptCTCyl.y + ptCTCyl.z * ptCTCyl.z - 2 * dCoef * ptCTCyl.x * ptCTCyl.y - dRad * dRad ; + vdTCoef[1] = 2 * ( dCoef * dCoef * vtKCyl.x * ptCTCyl.x + vtKCyl.y * ptCTCyl.y + vtKCyl.z * ptCTCyl.z - dCoef * ( vtKCyl.x * ptCTCyl.y + vtKCyl.y * ptCTCyl.x)) ; + vdTCoef[2] = dCoef * dCoef * vtKCyl.x * vtKCyl.x + vtKCyl.y * vtKCyl.y + vtKCyl.z * vtKCyl.z - 2 * dCoef * vtKCyl.x * vtKCyl.y ; + + int nTRoot = PolynomialRoots( 2, vdTCoef, vdTRoots) ; + + if ( nTRoot == 0 || nTRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, TCylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( TCylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + + } + else if ( nTRoot == 2) { + + Point3d ptTInter1 = ptCTCyl + vdTRoots[0] * vtKCyl ; + Point3d ptTInter2 = ptCTCyl + vdTRoots[1] * vtKCyl ; + + if ( ptTInter1.x > ptTInter2.x) { + + Point3d ptTemp = ptTInter1 ; + ptTInter1 = ptTInter2 ; + ptTInter2 = ptTemp ; + } + + if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && + ptTInter2.x > dLLong) { + + ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { + + ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; + ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; + + dMin = min( ptTInter1.z, ptTInter2.z) ; + dMax = max( ptTInter1.z, ptTInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { + + dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { + + ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + dMax = max( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + return true ; +} */ + + +/* +//---------------------------------------------------------------------------- +bool +VolZmap::MillCyl2( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) +{ + double dMin, dMax ; + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; + + if ( ! Control) + return true ; + + // Punti notevoli + Point3d ptI = ptLs ; + Point3d ptF = ptLe ; + + Point3d ptIT = ptI - vtToolDir * dHei ; + Point3d ptFT = ptF - vtToolDir * dHei ; + + // Vettori notevoli + Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; + Vector3d vtLong = ( vtMove * vtToolDir) * vtToolDir ; double dLong = vtLong.Len() ; + Vector3d vtOrt = vtMove - vtLong ; double dOrt = vtOrt.Len() ; + + double dCoef = dOrt / dLong ; + double dAng = atan( 1 / dCoef) ; + + Vector3d vtV1 = vtToolDir ; + Vector3d vtV2 = vtOrt ; vtV2.Normalize() ; + Vector3d vtV3 = vtV1 ^ vtV2 ; + + // Definizione dei sistemi di riferimento + Frame3d ICylFrame ; ICylFrame.Set( ptI, vtV1, vtV2, vtV3) ; + Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; + Frame3d ITCylFrame ; ITCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; + Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; + + Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; + Vector3d vtW3 = vtV3 ; + + Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtW3) ; + Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtW3) ; + + // Altri vettori notevoi + Vector3d vtKC = Z_AX ; vtKC.LocToLoc( m_LocalFrame, ICylFrame) ; + + Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV1 ; + Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV1 ; + Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtRIT * vtV1 ; + Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtRFT * vtV1 ; + + Vector3d vtRIPlus = vtRI + dRad * vtW3 ; + Vector3d vtRIMinus = vtRI - dRad * vtW3 ; + + + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; + + // Cilindro iniziale + ptC.LocToLoc( m_LocalFrame, ICylFrame) ; + + std::vector vdICylCoef(3); + std::vector vdICylRoots; + + vdICylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; + vdICylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; + vdICylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; + + + int nICylRoot = PolynomialRoots( 2, vdICylCoef, vdICylRoots) ; + + if ( nICylRoot == 0 || nICylRoot == 1) { + + Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPb.LocToLoc( m_LocalFrame, ICylFrame) ; + ptPt.LocToLoc( m_LocalFrame, ITCylFrame) ; + + if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && + ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { + + ptPb.LocToLoc( ICylFrame, m_LocalFrame) ; + ptPt.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ptPb.z, ptPt.z) ; + dMax = max( ptPb.z, ptPt.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nICylRoot == 2) { + + Point3d ptR1 = ptC + vdICylRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdICylRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < - dHei && ptR2.x >= - dHei && + ptR2.x < 0) { + + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < - dHei && ptR2.x >= 0) { + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Cilindro finale + ptC.LocToLoc( ICylFrame, FCylFrame) ; + + std::vector vdFCylCoef(3); + std::vector vdFCylRoots; + + vdFCylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; + vdFCylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; + vdFCylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; + + + int nFCylRoot = PolynomialRoots( 2, vdFCylCoef, vdFCylRoots) ; + + if ( nFCylRoot == 0 || nFCylRoot == 1) { + + Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPb.LocToLoc( m_LocalFrame, FCylFrame) ; + ptPt.LocToLoc( m_LocalFrame, FTCylFrame) ; + + if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && + ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { + + ptPb.LocToLoc( FCylFrame, m_LocalFrame) ; + ptPt.LocToLoc( FTCylFrame, m_LocalFrame) ; + + dMin = min( ptPb.z, ptPt.z) ; + dMax = max( ptPb.z, ptPt.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nFCylRoot == 2) { + + Point3d ptR1 = ptC + vdFCylRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdFCylRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < - dHei && ptR2.x >= - dHei && + ptR2.x < 0) { + + ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < - dHei && ptR2.x >= 0) { + + dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { + + ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; + ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { + + ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Traslazione ellisse fondo + + ptC.LocToLoc( FCylFrame, ICylFrame) ; + + std::vector vdEllipseCoef(3); + std::vector vdEllipseRoots; + + vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; + vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; + vdEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; + + + int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; + + if ( nEllipseRoot == 0 || nEllipseRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, ICylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( ICylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nEllipseRoot == 2) { + + Point3d ptR1 = ptC + vdEllipseRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdEllipseRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x >= 0 && + ptR2.x < dLong) { + + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dLong) { + + dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { + + ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; + + dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + // Traslazione ellisse punta + + ptC.LocToLoc( ICylFrame, ITCylFrame) ; + + std::vector vdTEllipseCoef(3); + std::vector vdTEllipseRoots; + + vdTEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; + vdTEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; + vdTEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; + + + int nTEllipseRoot = PolynomialRoots( 2, vdTEllipseCoef, vdTEllipseRoots) ; + + if ( nTEllipseRoot == 0 || nTEllipseRoot == 1) { + + Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; + + ptPi.LocToLoc( m_LocalFrame, ITCylFrame) ; + ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; + + if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && + ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { + + ptPi.LocToLoc( ITCylFrame, m_LocalFrame) ; + ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; + + dMin = min( ptPi.z, ptPf.z) ; + dMax = max( ptPi.z, ptPf.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + else if ( nTEllipseRoot == 2) { + + Point3d ptR1 = ptC + vdTEllipseRoots[0] * vtKC ; + Point3d ptR2 = ptC + vdTEllipseRoots[1] * vtKC ; + + if ( ptR1.x > ptR2.x) { + + Point3d ptTemp = ptR1 ; + ptR1 = ptR2 ; + ptR2 = ptTemp ; + } + + if ( ptR1.x < 0 && ptR2.x >= 0 && + ptR2.x < dLong) { + + ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x < 0 && ptR2.x >= dLong) { + + dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { + + ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; + ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ptR1.z, ptR2.z) ; + dMax = max( ptR1.z, ptR2.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { + + ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; + + dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + + // Parallelepipedo + Point3d ptInt1 = ptC + ( ( ( vtRI - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt2 = ptC + ( ( ( vtRI - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + Point3d ptInt3 = ptC + ( ( ( vtRF - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; + Point3d ptInt4 = ptC + ( ( ( vtRIT - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; + Point3d ptInt5 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + Point3d ptInt6 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; + + + ptInt1.LocToLoc( m_LocalFrame, ICylFrame) ; + ptInt2.LocToLoc( m_LocalFrame, RotFrame) ; + ptInt3.LocToLoc( m_LocalFrame, FCylFrame) ; + ptInt4.LocToLoc( m_LocalFrame, TRotFrame) ; + ptInt5.LocToLoc( m_LocalFrame, ICylFrame) ; + ptInt6.LocToLoc( m_LocalFrame, ICylFrame) ; + + bool bFlag = false ; + double dLim1, dLim2 ; + + + if ( ptInt1.x >= - dHei && ptInt1.x <= 0 && + ptInt1.z >= - dRad && ptInt1.z <= dRad) { + + ptInt1.LocToLoc( ICylFrame, m_LocalFrame) ; + + dLim1 = ptInt1.z ; + bFlag = true ; + } + + if ( ptInt2.y >= 0 && ptInt2.y <= dLen && + ptInt2.z >= - dRad && ptInt2.z <= dRad) { + + ptInt2.LocToLoc( RotFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt2.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt2.z ; + } + + if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && + ptInt3.x >= - dHei && ptInt3.x <= 0) { + + ptInt3.LocToLoc( FCylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt3.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt3.z ; + } + + if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && + ptInt4.y >= 0 && ptInt4.y <= dLen) { + + ptInt4.LocToLoc( TRotFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt4.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt4.z ; + } + + if ( ptInt5.y >= 0 && ptInt5.y <= dOrt && + ptInt5.x >= - dHei + dCoef * ptInt5.y && + ptInt5.x <= dCoef * ptInt5.y) { + + ptInt5.LocToLoc( ICylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt5.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt5.z ; + } + + if ( ptInt6.y >= 0 && ptInt6.y <= dOrt && + ptInt6.x >= - dHei + dCoef * ptInt6.y && + ptInt6.x <= dCoef * ptInt6.y) { + + ptInt6.LocToLoc( ICylFrame, m_LocalFrame) ; + + if ( bFlag == false) { + + dLim1 = ptInt6.z ; + + bFlag = true ; + } + else + + dLim2 = ptInt6.z ; + } + + + if ( bFlag == true) { // Una linea non confinata se entra in un volume chiuso ci deve uscire + + dMin = min( dLim1, dLim2) ; + dMax = max( dLim1, dLim2) ; + + SubtractIntervals( i, j, dMin, dMax) ; + } + } + } + + return true ; +} +*/ + +/* +//---------------------------------------------------------------------------- +bool +VolZmap::Conus_XYPerp( unsigned int nGrid, const Point3d ptS, const Point3d ptE, const Vector3d vtToolDir) +{ + unsigned int nStartI, nStartJ, nEndI, nEndJ ; + + // Verifica sull'interferenza utensile Zmap + bool bTest = BoundingBox( nGrid, ptS, ptE, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; + + if ( ! bTest) + return true ; + + // Parametri geometrici dell'utensile + double dStemHeigth = m_dHeight - m_dTipHeight ; + double dMinRad = min( m_dRadius, m_dTipRadius) ; + double dMaxRad = max( m_dRadius, m_dTipRadius) ; + double dSqTipRad = m_dTipRadius * m_dTipRadius ; + double dSqRad = m_dRadius * m_dRadius ; + double dDeltaRad = dMaxRad - dMinRad ; + double dSqMinRad = dMinRad * dMinRad ; + double dSqMaxRad = dMaxRad * dMaxRad ; + + // Studio delle simmetrie + Point3d ptI = ( ptS.z < ptE.z ? ptS : ptE) ; + Point3d ptF = ( ptS.z < ptE.z ? ptE : ptS) ; + + // Vettori caratterizzanti il moto + Vector3d vtMove = ptF - ptI ; + Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; + double dLen = vtMove.Len() ; + double dLenXY = vtMoveXY.LenXY() ; + + // Quote iniziale e finale + double dZI = ptI.z ; + double dZF = ptF.z ; + + // Sistema di riferimento sul piano + Point3d ptIxy( ptI.x, ptI.y, 0) ; + Point3d ptFxy( ptF.x, ptF.y, 0) ; + // Primo vettore del riferimento + Vector3d vtV1( - vtToolDir.x, - vtToolDir.y, 0) ; + vtV1.Normalize() ; + Vector3d vtV2 ; + + // Movimento verticale + if ( dLenXY / dLen < EPS_SMALL) { + // Secondo vettore del riferimento + vtV2 = vtV1 ; + vtV2.Rotate( Z_AX, 90) ; + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; + // Parte cilindrica + if ( dX1 > 0 && dX1 < dStemHeigth && abs( dX2) < m_dRadius) { + + double dH = sqrt( dSqRad - dX2 * dX2) ; + SubtractIntervals( nGrid, i, j, dZI - dH, dZF + dH) ; + } + // Parte conica + else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && abs( dX2) < dr) { + + double dH = sqrt( dr * dr - dX2 * dX2) ; + SubtractIntervals ( nGrid, i, j, dZI - dH, dZF + dH) ; + } + } + } + } + else { + // Secondo vettore del riferimento + Vector3d vtV2 = vtMoveXY ; + vtV2.Normalize() ; + + // Sistema di riferimento per determinare i piani + Vector3d vtW1 = ( m_dHeight > m_dTipHeight ? vtV1 : - vtV1) ; + Vector3d vtW2 = vtMove ; + vtW2.Normalize() ;// Se vtMove non è suff ort a vtW1 vtMove = vtMoveOrt + vtMoveLong e via + Vector3d vtW3 = vtW1 ^ vtW2 ; + + // Altezza cono + double dL = dMaxRad * m_dTipHeight / dDeltaRad ; + + // Vertice del cono iniziale + Point3d ptV = ptI - ( m_dHeight > m_dTipHeight ? ( dStemHeigth + dL) * vtW1 : ( dL - m_dHeight) * vtW1) ; + + // + double dCos = vtW2.z ; + double dSin = ( dCos < 1 ? sqrt( 1 - dCos * dCos) : 0) ; + + double dLimXY = dCos * m_dRadius ; + double dLimH = dSin * m_dRadius ; + double dDeltaZ = ptF.z - ptI.z ; + + double dMin, dMax ; + + + // Ciclo sui punti + for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { + for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { + + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + + Point3d ptC( dX, dY, 0) ; + Vector3d vtC = ptC - ptIxy ; + + double dX1 = vtC * vtV1 ; + double dX2 = vtC * vtV2 ; + + double dr = m_dRadius + ( m_dTipRadius - m_dRadius) * ( dX1 - dStemHeigth) / m_dTipHeight ; + + // Parte cilindrica + if ( dX1 > 0 && dX1 < dStemHeigth && + dX2 > - m_dRadius && dX2 < dLenXY + m_dRadius) + { + // Massimi + if ( dX2 < - dLimXY) + dMax = dZI + sqrt( dSqRad - dX2 * dX2) ; + else if ( dX2 < dLenXY - dLimXY) + dMax = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ; + else + dMax = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + // Minimi + if ( dX2 < dLimXY) + dMin = dZI + sqrt( dSqRad - dX2 * dX2) ; + else if ( dX2 < dLenXY + dLimXY) + dMin = dZI + dLimH + dDeltaZ * ( dX2 + dLimXY) / dLenXY ; + else + dMin = dZF + sqrt( dSqRad - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + // Parte conica + else if ( dX1 >= dStemHeigth && dX1 < m_dHeight && + dX2 > - dr && dX2 < dLenXY + dr) { + + double dRadLimXY = dr * dCos ; + double dRadLimH = dr * dSin ; + + // Massimi + if ( dX2 < - dRadLimXY) + dMax = dZI + sqrt( dr * dr - dX2 * dX2) ; + else if ( dX2 < dLenXY - dRadLimXY) + dMax = dZI + dRadLimH + dDeltaZ * ( dX2 + dRadLimXY) / dLenXY ; + else + dMax = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + // Minimi + if ( dX2 < dRadLimXY) + dMin = dZI + sqrt( dr * dr - dX2 * dX2) ; + else if ( dX2 < dLenXY + dRadLimXY) + dMin = dZI - dRadLimH + dDeltaZ * ( dX2 - dRadLimXY) / dLenXY ; + else + dMin = dZF + sqrt( dr * dr - ( dX2 - dLenXY) * ( dX2 - dLenXY)) ; + + SubtractIntervals( nGrid, i, j, dMin, dMax) ; + } + } + } + } + return true ; +}*/ + + +// Massimi + //if ( dX1 < - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dSqRad * dR2 * dR2)))/* && + // dISqDist < dRad * dRad) */ + + //dMax = dZI + sqrt( dSqRad - dISqDist) ; + + //else if ( /*dX1 >= - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && */ + // dX1 < dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) + + //dMax = dZI + dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) * dVLen / dPLen ; + + //else /*if ( dX1 >= dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && + // dFSqDist < dRad * dRad)*/ + + //dMax = dZI + dDeltaZ + sqrt( dSqRad - dFSqDist) ; + + // Minimi + // if ( dX1 < dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad))/* && + // dISqDist < dRad * dRad) */ + + // dMin = dZI - sqrt( dSqRad - dISqDist) ; + + //else if ( /*dX1 >= dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && */ + // dX1 < dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) + + // dMin = dZI - dR2 * sqrt( dSqRad - dX2 * dX2) + ( dX1 - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / dSqRad)) * dVLen / dPLen ; + + //else /*if ( dX1 >= dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && + // dFSqDist < dRad * dRad) */ + + //dMin = dZI + dDeltaZ - sqrt( dSqRad - dFSqDist) ; + + + \ No newline at end of file diff --git a/VolZmap.cpp b/VolZmap.cpp index f1a946e..71cf1ed 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -28,12 +28,16 @@ GEOOBJ_REGISTER( VOL_ZMAP, NGE_V_ZMP, VolZmap) ; //---------------------------------------------------------------------------- VolZmap::VolZmap(void) - : m_nStatus( TO_VERIFY), m_nTempProp(), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG) + : m_nStatus( TO_VERIFY), m_dStep( EPS_SMALL), m_nTempProp( 0), m_dLinTol( LIN_TOL_STD), m_dAngTolDeg( ANG_TOL_APPROX_DEG) { - m_dStep = 0 ; - m_nNx = 0 ; - m_nNy = 0 ; - m_nDim = 0 ; + m_nMapNum = 0 ; + for ( int i = 0 ; i < 3 ; ++ i) { + m_nVNx[i] = 0 ; + m_nVNy[i] = 0 ; + m_nVDim[i] = 0 ; + m_dVMinZ[i] = 0 ; + m_dVMaxZ[i] = 0 ; + } } //---------------------------------------------------------------------------- @@ -74,12 +78,24 @@ VolZmap::CopyFrom( const VolZmap& vzmSrc) if ( &vzmSrc == this) return true ; m_OGrMgr.Reset() ; - m_LocalFrame = vzmSrc.m_LocalFrame ; + + m_nMapNum = vzmSrc.m_nMapNum ; + + for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) { + + m_MapFrame[i] = vzmSrc.m_MapFrame[i] ; + + m_nVNx[i] = vzmSrc.m_nVNx[i] ; + m_nVNy[i] = vzmSrc.m_nVNy[i] ; + m_nVDim[i] = vzmSrc.m_nVDim[i] ; + + m_dVMinZ[i] = vzmSrc.m_dVMinZ[i] ; + m_dVMaxZ[i] = vzmSrc.m_dVMaxZ[i] ; + + m_TriZValues[i] = vzmSrc.m_TriZValues[i] ; + } + m_dStep = vzmSrc.m_dStep ; - m_nDim = vzmSrc.m_nDim ; - m_nNx = vzmSrc.m_nNx ; - m_nNy = vzmSrc.m_nNy ; - m_ZValues = vzmSrc.m_ZValues ; m_nStatus = vzmSrc.m_nStatus ; m_nTempProp = vzmSrc.m_nTempProp ; return true ; @@ -118,38 +134,44 @@ VolZmap::GetNgeId( void) const bool VolZmap::Save( NgeWriter& ngeOut) const { - // parametri di scrittura: sistema di riferimento, minimo incremento, numero di passi - // in direzione x e y, e per ogni casella, numero di valori e valori - if ( ! ngeOut.WriteFrame( m_LocalFrame, ";", true)) - return false ; - if ( ! ngeOut.WriteDouble( m_dStep, ",", false)) - return false ; - if ( ! ngeOut.WriteInt( m_nNx, ",", false)) - return false ; - if ( ! ngeOut.WriteInt( m_nNy, ";", true)) - return false ; - // ciclo sui dexel - for ( unsigned int i = 0 ; i < m_nDim ; ++ i) { - // numero di estremi - int nDim = int( m_ZValues[i].size()) ; - if ( ! ngeOut.WriteInt( nDim, ",", false)) + // parametri di scrittura: sistema di riferimento, numero di passi + // in direzione x e y, minimo incremento e per ogni casella, numero di valori e valori + for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) { + if ( ! ngeOut.WriteFrame( m_MapFrame[i], ",", true)) + return false ; + if ( ! ngeOut.WriteInt( m_nVNx[i], ",", false)) return false ; - // se dexel nullo - if ( nDim == 0) { + if ( ! ngeOut.WriteInt( m_nVNy[i], ",", true)) + return false ; + } + + if ( ! ngeOut.WriteDouble( m_dStep, ";", false)) + return false ; + + // ciclo sulle mappe + for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) { + // ciclo sui dexel + for ( unsigned int j = 0 ; j < m_nVDim[i] ; ++ j) { + // numero di estremi + int nDim = int( m_TriZValues[i][j].size()) ; + if ( ! ngeOut.WriteInt( nDim, ",", false)) + return false ; + // se dexel nullo + if ( nDim == 0) { // scrivo un valore dummy if ( ! ngeOut.WriteDouble( 0, ";", true)) return false ; - } - // altrimenti - else { - for ( unsigned int k = 0 ; k < m_ZValues[i].size() ; ++ k) { - bool bEndL = ( k == m_ZValues[i].size() - 1) ; - if ( ! ngeOut.WriteDouble( m_ZValues[i][k], ( bEndL ? ";" : ","), bEndL)) - return false ; } - } - } - + // altrimenti + else { + for ( unsigned int k = 0 ; k < m_TriZValues[i][j].size() ; ++ k) { + bool bEndL = ( k == m_TriZValues[i][j].size() - 1) ; + if ( ! ngeOut.WriteDouble( m_TriZValues[i][j][k], ( bEndL ? ";" : ","), bEndL)) + return false ; + } + } + } + } return true ; } @@ -158,49 +180,61 @@ bool VolZmap::Load( NgeReader& ngeIn) { m_nStatus = TO_VERIFY ; - // parametri di lettura: sistema di riferimento, minimo incremento, numero di passi - // in direzione x e y, e per ogni casella, numero di valori e valori - if ( ! ngeIn.ReadFrame( m_LocalFrame, ";", true)) - return false ; - if ( ! ngeIn.ReadDouble( m_dStep, ",", false)) - return false ; + // parametri di lettura: sistema di riferimento, numero di passi + // in direzione x e y, minimo incremento e per ogni casella, numero di valori e valori + int nTemp ; - if ( ! ngeIn.ReadInt( nTemp, ",", false)) - return false ; - m_nNx = nTemp ; - if ( ! ngeIn.ReadInt( nTemp, ";", true)) - return false ; - m_nNy = nTemp ; - // dimensione del vettore di dexel - m_nDim = m_nNx * m_nNy ; - m_ZValues.resize(m_nDim) ; + for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) { - // ciclo sui dexel - for ( unsigned int i = 0 ; i < m_nDim ; ++ i) { - // leggo il numero di estremi nel dexel + if ( ! ngeIn.ReadFrame( m_MapFrame[i], ";", true)) + return false ; if ( ! ngeIn.ReadInt( nTemp, ",", false)) return false ; - // devono essere pari - if ( ( nTemp % 2) != 0) + m_nVNx[i] = nTemp ; + if ( ! ngeIn.ReadInt( nTemp, ";", true)) return false ; - // se dexel nullo - if ( nTemp == 0) { - // leggo un valore dummy - double dDummy ; - if ( ! ngeIn.ReadDouble( dDummy, ",", true)) + m_nVNy[i] = nTemp ; + } + + if ( ! ngeIn.ReadDouble( m_dStep, ",", false)) + return false ; + + // dimensione dei vettori di dexel + for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) { + + m_nVDim[i] = m_nVNx[i] * m_nVNy[i] ; + m_TriZValues[i].resize(m_nVDim[i]) ; + } + + // ciclo sulle mappe + for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) { + // ciclo sui dexel + for ( unsigned int j = 0 ; j < m_nVDim[i] ; ++ j) { + // leggo il numero di estremi nel dexel + if ( ! ngeIn.ReadInt( nTemp, ",", false)) return false ; - } - // altrimenti - else { - // dimensiono l'array - m_ZValues[i].resize(nTemp) ; - // leggo i valori - for ( unsigned int k = 0 ; k < m_ZValues[i].size() ; ++ k) { - bool bEndL = ( k == m_ZValues[i].size() - 1) ; - if ( ! ngeIn.ReadDouble( m_ZValues[i][k], ( bEndL ? ";" : ","), bEndL)) + // devono essere pari + if ( ( nTemp % 2) != 0) + return false ; + // se dexel nullo + if ( nTemp == 0) { + // leggo un valore dummy + double dDummy ; + if ( ! ngeIn.ReadDouble( dDummy, ",", true)) return false ; } + // altrimenti + else { + // dimensiono l'array + m_TriZValues[i][j].resize(nTemp) ; + // leggo i valori + for ( unsigned int k = 0 ; k < m_TriZValues[i][j].size() ; ++ k) { + bool bEndL = ( k == m_TriZValues[i][j].size() - 1) ; + if ( ! ngeIn.ReadDouble( m_TriZValues[i][j][k], ( bEndL ? ";" : ","), bEndL)) + return false ; + } + } } } @@ -220,24 +254,24 @@ VolZmap::GetLocalBBox( BBox3d& b3Loc, int nFlag) const // se richiesto approssimato if ( ( nFlag & BBF_EXACT) == 0) { b3Loc.Add( ORIG) ; - b3Loc.Add( Point3d( m_nNx * m_dStep, m_nNy * m_dStep, m_dMaxZ)) ; - b3Loc.ToGlob( m_LocalFrame) ; + b3Loc.Add( Point3d( m_nVNx[0] * m_dStep, m_nVNy[0] * m_dStep, m_dVMaxZ[0])) ; + b3Loc.ToGlob( m_MapFrame[0]) ; return true ; } // calcolo preciso // ciclo sui dexel (punti in basso con ciclo aggiunto per punti in alto di ultima riga) double dY = 0 ; - for ( size_t j = 0 ; j <= m_nNy ; ++ j) { - size_t jc = ( ( j != m_nNy) ? j : m_nNy -1) ; + for ( size_t j = 0 ; j <= m_nVNy[0] ; ++ j) { + size_t jc = ( ( j != m_nVNy[0]) ? j : m_nVNy[0] -1) ; double dX = 0 ; // punto a sinistra di ogni dexel (aggiungo un ciclo per fare punto a destra di ultimo) - for ( size_t i = 0 ; i <= m_nNx ; ++ i) { - size_t ic = ( ( i != m_nNx) ? i : m_nNx -1) ; - size_t nPos = ic + jc * m_nNx ; - if ( m_ZValues[nPos].size() > 0) { - Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; - b3Loc.Add( ptP + m_ZValues[nPos][0] * m_LocalFrame.VersZ()) ; - b3Loc.Add( ptP + m_ZValues[nPos][m_ZValues[nPos].size()-1] * m_LocalFrame.VersZ()) ; + for ( size_t i = 0 ; i <= m_nVNx[0] ; ++ i) { + size_t ic = ( ( i != m_nVNx[0]) ? i : m_nVNx[0] -1) ; + size_t nPos = ic + jc * m_nVNx[0] ; + if ( m_TriZValues[0][nPos].size() > 0) { + Point3d ptP = m_MapFrame[0].Orig() + dX * m_MapFrame[0].VersX() + dY * m_MapFrame[0].VersY() ; + b3Loc.Add( ptP + m_TriZValues[0][nPos][0] * m_MapFrame[0].VersZ()) ; + b3Loc.Add( ptP + m_TriZValues[0][nPos][m_TriZValues[0][nPos].size()-1] * m_MapFrame[0].VersZ()) ; } // passo al punto successivo dX += m_dStep ; @@ -259,29 +293,29 @@ VolZmap::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const // reset box b3Ref.Reset() ; // trasformo il riferimento locale tramite quello passato - Frame3d frUse = m_LocalFrame ; + Frame3d frUse = m_MapFrame[0] ; frUse.ToGlob( frRef) ; // se richiesto approssimato if ( ( nFlag & BBF_EXACT) == 0) { b3Ref.Add( ORIG) ; - b3Ref.Add( Point3d( m_nNx * m_dStep, m_nNy * m_dStep, m_dMaxZ)) ; + b3Ref.Add( Point3d( m_nVNx[0] * m_dStep, m_nVNy[0] * m_dStep, m_dVMaxZ[0])) ; b3Ref.ToGlob( frUse) ; return true ; } // calcolo preciso // ciclo sui dexel (punti in basso con ciclo aggiunto per punti in alto di ultima riga) double dY = 0 ; - for ( size_t j = 0 ; j <= m_nNy ; ++ j) { - size_t jc = ( ( j != m_nNy) ? j : m_nNy -1) ; + for ( size_t j = 0 ; j <= m_nVNy[0] ; ++ j) { + size_t jc = ( ( j != m_nVNy[0]) ? j : m_nVNy[0] -1) ; double dX = 0 ; // punto a sinistra di ogni dexel (aggiungo un ciclo per fare punto a destra di ultimo) - for ( size_t i = 0 ; i <= m_nNx ; ++ i) { - size_t ic = ( ( i != m_nNx) ? i : m_nNx -1) ; - size_t nPos = ic + jc * m_nNx ; - if ( m_ZValues[nPos].size() > 0) { + for ( size_t i = 0 ; i <= m_nVNx[0] ; ++ i) { + size_t ic = ( ( i != m_nVNx[0]) ? i : m_nVNx[0] -1) ; + size_t nPos = ic + jc * m_nVNx[0] ; + if ( m_TriZValues[0][nPos].size() > 0) { Point3d ptP = frUse.Orig() + dX * frUse.VersX() + dY * frUse.VersY() ; - b3Ref.Add( ptP + m_ZValues[nPos][0] * frUse.VersZ()) ; - b3Ref.Add( ptP + m_ZValues[nPos][m_ZValues[nPos].size()-1] * frUse.VersZ()) ; + b3Ref.Add( ptP + m_TriZValues[0][nPos][0] * frUse.VersZ()) ; + b3Ref.Add( ptP + m_TriZValues[0][nPos][m_TriZValues[0][nPos].size()-1] * frUse.VersZ()) ; } // passo al punto successivo dX += m_dStep ; @@ -291,7 +325,7 @@ VolZmap::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const } return true ; -} +} //---------------------------------------------------------------------------- bool @@ -302,8 +336,9 @@ VolZmap::Translate( const Vector3d& vtMove) return false ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; - // traslo il riferimento - m_LocalFrame.Translate( vtMove) ; + // traslo i riferimenti + for ( int i = 0 ; i < int( m_nMapNum) ; ++ i) + m_MapFrame[i].Translate( vtMove) ; return true ; } @@ -316,8 +351,10 @@ VolZmap::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub return false ; // imposto ricalcolo della grafica m_OGrMgr.Reset() ; - // ruoto il riferimento - return m_LocalFrame.Rotate( ptAx, vtAx, dCosAng, dSinAng) ; + // ruoto i riferimenti + for ( int i = 0 ; i < int( m_nMapNum) ; ++ i) + m_MapFrame[i].Rotate( ptAx, vtAx, dCosAng, dSinAng) ; + return true ; } //---------------------------------------------------------------------------- @@ -360,7 +397,9 @@ VolZmap::ToGlob( const Frame3d& frRef) // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // trasformo il riferimento - return m_LocalFrame.ToGlob( frRef) ; + for ( int i = 0 ; i < int ( m_nMapNum) ; ++ i) + m_MapFrame[i].ToGlob( frRef) ; + return true ; } //---------------------------------------------------------------------------- @@ -373,7 +412,9 @@ VolZmap::ToLoc( const Frame3d& frRef) // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // trasformo il riferimento - return m_LocalFrame.ToLoc( frRef) ; + for ( int i = 0 ; i < int( m_nMapNum) ; ++ i) + m_MapFrame[i].ToLoc( frRef) ; + return true ; } //---------------------------------------------------------------------------- @@ -386,7 +427,9 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) // imposto ricalcolo della grafica m_OGrMgr.Reset() ; // trasformo il riferimento - return m_LocalFrame.LocToLoc( frOri, frDest) ; + for ( int i = 0 ; i < int( m_nMapNum) ; ++ i) + m_MapFrame[i].LocToLoc( frOri, frDest) ; + return true ; } diff --git a/VolZmap.h b/VolZmap.h index a605194..dbca216 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -60,9 +60,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW public : // IVolZmap bool CopyFrom( const IGeoObj* pGObjSrc) override ; - bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dPrec) override ; - bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec) override ; - bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec) override ; + bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dPrec, bool bTriDex) override ; + bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dPrec, bool bTriDex) override ; + bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex) override ; bool GetAllTriangles( TRIA3DLIST& lstTria) const override ; bool GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const override ; bool SetTolerances( double dLinTol, double dAngTolDeg = 90) override ; @@ -70,10 +70,12 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool SetAdvTool( const std::string& pToolName, double dH, double dR, double dTipH, double dTipR, double dCornR) override ; bool SetGenTool( const std::string& pToolName, const ICurveComposite* pToolOutline) override ; - bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) override ; bool GetDepth( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) override ; bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) override ; + + bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) override ; + public : // IGeoObjRW virtual int GetNgeId( void) const ; virtual bool Save( NgeWriter& ngeOut) const ; @@ -103,144 +105,110 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const ; bool AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const ; - - bool SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; - bool SubtractIntervals( const Point3d& ptP, double dMin, double dMax) ; - bool AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; - bool AddIntervals( const Point3d& ptP, double dMin, double dMax) ; - - // frese: cylindrical, ball-end, bull-nose e conus - // Versore utensile parallelo all'asse Z - // Fori - bool DrillingZ( const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) ; - - bool CBTDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - - // Tagli orizzontali - bool MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - bool CBTMillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - - inline bool GetMinMaxZSw( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ; - inline bool GetMinMaxZDr( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, double dMinRad, double dMaxRad, double dDir, double dDeltaZ) ; - inline bool GetMinMaxZ( unsigned int nI, unsigned int nJ, double dZCutBase, double dDeltaZ, double dSqDist, const Vector3d& vtToolDir) ; - - // generico 3 assi - bool MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - bool CBMillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - bool ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - - inline bool GetMinMaxZGen( unsigned int nI, unsigned int nJ, double dProj, double dSqd, double dLenPath, double dZheight, double dDelta, const Vector3d& vtToolDir) ; - + bool MarchingCubes( TRIA3DLIST& lstTria) const ; + bool IsThereMat( int nI, int nJ, int nK) const ; + bool IsThereMat( const int nMatr[][3], int nNum, double & dHx, double & dHy, double & dHz) const ; + bool IntersPos( int nVec1[], int nVec2[], Point3d & ptInt) const ; - // Versore utensile nel piano XY - // DeltaZ = 0 - bool DrillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + // OPERAZIONI SU INTERVALLI + bool SubtractIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) ; + bool SubtractIntervals( unsigned int nGrid, const Point3d& ptP, double dMin, double dMax) ; + bool AddIntervals( unsigned int nGrid, unsigned int nI, unsigned int nJ, double dMin, double dMax) ; + bool AddIntervals( unsigned int nGrid, const Point3d& ptP, double dMin, double dMax) ; - bool CBTDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool ConusDrillingXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - - bool MillingPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + // SOTTRAZIONI + // UTENSILI + // Asse di simmetria parallelo a Z + bool CylBall_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool CylBall_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool CylBall_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - bool CBTPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool ConusPerpXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) ; - - bool MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool PlaneGenCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool ConusPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool Conus_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool Conus_ZPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool Conus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - inline bool GetMinMaxXY( unsigned int nI, unsigned int nJ, double dProj, double dZheight, double dSqD, double dPathPerp, double dPathPar, double dScProd) ; - inline bool GetMMPlaneGenCyl( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, double dProj1, double dProj2) ; - inline bool GetMMPlaneGenBall( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, Point3d ptIxy, Vector3d vtMove, Vector3d vtV1, Vector3d vtV2) ; - - // DeltaZ != 0 - bool MillingXYVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool Dr_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) ; + bool Sw_ZMilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir) ; - bool MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool GenTool_ZDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool GenTool_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - bool XYLongVertCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - bool MillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - bool MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - bool MillingXYPlus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - bool MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingXYPlusConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + // Asse di simmetria nel piano + bool CylBall_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool CylBall_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool CylBall_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - // Virtual milling per componenti elementari + bool Conus_XYDrilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool Conus_XYPerp( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool Conus_XYMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - // Versore utensile parallelo all'asse Z - // Movimento parallelo al versore utensile - bool DrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - // Componenti - bool LongCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool LongConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + // Asse di simmetria con orientazione generica + bool CylBall_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool CylBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - // Angolo generico fra movimento e versore utensile - bool MillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - // Componenti - bool MillCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool MillConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + bool Conus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool Conus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - // Direzione generica del versore utensile - // Movimento parallelo al versore utensile - bool Drilling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool DrillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; + bool GenTool_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + bool GenTool_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; - // Componenti elementari degli untensili - bool LongBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) ; - bool LongCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool LongConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + // COMPONENTI + // Asse di simmetria diretto come l'asse Z - // Angolo generico fra movimento e versore utensile - bool Milling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - bool MillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) ; - - // Componenti elementari degli utensili - bool MillCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool MillCyl2( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) ; - bool MillBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) ; - bool MillConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) ; - bool MillConusAux( const Point3d& ptI, const Point3d& ptF, const Vector3d& vtV1, const Vector3d& vtV2, const Vector3d& vtV3, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, - double dHei, double dMaxRad, double dMinRad, double dCoef) ; + // Drilling + bool CompCyl_ZDrilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir, double dHei, double dRad) ; + bool CompConus_ZDrilling( unsigned int nGrid, const Point3d & ptLs, const Point3d & ptLe, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ; - // Traslazioni - bool Ball( const Point3d& ptLs, const Point3d& ptLe, double dRad) ; + // Milling + bool CompCyl_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) ; + bool CompConus_ZMilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ; - // Sottrazione per tridexel - bool ZDrillingCB( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir) ; + // Asse di simmetria con orientazione generica - // Bounding Box - inline bool BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) ; + // Drilling + bool CompCyl_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) ; + bool CompConus_Drilling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + + // Milling + bool CompCyl_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dRad) ; + bool CompConus_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, const Vector3d & vtToolDir, double dHei, double dMaxRad, double dMinRad) ; + bool CompConusAux_Milling( unsigned int nGrid, const Point3d & ptI, const Point3d & ptF, const Vector3d & vtV1, const Vector3d & vtV2, const Vector3d & vtV3, + unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + double dHei, double dMaxRad, double dMinRad, double dCoef) ; + + // Generica traslazione sfera + bool CompBall_Milling( unsigned int nGrid, const Point3d & ptS, const Point3d & ptE, double dRad) ; + + // BBox per utensili e solidi semplici inline bool BoundingBox( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) ; - inline bool BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2) ; - inline bool BBoxComponent( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, - double dRad, double dTipRad, double dHei) ; + unsigned int& nStI, unsigned int& nStJ, unsigned int& nEnI, unsigned int& nEnJ) ; inline bool BBoxComponent( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, + unsigned int& nStI, unsigned int& nStJ, unsigned int& nEnI, unsigned int& nEnJ, double dRad, double dTipRad, double dHei) ; - + + // Intersezioni bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) ; + bool IntersLineZMapBBox( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) ; + bool IntersLineDexel( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, unsigned int nI, unsigned int nJ, + double& dU1, double& dU2) ; bool IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) ; bool IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nI, unsigned int nJ, - double& dU1, double& dU2) ; + double& dU1, double& dU2) ; + bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, + const Frame3d& CylFrame, double dL, double dR, + Point3d& ptInt1, Point3d& ptInt2) ; + bool IntersZLineCylinder( const Point3d& ptLine, + const Point3d& ptBase, const Point3d& ptTop, const Vector3d& vtDir, double dCylR, + double& dInfZ, double& dSupZ) ; + bool IntersLineEllipticalCylinder( const Frame3d& CircFrame, const Vector3d& vtLineDir, const Point3d& ptLineSt, + PNTVECTOR& ptInters, double dObCoef, double dSqRad, double dL) ; + bool IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir, + const Frame3d& ConusFrame, double dTan, double dl, double dL, + Point3d& ptInt1, Point3d& ptInt2) ; + bool IntersLineSphere( const Point3d& ptLineSt, const Vector3d& vtLineDir, + const Point3d& ptCenter, double dRad, + Point3d& ptInt1, Point3d& ptInt2) ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; @@ -248,47 +216,27 @@ class VolZmap : public IVolZmap, public IGeoObjRW private : ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto Status m_nStatus ; // stato - int m_nTempProp ; // proprietà temporanea - - Frame3d m_LocalFrame ; - Frame3d m_LocalFrame2 ; - Frame3d m_LocalFrame3 ; - double m_dStep ; - - unsigned int m_nNx ; // i = 0, 1, ..., m_nNx - 1 - unsigned int m_nNy ; // j = 0, 1, ..., m_nNy - 1 - unsigned int m_nNx2 ; - unsigned int m_nNy2 ; - unsigned int m_nNx3 ; - unsigned int m_nNy3 ; - unsigned int m_nDim ; - unsigned int m_nDim2 ; - unsigned int m_nDim3 ; - - double m_dMinZ ; - double m_dMaxZ ; - - double m_dMinZ2 ; - double m_dMaxZ2 ; - - double m_dMinZ3 ; - double m_dMaxZ3 ; - - std::vector > m_ZValues ; - std::vector > m_ZValues2 ; - std::vector > m_ZValues3 ; - - double m_dLinTol ; - double m_dAngTolDeg ; - std::string m_sToolName ; - unsigned int m_nToolType ; + int m_nTempProp ; // proprietà temporanea + double m_dStep ; // passo delle griglie + unsigned int m_nMapNum ; // numero di griglie ( 1 o 3) + Frame3d m_MapFrame[3] ; // riferimenti delle griglie + unsigned int m_nVNx[3] ; // dimensione di ciascuna griglia in X + unsigned int m_nVNy[3] ; // dimensione di ciascuna griglia in Y + unsigned int m_nVDim[3] ; // dimensione di ciascuna griglia ( X * Y) + double m_dVMinZ[3] ; // minimo in Zlocale di ciascuna griglia + double m_dVMaxZ[3] ; // massimo in Zlocale di ciascuna griglia + std::vector> m_TriZValues[3] ; // dexel delle 3 griglie + double m_dLinTol ; // dati per utensile + double m_dAngTolDeg ; + std::string m_sToolName ; + unsigned int m_nToolType ; CurveComposite m_ToolOutline ; CurveComposite m_ToolArcLineApprox ; - double m_dHeight ; - double m_dTipHeight ; - double m_dRadius ; - double m_dRCorner ; - double m_dTipRadius ; + double m_dHeight ; + double m_dTipHeight ; + double m_dRadius ; + double m_dRCorner ; + double m_dTipRadius ; } ; //----------------------------------------------------------------------------- diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp deleted file mode 100644 index ae88760..0000000 --- a/VolZmapCalculus.cpp +++ /dev/null @@ -1,313 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2016-2016 -//---------------------------------------------------------------------------- -// File : VolZmap.cpp Data : 03.11.16 Versione : 1.6w1 -// Contenuto : Implementazione della classe Volume Zmap : intersezioni. -// -// -// -// Modifiche : 03.11.16 LM Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -//--------------------------- Include ---------------------------------------- -#include "stdafx.h" -#include "VolZmap.h" -#include "GeoConst.h" -#include "\EgtDev\Include\EgtNumUtils.h" - -using namespace std ; - -//---------------------------------------------------------------------------- -bool -VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, - const Point3d& ptMin, const Point3d& ptMax, double& dU1, double& dU2) -{ - // Il box è allineato agli assi - - dU1 = - INFINITO ; - dU2 = INFINITO ; - - // confronto con piani YZ (perpendicolari ad asse X) - if ( vtV.x > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.x - ptP.x) / vtV.x) ; - dU2 = min( dU2, ( ptMax.x - ptP.x) / vtV.x) ; - } - else if ( vtV.x < - EPS_ZERO) { - dU1 = max( dU1, ( ptMax.x - ptP.x) / vtV.x) ; - dU2 = min( dU2, ( ptMin.x - ptP.x) / vtV.x) ; - } - else if ( ptP.x < ptMin.x - EPS_SMALL || ptP.x > ptMax.x + EPS_SMALL) - return false ; - - // confronto con piani ZX (perpendicolari ad asse Y) - if ( vtV.y > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.y - ptP.y) / vtV.y) ; - dU2 = min( dU2, ( ptMax.y - ptP.y) / vtV.y) ; - } - else if ( vtV.y < - EPS_ZERO) { - dU1 = max( dU1, ( ptMax.y - ptP.y) / vtV.y) ; - dU2 = min( dU2, ( ptMin.y - ptP.y) / vtV.y) ; - } - else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL) - return false ; - - // confronto con piani XZ (perpendicolari ad asse Z) - if ( vtV.z > EPS_ZERO) { - dU1 = max( dU1, ( ptMin.z - ptP.z) / vtV.z) ; - dU2 = min( dU2, ( ptMax.z - ptP.z) / vtV.z) ; - } - else if ( vtV.z < - EPS_ZERO) { - dU1 = max( dU1, ( ptMax.z - ptP.z) / vtV.z) ; - dU2 = min( dU2, ( ptMin.z - ptP.z) / vtV.z) ; - } - else if ( ptP.z < ptMin.z - EPS_SMALL || ptP.z > ptMax.z + EPS_SMALL) - return false ; - - return ( dU2 >= dU1) ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) -{ - // Punti estremi del box dello Zmap - Point3d ptMin = ORIG ; - Point3d ptMax = ptMin + m_nNx * m_dStep * X_AX + m_nNy * m_dStep * Y_AX + m_dMaxZ * Z_AX ; - - if ( IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) && ( dU1 > 0 || dU2 > 0)) { - return true ; - } - - else { - return false ; - } -} - -//---------------------------------------------------------------------------- -bool -VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nI, - unsigned int nJ, double& dU1, double& dU2) -{ - // Determino l'indice del dexel e il doppio del numero di suo intervalli - unsigned int nDexelPos = nJ * m_nNx + nI ; - unsigned int nDexelSize = unsigned int( m_ZValues[nDexelPos].size()) ; - - // Se non c'è materiale non devo fare alcunché - if ( nDexelSize == 0) - return false ; - - // Determino estremi nel piano XY intrinseco del dexel - double dXmin = nI * m_dStep ; - double dYmin = nJ * m_dStep ; - double dXmax = ( nI + 1) * m_dStep ; - double dYmax = ( nJ + 1) * m_dStep ; - - // ciclo sugli intervalli - dU1 = INFINITO ; - dU2 = - INFINITO ; - bool bInters = false ; - for ( unsigned int nIndex = 0 ; nIndex < nDexelSize ; nIndex += 2) { - // estremi del box del singolo intervallo - Point3d ptE1( dXmin, dYmin, m_ZValues[nDexelPos][nIndex]) ; - Point3d ptE2( dXmax, dYmax, m_ZValues[nDexelPos][nIndex+1]) ; - double dt1, dt2 ; - if ( IntersLineBox( ptP, vtV, ptE1, ptE2, dt1, dt2)) { - bInters = true ; - dU1 = min( dU1, dt1) ; - dU2 = max( dU2, dt2) ; - } - } - - return bInters ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLength, double& dOutLength) -{ - // Porto il raggio nel riferimento intrinseco - Point3d ptP = ptPGlob ; - ptP.ToLoc( m_LocalFrame) ; - Vector3d vtV = vtDir ; - vtV.ToLoc( m_LocalFrame) ; - vtV.Normalize() ; - - // Studio dell'intersezione fra semiretta e BBox dello Zmap - double dU1, dU2 ; - bool bTest = IntersLineZMapBBox( ptP, vtV, dU1, dU2) ; - - // Semiretta esterna al box dello Zmap - if ( ! bTest) { - dInLength = - 2 ; - dOutLength = - 2 ; - return true ; - } - - Point3d ptI, ptF ; - // Una sola intersezione valida ( punto interno, intersezione valida 2) - if ( dU1 < 0 && dU2 > 0) { - ptI = ptP ; - ptF = ptP + dU2 * vtV ; - } - // due soluzioni valide ( punto esterno) - else { - ptI = ptP + dU1 * vtV ; - ptF = ptP + dU2 * vtV ; - } - - // Determinazione degli indici i j dei punti ptI e ptF - int nIi = Clamp( int( floor( ptI.x / m_dStep)), 0, m_nNx - 1) ; - int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nNy - 1) ; - int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nNx - 1) ; - int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nNy - 1) ; - - // Inizializzo distanze - dInLength = INFINITO ; - dOutLength = - INFINITO ; - - // Variazioni - double dDeltaX = ptF.x - ptI.x ; - double dDeltaY = ptF.y - ptI.y ; - - // se inclinazione da asse X minore di 45 gradi (in assoluto) - if ( abs( dDeltaY) <= abs( dDeltaX)) { - // mi muovo lungo X (i) - int nIncrI = ( nFi >= nIi ? 1 : - 1) ; - for ( int i = nIi, j = nIj ; - i != nFi + nIncrI ; - i += nIncrI) { - - // Controllo con nuovo i e j corrente (considero il bordo sinistro del dexel) - double dU1, dU2 ; - if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { - dInLength = min( dInLength, dU1) ; - dOutLength = max( dOutLength, dU2) ; - } - - // Mi sposto sul bordo destro del dexel - double dMoveX = ( ( i + max( nIncrI, 0)) * m_dStep - ptI.x) ; - double dMoveY = dMoveX * dDeltaY / dDeltaX ; - double dY = ptI.y + dMoveY ; - int OldJ = j ; - j = Clamp( int( floor( dY / m_dStep)), 0, m_nNy - 1) ; - - // Analisi del dexel - if ( j != OldJ) { - double dU1, dU2 ; - if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { - dInLength = min( dInLength, dU1) ; - dOutLength = max( dOutLength, dU2) ; - } - } - } - } - - // altrimenti - else { - // mi muovo lungo Y (j) - int nIncrJ = ( nFj >= nIj ? 1 : - 1) ; - for ( int i = nIi, j = nIj ; - j != nFj + nIncrJ ; - j += nIncrJ) { - - // Controllo con nuovo j e i corrente (considero il bordo sotto del dexel) - double dU1, dU2 ; - if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { - dInLength = min( dInLength, dU1) ; - dOutLength = max( dOutLength, dU2) ; - } - - // Mi sposto sul bordo sopra del dexel - double dMoveY = ( ( j + max( nIncrJ, 0)) * m_dStep - ptI.y) ; - double dMoveX = dMoveY * dDeltaX / dDeltaY ; - double dX = ptI.x + dMoveX ; - int OldI = i ; - i = Clamp( int( floor( dX / m_dStep)), 0, m_nNx - 1) ; - - // Analisi del dexel - if ( i != OldI) { - double dU1, dU2 ; - if ( IntersLineDexel( ptP, vtV, i, j, dU1, dU2)) { - dInLength = min( dInLength, dU1) ; - dOutLength = max( dOutLength, dU2) ; - } - } - } - } - - // Se non abbiamo incontrato materiale - if ( dInLength > dOutLength - EPS_SMALL) { - dInLength = - 2 ; - dOutLength = - 2 ; - return true ; - } - - // Se parto dall'interno - if ( dInLength < - EPS_SMALL) - dInLength = - 1 ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) -{ - // BBox - BBox3d b3Box( ORIG, ORIG + vtDiag) ; - - // lo porto nel riferimento intrinseco dello Zmap - b3Box.LocToLoc( frBox, m_LocalFrame) ; - - // BBox dello Zmap nel suo riferimento intrinseco - BBox3d b3Zmap( ORIG, Point3d( m_nNx * m_dStep, m_nNy * m_dStep, m_dMaxZ)) ; - - // Se non interferiscono, posso uscire - BBox3d b3Int ; - if ( ! b3Zmap.FindIntersection( b3Box, b3Int)) - return true ; - - // Limiti su indici - int nStI = Clamp( int( b3Int.GetMin().x / m_dStep), 0, m_nNx -1) ; - int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nNx -1) ; - int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nNy -1) ; - int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy -1) ; - - // Vettore direzione dei dexel nel riferimento del Box - Vector3d vtK = Z_AX ; vtK.LocToLoc( m_LocalFrame, frBox) ; - - // Riferimento intrinseco dei dexel nel riferimento del box - Point3d ptO = ORIG ; ptO.LocToLoc( m_LocalFrame, frBox) ; - Vector3d vtX = X_AX ; vtX.LocToLoc( m_LocalFrame, frBox) ; - Vector3d vtY = Y_AX ; vtY.LocToLoc( m_LocalFrame, frBox) ; - - // Ciclo di intersezione dei dexel con il BBox - for ( int i = nStI ; i <= nEnI ; ++ i) { - - for ( int j = nStJ ; j <= nEnJ ; ++ j) { - - int nPos = j * m_nNx + i ; - int nSize = int( m_ZValues[nPos].size()) ; - if ( nSize == 0) - continue ; - - Point3d ptC = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ; - - double dZmin, dZmax ; - if ( IntersLineBox( ptC, vtK, ORIG, ORIG + vtDiag, dZmin, dZmax)) { - - for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 2) { - if ( m_ZValues[nPos].size() == 0) - continue ; - if ( ! ( dZmax < m_ZValues[nPos][nIndex] - EPS_SMALL || - dZmin > m_ZValues[nPos][nIndex + 1] + EPS_SMALL)) - return false ; - } - } - } - } - - return true ; -} diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp deleted file mode 100644 index 7b25667..0000000 --- a/VolZmapCreation.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2015-2016 -//---------------------------------------------------------------------------- -// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 -// Contenuto : Implementazione della classe Volume Zmap (singola griglia) -// -// -// -// Modifiche : 22.01.15 DS Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -//--------------------------- Include ---------------------------------------- -#include "stdafx.h" -#include "CurveLine.h" -#include "VolZmap.h" -#include "GeoConst.h" -#include "IntersLineSurfTm.h" -#include "\EgtDev\Include\EgtNumUtils.h" - -using namespace std ; - - -//---------- Creazione da parallelepipedo ------------------------------------ -//---------------------------------------------------------------------------- -bool -VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec) -{ - // Controlli sui parametri - if ( dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) - return false ; - - // Definisco il sistema di riferimento in trinseco dello Zmap - m_LocalFrame.Set( ptO, X_AX, Y_AX, Z_AX) ; - - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL - m_dStep = max( dPrec, 100 * EPS_SMALL) ; - - // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe - // della griglia Zmap e da questi la dimensione del vettore di dexel - m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; - m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; - - m_nDim = m_nNx * m_nNy ; - - // Ridimensiono il vettore di dexel e creo lo Zmap - m_ZValues.resize( m_nDim) ; - - for ( int i = 0 ; i < int( m_nDim) ; i++) { - m_ZValues[i].resize(2) ; - m_ZValues[i][0] = 0 ; - m_ZValues[i][1] = dLengthZ ; - } - - // Assegno il minimo e massimo valore di Z della mappa - m_dMinZ = 0 ; - m_dMaxZ = dLengthZ ; - - m_nStatus = OK ; - return true ; -} - -//---------- Creazione da flat region ---------------------------------------- -//---------------------------------------------------------------------------- -bool -VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dLengthZ, double dPrec) -{ - Point3d ptMapOrig, ptMapEnd ; - - // Determino il bounding box della flat region - BBox3d SurfBBox ; - Surf.GetLocalBBox( SurfBBox, BBF_EXACT) ; - - // Determino i punti estremi del bounding box - SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; - - // Sistema di riferimento mappa - m_LocalFrame.Set( ptMapOrig, X_AX, Y_AX, Z_AX) ; - - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL - m_dStep = max( dPrec, 100 * EPS_SMALL) ; - - // Determino le dimensioni lineari X Y della griglia - double dLengthX = ptMapEnd.x - ptMapOrig.x ; - double dLengthY = ptMapEnd.y - ptMapOrig.y ; - - // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe - // della griglia Zmap e da questi la dimensione del vettore di dexel - m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; - m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; - - m_nDim = m_nNx * m_nNy ; - - // Ridimensiono il vettore di dexel e creo lo Zmap - m_ZValues.resize( m_nDim) ; - - // Determinazione e ridimensionamento dei dexel - // interni alla regione - for ( unsigned int i = 0 ; i < m_nNx ; ++ i) { - - // Definisco la retta da intersecare con la regione - double dX = ( i + 0.5) * m_dStep ; - Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; - CurveLine GridLine ; - GridLine.SetPVL( ptP0, Y_AX, dLengthY) ; - - // Determino le intersezioni della retta con la regione - CRVCVECTOR IntersectionResults ; - Surf.GetCurveClassification( GridLine, IntersectionResults) ; - // Parti di cui la retta analizzata è composta - int nPart = int( IntersectionResults.size()) ; - - // Analizzo le parti - for ( int k = 0 ; k < nPart ; ++ k) { - - // Tipo di curva - int nType = IntersectionResults[k].nClass ; - - // Se la retta è interna alla regione o coincidente con parte della sua frontiera - if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { - - // Parametri iniziale e finale - double dt1 = IntersectionResults[k].dParS ; - double dt2 = IntersectionResults[k].dParE ; - - // Indici corrispondenti alle coordinate dei punti - int nStartJ = Clamp( int( floor( dt1 * dLengthY / m_dStep + 0.5)), 0, m_nNy - 1) ; - int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep - 0.5)), 0, m_nNy - 1) ; - - // Ridimensiono e riempio i dexel - for ( int j = nStartJ ; j <= nEndJ ; ++ j) { - // Determino il dexel - int nPos = j * m_nNx + i ; - - m_ZValues[nPos].resize( 2) ; - // Aggiorno le quote estreme del segmento - m_ZValues[nPos][0] = 0 ; - m_ZValues[nPos][1] = dLengthZ ; - } - } - } - } - - // Assegno il minimo e massimo valore di Z della mappa - m_dMinZ = 0 ; - m_dMaxZ = dLengthZ ; - - m_nStatus = OK ; - - return true ; -} - -//---------- Creazione da trimesh -------------------------------------------- -//---------------------------------------------------------------------------- -bool -VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec) -{ - // Se la superficie non è chiusa non ha senso continuare - if ( ! Surf.IsClosed()) - return false ; - - // Determino il bounding box della TriMesh - BBox3d SurfBBox ; - Surf.GetLocalBBox( SurfBBox) ; - - // Determino i punti estremi del bounding box - Point3d ptMapOrig, ptMapEnd ; - SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; - - // Sistema di riferimento mappa - m_LocalFrame.Set( ptMapOrig, Frame3d::TOP) ; - - // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL - m_dStep = max( dPrec, 100 * EPS_SMALL) ; - - // Determino le dimensioni lineari X Y della griglia - double dLengthX = ptMapEnd.x - ptMapOrig.x ; - double dLengthY = ptMapEnd.y - ptMapOrig.y ; - double dLengthZ = ptMapEnd.z - ptMapOrig.z ; - - // A partire dalle dimensioni di xy del grezzo determino il numero di colonne e righe - // della griglia Zmap e da questi la dimensione del vettore di dexel - m_nNx = static_cast ( ceil( dLengthX / m_dStep)) ; - m_nNy = static_cast ( ceil( dLengthY / m_dStep)) ; - - m_nDim = m_nNx * m_nNy ; - - // Ridimensiono il vettore di dexel e creo lo Zmap - m_ZValues.resize( m_nDim) ; - - // Oggetto per calcolo massivo intersezioni - IntersParLinesSurfTm intPLSTM( m_LocalFrame, Surf) ; - - // Determinazione e ridimensionamento dei dexel interni alla trimesh - for ( unsigned int i = 0 ; i < m_nNx ; ++ i) { - - for ( unsigned int j = 0 ; j < m_nNy ; ++ j) { - - // Definisco la retta da intersecare con la trimesh - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - Point3d ptP0( dX, dY, 0) ; - - // Determino le intersezioni della retta con la TriMesh - ILSIVECTOR IntersectionResults ; - intPLSTM.GetInters( ptP0, dLengthZ, IntersectionResults) ; - - int nInt = int( IntersectionResults.size()) ; - - unsigned int nPos = j * m_nNx + i ; - - bool bInside = false ; - Point3d ptIn ; - for ( int k = 0 ; k < nInt ; ++ k) { - - int nIntType = IntersectionResults[k].nILTT ; - - // Se c'è intersezione - if ( nIntType != ILTT_NO) { - - double dCos = IntersectionResults[k].dCosDN ; - - // entro nella superficie trimesh - if ( dCos < - EPS_SMALL) { - - ptIn = IntersectionResults[k].ptI ; - - bInside = true ; - } - - // esco dalla superficie trimesh - else if ( dCos > EPS_SMALL && bInside) { - - Point3d ptOut = IntersectionResults[k].ptI ; - - unsigned int nCurrentSize = unsigned int( m_ZValues[nPos].size()) ; - - m_ZValues[nPos].resize( nCurrentSize + 2) ; - - m_ZValues[nPos][nCurrentSize] = ptIn.z - ptMapOrig.z ; - m_ZValues[nPos][nCurrentSize + 1] = ptOut.z - ptMapOrig.z ; - - bInside = false ; - } - } - } - } - } - - // Assegno il minimo e massimo valore di Z della mappa - m_dMinZ = 0 ; - m_dMaxZ = dLengthZ ; - - m_nStatus = OK ; - - return true ; -} \ No newline at end of file diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp deleted file mode 100644 index 9d8bf66..0000000 --- a/VolZmapGraphics.cpp +++ /dev/null @@ -1,255 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2015-2016 -//---------------------------------------------------------------------------- -// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 -// Contenuto : Implementazione della classe Volume Zmap (singola griglia) -// -// -// -// Modifiche : 22.01.15 DS Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -//--------------------------- Include ---------------------------------------- -#include "stdafx.h" -#include "VolZmap.h" -#include "GeoConst.h" -#include "\EgtDev\Include\EGkIntervals.h" - -using namespace std ; - -//---------------------------------------------------------------------------- -bool -VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const -{ - // per ora solo perpendicolari a XY (1) - if ( nDir != 1) - return false ; - // verifiche sugli indici - if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) - return false ; - int nPos = nPos1 + nPos2 * m_nNx ; - if ( nPos < 0 || nPos >= int( m_ZValues.size())) - return false ; - // calcolo coordinate punto - double dX = m_dStep * ( 0.5 + nPos1) ; - double dY = m_dStep * ( 0.5 + nPos2) ; - Point3d ptP = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; - // creo le polilinee - for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { - // aggiungo polilinea a lista - lstPL.emplace_back() ; - // inserisco punti estremi - lstPL.back().AddUPoint( 0, ptP + m_ZValues[nPos][i-1] * m_LocalFrame.VersZ()) ; - lstPL.back().AddUPoint( 1, ptP + m_ZValues[nPos][i] * m_LocalFrame.VersZ()) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const -{ - const int MAX_DIM_CHUNK = 128 ; - for ( int i = 0 ; i < int( m_nNx) ; i += MAX_DIM_CHUNK) { - int nDimChunkX = min( MAX_DIM_CHUNK, int( m_nNx) - i) ; - for ( int j = 0 ; j < int( m_nNy) ; j += MAX_DIM_CHUNK) { - int nDimChunkY = min( MAX_DIM_CHUNK, int( m_nNy) - j) ; - GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, MAX_DIM_CHUNK, lstTria) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, int nDimChk, TRIA3DLIST& lstTria) const -{ - // determino se è un semplice parallelepipedo - bool bIsSimple = true ; - double dBotZ ; - double dTopZ ; - for ( int i = 0 ; i < nDim1 && bIsSimple ; ++ i) { - for ( int j = 0 ; j < nDim2 && bIsSimple ; ++ j) { - int nPos = ( nPos1 + i) + ( nPos2 + j) * m_nNx ; - if ( nPos > int( m_nDim) || - int( m_ZValues[nPos].size()) != 2) - bIsSimple = false ; - else if ( i == 0 && j == 0) { - dBotZ = m_ZValues[nPos][0] ; - dTopZ = m_ZValues[nPos][1] ; - } - else if ( abs( m_ZValues[nPos][0] - dBotZ) > EPS_SMALL || - abs( m_ZValues[nPos][1] - dTopZ) > EPS_SMALL) - bIsSimple = false ; - } - } - - // se semplice parallelepipedo - if ( bIsSimple) { - CalcChunkPrisms( nPos1, nPos2, nDim1, nDim2, lstTria) ; - } - // se chunk di dimensioni accettabili - else if ( nDimChk >= 4) { - int nNewDimChk = nDimChk / 2 ; - for ( int i = nPos1 ; i < int( nPos1 + nDim1) ; i += nNewDimChk) { - int nDimChunkX = min( nNewDimChk, int( nPos1 + nDim1) - i) ; - for ( int j = nPos2 ; j < int( nPos2 + nDim2) ; j += nNewDimChk) { - int nDimChunkY = min( nNewDimChk, int( nPos2 + nDim2) - j) ; - GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, nNewDimChk, lstTria) ; - } - } - } - // altrimenti - else { - // elaboro ogni singolo dexel - for ( int i = 0 ; i < nDim1 ; ++ i) { - for ( int j = 0 ; j < nDim2 ; ++ j) { - CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ; - } - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const -{ - // verifiche sugli indici - if ( nPos1 < 0 || nPos1 + nDim1 > int( m_nNx) || nPos2 < 0 || nPos2 + nDim2 > int( m_nNy)) - return false ; - int nPos = nPos1 + nPos2 * m_nNx ; - if ( nPos < 0 || nPos >= int( m_nDim)) - return false ; - - // calcolo coordinate punti - double dX = m_dStep * nPos1 ; - double dY = m_dStep * nPos2 ; - Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; - Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_LocalFrame.VersX() ; - Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_LocalFrame.VersY() ; - Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_LocalFrame.VersY() ; - - // creo le facce sopra e sotto - Vector3d vtDZt = m_ZValues[nPos][1] * m_LocalFrame.VersZ() ; - Vector3d vtDZb = m_ZValues[nPos][0] * m_LocalFrame.VersZ() ; - // faccia superiore P1t->P2t->P3t->P4t : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; - // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; - - // creo le facce laterali - for ( int j = 0 ; j < nDim2 ; ++ j) { - int nPosD = nPos + nDim1 - 1 + j * m_nNx ; - int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nNx - 1) ? nPosD + 1 : - 1) ; - Point3d ptP2D = ptP2 + j * m_dStep * m_LocalFrame.VersY() ; - Point3d ptP3D = ptP2D + m_dStep * m_LocalFrame.VersY() ; - AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; - } - for ( int i = 0 ; i < nDim1 ; ++ i) { - int nPosD = nPos + ( nDim2 - 1) * m_nNx + i ; - int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nNy - 1) ? nPosD + m_nNx : - 1) ; - Point3d ptP4D = ptP4 + i * m_dStep * m_LocalFrame.VersX() ; - Point3d ptP3D = ptP4D + m_dStep * m_LocalFrame.VersX() ; - AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; - } - for ( int j = 0 ; j < nDim2 ; ++ j) { - int nPosD = nPos + j * m_nNx ; - int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ; - Point3d ptP1D = ptP1 + j * m_dStep * m_LocalFrame.VersY() ; - Point3d ptP4D = ptP1D + m_dStep * m_LocalFrame.VersY() ; - AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; - } - for ( int i = 0 ; i < nDim1 ; ++ i) { - int nPosD = nPos + i ; - int nPosSud = ( nPos2 > 0 ? nPosD - m_nNx : - 1) ; - Point3d ptP1D = ptP1 + i * m_dStep * m_LocalFrame.VersX() ; - Point3d ptP2D = ptP1D + m_dStep * m_LocalFrame.VersX() ; - AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const -{ - // verifiche sugli indici - if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) - return false ; - int nPos = nPos1 + nPos2 * m_nNx ; - if ( nPos < 0 || nPos >= int( m_nDim)) - return false ; - - // calcolo coordinate punto - double dX = m_dStep * nPos1 ; - double dY = m_dStep * nPos2 ; - Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; - Point3d ptP2 = ptP1 + m_dStep * m_LocalFrame.VersX() ; - Point3d ptP3 = ptP2 + m_dStep * m_LocalFrame.VersY() ; - Point3d ptP4 = ptP1 + m_dStep * m_LocalFrame.VersY() ; - - // creo le facce sopra e sotto di ogni intervallo (sempre visibili) - for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { - Vector3d vtDZt = m_ZValues[nPos][i] * m_LocalFrame.VersZ() ; - Vector3d vtDZb = m_ZValues[nPos][i-1] * m_LocalFrame.VersZ() ; - // faccia superiore P1t->P2t->P3t->P4t : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; - // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile - lstTria.emplace_back() ; - lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; - } - - // creo le facce laterali - int nPosEst = ( nPos1 < int( m_nNx - 1) ? nPos + 1 : - 1) ; - AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; - int nPosNord = ( nPos2 < int( m_nNy - 1) ? nPos + m_nNx : - 1) ; - AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; - int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ; - AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; - int nPosSud = ( nPos2 > 0 ? nPos - m_nNx : - 1) ; - AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, - const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const -{ - Intervals intFace ; - for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) - intFace.Add( m_ZValues[nPos][i-1], m_ZValues[nPos][i]) ; - if ( nPosAdj > 0) { - for ( int i = 1 ; i < int( m_ZValues[nPosAdj].size()) ; i += 2) - intFace.Subtract( m_ZValues[nPosAdj][i-1], m_ZValues[nPosAdj][i]) ; - } - double dMin, dMax ; - bool bFound = intFace.GetFirst( dMin, dMax) ; - while ( bFound) { - Vector3d vtDZt = dMax * vtZ ; - Vector3d vtDZb = dMin * vtZ ; - lstTria.emplace_back() ; - lstTria.back().Set( ptP + vtDZb, ptQ + vtDZb, ptQ + vtDZt, vtNorm) ; - lstTria.emplace_back() ; - lstTria.back().Set( ptQ + vtDZt, ptP + vtDZt, ptP + vtDZb, vtNorm) ; - bFound = intFace.GetNext( dMin, dMax) ; - } - return true ; -} - diff --git a/VolZmapVolume.cpp b/VolZmapVolume.cpp deleted file mode 100644 index 4ff5fd9..0000000 --- a/VolZmapVolume.cpp +++ /dev/null @@ -1,8524 +0,0 @@ -//---------------------------------------------------------------------------- -// EgalTech 2015-2016 -//---------------------------------------------------------------------------- -// File : VolZmap.cpp Data : 22.01.15 Versione : 1.6a4 -// Contenuto : Implementazione della classe Volume Zmap (singola griglia) -// -// -// -// Modifiche : 22.01.15 DS Creazione modulo. -// -// -//---------------------------------------------------------------------------- - -//--------------------------- Include ---------------------------------------- -#include "stdafx.h" -#include "VolZmap.h" -#include "GeoConst.h" - -using namespace std ; - -//---------- Sottrazione intervalli ------------------------------------------ - -//---------------------------------------------------------------------------- -bool -VolZmap::SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) -{ - // Controllo che dMin e dMax non siano quasi coincidenti - if ( abs( dMax - dMin) < EPS_SMALL) - return true ; - - // Controllo che dMin < dMax - if ( dMax < dMin ) - swap( dMax, dMin) ; - - // Calcolo nPos dello spillone - unsigned int nPos = nJ * m_nNx + nI ; - - // Ciclo sugli intervalli dello spillone - bool bModified = false ; - unsigned int i = 0 ; - while ( i + 1 < m_ZValues[nPos].size()) { - - // Intervallo da sottrarre è tutto a sinistra di quello corrente, non vi è intersezione - if ( m_ZValues[nPos][i] > dMax - EPS_SMALL) { - ; - } - - // Intersezione - else if ( m_ZValues[nPos][i + 1] > dMax + EPS_SMALL) { - // L'intervallo corrente corrente viene limitato a sinistra - if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i] = dMax ; - } - // L'intervallo si divide in due intervalli - else { - bModified = true ; - m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; - - for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 3 ; -- j) - - m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ; - - m_ZValues[nPos][i + 1] = dMin ; - m_ZValues[nPos][i + 2] = dMax ; - - i = i + 2 ; - } - } - - else { - // L'intervallo corrente viene eliminato - if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { - bModified = true ; - for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j) - - m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ; - - m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ; - - i = i - 2 ; - } - // L'intervallo corrente viene limitato a destra - else if ( m_ZValues[nPos][i + 1] > dMin + EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i + 1] = dMin ; - } - // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione - else { - ; - } - } - - i = i + 2 ; - } - - // Se eseguita modifica, imposto ricalcolo della grafica - if ( bModified) - m_OGrMgr.Reset() ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::SubtractIntervals( const Point3d& ptP, double dMin, double dMax) -{ - // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) - Point3d ptPL = ptP ; - ptPL.ToLoc( m_LocalFrame) ; - - double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco - double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) - - dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; - dhMin = dZ + dMin ; dhMax = dZ + dMax ; - - // Cerco il punto della griglia più vicino (indice è l'intero appena più basso) - double integerPartX = floor( dX / m_dStep) ; - double integerPartY = floor( dY / m_dStep) ; - - unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. - unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 - - // Controllo se le coordinate x e y del punto dato siano all'interno della griglia: - // se sono dentro la griglia chiamo l'altra subtract - if ( dX < m_dStep * m_nNx && - dY < m_dStep * m_nNy && - dX >= 0 && dY >= 0) { - // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e - // si esce dai limiti dell vector e vi è errore runtime - return SubtractIntervals( i, j, dhMin, dhMax) ; - } - - // altrimenti non succede niente - return true ; -} - -//---------- Addizione intervalli -------------------------------------------- - -//---------------------------------------------------------------------------- -bool -VolZmap::AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) -{ - // Controllo che dMin e dMax non siano quasi coincidenti - if ( abs( dMax - dMin) < EPS_SMALL) - return true ; - - // Controllo che dMin < dMax - if ( dMax < dMin) - swap( dMax, dMin) ; - - // Calcolo nPos - unsigned int nPos = nJ * m_nNx + nI ; - - // Se spillone vuoto - if ( m_ZValues[nPos].size() == 0) { - - m_ZValues[nPos].resize( 2) ; - - m_ZValues[nPos][0] = dMin ; - m_ZValues[nPos][1] = dMax ; - - m_OGrMgr.Reset() ; - - return true ; - } - - // Ciclo sugli intervalli dello spillone - bool bModified = false ; - unsigned int i = 0 ; - while ( i + 1 < m_ZValues[nPos].size()) { - - // Eventuale aggiustamento di intervalli sovrapposti - if ( i > 0) { - if ( m_ZValues[nPos][i] < m_ZValues[nPos][i - 1] + EPS_SMALL) { - // Se l'intervallo corrente non è contenuto totalmente si esegue l'istruzione successiva - if ( m_ZValues[nPos][i - 1] < m_ZValues[nPos][i + 1] + EPS_SMALL) - - m_ZValues[nPos][i - 1] = m_ZValues[nPos][i + 1] ; - - for ( unsigned int j = i ; j < m_ZValues[nPos].size() - 2 ; ++ j) - m_ZValues[nPos][j] = m_ZValues[nPos][j + 2] ; - - m_ZValues[nPos].resize( m_ZValues[nPos].size() - 2) ; - - i = i - 2 ; - } - } - - // Caso in cui devo aggiungere un intervallo a sinistra dell'intervallo corrente - if ( m_ZValues[nPos][i] > dMax + EPS_SMALL) { - bModified = true ; - - m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; - - for ( size_t j = m_ZValues[nPos].size() - 1 ; j >= i + 2 ; -- j) - m_ZValues[nPos][j] = m_ZValues[nPos][j - 2] ; - - m_ZValues[nPos][i] = dMin ; - m_ZValues[nPos][i + 1] = dMax ; - - i = i + 2 ; - } - - // Casi d'intersezione: - else if ( m_ZValues[nPos][i + 1] > dMax - EPS_SMALL) { - // Se l'intervallo da aggiungere sconfina a sinistra modifico il minimo dell'intervalo corrente - if ( m_ZValues[nPos][i] > dMin - EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i] = dMin ; - } - } - - else { - // Se l'intervallo corrente è tutto contenuto nell'intervallo da aggungere modifico gli estremi - if ( m_ZValues[nPos][i] > dMin + EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i] = dMin ; - m_ZValues[nPos][i + 1] = dMax ; - } - // Se l'intervallo da aggiungere sconfina a destra modifico il massimo dell'intervallo corrente - else if ( m_ZValues[nPos][i + 1] > dMin - EPS_SMALL) { - bModified = true ; - m_ZValues[nPos][i + 1] = dMax ; - } - else { - // Aggiungo intervallo a destra dell'ultimo intervallo - if ( i == m_ZValues[nPos].size() - 2) { - bModified = true ; - m_ZValues[nPos].resize( m_ZValues[nPos].size() + 2) ; - - m_ZValues[nPos][i + 2] = dMin ; - m_ZValues[nPos][i + 3] = dMax ; - - i = i + 2 ; - } - } - } - - i = i + 2 ; - } - - // se eseguita modifica, imposto ricalcolo della grafica - if ( bModified) - m_OGrMgr.Reset() ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::AddIntervals( const Point3d& ptP, double dMin, double dMax) -{ - // ptP è espresso nel sistema locale e viene convertito in quello intrinseco (localFrame) - Point3d ptPL = ptP ; - ptPL.ToLoc( m_LocalFrame) ; - - double dX, dY, dZ ; // Coordinate di ptPL nel sistema intrinseco - double dhMin, dhMax ; // Altezze dMin e dMax RIESPRESSE nel sistema intrinseco (dMin e dMax sono altezze rispetto a ptP) - - dX = ptPL.x ; dY = ptPL.y ; dZ = ptPL.z ; - dhMin = dZ + dMin ; dhMax = dZ + dMax ; - - // Cerco il punto della griglia più vicino - double integerPartX = floor( dX / m_dStep) ; - double integerPartY = floor( dY / m_dStep) ; - - unsigned int i = static_cast (integerPartX) ; // Indici del punto di griglia più vicino. - unsigned int j = static_cast (integerPartY) ; // i = 0, 1, ..., m_Nx - 1 ; j = 0, 1, ..., m_Ny - 1 - - // Controllo se le coordinate x e y del punto dato siano all'interno della griglia: - // se sono dentro la griglia chiamo l'altra subtract - if ( dX < m_dStep*m_nNx && dY < m_dStep*m_nNy - && dX >= 0 && dY >= 0) { - // Mettendo > - qlc può sempre capitare un punto compreso fra - qlc e 0 e - // si esce dai limiti dell vector e vi è errore runtime - return AddIntervals( i, j, dhMin, dhMax) ; - } - - // altrimenti non succede niente - return false ; -} - -//---------- Volumi ---------------------------------------------------------- - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) -{ - // Controllo sull'effettiva esistenza del movimento - if ( AreSamePointApprox( ptPs, ptPe) && AreSameVectorApprox( vtDs, vtDe)) - return true ; - - // Porto i dati del movimento nel riferimento intrinseco; quest'operazione è necessaria perché - // viene chiamata la funzione di sottrazione che accetta come parametri gli indici, - // non quella che chiede il punto, nella quale viene eseguita la trasformazione di coordinate. - Point3d ptLs = ptPs ; ptLs.ToLoc( m_LocalFrame) ; - Point3d ptLe = ptPe ; ptLe.ToLoc( m_LocalFrame) ; - Vector3d vtLs = vtDs ; vtLs.ToLoc( m_LocalFrame) ; - Vector3d vtLe = vtDe ; vtLe.ToLoc( m_LocalFrame) ; - - // Normalizzo i vettori - if ( ! vtLs.Normalize() || ! vtLe.Normalize()) - return false ; - - // Direzione utensile costante - if ( AreSameVectorApprox( vtLs, vtLe)) { - - // Versori della direzione utensile diretti come Z - if ( vtLs.LenXY() < EPS_SMALL) { - - // Movimento diretto come direzione utensile - if ( AreSamePointXYApprox( ptLs, ptLe)) { - if ( m_nToolType == GenericTool) - return DrillZ( ptLs, ptLe, vtLs) ; - else - return DrillingZ( ptLs, ptLe, vtLs) ; - } - - // Movimento perpendicolare a direzione utensile - if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) { - if ( m_nToolType == 0) - return MillZ( ptLs, ptLe, vtLs) ; - else - return MillingPerpZ( ptLs, ptLe, vtLs) ; - } - - // Movimento generico - if ( m_nToolType == 0) - return MillZ( ptLs, ptLe, vtLs) ; - else - return MillingZ( ptLs, ptLe, vtLs) ; - } - - // Versori della direzione utensile nel piano XY - else if ( abs( vtLs.z) < EPS_SMALL) { - - Vector3d vtDir( vtLs.x, vtLs.y, 0) ; vtDir.Normalize() ; - - // Movimento con Z costante (con vettore movimento parallelo od ortogonale al versore dell'utensile) - if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) { - - Vector3d vtTest( ptLe.x - ptLs.x, ptLe.y - ptLs.y, 0) ; - Vector3d vtTLong = ( vtTest * vtDir) * vtDir ; - Vector3d vtTOrt = vtTest - vtTLong ; - - // Movimento parallelo alla direzione dell'utensile (foratura) - if ( vtTOrt.IsSmall()) { - if ( m_nToolType == 0) - return DrillingGT( ptLs, ptLe, vtDir) ; - else - return DrillingXY( ptLs, ptLe, vtDir) ; - } - - // Movimento perpendicolare alla direzione dell'utensile - if ( vtTLong.IsSmall()) { - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtDir) ; - else - return MillingPerpXY( ptLs, ptLe, vtDir) ; - } - - // Movimento nel piano generico - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtDir) ; - else - return MillingXYPlaneGen( ptLs, ptLe, vtDir) ; - } - - // Movimento con Z non costante - else { - - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtDir) ; - - // Movimento verticale - if ( AreSamePointXYApprox( ptLs, ptLe)) - return MillingXYVert( ptLs, ptLe, vtDir) ; - - // Grandezze geometriche per selezione - Vector3d vtMove = ptLe - ptLs ; - Vector3d vtTLong = ( vtMove * vtDir) * vtDir ; - Vector3d vtTOrt = vtMove - ( vtMove * vtDir) * vtDir ; - - // Movimento LongVert - if ( vtTOrt.IsSmallXY()) - return MillingXYLongVert( ptLs, ptLe, vtDir) ; - - // Movimento perpendicolare alla direzione dell'utensile - if ( vtTLong.IsSmallXY()) - return MillingXY( ptLs, ptLe, vtDir) ; - - // Movimento generico con versore direzione nel piano - return Milling( ptLs, ptLe, vtDir) ; - } - } - - // Caso generico - else { - - Vector3d vtMove = ptLe - ptLs ; - Vector3d vtOrt = vtMove - ( vtMove * vtLs) * vtLs ; - - // Drilling - if ( vtOrt.IsSmall()) { - if ( m_nToolType == GenericTool) - return DrillingGT( ptLs, ptLe, vtLs) ; - else - return Drilling( ptLs, ptLe, vtLs) ; - } - // Milling - else { - if ( m_nToolType == GenericTool) - return MillingGT( ptLs, ptLe, vtLs) ; - else - return Milling( ptLs, ptLe, vtLs) ; - } - } - } - - // Altri casi, non gestiti - return false ; -} - -// Versore utensile parallelo all'asse Z -//---------------------------------------------------------------------------- -bool -VolZmap::DrillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Cilindro sfera toro - if ( m_nToolType == CylindricalMill || m_nToolType == BallEndMill || - m_nToolType == BullNoseMill) - - return CBTDrillZ( ptLs, ptLe, vtToolDir) ; - // Coni - else if ( m_nToolType == ConusMill) - - return ConusDrillingZ( ptLs, ptLe, vtToolDir) ; - - else - - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CBTDrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; - double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; - double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ; - double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ; - - // Verifico interferisca con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Determino i limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Determino quote estreme del tagliente - double dMax = ptLs.z - m_dHeight ; // Volendo si può effettuare un controllo su quota punto finale e iniziale, - double dMin = ptLe.z - m_dHeight ; // ma non è necessaria dal momento che Subtract intervals scambia min con max se max < min - double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale - double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente - - // Limite sul quadrato del raggio - double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ; - - // Ciclo sui punti nei limiti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - double dX = ( i + 0.5) * m_dStep ; - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - double dY = ( j + 0.5) * m_dStep ; - // punto - Point3d ptQ( dX, dY, 0) ; - // determino il quadrato della distanza - double dSqDist = SqDistXY( ptQ, ptLe) ; - // se distanza nei limiti, taglio - if ( dSqDist < dSqRad) - GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusDrillingZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) { - - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = ptLs.x - dMaxRad ; - double dMaxX = ptLs.x + dMaxRad ; - double dMinY = ptLs.y - dMaxRad ; - double dMaxY = ptLs.y + dMaxRad ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - double dDeltaZ = abs( ptLe.z - ptLs.z) ; - - Point3d ptO( ptLs.x, ptLs.y, 0) ; - - // Limiti su indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - - if ( m_dRadius < m_dTipRadius) - // Coda di rondine - return GetMinMaxZSw( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ; - // Punta di trapano - else - return GetMinMaxZDr( ptO, nStartI, nEndI, nStartJ, nEndJ, dMinZ, dMaxZ, dMinRad, dMaxRad, vtToolDir.z, dDeltaZ) ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxZSw( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, - unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, - double dMinRad, double dMaxRad, double dDir, double dDeltaZ) -{ - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - // Determinazione della posizione xy del dexel rispetto - // all'asse di simmetria dell'utensile - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptO ; - - double dSqDist = vtC * vtC ; - - // Se il dexel cade nel cerchio di interesse taglio - if ( dSqDist < dMaxRad * dMaxRad) { - - double dMin, dMax ; - - if ( dSqDist < dMinRad * dMinRad) { - dMin = dMinZ ; - dMax = dMaxZ ; - } - - else { - double dR = sqrt( dSqDist) ; - if ( dDir > 0) { - dMin = dMinZ ; - dMax = dMinZ + dDeltaZ + ( m_dTipHeight * ( dMaxRad - dR)) / ( dMaxRad - dMinRad) ; - } - else { - dMin = dMaxZ - dDeltaZ + ( m_dTipHeight * ( dR - dMaxRad)) / ( dMaxRad - dMinRad) ; - dMax = dMaxZ ; - } - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxZDr( const Point3d ptO, unsigned int nStartI, unsigned int nEndI, - unsigned int nStartJ, unsigned int nEndJ, double dMinZ, double dMaxZ, - double dMinRad, double dMaxRad, double dDir, double dDeltaZ) -{ - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptO ; - - double dSqDist = vtC * vtC ; - - // Se il dexel cade nel cerchio di interesse taglio - if ( dSqDist < dMaxRad * dMaxRad) { - - double dMin, dMax ; - - if ( dSqDist < dMinRad * dMinRad) { - dMin = dMinZ ; - dMax = dMaxZ ; - } - - else { - double dR = sqrt( dSqDist) ; - if ( dDir > 0) { - dMin = dMinZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMaxRad - dMinRad) ; - dMax = dMaxZ ; - } - else { - dMin = dMinZ ; - dMax = dMaxZ + ( m_dTipHeight * ( dR - dMinRad)) / ( dMinRad - dMaxRad) ; - } - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - // Cilindro sfera toro - if ( m_nToolType == CylindricalMill || - m_nToolType == BallEndMill || - m_nToolType == BullNoseMill) - - return CBTMillingPerpZ( ptLs, ptLe, vtToolDir) ; - // Coni - else if ( m_nToolType == ConusMill) - - return ConusPerpZ( ptLs, ptLe, vtToolDir) ; - - else - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CBTMillingPerpZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; - double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; - double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ; - double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ; - - // Verifico interferisca con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Determino i limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Determino quote estreme del tagliente - double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale - double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente - - // Limite sul quadrato del raggio - double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ; - - // Segmento di movimento (nel piano griglia) - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Point3d ptEnd( ptLe.x, ptLe.y, 0) ; - double dLen ; - Vector3d vtDir ; - DirDist( ptStart, ptEnd, vtDir, dLen) ; - - // Ciclo sui punti nei limiti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - double dX = ( i + 0.5) * m_dStep ; - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - double dY = ( j + 0.5) * m_dStep ; - // punto - Point3d ptQ( dX, dY, 0) ; - // determino il quadrato della distanza del punto dal segmento - double dProiez = vtDir * ( ptQ - ptStart) ; - if ( dProiez < 0) - dProiez = 0 ; - else if ( dProiez > dLen) - dProiez = dLen ; - Point3d ptMinDist = ptStart + vtDir * dProiez ; - double dSqDist = SqDistXY( ptQ, ptMinDist) ; - // se distanza nei limiti, taglio - if ( dSqDist < dSqRad) - GetMinMaxZ( i, j, dZCutBase, dDeltaZ, dSqDist, vtToolDir) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusPerpZ( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) -{ - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; - double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; - double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; - double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; // Ricordati del caso balordo da mettere nella documentazione - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - Point3d ptO( ptLs.x, ptLs.y, 0) ; - Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; - Vector3d vtV1 = vtMove ; vtV1.Normalize() ; - - double dZBase = ptLs.z ; - double dZStem = ptLs.z - ( m_dHeight - m_dTipHeight) * vtToolDir.z ; - double dZTip = ptLs.z - m_dHeight * vtToolDir.z ; - - // Limiti su indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; - - double dProj1 = vtC * vtV1 ; - Vector3d vtOrt = vtC - dProj1 * vtV1 ; - - if ( dProj1 < 0) { - - double dSqDist = vtC * vtC ; - - if ( dSqDist < dMinRad * dMinRad) { - - dMin = min( dZBase, dZTip) ; - dMax = max( dZBase, dZTip) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { - - double dr = sqrt( dSqDist) ; - - if ( m_dRadius < m_dTipRadius) { - - dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - } - else { - dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - else if ( dProj1 >= 0 && dProj1 < dLen) { - - double dSqDist = vtOrt * vtOrt ; - - if ( dSqDist < dMinRad * dMinRad) { - - dMin = min( dZBase, dZTip) ; - dMax = max( dZBase, dZTip) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { - - double dr = sqrt( dSqDist) ; - - if ( m_dRadius < m_dTipRadius) { - dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - } - - else { - dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - else if ( dProj1 >= dLen) { - - Vector3d vtCn = vtC - vtMove ; - - double dSqDist = vtCn * vtCn ; - - if ( dSqDist < dMinRad * dMinRad) { - dMin = min( dZBase, dZTip) ; - dMax = max( dZBase, dZTip) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - else if ( dSqDist >= dMinRad * dMinRad && dSqDist < dMaxRad * dMaxRad) { - - double dr = sqrt( dSqDist) ; - - if ( m_dRadius < m_dTipRadius) { - dMin = min( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - dMax = max( dZTip, dZStem + ( dr - dMinRad) * ( dZTip - dZStem) / ( dMaxRad - dMinRad)) ; - } - - else { - dMin = min( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - dMax = max( dZBase, dZTip + ( dr - dMinRad) * ( dZStem - dZTip) / ( dMaxRad - dMinRad)) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxZ( unsigned int nI, unsigned int nJ, double dZCutBase, - double dDeltaZ, double dSqDist, const Vector3d& vtToolDir) -{ - // Definisco variabili - double dSqRad = m_dRadius * m_dRadius ; - double dFactor = ( vtToolDir.z < 0 ? - 1 : 1) ; - double dZtip = ( vtToolDir.z < 0 ? dZCutBase + m_dHeight : dZCutBase - m_dHeight) ; - - // Caso utensile generico al momento non gestito - if ( m_nToolType == 0) - return false ; - - // Caso Cylindrical Mill - else if ( m_nToolType == 1) { - double dMin, dMax ; - - if ( abs(vtToolDir.z * dDeltaZ) < EPS_SMALL) { // Non è meglio fare if (vt * delta < - Eps_small ) else if ( vt * delta < Eps) else ? - dMin = min(dZCutBase, dZtip) ; - dMax = max(dZCutBase, dZtip) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min(dZtip, dZtip + dDeltaZ) ; - dMax = max(dZtip, dZtip + dDeltaZ) ; - } - else { - dMin = min(dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max(dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - - // Caso Ball-End Mill - else if ( m_nToolType == 2) { - double dMin, dMax ; - - double dH = sqrt( dSqRad - dSqDist) ; - - if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ; - dMax = max( dZCutBase, dZtip + dFactor*( m_dRadius - dH)) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min( dZtip + dFactor*( m_dRadius - dH), - dZtip + dFactor*( m_dRadius - dH) + dDeltaZ) ;// ocio - dMax = max( dZtip + dFactor*( m_dRadius - dH), - dZtip + dFactor*( m_dRadius - dH) + dDeltaZ) ;// ocio - } - else { - dMin = min( dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max( dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - - // Caso Bull-Nose Mill - else if ( m_nToolType == 3) { - - double dDeltaR = m_dRadius - m_dRCorner ; - - if ( dSqDist < dDeltaR*dDeltaR) { - - double dMin, dMax ; - - if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min( dZCutBase, dZtip) ; - dMax = max( dZCutBase, dZtip) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min( dZtip, dZtip + dDeltaZ) ; - dMax = max( dZtip, dZtip + dDeltaZ) ; - } - else { - dMin = min( dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max( dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - - else { - - double dSqRadC = m_dRCorner * m_dRCorner ; - double dSqd = dSqDist + dDeltaR * dDeltaR - 2 * sqrt( dSqDist) * dDeltaR ; - double dSqrt = sqrt(dSqRadC - dSqd) ; - - double dMin, dMax ; - if ( abs( vtToolDir.z * dDeltaZ) < EPS_SMALL) { - dMin = min( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ; - dMax = max( dZCutBase, dZtip + dFactor*( m_dRCorner - dSqrt)) ; - } - else if ( vtToolDir.z * dDeltaZ < 0) { - dMin = min( dZtip + dFactor *( m_dRCorner - dSqrt), - dZtip + dFactor *( m_dRCorner - dSqrt) + dDeltaZ) ; - dMax = max( dZtip + dFactor *( m_dRCorner - dSqrt), - dZtip + dFactor *( m_dRCorner - dSqrt) + dDeltaZ) ; - } - else { - dMin = min( dZCutBase, dZCutBase + dDeltaZ) ; - dMax = max( dZCutBase, dZCutBase + dDeltaZ) ; - } - return SubtractIntervals( nI, nJ, dMin, dMax) ; - } - } - - // Caso di utensile inesistente ( m_nToolType fuori dai valori concessi) - else - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - - if ( m_nToolType == 1 || m_nToolType == 2) - - return CBMillingZ( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == 3) - - return false ; - - else if ( m_nToolType == 4) { - - if ( m_dRadius > m_dTipRadius) - return ConusMillingZDr( ptLs, ptLe, vtToolDir) ; - else - return ConusMillingZSw( ptLs, ptLe, vtToolDir) ; - } - - else - return true ; // forse ci va il nuovo -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CBMillingZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Setto il fattore per l'orientazione in z - double dFactor = ( vtToolDir.z < 0 ? 1 : - 1) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - m_dRadius ; - double dMaxX = max( ptLs.x, ptLe.x) + m_dRadius ; - double dMinY = min( ptLs.y, ptLe.y) - m_dRadius ; - double dMaxY = max( ptLs.y, ptLe.y) + m_dRadius ; - double dMinZ = min( min( ptLs.z, ptLs.z + dFactor * m_dHeight), - min( ptLe.z, ptLe.z + dFactor * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z + dFactor * m_dHeight), - max( ptLe.z, ptLe.z + dFactor * m_dHeight)) ; - - // Verifico interferisca con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - // Determino i limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - // - double dZCutBase = ptLs.z ; // Quota della base del tagliente nella posizione iniziale - double dDeltaZ = ptLe.z - ptLs.z ; // Differenza delle quote fra le posizioni finale e iniziale della base del tagliente - - // Limite sul quadrato del raggio - double dSqRad = ( m_dRadius + EPS_SMALL) * ( m_dRadius + EPS_SMALL) ; - - // Segmento di movimento (nel piano griglia) - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Point3d ptEnd( ptLe.x, ptLe.y, 0) ; - double dLen ; - Vector3d vtDir ; - DirDist( ptStart, ptEnd, vtDir, dLen) ; - - // Ciclo sui punti nei limiti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - double dX = ( i + 0.5) * m_dStep ; - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - double dY = ( j + 0.5) * m_dStep ; - // punto - Point3d ptQ( dX, dY, 0) ; - // determino il quadrato della distanza del punto dal segmento - double dProj = vtDir * ( ptQ - ptStart) ; - double dProiez ; - - if ( dProj < 0) - dProiez = 0 ; - else if ( dProj < dLen) - dProiez = dProj ; - else - dProiez = dLen ; - - Point3d ptMinDist = ptStart + vtDir * dProiez ; - double dSqDist = SqDistXY( ptQ, ptMinDist) ; - - // se distanza nei limiti, taglio - if ( dSqDist < dSqRad) - GetMinMaxZGen( i, j, dProj, dSqDist, dLen, dZCutBase, dDeltaZ, vtToolDir) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusMillingZDr( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) -{ - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; - double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; - double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; - double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Punti iniziale e finale e proiezione sul piano del punto iniziale - Point3d ptI, ptF, ptO ; - - if ( vtToolDir.z > 0) { - ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - } - else { - ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - } - - // Quote iniziale e finale della base dell'utensile e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - // Vettori di movimento - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; - - // Sistema di riferimento sul cono e vertice del cono - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Point3d ptV = ptI - ( m_dHeight + m_dTipHeight * dMinRad / ( dMaxRad - dMinRad)) * vtV1 ; - - // Apertura del cono e parametri per determinare i piani - double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTanAlpha * dRatio ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 + - ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 - - ( dSin / dDen) * vtV3 ; - - Vector3d vtR0 = ptV - ORIG ; - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - // Limiti su indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - // Grandezze per determinare la configurazione geometrica dell'utensile - double dMin, dMax ; - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptO ; - Vector3d vtCf = vtC - vtMoveXY ; - - Vector3d vtUC = vtC ; vtUC.Normalize() ; - Vector3d vtUCf = vtCf ; vtUCf.Normalize() ; - - double dCCos = vtUC * vtV2 ; - double dCCosf = vtUCf * vtV2 ; - - double dProj = vtC * vtV2 ; - Vector3d vtOrt = vtC - dProj * vtV2 ; - - double dSqDistI = vtC * vtC ; - double dSqDistM = vtOrt * vtOrt ; - double dSqDistF = vtCf * vtCf ; - - // Se dentro la zona interessata dalla lavorazione valuto - // la tipologia di tale zona - if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || - ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || - ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { - - // Caso vettore utensile equiverso all'asse Z - if ( vtToolDir.z > 0) { - // Massimi - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - if ( dProj < dLen - dPMaxI) - - dMax = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxI) ; - else - dMax = dZF ; - - // Minimi - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZI - m_dHeight ; - - else { - - if ( ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMin = dZI - m_dHeight + ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - else - dMin = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMin = dZI - m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMin = dZF - m_dHeight + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - - dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - else { - - if ( dSqDistI < dMaxRad * dMaxRad) - - dMin = dZI - m_dHeight + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) - - dMin = dZI - m_dHeight + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - } - // Caso vettore utensile opposto all'asse Z - else { - // Massimi - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZI + m_dHeight ; - - else { - - if ( - ( vtMove * vtV1) / ( vtMove * vtV2) <= 1 / dTanAlpha) { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMax = dZI + m_dHeight - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMax = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - else - dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMax = dZI + m_dHeight + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMax = dZF + m_dHeight - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - - dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - else { - - if ( dSqDistI < dMaxRad * dMaxRad) - - dMax = dZI + m_dHeight - ( ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - - else if ( dProj >= dPMaxI && dProj < dPMaxI + dLen) - - dMax = dZI + m_dHeight - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - } - // Minimi - double dPMaxCirc = sqrt( dMaxRad * dMaxRad - dSqDistM) ; - - if ( dProj > dLen - dPMaxCirc) - dMin = dZF ; - else - dMin = dZI + ( dDeltaZ / dLen) * ( dProj + dPMaxCirc) ; - } - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusMillingZSw( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) -{ - double dMinZ = min( min( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - min( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - double dMaxZ = max( max( ptLs.z, ptLs.z - vtToolDir.z * m_dHeight), - max( ptLe.z, ptLe.z - vtToolDir.z * m_dHeight)) ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dMinRad = min( m_dRadius, m_dTipRadius) ; - - // Bounding box - double dMinX = min( ptLs.x, ptLe.x) - dMaxRad ; - double dMaxX = max( ptLs.x, ptLe.x) + dMaxRad ; - double dMinY = min( ptLs.y, ptLe.y) - dMaxRad ; - double dMaxY = max( ptLs.y, ptLe.y) + dMaxRad ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Punti iniziale e finale e proiezione sul piano del punto iniziale - Point3d ptI, ptF, ptO ; - - if ( vtToolDir.z > 0) { - - ptI = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - } - - else { - ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; ptO.x = ptI.x ; ptO.y = ptI.y ; ptO.z = 0 ; - ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - } - - Point3d ptICyl = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - - double dDeltaH = m_dHeight - m_dTipHeight ; - double dMinZCyl = min( ptICyl.z, ptICyl.z - vtToolDir.z * dDeltaH) ; - - // Punti contatto cono cilindro - Point3d ptIS = ptI - ( m_dHeight - m_dTipHeight) * vtToolDir ; - Point3d ptFS = ptF - ( m_dHeight - m_dTipHeight) * vtToolDir ; - - // Quote iniziali e finali e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; - double dDeltaZ = dZF - dZI ; double dADeltaZ = abs( dDeltaZ) ; - double dZIS = ptIS.z ; double dZFS = ptFS.z ; - - // Vettori di movimento - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dLen = vtMoveXY.LenXY() ; - - // Sistema di riferimento sul cono e vertice del cono - Vector3d vtV1 = - vtToolDir ; - Vector3d vtV2 = vtMoveXY ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Point3d ptV = ptI + ( m_dHeight - m_dTipHeight * ( 1 + dMinRad / ( dMaxRad - dMinRad))) * vtV1 ; - - // Apertura del cono e parametri per determinare i piani - double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTanAlpha * dRatio ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1- dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNp = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 + - ( dSin / dDen) * vtV3 ; - Vector3d vtNm = - ( dTanAlpha / dDen) * vtV1 + - ( dCos / dDen) * vtV2 - - ( dSin / dDen) * vtV3 ; - - Vector3d vtR0 = ptV - ORIG ; - double dDotp = vtR0 * vtNp ; - double dDotm = vtR0 * vtNm ; - - // Limiti su indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++j) { - - double dMin, dMax ; - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; Vector3d vtCf = vtC - vtMoveXY ; - - Vector3d vtUC = vtC ; Vector3d vtUCf = vtCf ; vtUC.Normalize() ; vtUCf.Normalize() ; - - double dCCos = vtUC * vtV2 ; double dCCosf = vtUCf * vtV2 ; - - double dProj = vtC * vtV2 ; - Vector3d vtOrt = vtC - dProj * vtV2 ; - - double dSqDistI = vtC * vtC ; - double dSqDistM = vtOrt * vtOrt ; - double dSqDistF = vtCf * vtCf ; - - if ( ( dProj < 0 && dSqDistI < dMaxRad * dMaxRad) || - ( dProj >= 0 && dProj < dLen && dSqDistM < dMaxRad * dMaxRad) || - ( dProj >= dLen && dSqDistF < dMaxRad * dMaxRad)) { - // Caso vettore utensile equiverso all'asse Z - if ( vtV1.z < 0) { - - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - // Massimi - if ( dRatio <= 1 / dTanAlpha) { - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZIS ; - - else { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMax = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; - else - dMax = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMax = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMax = dZFS - ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - else { - - if ( dSqDistI < dMinRad * dMinRad) - - dMax = dZIS ; - - else if ( dSqDistI < dMaxRad * dMaxRad) - - dMax = dZIS - ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else { - - if ( dProj >= dPMaxI) - - dMax = dZIS - m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - // Minimi - - if ( dSqDistF < dMaxRad * dMaxRad) - - dMin = dZFS - m_dTipHeight ; - - else if ( dProj <= dLen - dPMaxI) - - dMin = dZIS - m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; - - } - // Caso vettore utensile opposto all'asse Z - else { - - double dPMaxI = ( dMaxRad * dMaxRad - dSqDistM > 0 ? sqrt( dMaxRad * dMaxRad - dSqDistM) : 0) ; - - // Massimi - if ( dSqDistF < dMaxRad * dMaxRad) - - dMax = dZFS + m_dTipHeight ; - - else if ( dProj <= dLen - dPMaxI) - - dMax = dZIS + m_dTipHeight + ( dProj + dPMaxI) * dDeltaZ / dLen ; - - // Minimi - if ( dRatio <= 1 / dTanAlpha) { - - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZIS ; - - else { - - if ( dSqDistI < dMaxRad * dMaxRad && dCCos < dCos) - - dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else if ( dCCos >= dCos && dCCosf < dCos && dSqDistM < dMaxRad * dMaxRad * ( 1 - dCos * dCos)) { - - double dMinSql = dMinRad * dMinRad * ( 1 - dCos * dCos) ; - double dMaxSql = dMaxRad * dMaxRad * ( 1 - dCos * dCos) ; - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistM <= dMinSql) - - dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - - else if ( dSqDistM < dMaxSql) { - - if ( vtC * vtV3 > 0) - - dMin = ( dDotp - dX * vtNp.x - dY * vtNp.y) / vtNp.z ; - else - dMin = ( dDotm - dX * vtNm.x - dY * vtNm.y) / vtNm.z ; - } - } - else if ( dCCosf >= dCos) { - - double dPMinI = ( dMinRad * dMinRad - dSqDistM > 0 ? sqrt( dMinRad * dMinRad - dSqDistM) : 0) ; - - if ( dSqDistF < dMinRad * dMinRad) - - dMin = dZIS + ( dProj - dPMinI) * dDeltaZ / dLen ; - else - dMin = dZFS + ( ( sqrt( dSqDistF) - dMinRad) * m_dTipHeight) / ( dMaxRad - dMinRad) ; - } - else - dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - } - } - else { - - if ( dSqDistI < dMinRad * dMinRad) - - dMin = dZIS ; - - else if ( dSqDistI < dMaxRad * dMaxRad) - - dMin = dZIS + ( sqrt( dSqDistI) - dMinRad) * m_dTipHeight / ( dMaxRad - dMinRad) ; - - else - - dMin = dZIS + m_dTipHeight + ( dProj - dPMaxI) * dDeltaZ / dLen ; - - } - } - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Parte cilindrica - Vector3d vtCyl = ( vtV1.z < 0 ? vtCf : vtC) ; - Vector3d vtCylf = ( vtV1.z < 0 ? vtC : vtCf) ; - Vector3d vtMot = ( vtV1.z < 0 ? - vtV2 : vtV2) ; - - double dCylProj = vtCyl * vtMot ; - double dCylSqDistI = vtCyl * vtCyl ; - double dCylSqDistF = vtCylf * vtCylf ; - double dCylSqDistM = ( vtCyl - dCylProj * vtMot) * ( vtCyl - dCylProj * vtMot) ; - - - if ( dCylSqDistI < dMinRad * dMinRad - || dCylSqDistF < dMinRad * dMinRad - || ( dCylProj > 0 && dCylProj < dLen && dCylSqDistM < dMinRad * dMinRad)) { - - double dSt = sqrt( dMinRad * dMinRad - dCylSqDistM) ; - - // Minimi - if ( dCylSqDistI < dMinRad * dMinRad ) - - dMin = dMinZCyl ; - - else if ( dCylProj >= dSt) - - dMin = dMinZCyl + ( dCylProj - dSt) * dADeltaZ / dLen ; - - // Massimi - if ( dCylSqDistF < dMinRad * dMinRad) - - dMax = dMinZCyl + dDeltaH + dADeltaZ ; - - else if ( dCylProj <= dLen - dSt) - - dMax = dMinZCyl + dDeltaH + ( dCylProj + dSt) * dADeltaZ / dLen ; - - SubtractIntervals( i, j, dMin, dMax) ; - - } - } - } - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxZGen( unsigned int nI, unsigned int nJ, double dProj, double dSqd, - double dLenPath, double dZheight, double dDelta, const Vector3d& vtToolDir) -{ - // Controllo sul tipo di utensile: se 0 utensile generico (al momento non gestito) se maggiore di 3 utensile fuori dai tipi consentiti - if ( m_nToolType == 0 || m_nToolType > 3) - return false ; - - // Definisco variabili quota della punta, minimo e massimo dell'intervallo da sottrarre - double dZTip = ( vtToolDir.z < 0 ? dZheight + m_dHeight : dZheight - m_dHeight) ; - double dMin, dMax ; double dStart ; // dStart è un parametro che esprime l'ascissa in cui la retta congiungente le due posizioni iniziale e finale - double dRSqDist1, dRSqDist2 ; // di un punto del tagliente (nel sistema dell'asse dell'utensile nella posizione iniziale) assume la quota dZheight - - // Nei conti è comodo che dSqd assuma sempre il significato di distanza del punto dall'asse del movimento al quadrato - if ( dProj < 0) - dSqd = dSqd - dProj * dProj ; - else if ( dProj > dLenPath) - dSqd = dSqd - ( dProj - dLenPath) * ( dProj - dLenPath) ; - - // Caso di cylindrical mill - if ( m_nToolType == 1) { - - double dZ1, dZ2 ; - // Se lavora la punta - if ( vtToolDir.z * dDelta < 0) { - dZ1 = dZTip ; - dZ2 = dZheight ; - } - // Se lavora il fondo - else { - dZ1 = dZheight ; - dZ2 = dZTip ; - } - - dStart = sqrt( m_dRadius * m_dRadius - dSqd) ; - dRSqDist1 = dProj * dProj + dSqd ; - dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ; - - if ( dRSqDist1 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) { - - dMin = min( max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ; - dMax = max( min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ1 + dDelta), dZ2) ; - } - else if ( dRSqDist2 < (m_dRadius + EPS_SMALL) * (m_dRadius + EPS_SMALL)) { - - dMin = min( min(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ; - dMax = max( max(dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath, dZ2 + dDelta), dZ1 + dDelta) ; - } - else { - - dMin = min( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ; - dMax = max( dZ1 + ( dDelta * ( dProj + dStart)) / dLenPath, dZ2 + ( dDelta * ( dProj - dStart)) / dLenPath) ; - } - } - - // Caso di ball-end mill - else if ( m_nToolType == 2) { - - if ( dDelta < 0) { - dDelta = - dDelta ; - dProj = dLenPath - dProj ; - dZheight = dZheight - dDelta ; - dZTip = dZTip - dDelta ; - } - - dStart = sqrt( m_dRadius * m_dRadius - dSqd) ; - dRSqDist1 = dProj * dProj + dSqd ; - dRSqDist2 = ( dLenPath - dProj) * ( dLenPath - dProj) + dSqd ; - - if ( vtToolDir.z > 0) { - - // Semi-asse ellisse - double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ; - - if ( dRSqDist2 < m_dRadius * m_dRadius) { - - dMax = dZheight + dDelta ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj - dLenPath > dSemiAxMin * dTest) { - - double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMin = dZTip + m_dRadius + dDelta - dH ; - } - else if ( dProj > dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ; - - dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ; - } - else { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMin = dZTip + m_dRadius - dH ; - } - } - else { - - dMax = dZheight + ( dDelta * ( dProj + dStart)) / dLenPath ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj > dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dLenPath + dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : dLenPath) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( ( dPr0 - dLenPath) * dPar) / dSemiAxMin ; - - dMin = dZTip + dDelta + m_dRadius - dZ0 + ( dDelta / dLenPath) * ( dProj - dPr0) ; - } - else { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - - dMin = dZTip + m_dRadius - dH ; - } - } - } - - else { - - // Semi-asse ellisse - double dSemiAxMin = m_dRadius * sqrt( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dSqrSemiAxMin = m_dRadius * m_dRadius * ( 1 - dLenPath * dLenPath / ( dLenPath * dLenPath + dDelta * dDelta)) ; - double dXD2 = ( dProj - dLenPath) * ( dProj - dLenPath) ; - - if ( dRSqDist1 < m_dRadius * m_dRadius) { - - dMin = dZheight ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj < - dSemiAxMin * dTest) { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - - dMax = dZTip - m_dRadius + dH ; - } - else if ( dProj - dLenPath < - dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( dPr0 * dPar) / dSemiAxMin ; - - dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ; - } - else { - - double dSqrRad = dProj * dProj + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMax = dZTip - m_dRadius + dDelta + dH ; - } - } - else { - - dMin = dZheight + ( dDelta * ( dProj - dStart)) / dLenPath ; - - double dTest = ( 1 - dSqd / ( m_dRadius * m_dRadius) > 0 ? sqrt( 1 - dSqd / ( m_dRadius * m_dRadius)) : 0) ; - - if ( dProj - dLenPath < - dSemiAxMin * dTest) { - // Determino l'altezza del punto sull'ellisse da cui passa la retta - double dPr0 = ( ( 1 - dSqd / ( m_dRadius * m_dRadius)) > 0 ? dSemiAxMin * sqrt( ( 1 - dSqd / (m_dRadius * m_dRadius))) : 0) ; - double dPar = ( m_dRadius * m_dRadius - dSqrSemiAxMin > 0 ? sqrt( m_dRadius * m_dRadius - dSqrSemiAxMin) : 0) ; - double dZ0 = ( dPr0 * dPar) / dSemiAxMin ; - - dMax = dZTip - m_dRadius + dZ0 + ( dDelta / dLenPath) * ( dProj + dPr0) ; - } - else { - - double dSqrRad = ( dProj - dLenPath) * ( dProj - dLenPath) + dSqd ; - double dH = ( m_dRadius * m_dRadius - dSqrRad > 0 ? sqrt( m_dRadius * m_dRadius - dSqrRad) : 0) ; - dMax = dZTip + dDelta - m_dRadius + dH ; - } - } - } - } - // Caso di bull-nose mill - else - return true ; - - return SubtractIntervals( nI, nJ, dMin, dMax) ; -} - - -// Versore utensile nel piano XY - -// DeltaZ = 0 - -//---------------------------------------------------------------------------- -bool -VolZmap::DrillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - - if ( m_nToolType == CylindricalMill || - m_nToolType == BallEndMill || - m_nToolType == BullNoseMill) - - return CBTDrillXY( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == ConusMill) - - return ConusDrillingXY( ptLs, ptLe, vtToolDir) ; - - else - - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CBTDrillXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - if ( m_nToolType == ConusMill) - return ConusDrillingXY( ptLs, ptLe, vtToolDir) ; - - // Punti per la determinazione del materiale asportato - Vector3d vtMove = ptLe - ptLs ; - // Punti di riferimento dell'asportazione - Point3d ptLNs ; - Point3d ptLNe ; - // Parametro relativo all'utensile altezza della parte non cilindrica e fattore determinante - // la lunghezza della parte lavorata a seconda che lavori la punta o il fondo - double dCylH ; double dFactor ; - - // Caso utensile generico (al momento non gestito) - if ( m_nToolType == 0) - return false ; - // Caso Cylindrical Mill - else if ( m_nToolType == 1) - dCylH = m_dHeight ; - // Caso Ball-end Mill - else if ( m_nToolType == 2) - dCylH = m_dHeight - m_dRadius ; - // Caso Bull-nose Mill - else if ( m_nToolType == 3) - dCylH = m_dHeight - m_dRCorner ; - - // Normalizzo tale vettore e ne determino la lunghezza: - double dLenPath = vtMove.Len() ; vtMove.Normalize() ; - - // Prodotto scalare fra versore direzione utensile e direzione movimento - double dScProd = vtMove * vtToolDir ; - // Se lavora la punta - if ( dScProd < 0) { - // Trovo i punti di riferimento per la lavorazione - ptLNs = ptLs + ( vtMove * dCylH) ; - ptLNe = ptLe + ( vtMove * dCylH) ; - dFactor = 1 ; - } - // Se lavora il fondo - else { - ptLNs = ptLs ; - ptLNe = ptLe ; - dFactor = 0 ; - } - - // Quota z dei punti iniziale e finale - double dHz = ptLNs.z ; - - // Bounding box - double dMinX = min( ptLNs.x, ptLNe.x) - m_dRadius ; - double dMaxX = max( ptLNs.x, ptLNe.x) + m_dRadius ; - double dMinY = min( ptLNs.y, ptLNe.y) - m_dRadius ; - double dMaxY = max( ptLNs.y, ptLNe.y) + m_dRadius ; - double dMinZ = dHz - m_dRadius ; - double dMaxZ = dHz + m_dRadius ; - - // Verifico se il movimento intersca lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - // Determino i limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - //Proietto ptLNs sul piano XY: - Point3d ptStart( ptLNs.x, ptLNs.y, 0) ; - - // Ciclo sui punti - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - // Punto da valutare - Point3d ptC( (i + 0.5)*m_dStep, (j + 0.5)*m_dStep, 0) ; - // Vettore spostamento da ptLe a ptC - Vector3d vtC = ( ptC - ptStart) ; - // Componenti parallela e perpendicolare a vtMove - // Vettore ortogonale a vtMove - Vector3d vtOrt = vtMove ; - // Ruoto vtOrt affinché sia ortogonale - vtOrt.Rotate( Z_AX, -90) ; - - double dProj = vtC * vtOrt ; - Vector3d vtPara = vtOrt * dProj ; // Parallelo alla perpendicolare al movimento - Vector3d vtPerp = vtC - vtPara ; // Perpendicolare alla perpendicolare al movimento ( serve per unire le getminmax di drill e perp) - // Distanza di ptC dall'asse dell'untensile - double dSqDist = vtPerp.SqLen() ; - double dLimitMill = dLenPath + dFactor * ( m_dHeight - dCylH) ; - // Se dTestProj è positivo è vtC è dalla parte giusta - double dTestProj = vtC * vtMove ; - - if ( dTestProj > 0 && dSqDist < dLimitMill * dLimitMill) { - if ( dProj > - m_dRadius && dProj < m_dRadius) - GetMinMaxXY( i, j, dProj, dHz, dSqDist, 0, dLenPath, dScProd) ; - } - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusDrillingXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) -{ - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - double dMin, dMax ; - - // Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici - BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - // Parametri geometrici dell'utensile - double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dCylH = m_dHeight - m_dTipHeight ; - - Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; vtMove.Normalize() ; - - Point3d ptI = ( vtToolDir * vtMove < 0 ? ptLs : ptLe) ; double dZH = ptI.z ; - - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep , dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptI ; - - double dPL = vtC * vtV1 ; - double dPT = vtC * vtV2 ; - - if ( m_dRadius > m_dTipRadius) { - - if ( dPL < 0 && dPL > - dCylH - dLen && dPT > - dMaxRad && dPT < dMaxRad) { - - double dH = sqrt( dMaxRad * dMaxRad - dPT * dPT) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dPL <= - dCylH - dLen && dPL > - m_dHeight - dLen && - dPT > - dMaxRad + ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight && - dPT < dMaxRad - ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight) { - - double dr = dMaxRad - ( - dPL - dCylH - dLen) * ( dMaxRad - dMinRad) / m_dTipHeight ; - - double dH = sqrt( dr * dr - dPT * dPT) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else { - - if ( dPL < 0 && dPL > - dCylH && dPT > - dMinRad && dPT < dMinRad) { - - double dH = sqrt( dMinRad * dMinRad - dPT * dPT) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dPL <= - dCylH && dPL > - m_dHeight && - dPT > - dMinRad - ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight && - dPT < dMinRad + ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight) { - - double dr = dMinRad + ( - dPL - dCylH) * ( dMaxRad - dMinRad) / m_dTipHeight ; - - double dH = sqrt( dr * dr - dPT * dPT) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dPL <= - m_dHeight && dPL > - m_dHeight - dLen && dPT > - dMaxRad && dPT < dMaxRad) { - - double dH = sqrt( dMaxRad * dMaxRad - dPT * dPT) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - if ( m_nToolType == CylindricalMill || - m_nToolType == BallEndMill || - m_nToolType == BullNoseMill) - - return CBTPerpXY( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == ConusMill) - - return ConusPerpXY( ptLs, ptLe, vtToolDir) ; - - else - - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::CBTPerpXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - - if ( m_nToolType == ConusMill) - return ConusPerpXY( ptLs, ptLe, vtToolDir) ; - - // Determinazione delle posizioni iniziali e finali della punta dell'utensile - Point3d ptTLs = ptLs - vtToolDir * m_dHeight ; - Point3d ptTLe = ptLe - vtToolDir * m_dHeight ; - - // Quota Z - double dZH = ptLs.z ; - - // Estremi Bounding box - double dMinX = min( min( ptLs.x, ptLe.x), min( ptTLs.x, ptTLe.x)) - m_dRadius ; - double dMaxX = max( max( ptLs.x, ptLe.x), max( ptTLs.x, ptTLe.x)) + m_dRadius ; - double dMinY = min( min( ptLs.y, ptLe.y), min( ptTLs.y, ptTLe.y)) - m_dRadius ; - double dMaxY = max( max( ptLs.y, ptLe.y), max( ptTLs.y, ptTLe.y)) + m_dRadius ; - double dMinZ = dZH - m_dRadius ; - double dMaxZ = dZH + m_dRadius ; - - // Verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Proiezione sul piano XY delle grandezze di interesse - Point3d ptStart( ptLs.x, ptLs.y, 0) ; - Point3d ptEnd( ptLe.x, ptLe.y, 0) ; - Vector3d vtMove = ptEnd - ptStart ; - double dLenPath = vtMove.Len() ; - // Normalizzo il vettore vtMove congiungente le posizioni iniziale e finale della base dell'utensile - vtMove.Normalize() ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - // Punto su cui ciclare e vettore congiungente posizione iniziale della base a tale punto - Point3d ptC( (i + 0.5) * m_dStep, (j + 0.5) * m_dStep, 0) ; - Vector3d vtC = ptC - ptStart ; - // Proiezione di vtC sulla direzione del movimento - double dProj = vtC * vtMove ; - // Componente di vtC ortogonale al movimento - Vector3d vtPerp = vtC - vtMove * dProj ; - // Lunghezza quadrata del precedente vettore - double dSqDist = vtPerp.SqLen() ; - - if ( dProj > - m_dRadius && dProj < dLenPath + m_dRadius && vtPerp * vtToolDir < 0 && dSqDist < m_dHeight * m_dHeight) - GetMinMaxXY( i, j, dProj, dZH, dSqDist, dLenPath, 0, 0) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusPerpXY( const Point3d ptLs, const Point3d ptLe, const Vector3d vtToolDir) -{ - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - double dMin, dMax ; - - // Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici - bool bControl = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( bControl == false) - return true ; - - // Parametri geometrici dell'utensile - double dCylH = m_dHeight - m_dTipHeight ; - - Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.LenXY() ; - - // Sistema di riferimento - Vector3d vtV1 = - vtToolDir ; - Vector3d vtV2 = vtMove ; vtV2.Normalize() ; - - Point3d ptIC = ptLs ; double dZ = ptLs.z ; - - // Ciclo sui punti - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - double dY = ( j + 0.5) * m_dStep ; double dX = ( i + 0.5) * m_dStep ; - - Point3d ptCC( dX, dY, 0) ; Vector3d vtCC = ptCC - ptIC ; - - double dPCL = vtCC * vtV1 ; double dPCT = vtCC * vtV2 ; - - // Parte cilindrica - if( dPCL > 0 && dPCL < dCylH) { - - if ( dPCT > - m_dRadius && dPCT < 0) { - - double dH = sqrt( m_dRadius * m_dRadius - dPCT * dPCT) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dPCT >= 0 && dPCT < dLen) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dPCT >= dLen && dPCT < dLen + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dPCT - dLen) * ( dPCT - dLen)) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - // Parte non cilindrica - else if ( dPCL >= dCylH && dPCL < m_dHeight) { - - double dPNCL = dPCL - dCylH ; double dPNCT = dPCT ; - - if ( dPNCT > - m_dRadius - dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight && dPNCT < 0) { - - double dr = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; - - double dH = sqrt( dr * dr - dPNCT * dPNCT) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dPNCT >= 0 && dPNCT < dLen) { - - double dH = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dPNCT >= dLen && dPNCT < dLen + m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight) { - - double dr = m_dRadius + dPNCL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; - - double dH = sqrt( dr * dr - ( dPNCT - dLen) * ( dPNCT - dLen)) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - if ( m_nToolType == CylindricalMill || - m_nToolType == BallEndMill) - return PlaneGenCylBall( ptLs, ptLe, vtToolDir) ; - else - return ConusPlaneGen( ptLs, ptLe, vtToolDir) ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::PlaneGenCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI = ptLs ; Point3d ptF = ptLe ; - - // Quote dei punti ptI e ptF - double dZ = ptI.z ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - Vector3d vtMove = ptF - ptI ; - - if ( vtMove * vtToolDir > 0) { - Point3d ptTemp = ptI ; - ptI = ptF ; - ptF = ptTemp ; - vtMove = - vtMove ; - } - - Vector3d vtMoveOrt = vtMove - ( vtMove * vtToolDir) * vtToolDir ; double dLen2 = vtMoveOrt.Len() ; - Vector3d vtMoveLong = ( vtMove * vtToolDir) * vtToolDir ; double dLen1 = vtMoveLong.Len() ; - - // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; - - // Punti iniziale e finale proiettati sul piano - Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - if ( m_nToolType == 1) { - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; - double dProj2 = vtC * vtV2 ; - - GetMMPlaneGenCyl( i, j, dZ, dLen1, dLen2, dProj1, dProj2) ; - } - - else if ( m_nToolType == 2) - GetMMPlaneGenBall( i, j, dZ, dLen1, dLen2, ptIxy, vtMove, vtV1, vtV2) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMinMaxXY( unsigned int nI, unsigned int nJ, double dProj, double dZheight, - double dSqD, double dPathPerp, double dPathPar, double dScProd) -{ - // Definisco la variabile altezza della parte cilindrica dell'utensile - double dCylH ; - // Definisco variabili per determinazione intervallo da sottrarre - double dL, dR, dH ; - - // Caso di utensile generico ( per ora non gestito) - if ( m_nToolType == 0) - return false ; - // Se utensile standard setto altezza della parte cilindrica - else if ( m_nToolType == 1) - dCylH = m_dHeight ; - else if ( m_nToolType == 2) - dCylH = m_dHeight - m_dRadius ; - else if ( m_nToolType == 3) - dCylH = m_dHeight - m_dRCorner ; - // Caso di utensile non definito - else - return false ; - - // Parametri per isolare la lavorazione della parte cilindrica comune a tutti gli utensili standard - // Limite nella direziona parallela all'asse dell'utensile e parametro perpendicolare - double dLimPar, dParPerp ; - - // Tagli perpendicolari all'asse dell'utensile - if ( abs( dScProd) < EPS_SMALL) { - dLimPar = dCylH ; - dParPerp = dPathPerp ; - } - // Tagli paralleli all'asse dell'utensile - else { - dLimPar = dPathPar ; - dParPerp = 0 ; - } - - // Parte cilindrica della lavorazione - if ( dSqD < dLimPar * dLimPar) { - // Qui il raggio del semicerchio è m_dRadius - if ( dProj < 0) - // dH = sqrt( m_dRadius^2 - dProj^2) - dH = sqrt( m_dRadius * m_dRadius - ( dProj * dProj)) ; - // Qui l'altezza è costante - else if ( dProj < dParPerp) - // dH = m_dRadius - dH = m_dRadius ; - // Qui il raggio del semicerchio è m_dRadius - else if ( dProj < dParPerp + m_dRadius) - // dH = sqrt( m_dRadius^2 - ( dProj - dParPerp)^2) - dH = sqrt( m_dRadius * m_dRadius - ( dProj - dParPerp) * ( dProj - dParPerp)) ; - // Eseguo il taglio - return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ; - } - // Parte non cilindrica, questa parte esiste solo nei tagli (dScProd = 0) e nel foro con la punta quindi (dScProd < 0) - // e solo con frese non cilindriche - else { - if ( dScProd < EPS_SMALL) { - // Definisco variabili - // Caso fresa ball-end - if ( m_nToolType == 2) { - // Il raggio è sqrt( m_dRadius^2 - ( sqrt( dSqD) - dLimPar)^2) - if ( dProj < 0) { - dL = sqrt( dSqD) - dLimPar ; - dR = sqrt( m_dRadius * m_dRadius - dL * dL) ; - dH = sqrt( dR * dR - (dProj * dProj)) ; - } - // Qui dH non dipende da dProj - else if ( dProj < dParPerp) { - dL = sqrt( dSqD) - dLimPar ; - dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - } - // E' analogo al primo caso con la sostituzione di dProj con dProj - dParPerp - else if ( dProj < dParPerp + m_dRadius) { // In questo caso è equivalente a else - dL = sqrt( dSqD) - dLimPar ; - dR = sqrt( m_dRadius * m_dRadius - dL * dL) ; - dH = sqrt( dR * dR - ((dProj - dParPerp) * (dProj - dParPerp))) ; - } - } - // Caso di fresa bull-nose - else if ( m_nToolType == 3) { - // Raggio semicerchio m_dRadius - m_dRCorner + sqrt( m_dRCorner^2 - ( sqrt( dSqD) - dLimPar)^2) - if ( dProj < 0) { - dL = sqrt( dSqD) - dLimPar ; - dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; - dH = sqrt( dR * dR - ( dProj * dProj)) ; - } - // Qui dH non dipende da dProj - else if ( dProj < dParPerp) { - dL = sqrt( dSqD) - dLimPar ; - dH = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; - } - // E' analogo al primo caso con la sostituzione di di dProj con dProj - dParPerp - else if ( dProj < dParPerp + m_dRadius) { // In questo caso equivalente a else - dL = sqrt( dSqD) - dLimPar ; - dR = m_dRadius - m_dRCorner + sqrt( m_dRCorner * m_dRCorner - dL * dL) ; - dH = sqrt( dR * dR - ( ( dProj - dParPerp) * ( dProj - dParPerp))) ; - } - } - return SubtractIntervals( nI, nJ, dZheight - dH, dZheight + dH) ; - } - } - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMMPlaneGenCyl( unsigned int i, unsigned int j, double dZ, - double dLen1, double dLen2, double dProj1, double dProj2) -{ - double dMin, dMax ; - - if ( dProj2 > - m_dRadius && dProj2 < 0) { - - if ( dProj1 < 0 && dProj1 > - m_dHeight) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - else if ( dProj1 <= - m_dHeight) { - - if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - m_dHeight - ( dLen1 / dLen2) * ( dProj2 + m_dRadius)) - || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // In questo costrutto if-else non c'è bisogno di specificare nient'altro perché già siamo nella regione - m_dRadius < dProj2 < 0 - - double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; - double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - else if ( dProj2 >= 0 && dProj2 < m_dRadius) { - - if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - /* Oppure - double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ; - double dPar2 = ( dLen2 / dLen1) * dPar1 ; */ - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2) { - - if ( dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight) - || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { // modificato qui - - double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; - double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( dProj2 >= dLen2 && dProj1 < - dLen1) { - - if ( dProj1 > - m_dHeight - dLen1) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dLen2) * ( dProj2 - dLen2)) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( dProj2 >= m_dRadius && dProj2 < dLen2) { - - if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 > - ( dLen1 / dLen2) * dProj2) { - - double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin , dMax) ; - } - else if ( dProj1 <= - ( dLen1 / dLen2) * dProj2 - m_dHeight) { - - if ( ( dProj2 < dLen2 - m_dRadius && dProj1 > - ( dLen1 / dLen2) * ( dProj2 + m_dRadius) - m_dHeight) - || ( dProj2 >= dLen2 - m_dRadius && dProj1 > - m_dHeight - dLen1)) { - - double dPar = m_dHeight + ( dLen1 / dLen2) * ( dProj2 + m_dRadius) + dProj1 ; - double dL = m_dRadius - ( dLen2 / dLen1) * dPar ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) { - - if ( dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius) && dProj1 >= - dLen1) { - - double dL = ( dLen2 / dLen1) * ( ( dLen1 / dLen2) * dProj2 + dProj1) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 < - dLen1 && dProj1 > - dLen1 - m_dHeight) { - - double dL = dProj2 - dLen2 ; - double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::GetMMPlaneGenBall( unsigned int i, unsigned int j, double dZ, double dLen1, double dLen2, - Point3d ptIxy, Vector3d vtMove, Vector3d vtV1, Vector3d vtV2) -{ - double dMin, dMax ; - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; // vtV1, vtV2 sono paralleli al piano - double dProj2 = vtC * vtV2 ; - - double dCH = m_dHeight - m_dRadius ; - double dLMove = vtMove.LenXY() ; - - Point3d ptCS = ptIxy - dCH * vtV1 ; Point3d ptCE = ptCS + vtMove ; // vtMove è orizzontale - - Vector3d vtCS = ptC - ptCS ; Vector3d vtCE = ptC - ptCE ; - - double dProjMove = ( vtCS * vtMove) / dLMove ; - - Vector3d vtCSP = vtCS - ( ( vtCS * vtMove) / ( dLMove * dLMove)) * vtMove ; - - double dSQDist = vtCSP.SqLenXY() ; - double dSQDistS = vtCS.SqLenXY() ; - double dSQDistE = vtCE.SqLenXY() ; - - // parte cilindrica - - if ( dProj2 > - m_dRadius && dProj2 < 0) { - - if ( dProj1 > - dCH && dProj1 < 0) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( dProj2 >= 0 && dProj2 < m_dRadius) { - - if ( dProj1 < 0 && ( ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) || ( dProj2 >= dLen2 && dProj1 > - dLen1))) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - /* Oppure - double dPar1 = ( dLen1 / dLen2) * dProj2 + dProj1 ; - double dPar2 = ( dLen2 / dLen1) * dPar1 ; */ - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 >= dLen2 && dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) { - - double dL = dProj2 - dLen2 ; - double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( dProj2 >= m_dRadius && dProj1 < - ( dLen1 / dLen2) * ( dProj2 - m_dRadius)) { - - if ( dProj2 < dLen2 && dProj1 > - ( dLen1 / dLen2) * dProj2) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 < dLen2 && dProj1 <= - ( dLen1 / dLen2) * dProj2 && dProj1 > - ( dLen1 / dLen2) * dProj2 - dCH) { - - dMin = dZ - m_dRadius ; dMax = dZ + m_dRadius ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj2 >= dLen2 && dProj2 < dLen2 + m_dRadius) { - - if ( dProj1 > - dLen1) { - - double dPar = dProj2 + ( dLen2 / dLen1) * dProj1 ; - double dH = ( m_dRadius * m_dRadius - dPar * dPar > 0 ? sqrt( m_dRadius * m_dRadius - dPar * dPar) : 0) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 <= - dLen1 && dProj1 > - dLen1 - dCH) { - - double dL = dProj2 - dLen2 ; - double dH = sqrt( m_dRadius * m_dRadius - dL * dL) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - // parte non cilindrica - if ( dProjMove > - m_dRadius && dProjMove < 0) { - - if ( dSQDistS < m_dRadius * m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dSQDistS) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( dProjMove >= 0 && dProjMove < dLMove) { - - if ( dSQDist < m_dRadius * m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dSQDist) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else { - - if ( dSQDistE < m_dRadius * m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dSQDistE) ; - - dMin = dZ - dH ; dMax = dZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::ConusPlaneGen( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( Control == false) - return true ; - - double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dCylH = m_dHeight - m_dTipHeight ; - double dZH = ptLs.z ; - - m_nToolType = CylindricalMill ; - m_dHeight = dCylH ; - - MillingXYPlaneGen( ptLs, ptLe, vtToolDir) ; - - m_nToolType = ConusMill ; - m_dHeight = m_dHeight + m_dTipHeight ; - - Point3d ptI, ptF ; - - Vector3d vtV1 ; - - if ( m_dTipRadius < m_dRadius) { - - vtV1 = vtToolDir ; - ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs - vtV1 * dCylH : ptLe - vtV1 * dCylH) ; - ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe - vtV1 * dCylH : ptLs - vtV1 * dCylH) ; - } - - else { - vtV1 = - vtToolDir ; - ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe + vtV1 * m_dHeight : ptLs + vtV1 * m_dHeight) ; - ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs + vtV1 * m_dHeight : ptLe + vtV1 * m_dHeight) ; - } - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - Vector3d vtMove = ptF - ptI ; - Vector3d vtLong = ( vtMove * vtV1) * vtV1 ; double dLen1 = vtLong.LenXY() ; - Vector3d vtOrt = vtMove - vtLong ; double dLen2 = vtOrt.LenXY() ; - Vector3d vtTemp = vtV1 ; vtTemp.Rotate( Z_AX, 90) ; - - vtMove.Normalize() ; - - Vector3d vtV2 = ( vtMove * vtTemp > 0 ? vtTemp : - vtTemp) ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTan * dRatio ; - double dSin = ( abs( dCos) < 1 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - double dDeltaR = dMaxRad - dMinRad ; - double dMinLim = dMinRad * dCos ; - double dMaxLim = dMaxRad * dCos ; - - - // Versori normali e prodotti scalari per determinare i piani - Vector3d vtNInf = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNSup = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; - - Point3d ptV = ptI - vtV1 * ( dMaxRad * m_dTipHeight) / ( dMaxRad - dMinRad) ; - Vector3d vtR0 = ptV - ORIG ; - double dDotInf = vtR0 * vtNInf ; - double dDotSup = vtR0 * vtNSup ; - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - Point3d ptC( ( i + 0.5) * m_dStep, ( j + 0.5) * m_dStep, 0) ; - - - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; - - if ( dRatio <= m_dTipHeight / dDeltaR) { - - if ( dProj1 > - m_dTipHeight && dProj1 < 0 && - dProj2 > - dMaxRad - dTan * dProj1 && - dProj2 < dMaxLim + dProj1 * ( dMaxLim - dMinLim) / m_dTipHeight) { - - double dr = dMaxRad + dTan * dProj1 ; - double dH = sqrt( dr * dr - dProj2 * dProj2) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j , dMin, dMax) ; - } - else if ( dProj1 > dLen1 - m_dTipHeight && dProj1 < dLen1 && - dProj2 > dLen2 - dMaxRad - dTan * dProj1 && - dProj2 < dLen2 + dMaxLim + dProj1 * ( dMaxLim - dMinLim) / m_dTipHeight) { // Se due sistemi di riferimento hanno stessi versori di base e differiscono semplicemente per le origini, - // le proiezioni di un vettore sugli assi nei due sistemi differiscono per le componenti del vettore che congiunge le origini. - double dr = dMaxRad + dTan * ( dProj1 - dLen1) ; - double dH = sqrt( dr * dr - ( dProj2 - dLen2) * ( dProj2 - dLen2)) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 >= 0 && dProj1 < dLen1 && - dProj2 > - dMaxRad + dProj1 * dLen2 / dLen1 && - dProj2 < dMaxLim + dProj1 * dLen2 / dLen1) { - - double dr = abs( dProj2 - dProj1 * dLen2 / dLen1) ; // Proj2 del punto meno Proj2 del centro del cerchio - double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 > - m_dTipHeight && dProj1 < - m_dTipHeight + dLen1 && // Idem con patate - dProj2 > dMinLim + dProj1 * ( dLen2 / dLen1) && - dProj2 < dMinRad + dProj1 * ( dLen2 / dLen1)) { - - double dr = dProj2 - dProj1 * dLen2 / dLen1 ; - double dH = sqrt( dMinRad * dMinRad - dr * dr) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j , dMin, dMax) ; - } - else { // L'unico dominio non normale lo detrerminiamo per sottrazione :) - - dMin = ( dDotInf - ptC.x * vtNInf.x - ptC.y * vtNInf.y) / vtNInf.z ; - dMax = ( dDotSup - ptC.x * vtNSup.x - ptC.y * vtNSup.y) / vtNSup.z ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else { - - if ( dProj1 > - m_dTipHeight && dProj1 <= 0 && - dProj2 > - dMaxRad - dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight && - dProj2 < dMaxRad + dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight) { - - double dr = dMaxRad + dProj1 * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = sqrt( dr * dr - dProj2 * dProj2) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dProj1 > 0 && dProj1 < dLen1 && - dProj2 > - dMaxRad + dProj1 * ( dLen2 / dLen1) && - dProj2 < dMaxRad + dProj1 * ( dLen2 / dLen1)) { - - double dr = abs( dProj2 - dProj1 * ( dLen2 / dLen1)) ; - double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ; - - dMin = dZH - dH ; dMax = dZH + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - - -// DeltaZ != 0 - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - double dMin, dMax ; - - // Determinazione dell'interferenza dell'utensile con lo Zmap, bouding box e limiti su indici - bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( ! Control) - return true ; - - double dCylH = m_dHeight - m_dTipHeight ; - double dZDown = min( ptLs.z, ptLe.z) ; - double dZUp = max( ptLs.z, ptLe.z) ; - - // Definizione di un sistema di riferimento - Vector3d vtV1 = - vtToolDir ; - Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ; - - Point3d ptIC = ptLs ; Point3d ptINC = ptLs + dCylH * vtV1 ; - - Point3d ptICxy( ptIC.x, ptIC.y, 0) ; Point3d ptINCxy( ptINC.x, ptINC.y, 0) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep , dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtCC = ptC - ptICxy ; Vector3d vtNCC = ptC - ptINCxy ; - - double dCPL = vtCC * vtV1 ; double dCPT = vtCC * vtV2 ; - - double dNCPL = vtNCC * vtV1 ; double dNCPT = vtNCC * vtV2 ; - - // Parte cilindrica - if ( dCPL > 0 && dCPL < dCylH && dCPT > - m_dRadius && dCPT < m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dCPT * dCPT) ; - - dMin = dZDown - dH ; dMax = dZUp + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Parte non cilindrica - if ( m_nToolType == BallEndMill) { - - double dSqLen = vtNCC.SqLenXY() ; - - if ( dNCPL >= 0 && dSqLen < m_dRadius * m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqLen) ; - - dMin = dZDown - dH ; dMax = dZUp + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( m_nToolType == BullNoseMill) { - - if ( dNCPL >= 0 && dNCPL < m_dTipHeight) { - - double dR = m_dTipRadius + sqrt( m_dRCorner * m_dRCorner - dNCPL * dNCPL) ; - - if ( dNCPT > - dR && dNCPT < dR) { - - double dH = sqrt( dR * dR - dNCPT * dNCPT) ; - - dMin = dZDown - dH ; dMax = dZUp + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - else if ( m_nToolType == ConusMill) { - - if ( dNCPL >= 0 && dNCPL < m_dTipHeight && - dNCPT > - m_dRadius - dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight && - dNCPT < m_dRadius + dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight) { - - double dr = m_dRadius + dNCPL * ( m_dTipRadius - m_dRadius) / m_dTipHeight ; - - double dH = sqrt( dr * dr - dNCPT * dNCPT) ; - - dMin = dZDown - dH ; dMax = dZUp + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYLongVert( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - if ( m_nToolType == CylindricalMill || - m_nToolType == BallEndMill) - - return XYLongVertCylBall( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == ConusMill) - - return XYLongVertConus( ptLs, ptLe, vtToolDir) ; - - else - // Casi al momento non gestiti - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::XYLongVertCylBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - unsigned int nStartI, nEndI, nStartJ, nEndJ ; - double dMin, dMax ; - - bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - // Se Control è falso non vi è interferenza fra utensile e Zmap - if ( ! Control) - return true ; - - double dDeltaZ = ptLe.z - ptLs.z; - double dCylH = m_dHeight - m_dTipHeight ; - - Point3d ptI, ptF, ptBI, ptBF ; - Vector3d vtV1, vtV2 ; - Vector3d vtMove = ptLe - ptLs ; - - // Studio della parte sferica - if ( ptLs.z < ptLe.z) { - - ptBI = ptLs - vtToolDir * dCylH ; - ptBF = ptLe - vtToolDir * dCylH ; - } - - else { - ptBI = ptLe - vtToolDir * dCylH ; - ptBF = ptLs - vtToolDir * dCylH ; - } - - Point3d ptBIxy( ptBI.x, ptBI.y, 0) ; - Vector3d vtBMove = ptBF - ptBI ; vtBMove.Normalize() ; - Vector3d vtBV1 = ( vtToolDir * vtBMove > 0 ? vtToolDir : - vtToolDir) ; - - double dDeltaBZ = ptBF.z - ptBI.z ; - double dOriz = vtBMove * Z_AX ; - double dVert = vtBMove * vtBV1 ; - - double dSemiAxMin = m_dRadius * dOriz ; - - // Studio delle simmetrie della parte cilindrica - if ( vtToolDir * vtMove < 0 && dDeltaZ < 0) { - - ptI = ptLe - vtToolDir * dCylH ; - ptF = ptLs - vtToolDir * dCylH ; - vtMove = - vtMove ; - vtV1 = - vtToolDir ; - dDeltaZ = - dDeltaZ ; - } - - else if ( vtToolDir * vtMove > 0 && dDeltaZ > 0) { - ptI = ptLs - vtToolDir * dCylH ; - ptF = ptLe - vtToolDir * dCylH ; - vtV1 = - vtToolDir ; - } - - else if ( vtToolDir * vtMove > 0 && dDeltaZ < 0) { - ptI = ptLe ; - ptF = ptLs ; - vtV1 = vtToolDir ; - vtMove = - vtMove ; - dDeltaZ = - dDeltaZ ; - } - - else { - ptI = ptLs ; - ptF = ptLe ; - vtV1 = vtToolDir ; - } - - Point3d ptIxy( ptI.x, ptI.y, 0) ; double dZI = ptI.z ; - - vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; - - double dLen = abs( vtMove * vtV1) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - - double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtV2 ; - - Vector3d vtBC = ptC - ptBIxy ; - - double dBpr1 = vtBC * vtBV1 ; double dBpr2 = vtBC * vtV2 ; - - // Parte cilindrica - - if ( dProj2 > - m_dRadius && dProj2 < m_dRadius && - dProj1 > 0 && dProj1 < dLen + dCylH) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - // Massimi - if ( dProj1 > 0 && dProj1 < dLen) { - - double dZ0 = ptI.z + dProj1 * ( dDeltaZ / dLen) ; - - dMax = dZ0 + dH ; - } - else if ( dProj1 >= dLen && dProj1 < dLen + dCylH) - - dMax = ptI.z + dDeltaZ + dH ; - - // Minimi - if ( dProj1 > 0 && dProj1 < dCylH) - - dMin = ptI.z - dH ; - - else if ( dProj1 >= dCylH && dProj1 < dLen + dCylH) { - - double dZ0 = ptI.z + ( dProj1 - dCylH) * ( dDeltaZ / dLen) ; - - dMin = dZ0 - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Parte Non cilindrica - if ( m_nToolType == BallEndMill) { - - double dSqDistO = dBpr2 * dBpr2 ; - double dSqDistI = vtBC.SqLenXY() ; - double dSqDistF = ( dBpr1 - dLen) * ( dBpr1 - dLen) + dBpr2 * dBpr2 ; - - if ( ( dBpr1 < 0 && dSqDistI < m_dRadius * m_dRadius) || - ( dBpr1 >= 0 && dBpr1 < dLen && dSqDistO < m_dRadius * m_dRadius) || - ( dBpr1 >= dLen && dSqDistF < m_dRadius * m_dRadius)) { - - // Massimi - if ( dBpr1 < - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqDistI) ; - - dMax = ptBI.z + dH ; - } - else if ( dBpr1 >= - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius)) && - dBpr1 < dLen - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { - - double dZ0 = ptBI.z + dVert * sqrt( m_dRadius * m_dRadius - dSqDistO) ; - - dMax = dZ0 + dDeltaBZ * ( dBpr1 + dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) / dLen ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqDistF) ; - - dMax = ptBF.z + dH ; - } - - // Minimi - if ( dBpr1 < dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqDistI) ; - - dMin = ptBI.z - dH ; - } - else if ( dBpr1 >= dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius)) && - dBpr1 < dLen + dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) { - - double dZ0 = ptBI.z - dVert * sqrt( m_dRadius * m_dRadius - dSqDistO) ; - - dMin = dZ0 + dDeltaBZ * ( dBpr1 - dSemiAxMin * sqrt( 1 - dSqDistO / ( m_dRadius * m_dRadius))) / dLen ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqDistF) ; - - dMin = ptBF.z - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -/* -//---------------------------------------------------------------------------- -bool -VolZmap::XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - double dMin, dMax ; - unsigned int nStartI, nEndI, nStartJ, nEndJ ; - - bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( Control == false) - - return true ; - - // Parte cilindrica - m_nToolType = CylindricalMill ; - - double dSafeHeight = m_dHeight ; - double dSafeTipHeight = m_dTipHeight ; - double dCylH = m_dHeight - m_dTipHeight ; - - m_dHeight = dCylH ; - m_dTipHeight = 0 ; - - XYLongVertCylBall( ptLs, ptLe, vtToolDir) ; - - m_nToolType = ConusMill ; - m_dHeight = dSafeHeight ; - m_dTipHeight = dSafeTipHeight ; - - // Parte conica - - Point3d ptI, ptF ; - Vector3d vtV1 ; - - double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dDeltaR = dMaxRad - dMinRad ; - - double dStem ; - - if ( m_dRadius > m_dTipRadius) { - - vtV1 = vtToolDir ; - dStem = - dCylH ; - } - else { - - vtV1 = - vtToolDir ; - dStem = m_dHeight ; - } - - - if ( vtV1 * ( ptLe - ptLs) * ( ptLe.z - ptLs.z) > 0) { - - ptI = ( ptLe.z - ptLs.z < 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; - ptF = ( ptLe.z - ptLs.z < 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; - } - else { - - ptI = ( ptLe.z - ptLs.z > 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; - ptF = ( ptLe.z - ptLs.z > 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; - } - - double dZI = ptI.z ; - double dDeltaZ = ptF.z - ptI.z ; - - Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / dDeltaR) ; - - // Apertura del cono e parametri per determinare i piani - double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV3) ; - double dCos = dTan * dRatio ; - double dSen = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 - ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ; - Vector3d vtNd = - ( dTan / sqrt( 1 + dTan * dTan)) * vtV1 + ( dCos / sqrt( 1 + dTan * dTan)) * vtV3 + ( sqrt( 1 - dCos * dCos) / sqrt( 1 + dTan * dTan)) * vtV2 ; - Vector3d vtR0 = ptV - ORIG ; - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; double dOrtLen = abs( dProj2) ; - - if ( ( dProj1 > 0 && dProj1 < dPLen && dOrtLen < dMaxRad) || - ( dProj1 >= dPLen && dProj1 < dPLen + m_dTipHeight && - dOrtLen < dMaxRad + ( dProj1 - dPLen) * ( dDeltaR / m_dTipHeight))) { - - // DeltaZ < 0 - if ( dDeltaZ < 0) { - - if ( dRatio <= 1 / dTan) { - - if ( dProj1 < m_dTipHeight && dOrtLen < dMaxRad * dSen - dProj1 * dDeltaR * dSen / m_dTipHeight) { // Il limite inferiore d dProj1 è già stato imposto dall' if più esterno - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; - - dMax = dZI + dH ; - } - else if ( dProj1 > 0 && dProj1 < dPLen && - dOrtLen > dMaxRad * dSen && dOrtLen < dMaxRad) { - - double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ; - - dMax = dZI + dH + dProj1 * dDeltaZ / dPLen ; - } - else if ( dProj1 > m_dHeight && dProj1 < dPLen + m_dHeight && - dOrtLen < dMinRad * dSen) { - - double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ; - - dMax = dZI + dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ; - } - else if ( dProj1 >= dPLen && - dOrtLen > dMaxRad * dSen - ( dProj1 - dPLen) * dDeltaR * dSen / m_dTipHeight) { // I limiti superiori sono già stati imposti dall' if più esterno - - double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; - - double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; - - dMax = dZI + dDeltaZ + dH ; - } - else - - dMin = ( dOrtLen > 0 ? (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ; - - - - if ( dProj1 < dPLen) { // Limiti su dOrtLen già imposti dall' if esterno - - double dH = sqrt( dMaxRad * dMaxRad - dOrtLen* dOrtLen) ; - - dMin = dZI - dH + ( dProj1 - dPLen) * dDeltaZ / dPLen ; - } - else if ( dProj1 >= dPLen) { // Limiti su dOrtLen e su dProj1 già imposti dall' if esterno - - double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; - - double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; - - dMax = dZI + dDeltaZ - dH ; - } - - SubtractIntervals( i, j, dMax, dMin) ; - } - else { - // dRatio > - } - } - else { // dDeltaZ > 0 - - if () { // dRatio < - - } - else { // dRatio > - - } - - } - } - } - - return true ; -} -*/ - -//---------------------------------------------------------------------------- -bool -VolZmap::XYLongVertConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dZL1, dZL2 ; - unsigned int nStartI, nEndI, nStartJ, nEndJ ; - - bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( ! Control) - return true ; - - // Parte cilindrica - m_nToolType = CylindricalMill ; - - double dSafeHeight = m_dHeight ; - double dSafeTipHeight = m_dTipHeight ; - double dCylH = m_dHeight - m_dTipHeight ; - - m_dHeight = dCylH ; - m_dTipHeight = 0 ; - - XYLongVertCylBall( ptLs, ptLe, vtToolDir) ; - - m_nToolType = ConusMill ; - m_dHeight = dSafeHeight ; - m_dTipHeight = dSafeTipHeight ; - - // Parte conica - - Point3d ptI, ptF ; - Vector3d vtV1 ; - - double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dDeltaR = dMaxRad - dMinRad ; - - double dStem ; - - if ( m_dRadius > m_dTipRadius) { - - vtV1 = vtToolDir ; - dStem = - dCylH ; - } - else { - vtV1 = - vtToolDir ; - dStem = m_dHeight ; - } - - if ( vtV1 * ( ptLe - ptLs) * ( ptLe.z - ptLs.z) > 0) { - - ptI = ( ptLe.z - ptLs.z < 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; - ptF = ( ptLe.z - ptLs.z < 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; - } - - else { - ptI = ( ptLe.z - ptLs.z > 0 ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; - ptF = ( ptLe.z - ptLs.z > 0 ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; - } - - double dZI = ptI.z ; - double dDeltaZ = ptF.z - ptI.z ; - double dFactor = ( dDeltaZ > 0 ? - 1 : 1) ; - - Vector3d vtV2 = vtV1 ; vtV2.Rotate(Z_AX, 90) ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / dDeltaR) ; - - // Apertura del cono e parametri per determinare i piani - double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( dDeltaZ > 0 ? - ( vtMove * vtV1) / ( vtMove * vtV3) : ( vtMove * vtV1) / ( vtMove * vtV3)) ; - - double dCos = dTan * dRatio ; - double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTan / dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 - dFactor * ( dSin / dDen) * vtV2 ; - Vector3d vtNd = - ( dTan /dDen) * vtV1 + dFactor * ( dCos / dDen) * vtV3 + dFactor * ( dSin / dDen) * vtV2 ; - Vector3d vtR0 = ptV - ORIG ; - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - - double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtV2 ; double dOrtLen = abs( dProj2) ; - - if ( ( dProj1 > 0 && dProj1 < dPLen && dOrtLen < dMaxRad) || - ( dProj1 >= dPLen && dProj1 < dPLen + m_dTipHeight && - dOrtLen < dMaxRad + ( dProj1 - dPLen) * ( dDeltaR / m_dTipHeight))) { - - - if ( dRatio <= 1 / dTan) { - - if ( dProj1 < m_dTipHeight && dOrtLen < dMaxRad * dSin - dProj1 * dDeltaR * dSin / m_dTipHeight) { // Il limite inferiore d dProj1 è già stato imposto dall' if più esterno - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; - - dZL1 = dZI + dFactor * dH ; - } - else if ( dProj1 > 0 && dProj1 < dPLen && - dOrtLen > dMaxRad * dSin && dOrtLen < dMaxRad) { - - double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ; - - dZL1 = dZI + dFactor * dH + dProj1 * dDeltaZ / dPLen ; - } - else if ( dProj1 > m_dTipHeight && dProj1 < dPLen + m_dHeight && - dOrtLen < dMinRad * dSin) { - - double dH = sqrt( dMinRad * dMinRad - dOrtLen * dOrtLen) ; - - dZL1 = dZI + dFactor * dH + ( dProj1 - m_dTipHeight) * dDeltaZ / dPLen ; - } - else if ( dProj1 >= dPLen && - dOrtLen > dMaxRad * dSin - ( dProj1 - dPLen) * dDeltaR * dSin / m_dTipHeight) { // I limiti superiori sono già stati imposti dall' if più esterno - - double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; - - double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; - - dZL1 = dZI + dDeltaZ + dFactor * dH ; - } - else { - - if ( dDeltaZ < 0) - - dZL1 = ( dProj2 > 0 ? (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ; - else - dZL1 = ( dProj2 > 0 ? (dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z : (dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z) ; - } - - - - if ( dProj1 < dPLen) { // Limiti su dOrtLen già imposti dall' if esterno - - double dH = sqrt( dMaxRad * dMaxRad - dOrtLen* dOrtLen) ; - - dZL2 = dZI - dFactor * dH + dProj1 * dDeltaZ / dPLen ; - } - else if ( dProj1 >= dPLen) { // Limiti su dOrtLen e su dProj1 già imposti dall' if esterno - - double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; - - double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; - - dZL2 = dZI + dDeltaZ - dFactor * dH ; - } - - SubtractIntervals( i, j, dZL1, dZL2) ; - } - else { - - if ( dProj1 < dPLen && dOrtLen < dMaxRad) { - - double dH = sqrt( dMaxRad * dMaxRad - dOrtLen * dOrtLen) ; - - dZL1 = dZI + dH + dProj1 * dDeltaZ / dPLen ; - dZL2 = dZI - dH + dProj1 * dDeltaZ / dPLen ; - } - else if ( dProj1 >= dPLen) { - - double dr = dMaxRad - ( dProj1 - dPLen) * dDeltaR / m_dTipHeight ; - - double dH = sqrt( dr * dr - dOrtLen * dOrtLen) ; - - dZL1 = dZI + dDeltaZ + dH ; - dZL2 = dZI + dDeltaZ - dH ; - } - - SubtractIntervals( i, j, dZL1, dZL2) ; - } - } - } - } - - return true ; -} - - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXY( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - - if ( m_nToolType == CylindricalMill) - - return MillingXYCyl( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == BallEndMill) - - return MillingXYBall( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == ConusMill) - - return MillingXYConus( ptLs, ptLe, vtToolDir) ; - - else - - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI, ptF ; - - if ( ptLs.z < ptLe.z) { - ptI = ptLs ; - ptF = ptLe ; - } - else { - ptI = ptLe ; - ptF = ptLs ; - } - - // Quote dei punti ptI e ptF - double dZI = ptI.z ; double dZF = ptF.z ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - Vector3d vtMove = ptF - ptI ; //double dLenPath = vtMove.Len() ; - - // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMove ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determinazione punti notevoli del volume spazzato dall'utensile - Point3d ptPlaneSup, ptPlaneInf ; - - if ( vtV3.z > 0) { - ptPlaneInf = ptI - m_dRadius * vtV3 ; - ptPlaneSup = ptI + m_dRadius * vtV3 ; - } - else { - ptPlaneInf = ptI + m_dRadius * vtV3 ; - ptPlaneSup = ptI - m_dRadius * vtV3 ; - } - - // Prodotti scalari per costruire i piani passanti per i punti notevoli - Vector3d vtR0Inf = ptPlaneInf - ORIG ; - Vector3d vtR0Sup = ptPlaneSup - ORIG ; - - double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; - - // Determinazione delle proiezioni sul piano delle entità geometriche fondamentali - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ; - Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ; - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - Vector3d vtTemp = vtV1 ; vtTemp.Rotate( Z_AX, 90) ; - Vector3d vtW2 = ( vtTemp * vtV2 > 0 ? vtTemp : - vtTemp) ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano - double dProj2 = vtC * vtW2 ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza - - if ( dProj1 < 0 && dProj1 > - m_dHeight && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) { - - - // Minimi - if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) { - - dMin = dZInf ; - } - else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMin = dZF - dH ; - } - // Massimi - if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) { - - dMax = dZSup ; - } - else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMax = dZF + dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI, ptF ; - - if ( ptLs.z < ptLe.z) { - ptI = ptLs ; - ptF = ptLe ; - } - else { - ptI = ptLe ; - ptF = ptLs ; - } - - // Quote dei punti ptI e ptF e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - Vector3d vtMove = ptF - ptI ; - - // Determino sistema di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMove ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determinazione punti notevoli del volume spazzato dall'utensile - Point3d ptPlaneSup, ptPlaneInf ; - - if ( vtV3.z > 0) { - ptPlaneInf = ptI - m_dRadius * vtV3 ; - ptPlaneSup = ptI + m_dRadius * vtV3 ; - } - else { - ptPlaneInf = ptI + m_dRadius * vtV3 ; - ptPlaneSup = ptI - m_dRadius * vtV3 ; - } - - // Prodotti scalari per costruire i piani passanti per i punti notevoli - Vector3d vtR0Inf = ptPlaneInf - ORIG ; - Vector3d vtR0Sup = ptPlaneSup - ORIG ; - - double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; - - // Determinazione delle proiezioni sul piano delle entità geometriche fondamentali - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPlanePath = vtPlaneMove.Len() ; vtPlaneMove.Normalize() ; - Vector3d vtPlaneLim( m_dRadius * vtV3.x, m_dRadius * vtV3.y, 0) ; double dPlaneLim = vtPlaneLim.Len() ; - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - Vector3d vtTemp = vtToolDir ; vtTemp.Rotate( Z_AX, 90) ; - Vector3d vtW2 = ( vtTemp * vtV2 > 0 ? vtTemp : - vtTemp) ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - double dCylH = m_dHeight - m_dRadius ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - double dZInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - double dZSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - - Point3d ptC( dX, dY, 0) ; - Vector3d vtC = ptC - ptIxy ; - - double dProj1 = vtC * vtV1 ; // vtV1 è vtToolDir che per il momento giace nel piano - double dProj2 = vtC * vtW2 ; // vtPlaneMove è stato normalizzato dopo averne calcolato la lunghezza - - // Parte cilindrica - if ( dProj1 < 0 && dProj1 > - dCylH && dProj2 > - m_dRadius && dProj2 < dPlanePath + m_dRadius) { - - // Minimi - if ( dProj2 > - m_dRadius && dProj2 < dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dPlaneLim && dProj2 < dPlanePath + dPlaneLim) { - - dMin = dZInf ; - } - else if ( dProj2 >= dPlanePath + dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMin = dZF - dH ; - } - // Massimi - if ( dProj2 > - m_dRadius && dProj2 < - dPlaneLim) { - - double dH = sqrt( m_dRadius * m_dRadius - dProj2 * dProj2) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dPlaneLim && dProj2 < dPlanePath - dPlaneLim) { - - dMax = dZSup ; - } - else if ( dProj2 >= dPlanePath - dPlaneLim && dProj2 < dPlanePath + m_dRadius) { - - double dH = sqrt( m_dRadius * m_dRadius - ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath)) ; - - dMax = dZF + dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - // Parte sferica - else if ( dProj1 <= - dCylH && ( ( dProj2 > - m_dRadius && dProj2 < 0 && dProj2 * dProj2 + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius) || - ( dProj2 >= 0 && dProj2 < dPlanePath && dProj1 > - m_dHeight) || - ( dProj2 >= dPlanePath && dProj2 < dPlanePath + m_dRadius && ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + (- dProj1 - dCylH) * (- dProj1 - dCylH) < m_dRadius * m_dRadius))) { - - - double dSemiMin = dPlaneLim ; double dSemiMax = m_dRadius ; // Semi-assi dell'ellisse - double dl = - dProj1 - dCylH ; - - // Massimi - if ( dProj2 < - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dr = sqrt( dProj2 * dProj2 + dl * dl) ; - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMax = dZI + dH ; - } - else if ( dProj2 < dPlanePath - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dCos = abs( vtV3 * Z_AX) ; - - dMax = dZI + sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ; - } - else { - - double dL = dProj2 - dPlanePath ; - double dr = sqrt( dL * dL + dl * dl) ; - - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMax = dZF + dH ; - } - - // Minimi - if ( dProj2 < dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dr = sqrt( dProj2 * dProj2 + dl * dl) ; - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMin = dZI - dH ; - } - else if ( dProj2 < dPlanePath + dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) { - - double dCos = abs( vtV3 * Z_AX) ; - - dMin = dZI - sqrt( m_dRadius * m_dRadius - dl * dl) * dCos + ( dDeltaZ / dPlanePath) * ( dProj2 - dSemiMin * sqrt( 1 - ( dl * dl) / ( dSemiMax * dSemiMax))) ; - } - else { - - double dr = sqrt( ( dProj2 - dPlanePath) * ( dProj2 - dPlanePath) + dl * dl) ; - double dH = sqrt( m_dRadius * m_dRadius - dr * dr) ; - - dMin = dZF - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ) ; - - if ( ! Control) - return true ; - - double dCylH = m_dHeight - m_dTipHeight ; - - // Parte cilindrica - m_nToolType = CylindricalMill ; - m_dHeight = dCylH ; - - MillingXY( ptLs, ptLe, vtToolDir) ; - - m_nToolType = ConusMill ; - m_dHeight = m_dHeight + m_dTipHeight ; - - Vector3d vtV1, vtV2, vtV3 ; - Point3d ptI, ptF ; - - double dStem ; - - double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dDeltaR = dMaxRad - dMinRad ; - - // Studio della parte conica - if ( m_dRadius > m_dTipRadius) { - - vtV1 = vtToolDir ; - dStem = - dCylH ; - } - else { - - vtV1 = - vtToolDir ; - dStem = m_dHeight ; - } - - ptI = ( ptLs.z < ptLe.z ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; - ptF = ( ptLs.z < ptLe.z ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; double dZI = ptI.z ; double dDeltaZ = ptF.z - ptI.z ; - - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; double dPLen = vtMoveXY.LenXY() ; - Vector3d vtU2 = vtV1 ; vtU2.Rotate(Z_AX, 90) ; - - if ( vtMoveXY * vtU2 < 0) - - vtU2 = - vtU2 ; - - vtV2 = vtMove ; vtV2.Normalize() ; - vtV3 = vtV1 ^ vtV2 ; - - Point3d ptV = ptI - vtV1 * ( dMaxRad * m_dTipHeight / ( dMaxRad - dMinRad)) ; - - Vector3d vtV3XY( vtV3.x, vtV3.y, 0) ; - - double dPrV3 = vtV3XY.LenXY() ; - double dRl = dMaxRad * dPrV3 ; - double drl = dMinRad * dPrV3 ; - double dDl = dDeltaR * dPrV3 ; - - // Apertura del cono e parametri per determinare i piani - double dTanAlpha = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTanAlpha * dRatio ; - double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTanAlpha * dTanAlpha) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTanAlpha / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; - - Vector3d vtR0 = ptV - ORIG ; - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - - double dProj1 = - vtC * vtV1 ; double dProj2 = vtC * vtU2 ; - - if ( dProj1 > 0 && dProj1 < m_dTipHeight && - dProj2 > - dMaxRad + dProj1 * dDeltaR / m_dTipHeight && - dProj2 < dPLen + dMaxRad - dProj1 * dDeltaR / m_dTipHeight) { - /* - if ( dProj2 < - dRl + dProj1 * dDl / m_dTipHeight) { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - dProj2 * dProj2) ; - - dMin = dZI - dH ; - dMax = dZI + dH ; - } - else if ( dProj2 >= - dRl + dProj1 * dDl / m_dTipHeight && - dProj2 < dRl - dProj1 * dDl / m_dTipHeight) { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - dProj2 * dProj2) ; - - dMin = dZI - dH ; - dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - else if ( dProj2 >= dRl - dProj1 * dDl / m_dTipHeight && - dProj2 < dPLen - dRl + dProj1 * dDl / m_dTipHeight) { - - dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - dMax = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - } - else if ( dProj2 >= dPLen - dRl + dProj1 * dDl / m_dTipHeight && - dProj2 < dPLen + dRl - dProj1 * dDl / m_dTipHeight) { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; - - dMin = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; - dMax = dZI + dDeltaZ + dH ; - } - else { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; - - dMin = dZI + dDeltaZ - dH ; - dMax = dZI + dDeltaZ + dH ; - } */ - - // Massimi - if ( dProj2 < - dRl + dProj1 * dDl / m_dTipHeight) { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - dProj2 * dProj2) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dRl + dProj1 * dDl / m_dTipHeight && - dProj2 < dPLen - dRl + dProj1 * dDl / m_dTipHeight) - - dMax = ( vtV3.z < 0 ? ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z : ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z) ; - else { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; - - dMax = dZI + dDeltaZ + dH ; - } - - // Minimi - if ( dProj2 < dRl - dProj1 * dDl / m_dTipHeight) { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - dProj2 * dProj2) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dRl - dProj1 * dDl / m_dTipHeight && - dProj2 < dPLen + dRl - dProj1 * dDl / m_dTipHeight) - - dMin = ( vtV3.z < 0 ? ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z : ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z) ; - - else { - - double dr = dMaxRad - dProj1 * dDeltaR / m_dTipHeight ; - double dH = sqrt( dr * dr - ( dProj2 - dPLen) * ( dProj2 - dPLen)) ; - - dMin = dZI + dDeltaZ - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) { - - if ( m_nToolType == CylindricalMill) - - return MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == BallEndMill) - - return MillingXYPlusBall( ptLs, ptLe, vtToolDir) ; - - else if ( m_nToolType == ConusMill) - - return MillingXYPlusConus( ptLs, ptLe, vtToolDir) ; - - else - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlusCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dMinZ = min( ptLs.z, ptLe.z) - m_dRadius ; - double dMaxZ = max( ptLs.z, ptLe.z) + m_dRadius ; - - // Prima verifica sull'interferenza dell'utensile con lo Zmap - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return true ; - - Point3d ptI, ptF ; - - if ( ptLs.z <= ptLe.z) { - ptI = ptLs ; - ptF = ptLe ; - } - else { - ptI = ptLe ; - ptF = ptLs ; - } - - // Quote dei punti ptI e ptF e DeltaZ - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - Point3d ptIT = ptI - vtToolDir * m_dHeight ; - Point3d ptFT = ptF - vtToolDir * m_dHeight ; - - // Bounding box - double dMinX = min( min( ptI.x, ptIT.x), min( ptF.x, ptFT.x)) - m_dRadius ; - double dMaxX = max( max( ptI.x, ptIT.x), max( ptF.x, ptFT.x)) + m_dRadius ; - double dMinY = min( min( ptI.y, ptIT.y), min( ptF.y, ptFT.y)) - m_dRadius ; - double dMaxY = max( max( ptI.y, ptIT.y), max( ptF.y, ptFT.y)) + m_dRadius ; - - // Seconda verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Vettori di riferimento nello spazio e controllo per simmetria - Vector3d vtMove = ptF - ptI ; - Vector3d vtTool = vtToolDir ; - - if ( vtToolDir * vtMove > 0) { - - Point3d ptTemp = ptI ; - ptI = ptIT ; ptIT = ptTemp ; - ptTemp = ptF ; - ptF = ptFT ; - ptFT = ptTemp ; - vtTool = - vtTool ; - } - - Vector3d vtMoveLong = ( vtMove * vtTool) * vtTool ; double dLen1 = vtMoveLong.Len() ; - Vector3d vtMoveOrt = vtMove - vtMoveLong ; double dLen2 = vtMoveOrt.Len() ; - - // Vettori di riferimento nel piano - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; - Vector3d vtPlaneMoveLong( vtMoveLong.x, vtMoveLong.y, 0) ; double dPLen1 = vtPlaneMoveLong.LenXY() ; - Vector3d vtPlaneMoveOrt( vtMoveOrt.x, vtMoveOrt.y, 0) ; double dPLen2 = vtPlaneMoveOrt.LenXY() ; vtPlaneMoveOrt.Normalize() ; - - // Punti iniziale e finale proiettati sul piano - Point3d ptIxy( ptI.x, ptI.y, 0) ; Point3d ptFxy( ptF.x, ptF.y, 0) ; - - // Determino i sistemi di riferimento del movimento: costruisco un sistrema di vettori ortonormali e destrorsi spiccati dal punto iniziale del movimento - Vector3d vtV1 = vtTool ; - Vector3d vtV2 = vtMoveOrt ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Determinazione punti notevoli del volume spazzato dall'utensile - Point3d ptPlaneSup, ptPlaneInf ; - - if ( vtV3.z > 0) { - ptPlaneInf = ptI - m_dRadius * vtV3 ; - ptPlaneSup = ptI + m_dRadius * vtV3 ; - } - else { - ptPlaneInf = ptI + m_dRadius * vtV3 ; - ptPlaneSup = ptI - m_dRadius * vtV3 ; - } - - Point3d ptPlaneSupxy( ptPlaneSup.x, ptPlaneSup.y, 0) ; - Point3d ptPlaneInfxy( ptPlaneInf.x, ptPlaneInf.y, 0) ; - - double dr = sqrt( ( ptPlaneSupxy - ptIxy) * ( ptPlaneSupxy - ptIxy)) ; - - // Determinazione degli analoghi punti sulla punta dell'utensile e delle loro proiezioni sul piano XY - Point3d ptPlTInf = ptPlaneInf - m_dHeight * vtTool ; Point3d ptPlTInfxy( ptPlTInf.x, ptPlTInf.y, 0) ; - Point3d ptPlTSup = ptPlaneSup - m_dHeight * vtTool ; Point3d ptPlTSupxy( ptPlTSup.x, ptPlTSup.y, 0) ; - - // Prodotti scalari per costruire i piani passanti per i punti notevoli - Vector3d vtR0Inf = ptPlaneInf - ORIG ; - Vector3d vtR0Sup = ptPlaneSup - ORIG ; - Vector3d vtR0 = ptI - ORIG ; - double dPInf = vtR0Inf * vtV3 ; double dPSup = vtR0Sup * vtV3 ; double dP = vtR0 * vtV3 ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - double dZPInf = ( dPInf - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano inferiore come funzione di x e y - double dZPSup = ( dPSup - vtV3.x * dX - vtV3.y * dY) / vtV3.z ; // Quota Z Piano superiore come funzione di x e y - - // Punto e vettori del ciclo - Point3d ptC( dX, dY, 0) ; Vector3d vtCi = ptC - ptIxy ; - // Proiezione fondamentale - double dPro1 = vtCi * vtV1 ; double dPro2 = vtCi * vtPlaneMoveOrt ; - - - // Se il punto cade nella proiezione sul piano XY del volume spazzato si taglia - if ( ((dPro2 > - m_dRadius && dPro2 < m_dRadius) && (((dPro2 < dPLen2 - m_dRadius && (dPro1 > - m_dHeight - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) && dPro1 < 0))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < 0)))) - || ((dPro2 >= m_dRadius && dPro2 < dPLen2 + m_dRadius) && ((dPro2 < dPLen2 - m_dRadius && (dPro1 > - (dPLen1 / dPLen2) * (dPro2 + m_dRadius) - m_dHeight && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius))) || (dPro2 >= dPLen2 - m_dRadius && (dPro1 > - m_dHeight - dPLen1 && dPro1 < - (dPLen1 / dPLen2) * (dPro2 - m_dRadius)))))) { - - // Massimi ////////////////////////////////////////////////////////////////////////// - // Prima zona cilindrica superiore - if ( ( dPro2 > - m_dRadius && dPro2 < - dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; - - dMax = dZI + dH ; - } - - // Vettore per seconda zona cilindrica superiore - Vector3d vtCf = ptC - ptFxy ; - // Proiezione per seconda zona cilindrica sueriore - double dPr1 = vtCf * vtV1 ; double dPr2 = vtCf * vtPlaneMoveOrt ; - - // Seconda zona cilindrica superiore - if ( ( dPr2 >= - dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; - - dMax = dZF + dH ; - } - - // Vettore per Piano superiore e zona di fondo superiore - Vector3d vtCS = ptC - ptPlaneSupxy ; - // Proiezioni - double dPrS1 = vtCS * vtV1 ; double dPrS2 = vtCS * vtPlaneMoveOrt ; - - // Piano superiore - if ( dPrS2 >= 0 && dPrS2 < dPLen2 && dPrS1 > - m_dHeight - ( dPLen1/dPLen2) * dPrS2 && dPrS1 <= - ( dPLen1/dPLen2) * dPrS2) - - dMax = dZPSup ; - - // Vettore per zona di punta superiore - Vector3d vtCTS = ptC - ptPlTSupxy ; - // Proiezioni - double dPrTS1 = vtCTS * vtV1 ; double dPrTS2 = vtCTS * vtPlaneMoveOrt ; - - // Zona di punta superiore - if ( dPrTS1 <= 0 && dPrTS1 > - dPLen1) - if ( dPrTS2 <= - ( dPLen2 / dPLen1) * dPrTS1 && dPrTS2 > - ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrTS1) { - - double dDist = - ( dPLen2 / dPLen1) * dPrTS1 - dPrTS2 ; - double dL = dDist + dr ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrTS1 * dPrTS1 + ( ( dPLen2 / dPLen1) * dPrTS1) * ( ( dPLen2 / dPLen1) * dPrTS1)) ; - - dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; - } - - // Zona di fondo superiore - if ( dPrS1 < 0 && dPrS1 > - dPLen1) - if ( dPrS2 > - ( dPLen2 / dPLen1) * dPrS1 && dPrS2 < m_dRadius + dr - ( dPLen2 / dPLen1) * dPrS1) { - - double dL = abs( dr - ( dPLen2 / dPLen1) * dPrS1 - dPrS2) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrS1 * dPrS1 + ( ( dPLen2 / dPLen1) * dPrS1) * ( ( dPLen2 / dPLen1) * dPrS1)) ; - - dMax = dZI + ( dDeltaZ / dPLen) * dl + dH ; - } - - // Minimi ////////////////////////////////////////////////////////////////////////// - // Prima zona cilindrica inferiore - if ( ( dPro2 > - m_dRadius && dPro2 < dr) && ( dPro1 > - m_dHeight && dPro1 < 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPro2 * dPro2) ; - - dMin = dZI - dH ; - } - - // Seconda zona cilindrica inferiore - if ( ( dPr2 >= dr && dPr2 < m_dRadius) && ( dPr1 > - m_dHeight && dPr1 <= 0)) { - - double dH = sqrt( m_dRadius * m_dRadius - dPr2 * dPr2) ; - - dMin = dZF - dH ; - } - - // Vettore per piano inferiore e zona di fondo inferiore - Vector3d vtCI = ptC - ptPlaneInfxy ; - // Proiezioni - double dPrI1 = vtCI * vtV1 ; double dPrI2 = vtCI * vtPlaneMoveOrt ; - - // Piano inferiore - if ( dPrI2 >= 0 && dPrI2 < dPLen2 && dPrI1 > - m_dHeight - ( dPLen1/dPLen2) * dPrI2 && dPrI1 <= - ( dPLen1/dPLen2) * dPrI2) - - dMin = dZPInf ; - - // Zona di fondo inferiore - if ( dPrI1 <= 0 && dPrI1 > - dPLen1) - if ( dPrI2 > - ( dPLen2 / dPLen1) * dPrI1 && dPrI2 < ( m_dRadius - dr) - ( dPLen2 / dPLen1) * dPrI1) { - - double dDist = dPrI2 + ( dPLen2 / dPLen1) * dPrI1 ; - double dL = dDist + dr ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrI1 * dPrI1 + ( ( dPLen2 / dPLen1) * dPrI1) * ( ( dPLen2 / dPLen1) * dPrI1)) ; - - dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; - } - - // Vettore per zona di punta inferiore - Vector3d vtCTI = ptC - ptPlTInfxy ; - // Proiezioni - double dPrTI1 = vtCTI * vtV1 ; double dPrTI2 = vtCTI * vtPlaneMoveOrt ; - - // zona di punta inferiore - if ( dPrTI1 <= 0 && dPrTI1 > - dPLen1) - if ( dPrTI2 > - m_dRadius - dr - ( dPLen2 / dPLen1) * dPrTI1 && dPrTI2 < - ( dPLen2 / dPLen1) * dPrTI1) { - - double dL = abs( - dr - ( dPLen2 / dPLen1) * dPrTI1 - dPrTI2) ; - double dH = ( m_dRadius * m_dRadius - dL * dL > 0 ? sqrt( m_dRadius * m_dRadius - dL * dL) : 0) ; - double dl = sqrt( dPrTI1 * dPrTI1 + ( ( dPLen2 / dPLen1) * dPrTI1) * ( ( dPLen2 / dPLen1) * dPrTI1)) ; - - dMin = dZI + ( dDeltaZ / dPLen) * dl - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlusBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Parte cilindrica - - double dCylH = m_dHeight - m_dRadius ; - - m_dHeight = dCylH ; - - MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; - - m_dHeight = m_dHeight + m_dRadius ; - //////////////////////////////////////// - Point3d ptI, ptF ; - - if ( ptLs.z < ptLe.z) { - - ptI = ptLs ; - ptF = ptLe ; - } - else { - - ptI = ptLe ; - ptF = ptLs ; - } - - double dZI = ptI.z ; double dZF = ptF.z ; double dDeltaZ = dZF - dZI ; - - Point3d ptCI = ptI - dCylH * vtToolDir ; - Point3d ptCF = ptF - dCylH * vtToolDir ; - - Point3d ptCIxy( ptCI.x, ptCI.y, 0) ; - - // Bounding box - double dMinX = min( ptCI.x, ptCF.x) - m_dRadius ; - double dMaxX = max( ptCI.x, ptCF.x) + m_dRadius ; - double dMinY = min( ptCI.y, ptCF.y) - m_dRadius ; - double dMaxY = max( ptCI.y, ptCF.y) + m_dRadius ; - - Vector3d vtMove = ptF - ptI ; - Vector3d vtPlaneMove( vtMove.x, vtMove.y, 0) ; double dPLen = vtPlaneMove.LenXY() ; vtMove.Normalize() ; - - // Sistema di riferimento nel piano - Vector3d vtV2 = vtPlaneMove ; vtV2.Normalize() ; double dComp1 = vtV2 * X_AX ; double dComp2 = vtV2 * Y_AX ; - Vector3d vtV1 = dComp2 * X_AX - dComp1 * Y_AX ; - - // Determino il semi-asse minore - double dOriz = vtMove * Z_AX ; double dVert = vtMove * vtV2 ; - - double dSemiAxMin = m_dRadius * dOriz ; - - // Determinazione limiti sugli indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dMin, dMax ; - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - - Vector3d vtC = ptC - ptCIxy ; - - double dProj1 = vtC * vtV1 ; double dProj2 = vtC * vtV2 ; - - double dSqRadDistI = dProj1 * dProj1 + dProj2 * dProj2 ; - double dSqRadDistF = dProj1 * dProj1 + ( dProj2 - dPLen) * ( dProj2 - dPLen) ; - double dSqAxDist = dProj1 * dProj1 ; - - if ( ( dProj2 < 0 && dSqRadDistI < m_dRadius * m_dRadius) || - ( dProj2 >= 0 && dProj2 < dPLen && dSqAxDist < m_dRadius * m_dRadius) || - ( dProj2 >= dPLen && dSqRadDistF < m_dRadius * m_dRadius)) { - - // Massimi - if ( dProj2 < - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; - - dMax = dZI + dH ; - } - else if ( dProj2 >= - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) && - dProj2 < dPLen - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dProj0 = - dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ; - double dZ0 = dZI + dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ; - - dMax = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; - - dMax = dZF + dH ; - } - - // Minimi - if ( dProj2 < dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistI) ; - - dMin = dZI - dH ; - } - else if ( dProj2 >= dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) && - dProj2 < dPLen + dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius))) { - - double dProj0 = dSemiAxMin * sqrt( 1 - ( dSqAxDist) / ( m_dRadius * m_dRadius)) ; - double dZ0 = dZI - dVert * sqrt( m_dRadius * m_dRadius - dSqAxDist) ; - - dMin = dZ0 + ( dDeltaZ / dPLen) * ( dProj2 - dProj0) ; - } - else { - - double dH = sqrt( m_dRadius * m_dRadius - dSqRadDistF) ; - - dMin = dZF - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingXYPlusConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - double dMin, dMax ; - - bool Control = BoundingBox( ptLs, ptLe, vtToolDir, vtToolDir) ; - - if ( Control == false) - - return true ; - - double dMinRad = min( m_dRadius, m_dTipRadius) ; - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - double dDeltaR = dMaxRad - dMinRad ; - - double dCylH = m_dHeight - m_dTipHeight ; - - // Parte cilindrica - m_nToolType = CylindricalMill ; - m_dHeight = dCylH ; - - MillingXYPlusCyl( ptLs, ptLe, vtToolDir) ; - - m_nToolType = ConusMill ; - m_dHeight = m_dHeight + m_dTipHeight ; - - // Variabili di interesse per la parte conica - Vector3d vtV1, vtV2, vtV3 ; - Point3d ptI, ptF ; - - double dStem ; - - // Studio della parte conica - if ( m_dRadius > m_dTipRadius) { - - vtV1 = vtToolDir ; - dStem = - dCylH ; - } - else { - - vtV1 = - vtToolDir ; - dStem = m_dHeight ; - } - - ptI = ( ptLs.z < ptLe.z ? ptLs + vtV1 * dStem : ptLe + vtV1 * dStem) ; - ptF = ( ptLs.z < ptLe.z ? ptLe + vtV1 * dStem : ptLs + vtV1 * dStem) ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveLong = ( vtMove * vtV1) * vtV1 ; - Vector3d vtMoveOrt = vtMove - vtMoveLong ; - Vector3d vtMoveLongXY( vtMoveLong.x, vtMoveLong.y, 0) ; - Vector3d vtMoveOrtXY( vtMoveOrt.x, vtMoveOrt.y, 0) ; - - double dPLen1 = vtMoveLongXY.LenXY() ; - double dPLen2 = vtMoveOrtXY.LenXY() ; - double dPLen = sqrt( dPLen1 * dPLen1 + dPLen2 * dPLen2) ; - - vtV2 = ( vtMove * vtV1 > 0 ? vtMoveOrt : - vtMoveOrt) ; vtV2.Normalize() ; - vtV3 = vtV1 ^ vtV2 ; - - Vector3d vtU2 = vtMoveOrtXY ; vtU2.Normalize() ; - - Point3d ptV = ptI - vtV1 * ( ( dMaxRad * m_dTipHeight) / ( dDeltaR)) ; - - // Apertura del cono e parametri per determinare i piani - double dTan = ( dMaxRad - dMinRad) / m_dTipHeight ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTan * dRatio ; // dCos è compreso fra 0 e 1 poiché alpha è compreso fra 0 e Pi mezzi - double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - double dZI = ptI.z ; - double dDeltaZ = ptF.z - ptI.z ; - // double dCornerSlope = atan2( dDeltaZ, dPLen1) ; // dCornerSlope è compreso fra 0 ° e 90 °, per come è costruito il movimento, ma espresso in radianti - - // Punti di tagenza piano cono - Point3d ptPrs = ptI - vtV1 * m_dTipHeight + dMinRad * ( dCos * vtV2 + sqrt( 1 - dCos * dCos) * vtV3) ; - Point3d ptPRs = ptI + dMaxRad * ( dCos * vtV2 + sqrt( 1 - dCos * dCos) * vtV3) ; - Point3d ptPrd = ptI - vtV1 * m_dTipHeight + dMinRad * ( dCos * vtV2 - sqrt( 1 - dCos * dCos) * vtV3) ; - Point3d ptPRd = ptI + dMaxRad * ( dCos * vtV2 - sqrt( 1 - dCos * dCos) * vtV3) ; - - Point3d ptRInf = ( ptPRs.z < ptPRd.z ? ptPRs : ptPRd) ; - Point3d ptRSup = ( ptPRs.z < ptPRd.z ? ptPRd : ptPRs) ; - Point3d ptrInf = ( ptPrs.z < ptPrd.z ? ptPrs : ptPrd) ; - Point3d ptrSup = ( ptPrs.z < ptPrd.z ? ptPrd : ptPrs) ; - - // Versori normali e prodotti scalari per per determinare i piani - Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; - - Vector3d vtR0 = ptV - ORIG ; - - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - // Sistema di riferimento del movimento - Vector3d vtU3 = vtV1 ^ vtU2 ; - Frame3d MoveFrame ; MoveFrame.Set( ptI, vtV1, vtU2, vtU3) ; - - ptRInf.LocToLoc( m_LocalFrame, MoveFrame) ; double dPRInf = ptRInf.y ; - ptRSup.LocToLoc( m_LocalFrame, MoveFrame) ; double dPRSup = ptRSup.y ; - ptrInf.LocToLoc( m_LocalFrame, MoveFrame) ; double dPrInf = ptrInf.y ; - ptrSup.LocToLoc( m_LocalFrame, MoveFrame) ; double dPrSup = ptrSup.y ; - - // dMinX dMaxX dMinY dMaxY - double dMinX = min( min( ptI.x, ptF.x), min( ptI.x - vtV1.x * m_dTipHeight, ptF.x - vtV1.x * m_dTipHeight)) - dMaxRad; - double dMinY = min( min( ptI.y, ptF.y), min( ptI.y - vtV1.y * m_dTipHeight, ptF.y - vtV1.y * m_dTipHeight)) - dMaxRad; - double dMaxX = max( max( ptI.x, ptF.x), max( ptI.x - vtV1.x * m_dTipHeight, ptF.x - vtV1.x * m_dTipHeight)) + dMaxRad; - double dMaxY = max( max( ptI.y, ptF.y), max( ptI.y - vtV1.y * m_dTipHeight, ptF.y - vtV1.y * m_dTipHeight)) + dMaxRad; - - // Verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return true ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return true ; - - // Limiti su indici - unsigned int nStartI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - unsigned int nEndI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - unsigned int nStartJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - unsigned int nEndJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX, dY ; dX = ( i + 0.5) * m_dStep ; dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - - double dI1 = vtC * vtV1 ; double dI2 = vtC * vtU2 ; - - - if ( dRatio <= 1 / dTan) { - - - if ( vtMove * vtV1 > 0) { - - - double dLimInf = max( - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight, - dMaxRad + dI1 * ( dPLen2 / dPLen1)) ; - double dLimSup = min( dMinRad + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1), dPLen2 + dMinRad + ( dI1 - dPLen1 + m_dTipHeight) * ( dMaxRad - dMinRad) / m_dTipHeight) ; - - if ( dI1 > - m_dTipHeight && dI1 < dPLen1 && dI2 > dLimInf && dI2 < dLimSup) { - - // Massimi - if ( dI1 > 0 && dI2 < dPRSup + dI1 * ( dPLen2 / dPLen1)) { - - double dr = dI1 * ( dPLen2 / dPLen1) - dI2 ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato - double dl = dI1 * sqrt( 1 + (dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; - - dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; - } - else if ( dI1 < dPLen1 - m_dTipHeight && dI2 > dPrSup + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { - - double dr = dI2 - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato - double dl = ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; - // Controllare da qui - dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; - } - else if ( dI1 <= 0 && dI2 < dPRSup + dI1 * ( dPRSup - dPrSup) / m_dTipHeight) { - - double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = sqrt( dr * dr - dI2 * dI2) ; - - dMax = dZI + dH ; - } - else if ( dI1 >= dPLen1 - m_dTipHeight && dI2 > dPLen2 + dPRSup + ( dI1 - dPLen1) * ( dPRSup - dPrSup) / m_dTipHeight) { - - double dr = dMaxRad + ( dI1 - dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) ; - - dMax = dZI + dDeltaZ + dH ; - } - else - - dMax = max( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ; - - - - // Minimi - if ( dI1 > 0 && dI2 < dPRInf + dI1 * ( dPLen2 / dPLen1)) { - - double dr = dI1 * ( dPLen2 / dPLen1) - dI2 ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato - double dl = dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; - - dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; - } - else if ( dI1 < dPLen1 - m_dTipHeight && dI2 > dPrInf + ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { - - double dr = dI2 - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) ; // Non serve prenderne il valore assoluto poiché viene elevato a quadrato - double dl = ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; - - dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; - } - else if ( dI1 <= 0 && dI2 < dPRInf + dI1 * ( dPRInf - dPrInf) / m_dTipHeight) { - - double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = sqrt( dr * dr - dI2 * dI2) ; - - dMin = dZI - dH ; - } - else if ( dI1 >= dPLen1 - m_dTipHeight && dI2 > dPLen2 + dPRInf + ( dI1 - dPLen1) * ( dPRInf - dPrInf) / m_dTipHeight) { - - double dr = dMaxRad + ( dI1 - dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) ; - - dMin = dZI + dDeltaZ - dH ; - } - else - - dMin = min( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ; - - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - // vtMove * vtV1 < 0 - else { - - double dLimInf = max( - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight, - dMinRad - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) ; - double dLimSup = min( dMaxRad - dI1 * ( dPLen2 / dPLen1), dPLen2 + dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight) ; - - if ( dI1 > - dPLen1 - m_dTipHeight && dI1 < 0 && dI2 > dLimInf && dI2 < dLimSup) { - - // Massimi - if ( dI1 > - m_dTipHeight && dI2 < dPRSup + dI1 * ( dPRSup - dPrSup) / m_dTipHeight) { - - double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = ( dr * dr - dI2 * dI2 > 0 ? sqrt( dr * dr - dI2 * dI2) : 0) ; - - dMax = dZI + dH ; - } - else if ( dI1 < - dPLen1 && dI2 > dPLen2 + dPRSup + (dI1 + dPLen1) * ( dPRSup - dPrSup) / m_dTipHeight) { - - double dr = dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = ( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2) > 0 ? sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) : 0) ; - - dMax = dZI + dDeltaZ + dH ; - } - else if ( dI1 < - m_dTipHeight && dI2 < dPrSup - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { - - double dr = - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) - dI2 ; - double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; - double dl = - ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - - dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; - } - else if ( dI1 > - dPLen1 && dI2 > dPRSup - dI1 * ( dPLen2 / dPLen1)) { - - double dr = dI2 + dI1 * ( dPLen2 / dPLen1) ; - double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; - double dl = - dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - - dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; - } - else - - dMax = max( ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z, ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z ) ; - - - // Minimi - if ( dI1 > - m_dTipHeight && dI2 < dPRInf + dI1 * ( dPRInf - dPrInf) / m_dTipHeight) { - - double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = ( dr * dr - dI2 * dI2 > 0 ? sqrt( dr * dr - dI2 * dI2) : 0) ; - - dMin =dZI - dH ; - } - else if ( dI1 < - dPLen1 && dI2 > dPLen2 + dPRInf + ( dI1 + dPLen1) * ( dPRInf - dPrInf) / m_dTipHeight) { - - double dr = dMaxRad + ( dI1 + dPLen1) * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = ( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2) > 0 ? sqrt( dr * dr - ( dI2 - dPLen2) * ( dI2 - dPLen2)) : 0) ; - - dMin = dZI + dDeltaZ - dH ; - - } - else if ( dI1 < - m_dTipHeight && dI2 < dPrInf - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1)) { - - double dr = - ( dI1 + m_dTipHeight) * ( dPLen2 / dPLen1) - dI2 ; - double dH = ( dMinRad * dMinRad - dr * dr > 0 ? sqrt( dMinRad * dMinRad - dr * dr) : 0) ; - double dl = - ( dI1 + m_dTipHeight) * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - - dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; - } - else if ( dI1 > - dPLen1 && dI2 > dPRInf - dI1 * ( dPLen2 / dPLen1)) { - - double dr = dI2 + dI1 * ( dPLen2 / dPLen1) ; - double dH = ( dMaxRad * dMaxRad - dr * dr > 0 ? sqrt( dMaxRad * dMaxRad - dr * dr) : 0) ; - double dl = - dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - - dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; - } - else - - dMin = min( ( dDotd - vtNd.x * dX - vtNd.y * dY) / vtNd.z, ( dDots - vtNs.x * dX - vtNs.y * dY) / vtNs.z) ; - - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - // dRatio <= 1 / dTan - else { - - if ( dI1 > - m_dTipHeight && dI1 < 0 && - dI2 > - dMaxRad - dI1 * ( dMaxRad - dMinRad) / m_dTipHeight && - dI2 < dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight) { - - double dr = dMaxRad + dI1 * ( dMaxRad - dMinRad) / m_dTipHeight ; - double dH = sqrt( dr * dr - dI2 * dI2) ; - - dMin = dZI - dH ; - dMax = dZI + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( dI1 >= 0 && dI1 < dPLen1 && - dI2 > - dMaxRad + dI1 * ( dPLen2 / dPLen1) && - dI2 < dMaxRad + dI1 * ( dPLen2 / dPLen1)) { - - double dl = dI1 * sqrt( 1 + ( dPLen2 * dPLen2) / ( dPLen1 * dPLen1)) ; - double dr = dI2 - dI1 * dPLen2 / dPLen1 ; - double dH = sqrt( dMaxRad * dMaxRad - dr * dr) ; - - dMin = dZI + dl * ( dDeltaZ / dPLen) - dH ; - dMax = dZI + dl * ( dDeltaZ / dPLen) + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -// Virtual milling per componenti - -// Versore utensile nella direzione dell'asse Z - -// Foratura -//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -bool -VolZmap::DrillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve ; - - pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso segmento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - LongCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - LongConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utesile - else if ( ptStart.x < ptEnd.x) { - - double dMaxRad = ptEnd.x ; - double dMinRad = ptStart.x ; - - Point3d ptIn = ptI - vtToolDir * dHeight ; - Point3d ptFn = ptIn + vtMove ; - - LongConusV( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - } - else - dHeight = 0 ; - } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.GetNextCurve() ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::LongCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) { - - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - - if ( Control == false) - - return true ; - - Point3d ptI = ( ( ptLe - ptLs) * vtToolDir > 0 ? ptLe : ptLs) ; - Point3d ptF = ( ( ptLe - ptLs) * vtToolDir > 0 ? ptLs - dHei * vtToolDir : ptLe - dHei * vtToolDir) ; - - if ( ptI.z > ptF.z) { - - Point3d ptTemp = ptI ; - ptI = ptF ; - ptF = ptTemp ; - } - - Point3d ptO( ptI.x, ptI.y, 0) ; - - double dZI = ptI.z ; - double dZF = ptF.z ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; - - double dSqDist = vtC * vtC ; - - if ( dSqDist < dRad * dRad) - - SubtractIntervals( i, j, dZI, dZF) ; - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::LongConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dMaxRad, double dMinRad) { - - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - - if ( Control == false) - - return true ; - - Point3d ptO( ptLs.x, ptLs.y, 0) ; - - double dZMin, dZMax ; - - double dAngC = dHei / ( dMaxRad - dMinRad) ; - - if ( vtToolDir.z > 0) { - - dZMin = ( ptLs.z < ptLe.z ? ptLs.z - dHei : ptLe.z - dHei) ; - dZMax = ( ptLs.z < ptLe.z ? ptLe.z : ptLs.z) ; - } - else { - - dZMin = ( ptLs.z < ptLe.z ? ptLs.z : ptLe.z) ; - dZMax = ( ptLs.z < ptLe.z ? ptLe.z + dHei : ptLs.z + dHei) ; - } - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptO ; - - double dSqDist = vtC * vtC ; - - if ( dSqDist < dMinRad * dMinRad) - - SubtractIntervals( i, j, dZMin, dZMax) ; - - else if ( dSqDist < dMaxRad * dMaxRad) { - - double dr = sqrt( dSqDist) ; - - if ( vtToolDir.z > 0) - - SubtractIntervals( i, j, dZMin + dAngC * ( dr - dMinRad), dZMax) ; - else - SubtractIntervals( i, j, dZMin, dZMax - dAngC * ( dr - dMinRad)) ; - } - } - - return true ; -} - -// Fresatura - -//---------------------------------------------------------------------------- -bool -VolZmap::MillZ( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve ; - - pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso segmento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - MillCylV( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - MillConusV( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utensile - else if ( ptStart.x < ptEnd.x) { - - double dMaxRad = ptEnd.x ; - double dMinRad = ptStart.x ; - - Point3d ptIn = ptI - vtToolDir * dHeight ; - Point3d ptFn = ptIn + vtMove ; - - MillConusV( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - } - else - dHeight = 0 ; - } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.GetNextCurve() ; - } - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillCylV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - - if ( ! Control) - return true ; - - Point3d ptI, ptF ; - - if ( ( ptLe - ptLs) * vtToolDir < 0 && vtToolDir.z > 0) { - - ptI = ptLe ; - ptF = ptLs ; - } - else if ( ( ptLe - ptLs) * vtToolDir < 0 && vtToolDir.z < 0) { - - ptI = ptLs - dHei * vtToolDir ; - ptF = ptLe - dHei * vtToolDir ; - } - else if ( ( ptLe - ptLs) * vtToolDir > 0 && vtToolDir.z < 0) { - - ptI = ptLe - dHei * vtToolDir ; - ptF = ptLs - dHei * vtToolDir ; - } - else { - - ptI = ( vtToolDir.z > 0 ? ptLs : ptLs - vtToolDir * dHei) ; - ptF = ( vtToolDir.z > 0 ? ptLe : ptLe - vtToolDir * dHei) ; - } - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; - - Vector3d vtV1 = ptFxy - ptIxy ; double dPLen = vtV1.LenXY() ; vtV1.Normalize() ; - Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; - - double dZI = ptI.z ; - double dDeltaZ = ptF.z - ptI.z ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; //Vector3d vtCF = ptC - ptFxy ; - - double dX1 = vtC * vtV1 ; double dX2 = vtC * vtV2 ; - - double dLimX1 = sqrt( dRad * dRad - dX2 * dX2) ; - - if ( dX2 > - dRad && dX2 < dRad && - dX1 > - dLimX1 && - dX1 < dPLen + dLimX1) { - - // Massimi - if( dX1 > - dLimX1 && dX1 < dPLen - dLimX1) - - dMax = dZI + ( dX1 + dLimX1) * dDeltaZ / dPLen ; - - else if ( dX1 >= dPLen - dLimX1 && - dX1 < dPLen + dLimX1) - - dMax = dZI + dDeltaZ ; - - // Minimi - if ( dX1 > - dLimX1 && dX1 < dLimX1) - - dMin = dZI - dHei ; - - else if ( dX1 >= dLimX1 && - dX1 < dPLen + dLimX1) - - dMin = dZI - dHei + ( dX1 - dLimX1) * dDeltaZ / dPLen ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillConusV( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, - double dHei, double dMaxRad, double dMinRad) -{ - double dMin, dMax, dPLim, dMLim ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - - if ( ! Control) - return true ; - - Point3d ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; - Point3d ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; - - Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; - Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; - Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; - - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - double dZI = ptI.z ; - double dZTI = ptI.z - vtV1.z * dHei ; - double dDeltaZ = ptF.z - ptI.z ; - double dDeltaR = dMaxRad - dMinRad ; - - double dTan = dDeltaR / dHei ; - double dRatio = ( vtMove * vtV1) / ( vtMove * vtV2) ; - - double dCos = dTan * dRatio ; - double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - - Point3d ptV = ptI - vtV1 * ( dHei * dMaxRad / dDeltaR) ; - - Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; - Vector3d vtR0 = ptV - ORIG ; - - double dDots = vtR0 * vtNs ; - double dDotd = vtR0 * vtNd ; - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - - Vector3d vtCI = ptC - ptIxy ; double dSqDI = vtCI.SqLenXY() ; - Vector3d vtCF = ptC - ptFxy ; double dSqDF = vtCF.SqLenXY() ; - - double dIDO = vtCI * vtV3 ; - double dIDL = vtCI * vtV2 ; - double dIVarCos = dIDL / sqrt( dSqDI) ; - - double dFDL = vtCF * vtV2 ; - double dFVarCos = dFDL / sqrt( dSqDF) ; - - if ( dSqDI < dMaxRad * dMaxRad || dSqDF < dMaxRad * dMaxRad || - (abs( dIDO) < dMaxRad && dIDL > 0 && dIDL < dLOrt)) { - - // Caso dTan > 1 / dRatio - if ( dRatio > 1 / dTan) { - - // Limiti nella direzione positiva di vtV1 - if ( dSqDF < dMaxRad * dMaxRad) - - dPLim = dZI + dDeltaZ ; - - else - - dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; - - // Limiti nella direzione negativa di vtV1 - if ( dSqDI < dMinRad * dMinRad) - - dMLim = dZTI ; - - else if ( dSqDI < dMaxRad * dMaxRad) - - dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; - - else - - dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; - - } - else { - - // Limiti nella direzione positiva di vtV1 - if ( dSqDF < dMaxRad * dMaxRad) - - dPLim = dZI + dDeltaZ ; - - else - - dPLim = dZI + ( dIDL + sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; - - // Limiti nella direzione negativa di vtV1 - if ( dSqDI < dMinRad * dMinRad) - - dMLim = dZTI ; - - else if ( dSqDI >= dMinRad * dMinRad && dSqDI < dMaxRad * dMaxRad && dIVarCos < dCos) - - dMLim = dZTI + ( sqrt( dSqDI) - dMinRad) * ( dZI - dZTI) / dDeltaR ; - - else if ( dSqDI >= dMinRad * dMinRad && dIVarCos >= dCos && dFVarCos < dCos && abs( dIDO) < dMaxRad * dSin) { // da qui - - if ( dIDO > - dMaxRad * dSin && dIDO <= - dMinRad * dSin) - - dMLim = ( dDotd - dX * vtNd.x - dY * vtNd.y) / vtNd.z ; - - else if ( dIDO > - dMinRad * dSin && dIDO < dMinRad * dSin) - - dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; - - else if ( dIDO >= dMinRad * dSin && dIDO < dMaxRad * dSin) - - dMLim = ( dDots - dX * vtNs.x - dY * vtNs.y) / vtNs.z ; // a qui - } - else if ( dFVarCos >= dCos) { - - if ( dSqDF < dMinRad * dMinRad) - - dMLim = dZTI + ( dIDL - sqrt( dMinRad * dMinRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; - - else - - dMLim = dZTI + dDeltaZ + ( sqrt( dSqDF) - dMinRad) * ( dZI - dZTI) / dDeltaR ; - } - else - - dMLim = dZI + ( dIDL - sqrt( dMaxRad * dMaxRad - dIDO * dIDO)) * dDeltaZ / dLOrt ; - } - - dMin = min( dPLim, dMLim) ; - dMax = max( dPLim, dMLim) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -// Direzione generica del versore utensile -// Foratura -//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -bool -VolZmap::Drilling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - if ( m_nToolType == CylindricalMill) - - LongCyl( ptLs, ptLe, vtToolDir, m_dHeight, m_dRadius) ; - - else if ( m_nToolType == BallEndMill) { - - double dCylH = m_dHeight - m_dTipHeight ; - - LongCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; - - Point3d ptBs = ptLs - vtToolDir * ( m_dHeight - m_dTipHeight) ; - Point3d ptBe = ptLe - vtToolDir * ( m_dHeight - m_dTipHeight) ; - - Ball( ptBs, ptBe, m_dRadius) ; - } - - else if ( m_nToolType == BullNoseMill) - // Caso al momento non gestito - return false ; - - else if ( m_nToolType == ConusMill) { - - double dCylH = m_dHeight - m_dTipHeight ; - - LongCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; - - double dMinRad = ( m_dRadius > m_dTipRadius ? m_dTipRadius : m_dRadius) ; - double dMaxRad = ( m_dRadius > m_dTipRadius ? m_dRadius : m_dTipRadius) ; - - Point3d ptCs = ( m_dRadius > m_dTipRadius ? ptLs - dCylH * vtToolDir : ptLs - m_dHeight * vtToolDir) ; - Point3d ptCe = ( m_dRadius > m_dTipRadius ? ptLe - dCylH * vtToolDir : ptLe - m_dHeight * vtToolDir) ; - Vector3d vtDir = ( m_dRadius > m_dTipRadius ? vtToolDir : - vtToolDir) ; - - LongConus( ptCs, ptCe, vtDir, m_dTipHeight, dMaxRad, dMinRad) ; - } - - else if ( m_nToolType == GenericTool) - // Caso al momento non gestito - return false ; - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::DrillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve ; - - pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso di semento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - LongCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - LongConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utensile - else if ( ptStart.x < ptEnd.x) { - - double dMaxRad = ptEnd.x ; - double dMinRad = ptStart.x ; - - Point3d ptIn = ptI - vtToolDir * dHeight ; - Point3d ptFn = ptIn + vtMove ; - - LongConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - } - else - dHeight = 0 ; - } - - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.GetNextCurve() ; - } - - return true ; -} - -// Componenti elementari degli utensili -//---------------------------------------------------------------------------- -bool -VolZmap::LongCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) -{ - double dMin, dMax; - unsigned int nStartI, nEndI, nStartJ, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - - if ( ! Control) - return true ; - - // Studio delle simmetrie - Vector3d vtMove = ptLe - ptLs ; - - Point3d ptI = ( vtMove * vtToolDir > 0 ? ptLe : ptLs) ; - Point3d ptF = ( vtMove * vtToolDir > 0 ? ptLs - dHei * vtToolDir : ptLe - dHei * vtToolDir) ; - - if ( ptI.z > ptF.z) { - - Point3d ptTemp = ptI ; - ptI = ptF ; - ptF = ptTemp ; - } - - double dDeltaZ = ptF.z - ptI.z ; - double dZI = ptI.z ; - - // Definizione - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; - - Vector3d vtCyl = ptF - ptI ; double dLen = sqrt( vtCyl * vtCyl) ; - Vector3d vtCylVer( 0, 0, vtCyl.z) ; double dLVer = abs( vtCyl.z) ; - Vector3d vtCylOri( vtCyl.x, vtCyl.y, 0) ; double dLOri = vtCylOri.LenXY() ; - - double dCos = dLVer / dLen ; // Coseno dell'angolo formato da vtCyl con l'asse Z. - double dSin = dLOri / dLen ; // Seno dell'angolo formato da vtCyl con l'asse Z. - - double dSemiMin = dRad * dCos ; - - // Definizione del sistema di riferimento nel piano - Vector3d vtU1 = vtCylOri ; - - if ( vtU1.LenXY() < EPS_SMALL) { - - double dLenVector = sqrt(vtCyl.x * vtCyl.x + vtCyl.y * vtCyl.y) ; - - vtU1 = ( 1 + dLenVector) / dLenVector * vtU1 ; - } - - vtU1.Normalize() ; - - Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; - - // Definizione piani - Vector3d vtV = vtMove ; vtV.Normalize() ; - Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV ; - Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV ; - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; - - double dProjI1 = vtCI * vtU1 ; double dProjI2 = vtCI * vtU2 ; - double dProjF1 = vtCF * vtU1 ; double dProjF2 = vtCF * vtU2 ; - - if ( dProjI1 > - dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) && - dProjI1 < dLOri + dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) && - dProjI2 * dProjI2 < dRad * dRad) { - - // Massimi - if ( dProjI1 < dLOri - dCos * sqrt( dRad * dRad - dProjI2 * dProjI2)) { - - double dZ0 = dSin * sqrt( dRad * dRad - dProjI2 * dProjI2) ; - double dI10 = - dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) ; - - dMax = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; - } - else - - dMax = ( dDotF - vtV.x * dX - vtV.y *dY) / vtV.z ; - - // Minimi - if ( dProjI1 < dCos * sqrt( dRad * dRad - dProjI2 * dProjI2)) - - dMin = ( dDotI - vtV.x * dX - vtV.y *dY) / vtV.z ; - - else { - - double dZ0 = - dSin * sqrt( dRad * dRad - dProjI2 * dProjI2) ; - double dI10 = dCos * sqrt( dRad * dRad - dProjI2 * dProjI2) ; - - dMin = dZI + dZ0 + ( dProjI1 - dI10) * dDeltaZ / dLOri ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::LongBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, 0) ; - - if ( ! Control) - return true ; - - Point3d ptI = ( ( ptLe - ptLs) * vtToolDir < 0 ? ptLs : ptLe) ; - Point3d ptF = ( ( ptLe - ptLs) * vtToolDir < 0 ? ptLe : ptLs) ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; - - double dDeltaZ = ptF.z - ptI.z ; - double dZI = ptI.z ; - - Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; - Vector3d vtMoveVer( 0, 0, vtMove.z) ; double dLVer = abs( vtMove.z) ; - Vector3d vtMoveOri( vtMove.x, vtMove.y, 0) ; double dLOri = vtMoveOri.LenXY() ; - - // Definizione del sistema di riferimento nel piano - Vector3d vtU1 = vtMoveOri ; - - if ( vtU1.LenXY() < EPS_SMALL) { - - double dLenVector = sqrt(vtMove.x * vtMove.x + vtMove.y * vtMove.y) ; - - vtU1 = ( 1 + dLenVector) / dLenVector * vtU1 ; - } - - - vtU1.Normalize() ; - - Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; - - double dCos = dLVer / dLen ; // Sempre positivo - double dSin = dLOri / dLen ; // Sempre positivo - - double dSemiMin = dRad * abs( dCos) ; - - Vector3d vtV = vtMove ; vtV.Normalize() ; - - Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV ; - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - - Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; - - double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; - double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; - - double dLimP1 = sqrt( dRad * dRad - dPI2 * dPI2) ; - - // Dexel nella regione interessata dalla lavorazione - if ( ( dPI1 > - dCos * dLimP1 && - dPI1 < dLOri && dPI2 * dPI2 < dRad * dRad) || - ( dPF1 * dPF1 + dPF2 * dPF2 < dRad * dRad)) { - - if ( dDeltaZ > 0) { - - // Massimi - if ( dPI1 < dLOri - dCos * dLimP1) { - - double dPI0 = - dCos * dLimP1 ; - double dZ0 = dSin * dLimP1 ; - - dMax = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; - } - else { - - double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; - double dH = sqrt( dRad * dRad - dSqD) ; - - dMax = dZI + dDeltaZ + dH ; - } - - // Minimi - if ( dPI1 < dCos * dLimP1) - - dMin = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; - - else if ( dPI1 < dLOri + dCos * dLimP1) { - - double dPI0 = dCos * dLimP1 ; - double dZ0 = - dSin * dLimP1 ; - - dMin = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; - } - else { - - double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; - double dH = sqrt( dRad * dRad - dSqD) ; - - dMin = dZI + dDeltaZ - dH ; - } - } - else { - - // Massimi - if ( dPI1 < dCos * dLimP1) - - dMax = ( dDotI - dX * vtV.x - dY * vtV.y) / vtV.z ; - - else if ( dPI1 < dLOri + dCos * dLimP1) { - - double dPI0 = dCos * dLimP1 ; - double dZ0 = + dSin * dLimP1 ; - - dMax = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; - } - else { - - double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; - double dH = sqrt( dRad * dRad - dSqD) ; - - dMax = dZI + dDeltaZ + dH ; - } - - // Minimi - if ( dPI1 < dLOri - dCos * dLimP1) { - - double dPI0 = - dCos * dLimP1 ; - double dZ0 = - dSin * dLimP1 ; - - dMin = dZI + dZ0 + ( dPI1 - dPI0) * dDeltaZ / dLOri ; - } - else { - - double dSqD = dPF1 * dPF1 + dPF2 * dPF2 ; - double dH = sqrt( dRad * dRad - dSqD) ; - - dMin = dZI + dDeltaZ - dH ; - } - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::LongConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, - double dHei, double dMaxRad, double dMinRad) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - - if ( ! Control) - return true ; - - Vector3d vtMove = ptLe - ptLs ; double dLen = vtMove.Len() ; - Vector3d vtMZ( 0, 0, vtMove.z) ; double dLVer = abs( vtMove.z) ; - Vector3d vtMXY( vtMove.x, vtMove.y, 0) ; double dLOri = vtMXY.LenXY() ; - - double dSin = dLOri / dLen ; - double dCos = dLVer / dLen ; - - double dSemiMinR = dMaxRad * dCos ; - double dSemiMinr = dMinRad * dCos ; - - // Sistema di riferimento sul cono - Vector3d vtV1 = vtToolDir ; // controllare qui e negli altri coni che le proiezioni non siano troppo piccole FORSE CONVIENE FARE I CONTI CON VTMOVE NORMALIZZATO (QUESTO IN TUTTI I MOVIMENTI) - - double dCoef23 = ( vtV1.z > 0 ? 1 : - 1) ; - double dCoef21 = - dCoef23 * vtV1.z ; // vtV1.z := vtV1 * Z_AX - - Vector3d vtV2 = dCoef21 * vtV1 + dCoef23 * Z_AX ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Simmetrie del problema riguardanti il cono - Point3d ptCBot = ( vtV1 * vtMove > 0 ? ptLs : ptLe) ; - Point3d ptCTip = ptCBot - dHei * vtV1 ; - - double dDeltaR = dMaxRad - dMinRad ; - double dTan = dDeltaR / dHei ; - double dL = ( ( dMaxRad * dHei) / dDeltaR) ; - double dl = dL - dHei ; - - Point3d ptV = ptCBot - vtV1 * dL ; - - // Simmetrie del problema riguardanti il cilinidro - Point3d ptCylI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - Point3d ptCylF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - - double dDeltaZ = ptCylF.z - ptCylI.z ; - double dZCylI = ptCylI.z ; - - // Piani cono - Vector3d vtR0B = ptCBot - ORIG ; double dDotB = vtR0B * vtV1 ; - Vector3d vtR0T = ptCTip - ORIG ; double dDotT = vtR0T * vtV1 ; - - - // Piani cilindro - Vector3d vtR0I = ptCylI - ORIG ; double dDotI = vtR0I * vtV1 ; - Vector3d vtR0F = ptCylF - ORIG ; double dDotF = vtR0F * vtV1 ; - - - // Punti sul piano - Point3d ptCylIxy( ptCylI.x, ptCylI.y, 0) ; - Point3d ptCBotxy( ptCBot.x, ptCBot.y, 0) ; - - - // Riferimenti sul piano - Vector3d vtU1( ptCylF.x - ptCylI.x, ptCylF.y - ptCylI.y, 0) ; vtU1.Normalize() ; - Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; - - Vector3d vtW1( vtV1.x, vtV1.y, 0) ; vtW1.Normalize() ; - Vector3d vtW2 = vtW1 ; vtW2.Rotate( Z_AX, 90) ; - - // Sistema di riferimento del cono - Frame3d ConusFrame ; ConusFrame.Set( ptV, vtV1, vtV2, vtV3) ; - - - // Ciclo - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptCylIxy ; - - double dPCyl1 = vtC * vtU1 ; double dPCyl2 = vtC * vtU2 ; - - // Parte cilindrica - if ( dPCyl2 * dPCyl2 < dMaxRad * dMaxRad && - dPCyl1 > - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) && - dPCyl1 < dLOri + dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) { - - // Massimi - if ( dPCyl1 < dLOri - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) { - - double dZ0 = dSin * sqrt( dMaxRad * dMaxRad - dPCyl2 * dPCyl2) ; - double dP0 = - dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) ; - - dMax = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; - } - else - - dMax = ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; - - // Minimi - if ( dPCyl1 < dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad))) - - dMin = ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z ; - - else { - - double dZ0 = - dSin * sqrt( dMaxRad * dMaxRad - dPCyl2 * dPCyl2) ; - double dP0 = dSemiMinR * sqrt( 1 - ( dPCyl2 * dPCyl2) / ( dMaxRad * dMaxRad)) ; - - dMin = dZCylI + dZ0 + ( dPCyl1 - dP0) * dDeltaZ / ( dLOri) ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Parte conica - Vector3d vtD = Z_AX ; - - ptC.LocToLoc( m_LocalFrame, ConusFrame) ; - - vtD.LocToLoc( m_LocalFrame, ConusFrame) ; - - std::vector vdCoef(3); - std::vector vdRoots; - - vdCoef[0] = ( dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z) ; - vdCoef[1] = 2 * ( dTan * dTan * ptC.x * vtD.x - ptC.y * vtD.y - ptC.z * vtD.z) ; - vdCoef[2] = dTan * dTan * vtD.x * vtD.x - vtD.y * vtD.y - vtD.z * vtD.z ; - - int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; - - if ( nRoot == 1) { - - Point3d ptR1 = ptC + vdRoots[0] * vtD ; - - if ( ptR1.x >= dl && ptR1.x < dL) { - - ptR1.LocToLoc( ConusFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dl) { - - dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nRoot == 2) { - - Point3d ptR1 = ptC + vdRoots[0] * vtD ; - Point3d ptR2 = ptC + vdRoots[1] * vtD ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { - - dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( ConusFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( ConusFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { - - dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { - - ptR1.LocToLoc( ConusFrame, m_LocalFrame) ; - ptR2.LocToLoc( ConusFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { - - ptR1.LocToLoc( ConusFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotB - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -// Fresatura -//---------------------------------------------------------------------------- -bool -VolZmap::Milling( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - - if ( m_nToolType == CylindricalMill) - - return MillCyl( ptLs, ptLe, vtToolDir, m_dHeight, m_dRadius) ; - - else if ( m_nToolType == BallEndMill) { - - double dCylH = m_dHeight - m_dTipHeight ; - - MillCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; - - Point3d ptBs = ptLs - vtToolDir * ( m_dHeight - m_dTipHeight) ; - Point3d ptBe = ptLe - vtToolDir * ( m_dHeight - m_dTipHeight) ; - - Ball( ptBs, ptBe, m_dRadius) ; - return true ; - } - - else if ( m_nToolType == BullNoseMill) - // Caso al momento non gestito - return false ; - - else if ( m_nToolType == ConusMill) { - - double dCylH = m_dHeight - m_dTipHeight ; - - MillCyl( ptLs, ptLe, vtToolDir, dCylH, m_dRadius) ; - - double dMinRad = ( m_dRadius > m_dTipRadius ? m_dTipRadius : m_dRadius) ; - double dMaxRad = ( m_dRadius > m_dTipRadius ? m_dRadius : m_dTipRadius) ; - - Point3d ptCs = ( m_dRadius > m_dTipRadius ? ptLs - dCylH * vtToolDir : ptLs - m_dHeight * vtToolDir) ; - Point3d ptCe = ( m_dRadius > m_dTipRadius ? ptLe - dCylH * vtToolDir : ptLe - m_dHeight * vtToolDir) ; - Vector3d vtDir = ( m_dRadius > m_dTipRadius ? vtToolDir : - vtToolDir) ; - - MillConus( ptCs, ptCe, vtDir, m_dTipHeight, dMaxRad, dMinRad) ; - return true ; - } - - else if ( m_nToolType == GenericTool) - // Caso al momento non gestito - return false ; - - else - return false ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillingGT( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir) -{ - // Posizioni iniziale e finale dell'utensile - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - // vettore movimento - Vector3d vtMove = ptLe - ptLs ; - - CurveComposite ToolProfile ; - int i = m_ToolArcLineApprox.GetCurveCount() ; - - // Settaggio profilo - if ( m_ToolArcLineApprox.GetCurveCount() == 0) - // Se l'utensile non è stato approssimato uso l'originale - ToolProfile.CopyFrom( & m_ToolOutline) ; - else - // altrimenti usi l'approssimazione - ToolProfile.CopyFrom( & m_ToolArcLineApprox) ; - - // Dichiaro un puntatore a curva da usare nel ciclo - const ICurve* pCurve = ToolProfile.GetFirstCurve() ; - - // Ciclo sulle curve - while ( pCurve != nullptr) { - - double dHeight ; - - int nCurveType = pCurve -> GetType() ; - - // Caso di semento - if ( nCurveType == CRV_LINE) { - - Point3d ptStart, ptEnd ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - - if ( abs( ptStart.y - ptEnd.y) > EPS_SMALL) { - - dHeight = abs( ptStart.y - ptEnd.y) ; - - // Il componente è un cilindro - if ( abs( ptStart.x - ptEnd.x) < EPS_SMALL) { - - double dRadius = ptStart.x ; - - MillCyl( ptI, ptF, vtToolDir, dHeight, dRadius) ; - } - // Il componente è un cono con vettore equiverso a quello dell'utensile - else if ( ptStart.x > ptEnd.x) { - - double dMaxRad = ptStart.x ; - double dMinRad = ptEnd.x ; - - MillConus( ptI, ptF, vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - // Il componente è un cono con vettore opposto a quello dell'utensile - else if ( ptStart.x < ptEnd.x) { - - double dMaxRad = ptEnd.x ; - double dMinRad = ptStart.x ; - - Point3d ptIn = ptI - vtToolDir * dHeight ; - Point3d ptFn = ptIn + vtMove ; - - MillConus( ptIn, ptFn, - vtToolDir, dHeight, dMaxRad, dMinRad) ; - } - } - else - dHeight = 0 ; - } - // Caso arco - else if ( nCurveType == CRV_ARC) { - - // Centro e Punti iniziale e finale del cerchio - Point3d ptStart, ptEnd, ptO ; - - pCurve -> GetStartPoint( ptStart) ; - pCurve -> GetEndPoint( ptEnd) ; - pCurve -> GetCenterPoint( ptO) ; - - // Determino il raggio - Vector3d vtStRad = ptStart - ptO ; - Vector3d vtEnRad = ptEnd - ptO ; - - double dRadius = 0.5 * ( vtStRad.LenXY() + vtEnRad.LenXY()) ; - - // Determino le posizioni iniziale e finale del centrodella sfera - Point3d ptOSt = ptI - vtToolDir * ( ptStart.y - ptO.y) ; - Point3d ptOEn = ptOSt + vtMove ; - - // Eseguo l'asportazione del materiale - Ball( ptOSt, ptOEn, dRadius) ; - - - // aggiorno l'altezza - dHeight = abs( ptStart.y - ptEnd.y) ; - } - - // Determino le posizioni iniziale e finale del componente successivo - ptI = ptI - vtToolDir * dHeight ; - ptF = ptI + vtMove ; - - // Aggiorno il puntatore - pCurve = ToolProfile.GetNextCurve() ; - } - - return true ; -} - -// Componenti elementari degli utensili -//---------------------------------------------------------------------------- -bool -VolZmap::MillCyl( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - - if ( ! Control) - return true ; - - Point3d ptI ; - Point3d ptF ; - Vector3d vtV1 ; - - // Studio delle simmetrie - if ( vtToolDir.z < 0) { - - vtV1 = - vtToolDir ; - - ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs + dHei * vtV1 : ptLe + dHei * vtV1) ; - ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe + dHei * vtV1 : ptLs + dHei * vtV1) ; - } - else { - - vtV1 = vtToolDir ; - - ptI = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; - ptF = ( vtV1 * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; - } - - Point3d ptIT = ptI - vtV1 * dHei ; - Point3d ptFT = ptF - vtV1 * dHei ; - - // Definizione di un sintema di riferimento nel piano - Vector3d vtU1( - vtV1.x, - vtV1.y, 0) ; - double dCos = vtV1.z ; - double dSin = vtU1.LenXY() ; - vtU1.Normalize() ; // Ocio che la sua lunghezza sia maggiore di EPS_SMALL - Vector3d vtU2 = vtU1 ; vtU2.Rotate( Z_AX, 90) ; - - double dZI = ptI.z ; - double dZF = ptF.z ; - double dDeltaZ = ptIT.z - ptI.z ; - //double dDeltaFz = ptFT.z - ptF.z ; - - double dL = dSin * dHei ; - - Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; - Vector3d vtMLong = ( vtMove * vtV1) * vtV1 ; double dLLong = vtMLong.Len() ; - Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; - - double dCoef = dLOrt / dLLong ; - double dAng = atan( 1 / dCoef) ; - - // vtV1, vtV2 e vtV3 definiscono gli assi dei sistemi di riferimento intrinseci - Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - Frame3d CylFrame ; CylFrame.Set( ptI, vtV1, vtV2, vtV3) ; - Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; - Frame3d TCylFrame ; TCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; - Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; - - // Altri punti notevoli - Point3d ptIPlus = ptI + dRad * vtV3 ; - Point3d ptIMinus = ptI - dRad * vtV3 ; - Point3d ptFPlus = ptIPlus + vtMove ; - Point3d ptFMinus = ptIMinus + vtMove ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; - - // Grandezze per la definizione dei piani - Vector3d vtRI = ptI - ORIG ; double dDotI = vtV1 * vtRI ; - Vector3d vtRF = ptF - ORIG ; double dDotF = vtV1 * vtRF ; - - Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtV1 * vtRIT ; - Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtV1 * vtRFT ; - - Vector3d vtRIPlus = ptIPlus - ORIG ; - - Vector3d vtRIMinus = ptIMinus - ORIG ; - - Vector3d vtRFPlus = ptFPlus - ORIG ; - - Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; - Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; - - Vector3d vtRITPlus = ptIPlus - ORIG - vtV1 * dHei ; - - Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtV3) ; - Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtV3) ; - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; - - Vector3d vtCI = ptC - ptIxy ; - Vector3d vtCF = ptC - ptFxy ; - Vector3d vtC = ptC - ORIG ; - - double dPI1 = vtCI * vtU1 ; double dPI2 = vtCI * vtU2 ; - double dPF1 = vtCF * vtU1 ; double dPF2 = vtCF * vtU2 ; - - // Forse queste parti cilindriche andrebbero fatte per intersezione se il versoreutensile è molto verticale - // Parte cilindrica I - if ( dPI1 > - dCos * sqrt( dRad * dRad - dPI2 * dPI2) && - dPI1 < dL + dCos * sqrt( dRad * dRad - dPI2 * dPI2) && - dPI2 * dPI2 < dRad * dRad) { - - // Minimi - if ( dPI1 < dL - dCos * sqrt( dRad * dRad - dPI2 * dPI2)) { - - double dZ0 = - dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; - double dI10 = - dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; - - dMin = dZI + dZ0 + ( dPI1 - dI10) * dDeltaZ / dL ; - } - else - - dMin = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - // Massimi - if ( dPI1 < dCos * sqrt( dRad * dRad - dPI2 * dPI2)) - - dMax = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - else { - - double dZ0 = dSin * sqrt( dRad * dRad - dPI2 * dPI2) ; - double dI10 = dCos * sqrt( dRad * dRad - dPI2 * dPI2) ; - - dMax = dZI + dZ0 + ( dPI1 - dI10) * dDeltaZ / dL ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Parte cilindrica F - if ( dPF1 > - dCos * sqrt( dRad * dRad - dPF2 * dPF2) && - dPF1 < dL + dCos * sqrt( dRad * dRad - dPF2 * dPF2) && - dPF2 * dPF2 < dRad * dRad) { - - // Minimi - if ( dPF1 < dL - dCos * sqrt( dRad * dRad - dPF2 * dPF2)) { - - double dZ0 = - dSin * sqrt( dRad * dRad - dPF2 * dPF2) ; - double dI10 = - dCos * sqrt( dRad * dRad - dPF2 * dPF2) ; - - dMin = dZF + dZ0 + ( dPF1 - dI10) * dDeltaZ / dL ; - } - else - - dMin = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - // Massimi - if ( dPF1 < dCos * sqrt( dRad * dRad - dPF2 * dPF2)) - - dMax = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - else { - - double dZ0 = dSin * sqrt( dRad * dRad - dPF2 * dPF2) ; - double dI10 = dCos * sqrt( dRad * dRad - dPF2 * dPF2) ; - - dMax = dZF + dZ0 + ( dPF1 - dI10) * dDeltaZ / dL ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Parallelepipedo - Point3d ptInt1 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; - Point3d ptInt2 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; - Point3d ptInt3 = ptC + ( ( ( vtRIPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; - Point3d ptInt4 = ptC + ( ( ( vtRIPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; - Point3d ptInt5 = ptC + ( ( ( vtRFPlus - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; - Point3d ptInt6 = ptC + ( ( ( vtRITPlus - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; - - - ptInt1.LocToLoc( m_LocalFrame, CylFrame) ; - ptInt2.LocToLoc( m_LocalFrame, CylFrame) ; - ptInt3.LocToLoc( m_LocalFrame, CylFrame) ; - ptInt4.LocToLoc( m_LocalFrame, RotFrame) ; - ptInt5.LocToLoc( m_LocalFrame, CylFrame) ; - ptInt6.LocToLoc( m_LocalFrame, TRotFrame) ; - - bool bFlag = false ; - double dLim1, dLim2 ; - - if ( ptInt1.y >= 0 && ptInt1.y <= dLOrt && - ptInt1.x >= - dHei + ptInt1.y * ( dLLong / dLOrt) && - ptInt1.x <= ptInt1.y * ( dLLong / dLOrt)) { - - ptInt1.LocToLoc( CylFrame, m_LocalFrame) ; - - - dLim1 = ptInt1.z ; - bFlag = true ; - } - - if ( ptInt2.y >= 0 && ptInt2.y <= dLOrt && - ptInt2.x >= - dHei + ptInt2.y * ( dLLong / dLOrt) && - ptInt2.x <= ptInt2.y * ( dLLong / dLOrt)) { - - ptInt2.LocToLoc( CylFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt2.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt2.z ; - } - - if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && - ptInt3.x >= - dHei && ptInt3.x <= 0) { - - ptInt3.LocToLoc( CylFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt3.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt3.z ; - } - - if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && - ptInt4.y >= 0 && ptInt4.y <= dLen) { - - ptInt4.LocToLoc( RotFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt4.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt4.z ; - } - - if ( ptInt5.z >= - dRad && ptInt5.z <= dRad && - ptInt5.x >= dLLong- dHei && ptInt5.x <= dLLong) { - - ptInt5.LocToLoc( CylFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt5.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt5.z ; - } - - if ( ptInt6.z >= - dRad && ptInt6.z <= dRad && - ptInt6.y >= 0 && ptInt6.y <= dLen) { - - ptInt6.LocToLoc( TRotFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt6.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt6.z ; - } - - - if ( bFlag == true) { // Una linea non confinata se entra in un volume chiuso ci deve uscire - - dMin = min( dLim1, dLim2) ; - dMax = max( dLim1, dLim2) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Traslazione dell'ellisse - - Vector3d vtK = Z_AX ; - - vtK.LocToLoc( m_LocalFrame, CylFrame) ; - ptC.LocToLoc( m_LocalFrame, CylFrame) ; - - std::vector vdCoef(3); - std::vector vdRoots; - - vdCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; - vdCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; - vdCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; - - - int nRoot = PolynomialRoots( 2, vdCoef, vdRoots) ; - - if ( nRoot == 0 || nRoot == 1) { - - Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPi.LocToLoc( m_LocalFrame, CylFrame) ; - ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; - - if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && - ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { - - ptPi.LocToLoc( CylFrame, m_LocalFrame) ; - ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; - - dMin = min( ptPi.z, ptPf.z) ; - dMax = max( ptPi.z, ptPf.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nRoot == 2) { - - Point3d ptInter1 = ptC + vdRoots[0] * vtK ; - Point3d ptInter2 = ptC + vdRoots[1] * vtK ; - - - if ( ptInter1.x > ptInter2.x) { - - Point3d ptTemp = ptInter1 ; - ptInter1 = ptInter2 ; - ptInter2 = ptTemp ; - } - - if ( ptInter1.x > 0 && ptInter1.x < dLLong && - ptInter2.x > dLLong) { - - ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; - - dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; - dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { - - ptInter1.LocToLoc( CylFrame, m_LocalFrame) ; - ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; - - dMin = min( ptInter1.z, ptInter2.z) ; - dMax = max( ptInter1.z, ptInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { - - dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { - - ptInter2.LocToLoc( CylFrame, m_LocalFrame) ; - - dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; - dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - ptC.LocToLoc( CylFrame, TCylFrame) ; - vtK.LocToLoc( CylFrame, TCylFrame) ; - - std::vector vdTCoef(3); - std::vector vdTRoots; - - vdTCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; - vdTCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; - vdTCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; - - int nTRoot = PolynomialRoots( 2, vdTCoef, vdTRoots) ; - - if ( nTRoot == 0 || nTRoot == 1) { - - Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPi.LocToLoc( m_LocalFrame, TCylFrame) ; - ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; - - if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && - ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { - - ptPi.LocToLoc( TCylFrame, m_LocalFrame) ; - ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; - - dMin = min( ptPi.z, ptPf.z) ; - dMax = max( ptPi.z, ptPf.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - } - else if ( nTRoot == 2) { - - Point3d ptTInter1 = ptC + vdTRoots[0] * vtK ; - Point3d ptTInter2 = ptC + vdTRoots[1] * vtK ; - - if ( ptTInter1.x > ptTInter2.x) { - - Point3d ptTemp = ptTInter1 ; - ptTInter1 = ptTInter2 ; - ptTInter2 = ptTemp ; - } - - if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && - ptTInter2.x > dLLong) { - - ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; - - dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; - dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { - - ptTInter1.LocToLoc( TCylFrame, m_LocalFrame) ; - ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; - - dMin = min( ptTInter1.z, ptTInter2.z) ; - dMax = max( ptTInter1.z, ptTInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { - - dMin = min( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { - - ptTInter2.LocToLoc( TCylFrame, m_LocalFrame) ; - - dMin = min( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; - dMax = max( ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillCyl2( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dHei, double dRad) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, dRad, dHei) ; - - if ( ! Control) - return true ; - - // Punti notevoli - Point3d ptI = ptLs ; - Point3d ptF = ptLe ; - - Point3d ptIT = ptI - vtToolDir * dHei ; - Point3d ptFT = ptF - vtToolDir * dHei ; - - // Vettori notevoli - Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; - Vector3d vtLong = ( vtMove * vtToolDir) * vtToolDir ; double dLong = vtLong.Len() ; - Vector3d vtOrt = vtMove - vtLong ; double dOrt = vtOrt.Len() ; - - double dCoef = dOrt / dLong ; - double dAng = atan( 1 / dCoef) ; - - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtOrt ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Definizione dei sistemi di riferimento - Frame3d ICylFrame ; ICylFrame.Set( ptI, vtV1, vtV2, vtV3) ; - Frame3d FCylFrame ; FCylFrame.Set( ptF, vtV1, vtV2, vtV3) ; - Frame3d ITCylFrame ; ITCylFrame.Set( ptIT, vtV1, vtV2, vtV3) ; - Frame3d FTCylFrame ; FTCylFrame.Set( ptFT, vtV1, vtV2, vtV3) ; - - Vector3d vtW1 = vtV1 ; vtW1.Rotate( vtV3, - 180 * dAng / PIGRECO) ; - Vector3d vtW2 = vtV2 ; vtW2.Rotate( vtV3, - 180 * dAng / PIGRECO) ; - Vector3d vtW3 = vtV3 ; - - Frame3d RotFrame ; RotFrame.Set( ptI, vtW1, vtW2, vtW3) ; - Frame3d TRotFrame ; TRotFrame.Set( ptIT, vtW1, vtW2, vtW3) ; - - // Altri vettori notevoi - Vector3d vtKC = Z_AX ; vtKC.LocToLoc( m_LocalFrame, ICylFrame) ; - - Vector3d vtRI = ptI - ORIG ; double dDotI = vtRI * vtV1 ; - Vector3d vtRF = ptF - ORIG ; double dDotF = vtRF * vtV1 ; - Vector3d vtRIT = ptIT - ORIG ; double dDotIT = vtRIT * vtV1 ; - Vector3d vtRFT = ptFT - ORIG ; double dDotFT = vtRFT * vtV1 ; - - Vector3d vtRIPlus = vtRI + dRad * vtW3 ; - Vector3d vtRIMinus = vtRI - dRad * vtW3 ; - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; - - // Cilindro iniziale - ptC.LocToLoc( m_LocalFrame, ICylFrame) ; - - std::vector vdICylCoef(3); - std::vector vdICylRoots; - - vdICylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; - vdICylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; - vdICylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; - - - int nICylRoot = PolynomialRoots( 2, vdICylCoef, vdICylRoots) ; - - if ( nICylRoot == 0 || nICylRoot == 1) { - - Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPb.LocToLoc( m_LocalFrame, ICylFrame) ; - ptPt.LocToLoc( m_LocalFrame, ITCylFrame) ; - - if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && - ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { - - ptPb.LocToLoc( ICylFrame, m_LocalFrame) ; - ptPt.LocToLoc( ITCylFrame, m_LocalFrame) ; - - dMin = min( ptPb.z, ptPt.z) ; - dMax = max( ptPb.z, ptPt.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nICylRoot == 2) { - - Point3d ptR1 = ptC + vdICylRoots[0] * vtKC ; - Point3d ptR2 = ptC + vdICylRoots[1] * vtKC ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - if ( ptR1.x < - dHei && ptR2.x >= - dHei && - ptR2.x < 0) { - - ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; - - dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < - dHei && ptR2.x >= 0) { - - dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { - - ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; - ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { - - ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; - - dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - // Cilindro finale - ptC.LocToLoc( ICylFrame, FCylFrame) ; - - std::vector vdFCylCoef(3); - std::vector vdFCylRoots; - - vdFCylCoef[0] = ptC.y * ptC.y + ptC.z * ptC.z - dRad * dRad ; - vdFCylCoef[1] = 2 * ( ptC.y * vtKC.y + ptC.z * vtKC.z) ; - vdFCylCoef[2] = vtKC.y * vtKC.y + vtKC.z * vtKC.z ; - - - int nFCylRoot = PolynomialRoots( 2, vdFCylCoef, vdFCylRoots) ; - - if ( nFCylRoot == 0 || nFCylRoot == 1) { - - Point3d ptPb ; ptPb.x = dX ; ptPb.y = dY ; ptPb.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPt ; ptPt.x = dX ; ptPt.y = dY ; ptPt.z = ( dDotFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPb.LocToLoc( m_LocalFrame, FCylFrame) ; - ptPt.LocToLoc( m_LocalFrame, FTCylFrame) ; - - if ( ptPb.y * ptPb.y + ptPb.z * ptPb.z < dRad * dRad && - ptPt.y * ptPt.y + ptPt.z * ptPt.z < dRad * dRad) { - - ptPb.LocToLoc( FCylFrame, m_LocalFrame) ; - ptPt.LocToLoc( FTCylFrame, m_LocalFrame) ; - - dMin = min( ptPb.z, ptPt.z) ; - dMax = max( ptPb.z, ptPt.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nFCylRoot == 2) { - - Point3d ptR1 = ptC + vdFCylRoots[0] * vtKC ; - Point3d ptR2 = ptC + vdFCylRoots[1] * vtKC ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - if ( ptR1.x < - dHei && ptR2.x >= - dHei && - ptR2.x < 0) { - - ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; - - dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < - dHei && ptR2.x >= 0) { - - dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x < 0) { - - ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; - ptR2.LocToLoc( FCylFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= - dHei && ptR1.x < 0 && ptR2.x >= 0) { - - ptR1.LocToLoc( FCylFrame, m_LocalFrame) ; - - dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - // Traslazione ellisse fondo - - ptC.LocToLoc( FCylFrame, ICylFrame) ; - - std::vector vdEllipseCoef(3); - std::vector vdEllipseRoots; - - vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; - vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; - vdEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; - - - int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; - - if ( nEllipseRoot == 0 || nEllipseRoot == 1) { - - Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPi.LocToLoc( m_LocalFrame, ICylFrame) ; - ptPf.LocToLoc( m_LocalFrame, FCylFrame) ; - - if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && - ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { - - ptPi.LocToLoc( ICylFrame, m_LocalFrame) ; - ptPf.LocToLoc( FCylFrame, m_LocalFrame) ; - - dMin = min( ptPi.z, ptPf.z) ; - dMax = max( ptPi.z, ptPf.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nEllipseRoot == 2) { - - Point3d ptR1 = ptC + vdEllipseRoots[0] * vtKC ; - Point3d ptR2 = ptC + vdEllipseRoots[1] * vtKC ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - if ( ptR1.x < 0 && ptR2.x >= 0 && - ptR2.x < dLong) { - - ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; - - dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < 0 && ptR2.x >= dLong) { - - dMin = min( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - dMax = max( ( dDotI - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { - - ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; - ptR2.LocToLoc( ICylFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { - - ptR1.LocToLoc( ICylFrame, m_LocalFrame) ; - - dMin = min( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - dMax = max( ( dDotF - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - // Traslazione ellisse punta - - ptC.LocToLoc( ICylFrame, ITCylFrame) ; - - std::vector vdTEllipseCoef(3); - std::vector vdTEllipseRoots; - - vdTEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dRad * dRad ; - vdTEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKC.x * ptC.x + vtKC.y * ptC.y + vtKC.z * ptC.z - dCoef * ( vtKC.x * ptC.y + vtKC.y * ptC.x)) ; - vdTEllipseCoef[2] = dCoef * dCoef * vtKC.x * vtKC.x + vtKC.y * vtKC.y + vtKC.z * vtKC.z - 2 * dCoef * vtKC.x * vtKC.y ; - - - int nTEllipseRoot = PolynomialRoots( 2, vdTEllipseCoef, vdTEllipseRoots) ; - - if ( nTEllipseRoot == 0 || nTEllipseRoot == 1) { - - Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPi.LocToLoc( m_LocalFrame, ITCylFrame) ; - ptPf.LocToLoc( m_LocalFrame, FTCylFrame) ; - - if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dRad * dRad && - ptPf.y * ptPf.y + ptPf.z * ptPf.z < dRad * dRad) { - - ptPi.LocToLoc( ITCylFrame, m_LocalFrame) ; - ptPf.LocToLoc( FTCylFrame, m_LocalFrame) ; - - dMin = min( ptPi.z, ptPf.z) ; - dMax = max( ptPi.z, ptPf.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nTEllipseRoot == 2) { - - Point3d ptR1 = ptC + vdTEllipseRoots[0] * vtKC ; - Point3d ptR2 = ptC + vdTEllipseRoots[1] * vtKC ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - if ( ptR1.x < 0 && ptR2.x >= 0 && - ptR2.x < dLong) { - - ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; - - dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < 0 && ptR2.x >= dLong) { - - dMin = min( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - dMax = max( ( dDotIT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x < dLong) { - - ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; - ptR2.LocToLoc( ITCylFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dLong && ptR2.x >= dLong) { - - ptR1.LocToLoc( ITCylFrame, m_LocalFrame) ; - - dMin = min( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - dMax = max( ( dDotFT - dX * vtV1.x - dY * vtV1.y) / vtV1.z, ptR1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - - // Parallelepipedo - Point3d ptInt1 = ptC + ( ( ( vtRI - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; - Point3d ptInt2 = ptC + ( ( ( vtRI - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; - Point3d ptInt3 = ptC + ( ( ( vtRF - vtC) * vtV2) / ( Z_AX * vtV2)) * Z_AX ; - Point3d ptInt4 = ptC + ( ( ( vtRIT - vtC) * vtW1) / ( Z_AX * vtW1)) * Z_AX ; - Point3d ptInt5 = ptC + ( ( ( vtRIPlus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; - Point3d ptInt6 = ptC + ( ( ( vtRIMinus - vtC) * vtV3) / ( Z_AX * vtV3)) * Z_AX ; - - - ptInt1.LocToLoc( m_LocalFrame, ICylFrame) ; - ptInt2.LocToLoc( m_LocalFrame, RotFrame) ; - ptInt3.LocToLoc( m_LocalFrame, FCylFrame) ; - ptInt4.LocToLoc( m_LocalFrame, TRotFrame) ; - ptInt5.LocToLoc( m_LocalFrame, ICylFrame) ; - ptInt6.LocToLoc( m_LocalFrame, ICylFrame) ; - - bool bFlag = false ; - double dLim1, dLim2 ; - - - if ( ptInt1.x >= - dHei && ptInt1.x <= 0 && - ptInt1.z >= - dRad && ptInt1.z <= dRad) { - - ptInt1.LocToLoc( ICylFrame, m_LocalFrame) ; - - dLim1 = ptInt1.z ; - bFlag = true ; - } - - if ( ptInt2.y >= 0 && ptInt2.y <= dLen && - ptInt2.z >= - dRad && ptInt2.z <= dRad) { - - ptInt2.LocToLoc( RotFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt2.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt2.z ; - } - - if ( ptInt3.z >= - dRad && ptInt3.z <= dRad && - ptInt3.x >= - dHei && ptInt3.x <= 0) { - - ptInt3.LocToLoc( FCylFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt3.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt3.z ; - } - - if ( ptInt4.z >= - dRad && ptInt4.z <= dRad && - ptInt4.y >= 0 && ptInt4.y <= dLen) { - - ptInt4.LocToLoc( TRotFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt4.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt4.z ; - } - - if ( ptInt5.y >= 0 && ptInt5.y <= dOrt && - ptInt5.x >= - dHei + dCoef * ptInt5.y && - ptInt5.x <= dCoef * ptInt5.y) { - - ptInt5.LocToLoc( ICylFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt5.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt5.z ; - } - - if ( ptInt6.y >= 0 && ptInt6.y <= dOrt && - ptInt6.x >= - dHei + dCoef * ptInt6.y && - ptInt6.x <= dCoef * ptInt6.y) { - - ptInt6.LocToLoc( ICylFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt6.z ; - - bFlag = true ; - } - else - - dLim2 = ptInt6.z ; - } - - - if ( bFlag == true) { // Una linea non confinata se entra in un volume chiuso ci deve uscire - - dMin = min( dLim1, dLim2) ; - dMax = max( dLim1, dLim2) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillBall( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, double dRad) -{ - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - bool bControl = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; - if ( ! bControl) - return true ; - - Point3d ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - Point3d ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - - Vector3d vtMove = ptF - ptI ; - - Vector3d vtV1( vtMove.x, vtMove.y, 0) ; vtV1.Normalize() ; - Vector3d vtV2( vtV1) ; vtV2.Rotate( Z_AX, 90) ; - - double dZI = ptI.z ; - double dDeltaZ = ptF.z - ptI.z ; - double dPLen = vtMove.LenXY() ; - - double dSin = dPLen / vtMove.Len() ; - double dCos = dDeltaZ / vtMove.Len() ; - - double dMin, dMax ; - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - - double dP1 = vtC * vtV1 ; double dP2 = vtC * vtV2 ; - - if ( ( dP1 >= 0 && dP1 <= dPLen && abs( dP2) < dRad) || - ( dP1 * dP1 + dP2 * dP2 < dRad * dRad) || - ( ( dP1 - dPLen) * ( dP1 - dPLen) + dP2 * dP2 < dRad * dRad)) { - - // Massimi - if ( dP1 < - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { - - double dH = sqrt( dRad * dRad - dP1 * dP1 - dP2 * dP2) ; - dMax = dZI + dH ; - } - else if ( dP1 < dPLen - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { - - double dP0 = - dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; - double dZ0 = dRad * dSin * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; - - dMax = dZI + dZ0 + ( dP1 - dP0) * dDeltaZ / dPLen ; - } - else { - - double dH = sqrt( dRad * dRad - ( dP1 - dPLen) * ( dP1 - dPLen) - dP2 * dP2) ; - dMax = dZI + dDeltaZ + dH ; - } - - // Minimi - if ( dP1 < dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { - - double dH = sqrt( dRad * dRad - dP1 * dP1 - dP2 * dP2) ; - dMin = dZI - dH ; - } - else if ( dP1 < dPLen + dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad))) { - - double dP0 = dRad * dCos * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; - double dZ0 = - dRad * dSin * sqrt( 1 - ( dP2 * dP2) / ( dRad * dRad)) ; - - dMin = dZI + dZ0 + ( dP1 - dP0) * dDeltaZ / dPLen ; - } - else { - - double dH = sqrt( dRad * dRad - ( dP1 - dPLen) * ( dP1 - dPLen) - dP2 * dP2) ; - dMin = dZI + dDeltaZ - dH ; - } - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillConus( const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtToolDir, - double dHei, double dMaxRad, double dMinRad) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, vtToolDir, vtToolDir, nStartI, nStartJ, nEndI, nEndJ, dMaxRad, dMinRad, dHei) ; - - if ( ! Control) - return true ; - - double dDeltaR = dMaxRad - dMinRad ; - - Point3d ptI = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLs : ptLe) ; - Point3d ptF = ( vtToolDir * ( ptLe - ptLs) > 0 ? ptLe : ptLs) ; - - Point3d ptIT = ptI - vtToolDir * dHei ; - Point3d ptFT = ptF - vtToolDir * dHei ; - - double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; - double dl = dL - dHei ; - - Point3d ptIV = ptI - vtToolDir * dL ; - Point3d ptFV = ptF - vtToolDir * dL ; - - Vector3d vtMove = ptF - ptI ; double dLen = vtMove.Len() ; - - Vector3d vtMLong = ( vtMove * vtToolDir) * vtToolDir ; double dLLong = vtMLong.Len() ; - Vector3d vtMOrt = vtMove - vtMLong ; double dLOrt = vtMOrt.Len() ; - - Vector3d vtV1 = vtToolDir ; - Vector3d vtV2 = vtMOrt ; vtV2.Normalize() ; - Vector3d vtV3 = vtV1 ^ vtV2 ; - - // Apertura del cono e parametri per determinare i piani - double dTan = dDeltaR / dHei ; - double dRatio = dLLong / dLOrt ; - - double dCos = dTan * dRatio ; - double dSin = ( 1 - dCos * dCos > 0 ? sqrt( 1 - dCos * dCos) : 0) ; - - double dDen = sqrt( 1 + dTan * dTan) ; - double dCoef = dLOrt / dLLong ; // Per traslazione ellissi - - if ( dRatio > 1 / dTan) - - return MillConusAux( ptI, ptF, vtV1, vtV2, vtV3, nStartI, nStartJ, nEndI, nEndJ, dHei, dMaxRad, dMinRad, dCoef) ; - - - // Versori normali e prodotti scalari per per determinare i piani - // Piani laterali: - Vector3d vtNs = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 + ( dSin / dDen) * vtV3 ; - Vector3d vtNd = - ( dTan / dDen) * vtV1 + ( dCos / dDen) * vtV2 - ( dSin / dDen) * vtV3 ; - Vector3d vtRIV = ptIV - ORIG ; - // double dDots = vtRIV * vtNs ; // forse qui è meglio due punti ptIT + vtV3 * dMinRad e ptIT - vtV3 * dMinRad - // double dDotd = vtRIV * vtNd ; - - Vector3d vtS1 = vtNs ; - Vector3d vtS2 = vtMove ; vtS2.Normalize() ; // double dDotTestqs = vtS1 * vtS2 ; - Vector3d vtS3 = vtS1 ^ vtS2 ; - - Vector3d vtD1 = vtNd ; - Vector3d vtD2 = vtS2 ; // double dDotTestD = vtD1 * vtD2 ; - Vector3d vtD3 = vtD1 ^ vtD2 ; - - Point3d ptS = ptI + vtV2 * ( dMaxRad * dCos) + vtV3 * ( dMaxRad * dSin) ; - Point3d ptD = ptI + vtV2 * ( dMaxRad * dCos) - vtV3 * ( dMaxRad * dSin) ; - Point3d ptST = ptIT + vtV2 * ( dMinRad * dCos) + vtV3 * ( dMinRad * dSin) ; - - Vector3d vtLen = ptST - ptS ; - - double dPLong = abs( vtLen * vtS3) ; - double dPOrt = abs( vtLen * vtS2) ; - // Vector3d vtLTr = vtLen - dPLong * vtS3 ; - - // double dPOrt = vtLTr.Len() ; - - // Piani di fondo e punta: - Vector3d vtU1 = - dLOrt * vtV1 + dLLong * vtV2 ; vtU1.Normalize() ; - Vector3d vtU2 = vtMove ; vtU2.Normalize() ; // double dDotTest = vtU1 * vtU2 ; - Vector3d vtU3 = vtU1 ^ vtU2 ; - - Point3d ptU = ptI + vtV2 * ( dMaxRad * dCos) ; - Point3d ptTU = ptIT + vtV2 * ( dMinRad * dCos) ; - - Vector3d vtRU = ptU - ORIG ; // double dDotB = vtRU * vtU1 ; - Vector3d vtRUT = ptTU - ORIG ; // double dDotT = vtRUT * vtU1 ; - - // Piani finale e iniziale: - Vector3d vtVAux = ptTU - ptU ; - - double dAuxOrt = vtVAux * vtV2 ; - double dAuxLong = vtVAux * vtV1 ; // Tenere in considerazione per tronchi con dimensioni tali da poter approssimare tori - - Vector3d vtW1 = - dAuxOrt * vtV1 + dAuxLong * vtV2 ; double dLAux1 = vtW1.Len() ; vtW1.Normalize() ; - Vector3d vtW2 = vtVAux ; double dLAux2 = vtW2.Len() ; vtW2.Normalize() ; // double dDottest = vtW1 * vtW2 ; - Vector3d vtW3 = vtW1 ^ vtW2 ; - - double dPr2 = vtLen * vtW2 ; double prova1 = vtLen * vtW3 ; double prova2 = dSin * dDeltaR ; - - Point3d ptFU = ptU + vtMove ; - - Vector3d vtRFU = ptFU - ORIG ; // double dDotPF = vtRFU * vtW1 ; - - // Piani cono: - Vector3d vtRCI = ptI - ORIG ; double dDotCI = vtRCI * vtV1 ; - Vector3d vtRCIT = ptIT - ORIG ; double dDotCIT = vtRCIT * vtV1 ; - - Vector3d vtRCF = ptF - ORIG ; double dDotCF = vtRCF * vtV1 ; - Vector3d vtRCFT = ptFT - ORIG ; double dDotCFT = vtRCFT * vtV1 ; - - - // Sistemi di riferimento - Frame3d IConeFrame ; IConeFrame.Set( ptIV, vtV1, vtV2, vtV3) ; - Frame3d FConeFrame ; FConeFrame.Set( ptFV, vtV1, vtV2, vtV3) ; - Frame3d PlSFrame ; PlSFrame.Set( ptS, vtS1, vtS2, vtS3) ; - Frame3d PlDFrame ; PlDFrame.Set( ptD, vtD1, vtD2, vtD3) ; - Frame3d PlBFrame ; PlBFrame.Set( ptU, vtU1, vtU2, vtU3) ; - Frame3d PlTFrame ; PlTFrame.Set( ptTU, vtU1, vtU2, vtU3) ; - Frame3d PlIFrame ; PlIFrame.Set( ptU, vtW1, vtW2, vtW3) ; - Frame3d PlFFrame ; PlFFrame.Set( ptFU, vtW1, vtW2, vtW3) ; - Frame3d LargeEllipse ; LargeEllipse.Set( ptI, vtV1, vtV2, vtV3) ; - Frame3d FLargeEllipse ; FLargeEllipse.Set( ptF, vtV1, vtV2, vtV3) ; - Frame3d SmallEllipse ; SmallEllipse.Set( ptIT, vtV1, vtV2, vtV3) ; - Frame3d FSmallEllipse ; FSmallEllipse.Set( ptFT, vtV1, vtV2, vtV3) ; - - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; Vector3d vtK = Z_AX ; - - // Cono I - ptC.LocToLoc( m_LocalFrame, IConeFrame) ; - vtK.LocToLoc( m_LocalFrame, IConeFrame) ; - - std::vector vdIConeCoef(3); - std::vector vdIConeRoots; - - vdIConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; - vdIConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; - vdIConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; - - int nIConeRoot = PolynomialRoots( 2, vdIConeCoef, vdIConeRoots) ; - - if ( nIConeRoot == 1) { - - Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; - - if ( ptR1.x >= dl && ptR1.x < dL) { - - ptR1.LocToLoc( IConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dl) { - - dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nIConeRoot == 2) { - - Point3d ptR1 = ptC + vdIConeRoots[0] * vtK ; - Point3d ptR2 = ptC + vdIConeRoots[1] * vtK ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { - - dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( IConeFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( IConeFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { - - dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { - - ptR1.LocToLoc( IConeFrame, m_LocalFrame) ; - ptR2.LocToLoc( IConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { - - ptR1.LocToLoc( IConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - // Cono F - ptC.LocToLoc( IConeFrame, FConeFrame) ; - vtK.LocToLoc( IConeFrame, FConeFrame) ; - - std::vector vdFConeCoef(3); - std::vector vdFConeRoots; - - vdFConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; - vdFConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtK.x - ptC.y * vtK.y - ptC.z * vtK.z) ; - vdFConeCoef[2] = dTan * dTan * vtK.x * vtK.x - vtK.y * vtK.y - vtK.z * vtK.z ; - - int nFConeRoot = PolynomialRoots( 2, vdFConeCoef, vdFConeRoots) ; - - if ( nFConeRoot == 1) { - - Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; - - if ( ptR1.x >= dl && ptR1.x < dL) { - - ptR1.LocToLoc( FConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dl) { - - dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nFConeRoot == 2) { - - Point3d ptR1 = ptC + vdFConeRoots[0] * vtK ; - Point3d ptR2 = ptC + vdFConeRoots[1] * vtK ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - - if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { - - dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( FConeFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( FConeFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { - - dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { - - ptR1.LocToLoc( FConeFrame, m_LocalFrame) ; - ptR2.LocToLoc( FConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { - - ptR1.LocToLoc( FConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - // Solido interno - - ptC.LocToLoc( FConeFrame, m_LocalFrame) ; - vtK.LocToLoc( FConeFrame, m_LocalFrame) ; - - Point3d ptInt1 = ptC + ( ( ( vtRIV - vtC) * vtS1) / ( vtK * vtS1)) * vtK ; - Point3d ptInt2 = ptC + ( ( ( vtRIV - vtC) * vtD1) / ( vtK * vtD1)) * vtK ; - Point3d ptInt3 = ptC + ( ( ( vtRU - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; - Point3d ptInt4 = ptC + ( ( ( vtRUT - vtC) * vtU1) / ( vtK * vtU1)) * vtK ; - Point3d ptInt5 = ptC + ( ( ( vtRU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; - Point3d ptInt6 = ptC + ( ( ( vtRFU - vtC) * vtW1) / ( vtK * vtW1)) * vtK ; - - ptInt1.LocToLoc( m_LocalFrame, PlSFrame) ; - ptInt2.LocToLoc( m_LocalFrame, PlDFrame) ; - ptInt3.LocToLoc( m_LocalFrame, PlBFrame) ; - ptInt4.LocToLoc( m_LocalFrame, PlTFrame) ; - ptInt5.LocToLoc( m_LocalFrame, PlIFrame) ; - ptInt6.LocToLoc( m_LocalFrame, PlFFrame) ; - - double dLim1, dLim2 ; - bool bFlag = false ; - - if ( ptInt1.z >= 0 && ptInt1.z <= dPLong && - ptInt1.y >= - ptInt1.z * dPOrt / dPLong && - ptInt1.y <= dLen - ptInt1.z * dPOrt / dPLong ) { - - ptInt1.LocToLoc( PlSFrame, m_LocalFrame) ; - - dLim1 = ptInt1.z ; - bFlag = true ; - } - - if ( ptInt2.z >= - dPLong && ptInt2.z <= 0 && - ptInt2.y >= ptInt2.z * dPOrt / dPLong && - ptInt2.y <= dLen + ptInt2.z * dPOrt / dPLong) { - - ptInt2.LocToLoc( PlDFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt2.z ; - bFlag = true ; - } - else - - dLim2 = ptInt2.z ; - } - - if ( ptInt3.y >= 0 && ptInt3.y <= dLen && - ptInt3.z > - dMaxRad * dSin && - ptInt3.z < dMaxRad * dSin) { - - ptInt3.LocToLoc( PlBFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt3.z ; - bFlag = true ; - } - else - - dLim2 = ptInt3.z ; - } - - if ( ptInt4.y >= 0 && ptInt4.y <= dLen && - ptInt4.z > - dMinRad * dSin && - ptInt4.z < dMinRad * dSin) { - - ptInt4.LocToLoc( PlTFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt4.z ; - bFlag = true ; - } - else - - dLim2 = ptInt4.z ; - } - - if ( ptInt5.y >= 0 && ptInt5.y <= dPr2 && - ptInt5.z > - dSin * dMaxRad + ptInt5.y * prova1 / dPr2 && - ptInt5.z < dSin * dMaxRad - ptInt5.y * prova1 / dPr2) { - - ptInt5.LocToLoc( PlIFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt5.z ; - bFlag = true ; - } - else - - dLim2 = ptInt5.z ; - } - - if ( ptInt6.y >= 0 && ptInt6.y <= dPr2 && - ptInt6.z > - dSin * dMaxRad + ptInt6.y * prova1 / dPr2 && - ptInt6.z < dSin * dMaxRad - ptInt6.y * prova1 / dPr2) { - - ptInt6.LocToLoc( PlFFrame, m_LocalFrame) ; - - if ( bFlag == false) { - - dLim1 = ptInt6.z ; - bFlag = true ; - } - else - - dLim2 = ptInt6.z ; - } - - if( bFlag == true) { - - dMin = min( dLim1, dLim2) ; - dMax = max( dLim1, dLim2) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - - // Traslazioni ellissi - - ptC.LocToLoc( m_LocalFrame, LargeEllipse) ; - vtK.LocToLoc( m_LocalFrame, LargeEllipse) ; - - std::vector vdLargeCoef(3); - std::vector vdLargeRoots; - - vdLargeCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMaxRad * dMaxRad ; - vdLargeCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; - vdLargeCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; - - - int nLRoot = PolynomialRoots( 2, vdLargeCoef, vdLargeRoots) ; - - if ( nLRoot == 0) { - - Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPi.LocToLoc( m_LocalFrame, LargeEllipse) ; - ptPf.LocToLoc( m_LocalFrame, FLargeEllipse) ; - - if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMaxRad * dMaxRad && - ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMaxRad * dMaxRad) { - - ptPi.LocToLoc( LargeEllipse, m_LocalFrame) ; - ptPf.LocToLoc( FLargeEllipse, m_LocalFrame) ; - - dMin = min( ptPi.z, ptPf.z) ; - dMax = max( ptPi.z, ptPf.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nLRoot == 2) { - - Point3d ptInter1 = ptC + vdLargeRoots[0] * vtK ; - Point3d ptInter2 = ptC + vdLargeRoots[1] * vtK ; - - - if ( ptInter1.x > ptInter2.x) { - - Point3d ptTemp = ptInter1 ; - ptInter1 = ptInter2 ; - ptInter2 = ptTemp ; - } - - if ( ptInter1.x > 0 && ptInter1.x < dLLong && - ptInter2.x > dLLong) { - - ptInter1.LocToLoc( LargeEllipse, m_LocalFrame) ; - - dMin = min( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; - dMax = max( ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { - - ptInter1.LocToLoc( LargeEllipse, m_LocalFrame) ; - ptInter2.LocToLoc( LargeEllipse, m_LocalFrame) ; - - dMin = min( ptInter1.z, ptInter2.z) ; - dMax = max( ptInter1.z, ptInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { - - dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { - - ptInter2.LocToLoc( LargeEllipse, m_LocalFrame) ; - - dMin = min( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; - dMax = max( ( dDotCI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - ptC.LocToLoc( LargeEllipse, SmallEllipse) ; - vtK.LocToLoc( LargeEllipse, SmallEllipse) ; - - std::vector vdSmallCoef(3); - std::vector vdSmallRoots; - - vdSmallCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMinRad * dMinRad ; - vdSmallCoef[1] = 2 * ( dCoef * dCoef * vtK.x * ptC.x + vtK.y * ptC.y + vtK.z * ptC.z - dCoef * ( vtK.x * ptC.y + vtK.y * ptC.x)) ; - vdSmallCoef[2] = dCoef * dCoef * vtK.x * vtK.x + vtK.y * vtK.y + vtK.z * vtK.z - 2 * dCoef * vtK.x * vtK.y ; - - int nSRoot = PolynomialRoots( 2, vdSmallCoef, vdSmallRoots) ; - - if ( nSRoot == 0) { - - Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPi.LocToLoc( m_LocalFrame, SmallEllipse) ; - ptPf.LocToLoc( m_LocalFrame, FSmallEllipse) ; - - if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMinRad * dMinRad && - ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMinRad * dMinRad) { - - ptPi.LocToLoc( SmallEllipse, m_LocalFrame) ; - ptPf.LocToLoc( FSmallEllipse, m_LocalFrame) ; - - dMin = min( ptPi.z, ptPf.z) ; - dMax = max( ptPi.z, ptPf.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nSRoot == 2) { - - Point3d ptTInter1 = ptC + vdSmallRoots[0] * vtK ; - Point3d ptTInter2 = ptC + vdSmallRoots[1] * vtK ; - - if ( ptTInter1.x > ptTInter2.x) { - - Point3d ptTemp = ptTInter1 ; - ptTInter1 = ptTInter2 ; - ptTInter2 = ptTemp ; - } - - if ( ptTInter1.x > 0 && ptTInter1.x < dLLong && - ptTInter2.x > dLLong) { - - ptTInter1.LocToLoc( SmallEllipse, m_LocalFrame) ; - - dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; - dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptTInter1.x > 0 && ptTInter2.x < dLLong) { - - ptTInter1.LocToLoc( SmallEllipse, m_LocalFrame) ; - ptTInter2.LocToLoc( SmallEllipse, m_LocalFrame) ; - - dMin = min( ptTInter1.z, ptTInter2.z) ; - dMax = max( ptTInter1.z, ptTInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptTInter1.x < 0 && ptTInter2.x > dLLong) { - - dMin = min( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotCFT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptTInter1.x < 0 && ptTInter2.x > 0 && ptTInter2.x < dLLong) { - - ptTInter2.LocToLoc( SmallEllipse, m_LocalFrame) ; - - dMin = min( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; - dMax = max( ( dDotCIT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptTInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -VolZmap::MillConusAux( const Point3d& ptI, const Point3d& ptF, const Vector3d& vtV1, const Vector3d& vtV2, const Vector3d& vtV3, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, - double dHei, double dMaxRad, double dMinRad, double dCoef) -{ - double dDeltaR = dMaxRad - dMinRad ; - double dL = ( ( dMaxRad * dHei) / ( dDeltaR)) ; - double dTan = dDeltaR / dHei ; - double dl = dL - dHei ; - - double dLLong = abs( ( ptF - ptI) * vtV1) ; - double dLOrt = abs( ( ptF - ptI) * vtV2) ; - - - Point3d ptV = ptI - vtV1 * dL ; - Point3d ptT = ptI - vtV1 * dHei ; - - Frame3d ConeFrame ; ConeFrame.Set( ptV, vtV1, vtV2, vtV3) ; - Frame3d IEllipseFrame ; IEllipseFrame.Set( ptI, vtV1, vtV2, vtV3) ; - Frame3d FEllipseFrame ; FEllipseFrame.Set( ptF, vtV1, vtV2, vtV3) ; - - Vector3d vtI = ptI - ORIG ; double dDotI = vtI * vtV1 ; - Vector3d vtT = ptT - ORIG ; double dDotT = vtT * vtV1 ; - Vector3d vtF = ptF - ORIG ; double dDotF = vtF * vtV1 ; - - Vector3d vtK = Z_AX ; - Vector3d vtKC = vtK ; vtKC.LocToLoc( m_LocalFrame, ConeFrame) ; - Vector3d vtKE = vtK ; vtKE.LocToLoc( m_LocalFrame, IEllipseFrame) ; - - double dMin, dMax ; - - for ( unsigned int i = nStI ; i <= nEnI ; ++ i) { - - for ( unsigned int j = nStJ ; j <= nEnJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ORIG ; - - // Cono - ptC.LocToLoc( m_LocalFrame, ConeFrame) ; - - std::vector vdConeCoef(3); - std::vector vdConeRoots; - - vdConeCoef[0] = dTan * dTan * ptC.x * ptC.x - ptC.y * ptC.y - ptC.z * ptC.z ; - vdConeCoef[1] = 2 * ( dTan * dTan * ptC.x * vtKC.x - ptC.y * vtKC.y - ptC.z * vtKC.z) ; - vdConeCoef[2] = dTan * dTan * vtKC.x * vtKC.x - vtKC.y * vtKC.y - vtKC.z * vtKC.z ; - - int nConeRoot = PolynomialRoots( 2, vdConeCoef, vdConeRoots) ; - - - if ( nConeRoot == 1) { - - Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; - - if ( ptR1.x >= dl && ptR1.x < dL) { - - ptR1.LocToLoc( ConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= 0 && ptR1.x < dl) { - - dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - else if ( nConeRoot == 2) { - - Point3d ptR1 = ptC + vdConeRoots[0] * vtKC ; - Point3d ptR2 = ptC + vdConeRoots[1] * vtKC ; - - if ( ptR1.x > ptR2.x) { - - Point3d ptTemp = ptR1 ; - ptR1 = ptR2 ; - ptR2 = ptTemp ; - } - - if ( ptR1.x < 0 && ptR2.x > 0 && ptR2.x < dl) { - - dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x < 0 && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( ConeFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dl && ptR2.x < dL) { - - ptR2.LocToLoc( ConeFrame, m_LocalFrame) ; - - dMin = min( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR2.z, ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x > 0 && ptR1.x < dl && ptR2.x >= dL) { - - dMin = min( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotT - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x < dL) { - - ptR1.LocToLoc( ConeFrame, m_LocalFrame) ; - ptR2.LocToLoc( ConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ptR2.z) ; - dMax = max( ptR1.z, ptR2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptR1.x >= dl && ptR1.x < dL && ptR2.x >= dL) { - - ptR1.LocToLoc( ConeFrame, m_LocalFrame) ; - - dMin = min( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ptR1.z, ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - - // Tralsazione dell'ellisse - - ptC.LocToLoc( ConeFrame, IEllipseFrame) ; - - std::vector vdEllipseCoef(3); - std::vector vdEllipseRoots; - - vdEllipseCoef[0] = dCoef * dCoef * ptC.x * ptC.x + ptC.y * ptC.y + ptC.z * ptC.z - 2 * dCoef * ptC.x * ptC.y - dMaxRad * dMaxRad ; - vdEllipseCoef[1] = 2 * ( dCoef * dCoef * vtKE.x * ptC.x + vtKE.y * ptC.y + vtKE.z * ptC.z - dCoef * ( vtKE.x * ptC.y + vtKE.y * ptC.x)) ; - vdEllipseCoef[2] = dCoef * dCoef * vtKE.x * vtKE.x + vtKE.y * vtKE.y + vtKE.z * vtKE.z - 2 * dCoef * vtKE.x * vtKE.y ; - - - int nEllipseRoot = PolynomialRoots( 2, vdEllipseCoef, vdEllipseRoots) ; - - - if ( nEllipseRoot == 0 || nEllipseRoot == 1) { - - Point3d ptPi ; ptPi.x = dX ; ptPi.y = dY ; ptPi.z = ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - Point3d ptPf ; ptPf.x = dX ; ptPf.y = dY ; ptPf.z = ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z ; - - ptPi.LocToLoc( m_LocalFrame, IEllipseFrame) ; - ptPf.LocToLoc( m_LocalFrame, FEllipseFrame) ; - - if ( ptPi.y * ptPi.y + ptPi.z * ptPi.z < dMaxRad * dMaxRad && - ptPf.y * ptPf.y + ptPf.z * ptPf.z < dMaxRad * dMaxRad) { - - ptPi.LocToLoc( IEllipseFrame, m_LocalFrame) ; - ptPf.LocToLoc( FEllipseFrame, m_LocalFrame) ; - - dMin = min( ptPi.z, ptPf.z) ; - dMax = max( ptPi.z, ptPf.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - if ( nEllipseRoot == 2) { - - Point3d ptInter1 = ptC + vdEllipseRoots[0] * vtKE ; - Point3d ptInter2 = ptC + vdEllipseRoots[1] * vtKE ; - - - if ( ptInter1.x > ptInter2.x) { - - Point3d ptTemp = ptInter1 ; - ptInter1 = ptInter2 ; - ptInter2 = ptTemp ; - } - - if ( ptInter1.x > 0 && ptInter1.x < dLLong && - ptInter2.x > dLLong) { - - ptInter1.LocToLoc( IEllipseFrame, m_LocalFrame) ; - - dMin = min( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; - dMax = max( ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x > 0 && ptInter2.x < dLLong) { - - ptInter1.LocToLoc( IEllipseFrame, m_LocalFrame) ; - ptInter2.LocToLoc( IEllipseFrame, m_LocalFrame) ; - - dMin = min( ptInter1.z, ptInter2.z) ; - dMax = max( ptInter1.z, ptInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x < 0 && ptInter2.x > dLLong) { - - dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ( dDotF - vtV1.x * dX - vtV1.y * dY) / vtV1.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - else if ( ptInter1.x < 0 && ptInter2.x > 0 && ptInter2.x < dLLong) { - - ptInter2.LocToLoc( IEllipseFrame, m_LocalFrame) ; - - dMin = min( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; - dMax = max( ( dDotI - vtV1.x * dX - vtV1.y * dY) / vtV1.z, ptInter2.z) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - -// Traslazioni -//---------------------------------------------------------------------------- -bool -VolZmap::Ball( const Point3d& ptLs, const Point3d& ptLe, double dRad) -{ - double dMin, dMax ; - unsigned int nStartI, nStartJ, nEndI, nEndJ ; - - bool Control = BBoxComponent( ptLs, ptLe, V_NULL, V_NULL, nStartI, nStartJ, nEndI, nEndJ, dRad, 0, 0) ; - - if ( ! Control) - return true ; - - Point3d ptI = ( ptLs.z < ptLe.z ? ptLs : ptLe) ; - Point3d ptF = ( ptLs.z < ptLe.z ? ptLe : ptLs) ; - - Point3d ptIxy( ptI.x, ptI.y, 0) ; - Point3d ptFxy( ptF.x, ptF.y, 0) ; - - Vector3d vtMove = ptF - ptI ; - Vector3d vtMoveXY( vtMove.x, vtMove.y, 0) ; - - double dVLen = abs( vtMove.z) ; // Verticale e planare rispetto ai dexel - double dPLen = vtMoveXY.LenXY() ; - double dLen = vtMove.Len() ; - - double dR1 = dVLen / dLen ; - double dR2 = dPLen / dLen ; - - double dZI = ptI.z ; - double dDeltaZ = ptF.z - ptI.z ; - - - if ( dPLen < EPS_SMALL) { - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtC = ptC - ptIxy ; - - double dSqLen = vtC.SqLen() ; - - if ( dSqLen < dRad * dRad) { - - double dH = sqrt( dRad * dRad - dSqLen) ; - - dMin = dZI - dH ; - dMax = dZI + dDeltaZ + dH ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - else { - - Vector3d vtV1 = vtMoveXY ; vtV1.Normalize() ; - Vector3d vtV2 = vtV1 ; vtV2.Rotate( Z_AX, 90) ; - - for ( unsigned int i = nStartI ; i <= nEndI ; ++ i) { - - for ( unsigned int j = nStartJ ; j <= nEndJ ; ++ j) { - - double dX = ( i + 0.5) * m_dStep ; double dY = ( j + 0.5) * m_dStep ; - - Point3d ptC( dX, dY, 0) ; Vector3d vtCI = ptC - ptIxy ; Vector3d vtCF = ptC - ptFxy ; - - double dX1 = vtCI * vtV1 ; double dX2 = vtCI * vtV2 ; - - double dISqDist = vtCI * vtCI ; double dFSqDist = vtCF * vtCF ; - - if ( dISqDist < dRad * dRad || dFSqDist < dRad * dRad || - ( dX1 > 0 && dX1 < dPLen && dX2 * dX2 < dRad * dRad)) { - - // Massimi - if ( dX1 < - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad * dR2 * dR2)) && - dISqDist < dRad * dRad) - - dMax = dZI + sqrt( dRad * dRad - dISqDist) ; - - else if ( dX1 >= - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && - dX1 < dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) - - dMax = dZI + dR2 * sqrt( dRad * dRad - dX2 * dX2) + ( dX1 + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) * dVLen / dPLen ; - - else if ( dX1 >= dPLen - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && - dFSqDist < dRad * dRad) - - dMax = dZI + dDeltaZ + sqrt( dRad * dRad - dFSqDist) ; - - // Minimi - if ( dX1 < dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && - dISqDist < dRad * dRad) - - dMin = dZI - sqrt( dRad * dRad - dISqDist) ; - - else if ( dX1 >= dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && - dX1 < dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) - - dMin = dZI - dR2 * sqrt( dRad * dRad - dX2 * dX2) + ( dX1 - dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad))) * dVLen / dPLen ; - - else if ( dX1 >= dPLen + dRad * dR1 * sqrt( 1 - ( dX2 * dX2) / ( dRad * dRad)) && - dFSqDist < dRad * dRad) - - dMin = dZI + dDeltaZ - sqrt( dRad * dRad - dFSqDist) ; - - SubtractIntervals( i, j, dMin, dMax) ; - } - } - } - } - - return true ; -} - - -// Bounding Box, interferenza dell'utensile con lo Zmap e limiti su indici -//---------------------------------------------------------------------------- -inline bool -VolZmap::BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ) -{ - // Determinazione del raggio massimo dell'utensile - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - - // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale - Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; - Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; - - // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento - double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad; - double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad; - double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad; - double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad; - double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad; - double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad; - - // Verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return false ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return false ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return false ; - - // Limiti su indici - nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - nEnI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - nEnJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::BoundingBox( unsigned int nGrid, const Point3d& ptP1, const Point3d& ptP2, - const Vector3d& vtV1, const Vector3d& vtV2, - unsigned int& nStI, unsigned int& nStJ, unsigned int& nEnI, unsigned int& nEnJ) -{ - // NB: E' vitale che vengano passati i punti e i vettori nel sistema di riferimento - // di riferimento opportuno. - unsigned int nMaxNx, nMaxNy ; - - double dMaxXValue, dMaxYValue ; - double dMinZValue, dMaxZValue ; - - if ( nGrid == 1) { - - nMaxNx = m_nNx ; nMaxNy = m_nNy ; - - dMaxXValue = m_nNx * m_dStep ; dMaxYValue = m_nNy * m_dStep ; - - dMinZValue = m_dMinZ ; dMaxZValue = m_dMaxZ ; - } - else if ( nGrid == 2) { - - nMaxNx = m_nNx2 ; nMaxNy = m_nNy2 ; - - dMaxXValue = m_nNx2 * m_dStep ; dMaxYValue = m_nNy2 * m_dStep ; - - dMinZValue = m_dMinZ2 ; dMaxZValue = m_dMaxZ2 ; - } - else if ( nGrid == 3) { - - nMaxNx = m_nNx3 ; nMaxNy = m_nNy3 ; - - dMaxXValue = m_nNx3 * m_dStep ; dMaxYValue = m_nNy3 * m_dStep ; - - dMinZValue = m_dMinZ3 ; dMaxZValue = m_dMaxZ3 ; - } - - // Determinazione del raggio massimo dell'utensile - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - - // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale - Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; - Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; - - // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento - double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad ; - double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad ; - double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad ; - double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad ; - double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad ; - double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad ; - - // Verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > dMaxXValue - EPS_SMALL) - return false ; - if ( dMaxY < EPS_SMALL || dMinY > dMaxYValue - EPS_SMALL) - return false ; - if ( dMaxZ < dMinZValue + EPS_SMALL || dMinZ > dMaxZValue - EPS_SMALL) - return false ; - - // Limiti su indici - nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - nEnI = ( dMaxX > dMaxXValue - EPS_SMALL ? nMaxNx - 1 : static_cast ( dMaxX / m_dStep)) ; - nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - nEnJ = ( dMaxY > dMaxYValue - EPS_SMALL ? nMaxNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::BoundingBox( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2) -{ - // Determinazione del raggio massimo dell'utensile - double dMaxRad = max( m_dRadius, m_dTipRadius) ; - - // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale - Point3d ptP1T = ptP1 - m_dHeight * vtV1 ; - Point3d ptP2T = ptP2 - m_dHeight * vtV2 ; - - // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento - double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad ; - double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad ; - double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad ; - double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad ; - double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad ; - double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad ; - - // Verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return false ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return false ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return false ; - - return true ; -} - -//---------------------------------------------------------------------------- -inline bool -VolZmap::BBoxComponent( const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV1, const Vector3d& vtV2, - unsigned int & nStI, unsigned int & nStJ, unsigned int & nEnI, unsigned int & nEnJ, - double dRad, double dTipRad, double dHei) -{ - // Determinazione del raggio massimo dell'utensile - double dMaxRad = max( dRad, dTipRad) ; - - // Determinazione delle posizioni della punta dell'utensile nelle posizioni iniziale e finale - Point3d ptP1T = ptP1 - dHei * vtV1 ; - Point3d ptP2T = ptP2 - dHei * vtV2 ; - - // Determinazione dei limiti del più piccolo parallelepipedo contenente il movimento - double dMinX = min( min( ptP1.x, ptP1T.x), min( ptP2.x, ptP2T.x)) - dMaxRad; - double dMinY = min( min( ptP1.y, ptP1T.y), min( ptP2.y, ptP2T.y)) - dMaxRad; - double dMinZ = min( min( ptP1.z, ptP1T.z), min( ptP2.z, ptP2T.z)) - dMaxRad; - double dMaxX = max( max( ptP1.x, ptP1T.x), max( ptP2.x, ptP2T.x)) + dMaxRad; - double dMaxY = max( max( ptP1.y, ptP1T.y), max( ptP2.y, ptP2T.y)) + dMaxRad; - double dMaxZ = max( max( ptP1.z, ptP1T.z), max( ptP2.z, ptP2T.z)) + dMaxRad; - - // Verifica dell'interferenza dell'utensile con lo Zmap - if ( dMaxX < EPS_SMALL || dMinX > m_nNx * m_dStep - EPS_SMALL) - return false ; - if ( dMaxY < EPS_SMALL || dMinY > m_nNy * m_dStep - EPS_SMALL) - return false ; - if ( dMaxZ < m_dMinZ + EPS_SMALL || dMinZ > m_dMaxZ - EPS_SMALL) - return false ; - - // Limiti su indici - nStI = ( dMinX < EPS_SMALL ? 0 : static_cast ( dMinX / m_dStep)) ; - nEnI = ( dMaxX > m_nNx * m_dStep - EPS_SMALL ? m_nNx - 1 : static_cast ( dMaxX / m_dStep)) ; - nStJ = ( dMinY < EPS_SMALL ? 0 : static_cast ( dMinY / m_dStep)) ; - nEnJ = ( dMaxY > m_nNy * m_dStep - EPS_SMALL ? m_nNy - 1 : static_cast ( dMaxY / m_dStep)) ; - - return true ; -} \ No newline at end of file