From d21f27ae2dc2f59b03f04be1aed3701c31df4fb3 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 1 Feb 2016 07:42:49 +0000 Subject: [PATCH] EgtGeomKernel 1.6l10 : - migliorie a Zmap. --- EgtGeomKernel.rc | Bin 11718 -> 11734 bytes GdbExecutor.cpp | 169 ++++++++++++- GdbExecutor.h | 7 +- VolZmap.cpp | 628 ++++++++++++++++++++++++++++++++++++++++++++++- VolZmap.h | 49 +++- 5 files changed, 834 insertions(+), 19 deletions(-) diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index cf2f93cd2a61123a1d28c7fc75b844fa5756f832..688c161702a123f3edef235e94762f68c5eb68d7 100644 GIT binary patch delta 134 zcmX>WeJy&!A2wz~27}G_`OY&eJpyzA2vqw&HvdHnHkL|I|}M<4&a)^0v0*XGGetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) return false ; - // recupero punto iniziale + // recupero punto iniziale Point3d ptO ; if ( ! GetPointParam( vsParams[2], frRef, ptO)) return false ; - // recupero precisione + // recupero precisione double dPrec ; if ( ! FromString( vsParams[3], dPrec)) return false ; - // recupero LunghezzaX + // recupero LunghezzaX double dLengthX ; if ( ! FromString( vsParams[4], dLengthX)) return false ; - // recupero LunghezzaY + // recupero LunghezzaY double dLengthY ; if ( ! FromString( vsParams[5], dLengthY)) return false ; - // recupero LunghezzaZ + // recupero LunghezzaZ double dLengthZ ; if ( ! FromString( vsParams[6], dLengthZ)) return false ; @@ -2603,7 +2628,135 @@ GdbExecutor::ExecuteVolZmap(const string& sCmd2, const STRVECTOR& vsParams) pZprova->CreateMap( ptO, dPrec, dLengthX, dLengthY, dLengthZ); // inserisco nel DB - return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; + return AddGeoObj(vsParams[0], vsParams[1], Release( pZprova)) ; +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::VolZmapIntervalsSubtraction( const STRVECTOR& vsParams) +{ + // parametri : Id, IdParent, ptP, dMin, dMax + if ( vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero punto + Point3d ptP ; + if ( ! GetPointParam( vsParams[2], frRef, ptP)) + return false ; + // recupero minimo + double dMin ; + if ( ! FromString( vsParams[3], dMin)) + return false ; + // recupero massimo + double dMax ; + if ( ! FromString( vsParams[4], dMax)) + return false ; + // recupero lo Zmap + int nIdZmap = GetIdParam( vsParams[0]) ; + VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nIdZmap)) ; + if ( pZmap == nullptr) + return false ; + // eseguo la sottrazione + return pZmap->SubtractIntervals( ptP, dMin, dMax) ; +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::VolZmapIntervalsAddiction( const STRVECTOR& vsParams) +{ + // parametri : Id, IdParent, ptP, dMin, dMax + if ( vsParams.size() != 5) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero punto + Point3d ptP ; + if ( ! GetPointParam( vsParams[2], frRef, ptP)) + return false ; + // recupero minimo + double dMin ; + if ( ! FromString( vsParams[3], dMin)) + return false ; + // recupero massimo + double dMax ; + if ( ! FromString( vsParams[4], dMax)) + return false ; + // recupero lo Zmap + int nIdZmap = GetIdParam( vsParams[0]) ; + VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nIdZmap)) ; + if ( pZmap == nullptr) + return false ; + // eseguo l'addizione + return pZmap->AddIntervals( ptP, dMin, dMax) ; +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::VolZmapMilling( const STRVECTOR& vsParams) +{ + // parametri : Id, IdParent, ptPs, ptPe, vtVs, vtVe + if ( vsParams.size() != 6) + return false ; + // recupero il riferimento in cui è immerso + Frame3d frRef ; + if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) + return false ; + // recupero punto iniziale + Point3d ptPs ; + if ( ! GetPointParam( vsParams[2], frRef, ptPs)) + return false ; + // recupero punto finale + Point3d ptPe ; + if ( ! GetPointParam( vsParams[3], frRef, ptPe)) + return false ; + // recupero il vettore direzione iniziale + Vector3d vtDs ; + if ( ! GetVectorParam( vsParams[4], frRef, vtDs)) + return false ; + // recupero il vettore direzione iniziale + Vector3d vtDe ; + if ( ! GetVectorParam( vsParams[5], frRef, vtDe)) + return false ; + // recupero lo Zmap + int nIdZmap = GetIdParam( vsParams[0]) ; + VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nIdZmap)) ; + if ( pZmap == nullptr) + return false ; + // eseguo la lavorazione + return pZmap->MillingStep( ptPs, ptPe, vtDs, vtDe) ; +} + +//---------------------------------------------------------------------------- +bool +GdbExecutor::VolZmapSetTool( const STRVECTOR& vsParams) +{ + // parametri : ZmapId, CrvId, nToolType, sToolName + if ( vsParams.size() != 4) + return false ; + // recupero lo Zmap + int nZmapId = GetIdParam( vsParams[0]) ; + VolZmap* pZmap = GetBasicVolZmap( m_pGDB->GetGeoObj( nZmapId)) ; + if ( pZmap == nullptr) + return false ; + // recupero il profilo utensile + int nCrvId = GetIdParam( vsParams[1]) ; + CurveComposite* pToolOutline = GetBasicCurveComposite( m_pGDB->GetGeoObj( nCrvId)) ; + if ( pToolOutline == nullptr) + return false ; + // recupero tipo utensile + int nToolType ; + if ( ! FromString( vsParams[2], nToolType)) + return false ; + // recupero la stringa nome dell'utensile + string sToolName ; + sToolName = vsParams[3] ; + // assegno utensile + return pZmap->SetTool( sToolName, nToolType, pToolOutline) ; } //---------------------------------------------------------------------------- diff --git a/GdbExecutor.h b/GdbExecutor.h index 4860c1a..59345b6 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -113,7 +113,12 @@ class GdbExecutor : public IGdbExecutor bool SurfTriMeshChangeSmoothAng( const STRVECTOR& vsParams) ; bool SurfTriMeshDoCompacting( const STRVECTOR& vsParams) ; bool SurfTriMeshDoSewing( const STRVECTOR& vsParams) ; - bool ExecuteVolZmap(const std::string& sCmd2, const STRVECTOR& vsParams); + bool ExecuteVolZmap( const std::string& sCmd2, const STRVECTOR& vsParams) ; + bool VolZmapCreate( const STRVECTOR& vsParams) ; + bool VolZmapIntervalsSubtraction( const STRVECTOR& vsParams) ; + bool VolZmapIntervalsAddiction( const STRVECTOR& vsParams) ; + bool VolZmapMilling( const STRVECTOR& vsParams) ; + bool VolZmapSetTool( const STRVECTOR& vsParams) ; bool ExecuteText( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool TextSimple( const STRVECTOR& vsParams) ; bool TextComplete( const STRVECTOR& vsParams) ; diff --git a/VolZmap.cpp b/VolZmap.cpp index 3d35962..08c3b3f 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -17,6 +17,7 @@ #include "GeoObjFactory.h" #include "NgeWriter.h" #include "NgeReader.h" +#include "\EgtDev\Include\EGkIntervals.h" using namespace std ; @@ -371,7 +372,7 @@ VolZmap::CreateMap( const Point3d& ptO, double dPrec, double dLengthX, double dL m_ZValues.resize( m_nDim) ; for ( int i = 0 ; i < int( m_nDim) ; i++) { - m_ZValues[i].resize(2) ;///? + m_ZValues[i].resize(2) ; m_ZValues[i][0] = 0 ; m_ZValues[i][1] = dLengthZ ; @@ -381,12 +382,281 @@ VolZmap::CreateMap( const Point3d& ptO, double dPrec, double dLengthX, double dL return true ; } +//---------------------------------------------------------------------------- +bool +VolZmap::SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + unsigned int nPos ; + //unsigned int nKD ; + //unsigned int nKU ; + //unsigned int nDelta ; // Variazione di dimensione del vettore + + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + + return true ; + // Controllo che dMin < dMax + + if ( dMax < dMin ) { + + double dTemp = dMax ; + + dMax = dMin ; + dMin = dMax ; + } + + // Calcolo nPos + nPos = nJ*m_nNx + nI ; // O nJ*m_Nx + nI + 1 ? + + unsigned int i = 0 ; + + while ( i < m_ZValues[nPos].size() - 1) { + + if ( m_ZValues[nPos].size() == 0) + return true ; + // Casi: + // 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) { + + m_ZValues[nPos][i] = dMax ; + } + // L'intervallo si divide in due intervalli + else { + + 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) { + + 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) { + + m_ZValues[nPos][i + 1] = dMin ; + } + // L'intervallo da sottrarre è tutto a destra di quello corrente, non vi è intersezione + else { + + } + } + + i = i + 2 ; + } + + 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) ; // ptPL è ora espresso rispetto al sistema di riferimento intrinseco. + + 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 + + return SubtractIntervals( i, j, dhMin, dhMax) ; + } + // altrimenti non succede niente + else { + + return true ; + } + +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) +{ + unsigned int nPos ; + //unsigned int nKD ; + //unsigned int nKU ; + //unsigned int nDelta ; // Variazione di dimensione del vettore + + // Controllo che dMin e dMax non siano quasi coincidenti + if ( abs( dMax - dMin) < EPS_SMALL) + + return true ; + + // Controllo che dMin < dMax + if ( dMax < dMin ) { + + double dTemp = dMax ; + + dMax = dMin ; + dMin = dMax ; + } + + // Calcolo nPos + nPos = nJ*m_nNx + nI ; // O nJ*m_Nx + nI + 1 ? + + if ( m_ZValues[nPos].size() == 0) { + + m_ZValues[nPos].resize( 2) ; + + m_ZValues[nPos][0] = dMin ; + m_ZValues[nPos][1] = dMax ; + + return true ; + } + + unsigned int i = 0 ; + + while ( i < m_ZValues[nPos].size() - 1) { + + if ( i > 0) { + // Caso in cui un intervallo precedente sconfini in quello corrente + 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) { + + 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) { + + 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) { + + 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) { + + m_ZValues[nPos][i + 1] = dMax ; + } + else { + // Aggiungo intervallo a destra dell'ultimo intervallo + if ( i == m_ZValues[nPos].size() - 2) { + + 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 ; + } + + 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) ; // ptPL è ora espresso rispetto al sistema di riferimento intrinseco. + + 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 + + return AddIntervals( i, j, dhMin, dhMax) ; + } + // altrimenti non succede niente + else { + + return false ; + } +} + //---------------------------------------------------------------------------- bool VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const { - // pulisco la lista - lstPL.clear() ; // per ora solo perpendicolari a XY (1) if ( nDir != 1) return false ; @@ -410,3 +680,355 @@ VolZmap::GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) con } return true ; } + +//---------------------------------------------------------------------------- +bool +VolZmap::GetAllTriangles( TRIA3DLIST& lstTria) const +{ + const int DIM_CHUNK = 4 ; + for ( int i = 0 ; i < int( m_nNx) ; i += DIM_CHUNK) { + int nDimChunkX = min( DIM_CHUNK, int( m_nNx) - i) ; + for ( int j = 0 ; j < int( m_nNy) ; j += DIM_CHUNK) { + int nDimChunkY = min( DIM_CHUNK, int( m_nNy) - j) ; + GetChunkPrisms( i, j, nDimChunkX, nDimChunkY, lstTria) ; + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, 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) ; + } + // altrimenti + else { + // elaboro ogni singolo dexel + for ( int i = 0 ; i < nDim1 ; ++ i) { + for ( int j = 0 ; j < nDim2 ; ++ j) { + CalcDexelPrisms( nPos1 + i, nPos2 + j, lstTria) ; + } + } + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const +{ + // verifiche sugli indici + if ( nPos1 < 0 || nPos1 + nDim1 > int( m_nNx) || nPos2 < 0 || nPos2 + nDim2 > int( m_nNy)) + return false ; + int nPos = nPos1 + nPos2 * m_nNx ; + if ( nPos < 0 || nPos >= int( m_nDim)) + return false ; + + // calcolo coordinate punti + double dX = m_dStep * nPos1 ; + double dY = m_dStep * nPos2 ; + Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; + Point3d ptP2 = ptP1 + nDim1 * m_dStep * m_LocalFrame.VersX() ; + Point3d ptP3 = ptP2 + nDim2 * m_dStep * m_LocalFrame.VersY() ; + Point3d ptP4 = ptP1 + nDim2 * m_dStep * m_LocalFrame.VersY() ; + + // creo le facce sopra e sotto + Vector3d vtDZt = m_ZValues[nPos][1] * m_LocalFrame.VersZ() ; + Vector3d vtDZb = m_ZValues[nPos][0] * m_LocalFrame.VersZ() ; + // faccia superiore P1t->P2t->P3t->P4t : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; + // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; + + // creo le facce laterali + for ( int j = 0 ; j < nDim2 ; ++ j) { + int nPosD = nPos + nDim1 - 1 + j * m_nNx ; + int nPosEst = ( nPos1 + nDim1 - 1 < int( m_nNx - 1) ? nPosD + 1 : - 1) ; + Point3d ptP2D = ptP2 + j * m_dStep * m_LocalFrame.VersY() ; + Point3d ptP3D = ptP2D + m_dStep * m_LocalFrame.VersY() ; + AddDexelSideFace( nPosD, nPosEst, ptP2D, ptP3D, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; + } + for ( int i = 0 ; i < nDim1 ; ++ i) { + int nPosD = nPos + ( nDim2 - 1) * m_nNx + i ; + int nPosNord = ( nPos2 + nDim2 - 1 < int( m_nNy - 1) ? nPosD + m_nNx : - 1) ; + Point3d ptP4D = ptP4 + i * m_dStep * m_LocalFrame.VersX() ; + Point3d ptP3D = ptP4D + m_dStep * m_LocalFrame.VersX() ; + AddDexelSideFace( nPosD, nPosNord, ptP3D, ptP4D, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; + } + for ( int j = 0 ; j < nDim2 ; ++ j) { + int nPosD = nPos + j * m_nNx ; + int nPosWest = ( nPos1 > 0 ? nPosD - 1 : - 1) ; + Point3d ptP1D = ptP1 + j * m_dStep * m_LocalFrame.VersY() ; + Point3d ptP4D = ptP1D + m_dStep * m_LocalFrame.VersY() ; + AddDexelSideFace( nPosD, nPosWest, ptP4D, ptP1D, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; + } + for ( int i = 0 ; i < nDim1 ; ++ i) { + int nPosD = nPos + i ; + int nPosSud = ( nPos2 > 0 ? nPosD - m_nNx : - 1) ; + Point3d ptP1D = ptP1 + i * m_dStep * m_LocalFrame.VersX() ; + Point3d ptP2D = ptP1D + m_dStep * m_LocalFrame.VersX() ; + AddDexelSideFace( nPosD, nPosSud, ptP1D, ptP2D, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CalcDexelPrisms( int nPos1, int nPos2, TRIA3DLIST& lstTria) const +{ + // verifiche sugli indici + if ( nPos1 < 0 || nPos1 >= int( m_nNx) || nPos2 < 0 || nPos2 >= int( m_nNy)) + return false ; + int nPos = nPos1 + nPos2 * m_nNx ; + if ( nPos < 0 || nPos >= int( m_nDim)) + return false ; + + // calcolo coordinate punto + double dX = m_dStep * nPos1 ; + double dY = m_dStep * nPos2 ; + Point3d ptP1 = m_LocalFrame.Orig() + dX * m_LocalFrame.VersX() + dY * m_LocalFrame.VersY() ; + Point3d ptP2 = ptP1 + m_dStep * m_LocalFrame.VersX() ; + Point3d ptP3 = ptP2 + m_dStep * m_LocalFrame.VersY() ; + Point3d ptP4 = ptP1 + m_dStep * m_LocalFrame.VersY() ; + + // creo le facce sopra e sotto di ogni intervallo (sempre visibili) + for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) { + Vector3d vtDZt = m_ZValues[nPos][i] * m_LocalFrame.VersZ() ; + Vector3d vtDZb = m_ZValues[nPos][i-1] * m_LocalFrame.VersZ() ; + // faccia superiore P1t->P2t->P3t->P4t : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZt, ptP2 + vtDZt, ptP3 + vtDZt, m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZt, ptP4 + vtDZt, ptP1 + vtDZt, m_LocalFrame.VersZ()) ; + // faccia inferiore P1b->P4b->P3b->P2b : sempre visibile + lstTria.emplace_back() ; + lstTria.back().Set( ptP1 + vtDZb, ptP4 + vtDZb, ptP3 + vtDZb, - m_LocalFrame.VersZ()) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP3 + vtDZb, ptP2 + vtDZb, ptP1 + vtDZb, - m_LocalFrame.VersZ()) ; + } + + // creo le facce laterali + int nPosEst = ( nPos1 < int( m_nNx - 1) ? nPos + 1 : - 1) ; + AddDexelSideFace( nPos, nPosEst, ptP2, ptP3, m_LocalFrame.VersZ(), m_LocalFrame.VersX(), lstTria) ; + int nPosNord = ( nPos2 < int( m_nNy - 1) ? nPos + m_nNx : - 1) ; + AddDexelSideFace( nPos, nPosNord, ptP3, ptP4, m_LocalFrame.VersZ(), m_LocalFrame.VersY(), lstTria) ; + int nPosWest = ( nPos1 > 0 ? nPos - 1 : - 1) ; + AddDexelSideFace( nPos, nPosWest, ptP4, ptP1, m_LocalFrame.VersZ(), - m_LocalFrame.VersX(), lstTria) ; + int nPosSud = ( nPos2 > 0 ? nPos - m_nNx : - 1) ; + AddDexelSideFace( nPos, nPosSud, ptP1, ptP2, m_LocalFrame.VersZ(), - m_LocalFrame.VersY(), lstTria) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::AddDexelSideFace( int nPos, int nPosAdj, const Point3d& ptP, const Point3d& ptQ, + const Vector3d& vtZ, const Vector3d& vtNorm, TRIA3DLIST& lstTria) const +{ + Intervals intFace ; + for ( int i = 1 ; i < int( m_ZValues[nPos].size()) ; i += 2) + intFace.Add( m_ZValues[nPos][i-1], m_ZValues[nPos][i]) ; + if ( nPosAdj > 0) { + for ( int i = 1 ; i < int( m_ZValues[nPosAdj].size()) ; i += 2) + intFace.Subtract( m_ZValues[nPosAdj][i-1], m_ZValues[nPosAdj][i]) ; + } + double dMin, dMax ; + bool bFound = intFace.GetFirst( dMin, dMax) ; + while ( bFound) { + Vector3d vtDZt = dMax * vtZ ; + Vector3d vtDZb = dMin * vtZ ; + lstTria.emplace_back() ; + lstTria.back().Set( ptP + vtDZb, ptQ + vtDZb, ptQ + vtDZt, vtNorm) ; + lstTria.emplace_back() ; + lstTria.back().Set( ptQ + vtDZt, ptP + vtDZt, ptP + vtDZb, vtNorm) ; + bFound = intFace.GetNext( dMin, dMax) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SetTool( const string& pToolName, unsigned int nToolType, const CurveComposite* pToolOutline) +{ + m_sToolName = pToolName ; + + m_nToolType = nToolType ; + + m_ToolOutline.CopyFrom( pToolOutline) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtDe) +{ + // Dimensioni dell'utensile + BBox3d Bounding ; + m_ToolOutline.GetLocalBBox( Bounding) ; + double dHeight = Bounding.GetMax().y - Bounding.GetMin().y ; + double dRadius = Bounding.GetMax().x - Bounding.GetMin().x ; + + // Porto i dati del movimento nel riferimento intrinseco + 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) ; + + // Direzione utensile costante e come asse Z dello Zmap + if ( AreSameVectorApprox( vtLs, vtLe) && vtLs.IsZplus()) { + // Movimento diretto come direzione utensile + if ( AreSamePointXYApprox( ptLs, ptLe)) + return MillingDrill(ptLs, ptLe, dHeight, dRadius) ; + // Movimento perpendicolare a direzione utensile + else if ( abs( ptLe.z - ptLs.z) < EPS_SMALL) + return MillingPerp(ptLs, ptLe, dHeight, dRadius) ; + // Movimento generico (per ora non gestito) + else + return false ; + } + // Altri casi, non gestiti + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingDrill( const Point3d& ptLs, const Point3d& ptLe, double dHeight, double dRadius) +{ + // Bounding box + double dMinX = min( ptLs.x, ptLe.x) - dRadius ; + double dMinY = min( ptLs.y, ptLe.y) - dRadius ; + double dMaxX = max( ptLs.x, ptLe.x) + dRadius ; + double dMaxY = max( ptLs.y, ptLe.y) + 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 - dHeight ; + double dMin = ptLe.z - dHeight ; + + // Limite sul quadrato del raggio + double dSqRad = ( dRadius + EPS_SMALL) * ( 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) + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::MillingPerp( Point3d& ptLs, Point3d& ptLe, double dHeight, double dRadius) +{ + // Bounding box + double dMinX = min( ptLs.x, ptLe.x) - dRadius ; + double dMinY = min( ptLs.y, ptLe.y) - dRadius ; + double dMaxX = max( ptLs.x, ptLe.x) + dRadius ; + double dMaxY = max( ptLs.y, ptLe.y) + 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 ; + double dMin = ptLs.z - dHeight ; // Questa andrà eliminata in futuro oppure la teniamo e la usiamo al bisogno + + // Limite sul quadrato del raggio + double dSqRad = ( dRadius + EPS_SMALL) * ( 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) + SubtractIntervals( i, j, dMin, dMax) ; + } + } + + return true ; +} diff --git a/VolZmap.h b/VolZmap.h index 1aa6595..5614f88 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -18,8 +18,11 @@ #include "GeoObjRW.h" #include "/EgtDev/Include/EGkVolZmap.h" #include "/EgtDev/Include/EGkPoint3d.h" +#include "/EgtDev/Include/EGkVector3d.h" +#include "CurveComposite.h" #include +#include //---------------------------------------------------------------------------- @@ -59,8 +62,15 @@ class VolZmap : public IVolZmap, public IGeoObjRW public : // IVolZmap virtual bool CopyFrom( const IGeoObj* pGObjSrc) ; - bool CreateMap( const Point3d& ptO, double dPrec, double dLengthX, double dLengthY, double dLengthZ) ; + virtual bool GetAllTriangles( TRIA3DLIST& lstTria) const ; virtual bool GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const ; + bool CreateMap( const Point3d& ptO, double dPrec, double dLengthX, double dLengthY, double dLengthZ) ; + bool SubtractIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; + bool SubtractIntervals( const Point3d& ptP, double dMin, double dMax) ; + bool AddIntervals( unsigned int nI, unsigned int nJ, double dMin, double dMax) ; + bool AddIntervals( const Point3d& ptP, double dMin, double dMax) ; + bool SetTool( const std::string& pToolName, unsigned int nToolType, const CurveComposite* pToolOutline) ; + bool MillingStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtDe) ; public : // IGeoObjRW virtual int GetNgeId( void) const ; @@ -79,6 +89,13 @@ class VolZmap : public IVolZmap, public IGeoObjRW private : bool CopyFrom( const VolZmap& clSrc) ; + bool GetChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const ; + bool CalcChunkPrisms( int nPos1, int nPos2, int nDim1, int nDim2, TRIA3DLIST& lstTria) const ; + 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 MillingDrill( const Point3d& ptLs, const Point3d& ptLe, double dHeight, double dRadius) ; + bool MillingPerp( Point3d& ptPs, Point3d& ptPe, double dHeight, double dRadius) ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ; @@ -88,12 +105,30 @@ class VolZmap : public IVolZmap, public IGeoObjRW Status m_nStatus ; // stato int m_nTempProp ; // proprietà temporanea - double m_dStep ; + Frame3d m_LocalFrame ;//////FORSE E' MEGLIO CHIAMARLO INTRINSECO? E IN VISTA DEGLI ALTRI FORSE E' BENE AGGIUNGERE UN IDENTIFICATIVO? + 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_nDim ; - unsigned int m_nNx ; - unsigned int m_nNy ; - Frame3d m_LocalFrame ; - - std::vector > m_ZValues ; + + CurveComposite m_ToolOutline ; + std::string m_sToolName ; + unsigned int m_nToolType ; // 0, 1, 2 per cylindrical mill, fresa ball-end, bull nose } ; + +//----------------------------------------------------------------------------- +inline VolZmap* CreateBasicVolZmap( void) + { return (static_cast( CreateGeoObj( VOL_ZMAP))) ; } +inline VolZmap* CloneBasicVolZmap( const IGeoObj* pGObj) + { if ( pGObj == nullptr || pGObj->GetType() != VOL_ZMAP) + return nullptr ; + return (static_cast(pGObj->Clone())) ; } +inline const VolZmap* GetBasicVolZmap( const IGeoObj* pGObj) + { if ( pGObj == nullptr || pGObj->GetType() != VOL_ZMAP) + return nullptr ; + return (static_cast(pGObj)) ; } +inline VolZmap* GetBasicVolZmap( IGeoObj* pGObj) + { if ( pGObj == nullptr || pGObj->GetType() != VOL_ZMAP) + return nullptr ; + return (static_cast(pGObj)) ; }