diff --git a/CurveArc.cpp b/CurveArc.cpp index 804a562..efe1ff7 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -701,7 +701,11 @@ CurveArc::GetLocalBBox( BBox3d& b3Loc, int nFlag) const return false ; // assegno il box in locale b3Loc.Reset() ; - ArcApproxer aAppr( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, false, *this) ; + double dLinTol = LIN_TOL_APPROX ; + double dAngTolDeg = ANG_TOL_APPROX_DEG ; + if ( ( nFlag & BBF_EXACT) != 0) + dLinTol = LIN_TOL_MIN ; + ArcApproxer aAppr( dLinTol, dAngTolDeg, false, *this) ; double dU ; Point3d ptPos ; while ( aAppr.GetPoint( dU, ptPos)) diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 585ac40..5679d1f 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -496,7 +496,7 @@ CurveBezier::GetLocalBBox( BBox3d& b3Loc, int nFlag) const else { // costruisco una approssimazione lineare PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL)) return false ; // ciclo sui punti della approssimazione Point3d ptTemp ; @@ -539,7 +539,7 @@ CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref, int nFlag) const else { // costruisco una approssimazione lineare PolyLine PL ; - if ( ! ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + if ( ! ApproxWithLines( LIN_TOL_MIN, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL)) return false ; // ciclo sui punti della approssimazione Point3d ptTemp ; diff --git a/VolTriZmapCalculus.cpp b/VolTriZmapCalculus.cpp index 2715de0..5d3896e 100644 --- a/VolTriZmapCalculus.cpp +++ b/VolTriZmapCalculus.cpp @@ -57,7 +57,7 @@ VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, else if ( ptP.y < ptMin.y - EPS_SMALL || ptP.y > ptMax.y + EPS_SMALL) return false ; - // confronto con piani XZ (perpendicolari ad asse Z) + // confronto con piani XY (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) ; @@ -72,205 +72,23 @@ VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, return ( dU2 >= dU1) ; } -//---------------------------------------------------------------------------- -bool -VolZmap::IntersLineVoxel( const Point3d& ptP, const Vector3d& vtV, int nIndI, int nIndJ, int nIndK, - int& nFaceF, int& nFaceL, double& dUF, double& dUL) const -{ - // Controllo sull'ammissibilità del voxel - if ( nIndI < - 1 || nIndI >= int( m_nNx[0]) || - nIndJ < - 1 || nIndJ >= int( m_nNy[0]) || - nIndK < - 1 || nIndK >= int( m_nNy[1])) - return false ; - - Point3d ptInt, ptIntF, ptIntL ; - double dSqEps = EPS_SMALL * EPS_SMALL ; - int nIntNum = 0 ; - - double dU1 = ( ( nIndJ + 0.5) * m_dStep - ptP.y) / vtV.y ; - double dU2 = ( ( nIndI + 0.5) * m_dStep - ptP.x) / vtV.x ; - double dU3 = ( ( nIndJ + 1.5) * m_dStep - ptP.y) / vtV.y ; - double dU4 = ( ( nIndI + 1.5) * m_dStep - ptP.x) / vtV.x ; - double dU5 = ( ( nIndK + 0.5) * m_dStep - ptP.z) / vtV.z ; - double dU6 = ( ( nIndK + 1.5) * m_dStep - ptP.z) / vtV.z ; - - // Intersezione con le facce 1 e 3 - if ( abs( vtV.y) > EPS_ZERO) { - - // Intersezione con la prima faccia - ptInt = ptP + dU1 * vtV ; - - if ( ptInt.x >= ( nIndI + 0.5) * m_dStep && - ptInt.x <= ( nIndI + 1.5) * m_dStep && - ptInt.z >= ( nIndK + 0.5) * m_dStep && - ptInt.z <= ( nIndK + 1.5) * m_dStep) { - - dUF = dU1 ; - nFaceF = 1 ; - ptIntF = ptInt ; - ++ nIntNum ; - } - - // Intersezione con la terza faccia - ptInt = ptP + dU3 * vtV ; - - if ( ptInt.x >= ( nIndI + 0.5) * m_dStep && - ptInt.x <= ( nIndI + 1.5) * m_dStep && - ptInt.z >= ( nIndK + 0.5) * m_dStep && - ptInt.z <= ( nIndK + 1.5) * m_dStep) { - - if ( nIntNum == 0) { - - dUF = dU3 ; - nFaceF = 3 ; - ptIntF = ptInt ; - ++ nIntNum ; - } - else if ( nIntNum == 1 && - ( ptIntF - ptInt).SqLen() > dSqEps) { - - dUL = dU3 ; - nFaceL = 3 ; - ptIntL = ptInt ; - ++ nIntNum ; - } - } - } - - // Intersezione con le facce 2 e 4 - if ( abs( vtV.x) > EPS_ZERO) { - - // Intersezione con la seconda faccia - ptInt = ptP + dU2 * vtV ; - - if ( ptInt.y >= ( nIndJ + 0.5) * m_dStep && - ptInt.y <= ( nIndJ + 1.5) * m_dStep && - ptInt.z >= ( nIndK + 0.5) * m_dStep && - ptInt.z <= ( nIndK + 1.5) * m_dStep) { - - if ( nIntNum == 0) { - - dUF = dU2 ; - nFaceF = 2 ; - ptIntF = ptInt ; - ++ nIntNum ; - } - else if ( nIntNum == 1 && - ( ptIntF - ptInt).SqLen() > dSqEps) { - - dUL = dU2 ; - nFaceL = 2 ; - ptIntL = ptInt ; - ++ nIntNum ; - } - } - - // Intersezione con la quarta faccia - ptInt = ptP + dU4 * vtV ; - - if ( ptInt.y >= ( nIndJ + 0.5) * m_dStep && - ptInt.y <= ( nIndJ + 1.5) * m_dStep && - ptInt.z >= ( nIndK + 0.5) * m_dStep && - ptInt.z <= ( nIndK + 1.5) * m_dStep) { - - if ( nIntNum == 0) { - - dUF = dU4 ; - nFaceF = 4 ; - ptIntF = ptInt ; - ++ nIntNum ; - } - else if ( nIntNum == 1 && - ( ptIntF - ptInt).SqLen() > dSqEps) { - - dUL = dU4 ; - nFaceL = 4 ; - ptIntL = ptInt ; - ++ nIntNum ; - } - } - } - - // Intersezione con le facce 5 e 6 - if ( abs( vtV.z) > EPS_ZERO) { - - // Intersezione con la quinta faccia - ptInt = ptP + dU5 * vtV ; - - if ( ptInt.x >= ( nIndI + 0.5) * m_dStep && - ptInt.x <= ( nIndI + 1.5) * m_dStep && - ptInt.y >= ( nIndJ + 0.5) * m_dStep && - ptInt.y <= ( nIndJ + 1.5) * m_dStep) { - - if ( nIntNum == 0) { - - dUF = dU5 ; - nFaceF = 5 ; - ptIntF = ptInt ; - ++ nIntNum ; - } - else if ( nIntNum == 1 && - ( ptIntF - ptInt).SqLen() > dSqEps) { - - dUL = dU5 ; - nFaceL = 5 ; - ptIntL = ptInt ; - ++ nIntNum ; - } - } - - // Intersezione con la sesta faccia - ptInt = ptP + dU6 * vtV ; - - if ( ptInt.x >= ( nIndI + 0.5) * m_dStep && - ptInt.x <= ( nIndI + 1.5) * m_dStep && - ptInt.y >= ( nIndJ + 0.5) * m_dStep && - ptInt.y <= ( nIndJ + 1.5) * m_dStep) { - - - if ( nIntNum == 0) { - - dUF = dU6 ; - nFaceF = 6 ; - ptIntF = ptInt ; - ++ nIntNum ; - } - else if ( nIntNum == 1 && - ( ptIntF - ptInt).SqLen() > dSqEps) { - - dUL = dU6 ; - nFaceL = 6 ; - ptIntL = ptInt ; - ++ nIntNum ; - } - } - } - - if ( dUF > dUL) { - - swap( dUF, dUL) ; - swap( nFaceF, nFaceL) ; - } - return ( nIntNum == 2) ; -} - //---------------------------------------------------------------------------- bool -VolZmap::IntersLineZMapBBox( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, double& dU1, double& dU2) +VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, double& dU1, double& dU2) { // Punti estremi del box dello Zmap Point3d ptMin = ORIG ; Point3d ptMax = ptMin + Vector3d( m_nNx[nGrid] * m_dStep, m_nNy[nGrid] * m_dStep, m_dMaxZ[nGrid]) ; - return ( IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) && ( dU1 > 0 || dU2 > 0)) ; + return IntersLineBox( ptP, vtV, ptMin, ptMax, dU1, dU2) ; } //---------------------------------------------------------------------------- bool -VolZmap::IntersLineDexel( unsigned int nGrid, const Point3d& ptP, const Vector3d& vtV, unsigned int nI, - unsigned int nJ, double& dU1, double& dU2) +VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ, + double& dU1, double& dU2) { - // Determino l'indice del dexel e il doppio del numero di suo intervalli + // Determino l'indice del dexel e il numero di suoi intervalli unsigned int nDexelPos = nJ * m_nNx[nGrid] + nI ; unsigned int nDexelSize = unsigned int( m_Values[nGrid][nDexelPos].size()) ; @@ -292,11 +110,11 @@ VolZmap::IntersLineDexel( unsigned int nGrid, const Point3d& ptP, const Vector3d // estremi del box del singolo intervallo Point3d ptE1( dXmin, dYmin, m_Values[nGrid][nDexelPos][nIndex].dMin) ; Point3d ptE2( dXmax, dYmax, m_Values[nGrid][nDexelPos][nIndex].dMax) ; - double dt1, dt2 ; - if ( IntersLineBox( ptP, vtV, ptE1, ptE2, dt1, dt2)) { + double dP1, dP2 ; + if ( IntersLineBox( ptP, vtV, ptE1, ptE2, dP1, dP2)) { bInters = true ; - dU1 = min( dU1, dt1) ; - dU2 = max( dU2, dt2) ; + dU1 = min( dU1, dP1) ; + dU2 = max( dU2, dP2) ; } } @@ -304,21 +122,68 @@ VolZmap::IntersLineDexel( unsigned int nGrid, const Point3d& ptP, const Vector3d } //---------------------------------------------------------------------------- +bool +VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ, + double& dU1, double& dU2) +{ + // Determino l'indice del dexel e il numero di suoi intervalli + unsigned int nDexelPos = nJ * m_nNx[nGrid] + nI ; + unsigned int nDexelSize = unsigned int( m_Values[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 += 1) { + // estremi del box del singolo intervallo + Point3d ptE1( dXmin, dYmin, m_Values[nGrid][nDexelPos][nIndex].dMin) ; + Point3d ptE2( dXmax, dYmax, m_Values[nGrid][nDexelPos][nIndex].dMax) ; + double dP1, dP2 ; + if ( IntersLineBox( ptP, vtV, ptE1, ptE2, dP1, dP2)) { + if ( dP2 >= 0) { + bInters = true ; + if ( dP1 >= 0) + dU1 = min( dU1, dP1) ; + else + dU1 = - 1 ; + dU2 = max( dU2, dP2) ; + } + } + } + + return bInters ; +} + +//---------------------------------------------------------------------------- +// InLength = distanza di ingresso (se -1 il punto è interno, se -2 il punto è esterno e il raggio non interseca lo Zmap) +// OutLength = distanza di uscita bool VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLength, double& dOutLength) { + int nGrid = 0 ; + // Porto il raggio nel riferimento intrinseco Point3d ptP = ptPGlob ; - ptP.ToLoc( m_MapFrame[0]) ; + ptP.ToLoc( m_MapFrame[nGrid]) ; Vector3d vtV = vtDir ; - vtV.ToLoc( m_MapFrame[0]) ; + vtV.ToLoc( m_MapFrame[nGrid]) ; vtV.Normalize() ; - // Studio dell'intersezione fra semiretta e BBox dello Zmap + // Intersezione fra semiretta e BBox dello Zmap double dU1, dU2 ; - bool bTest = IntersLineZMapBBox( 0, ptP, vtV, dU1, dU2) ; + bool bTest = IntersLineZMapBBox( ptP, vtV, nGrid, dU1, dU2) && ( dU1 > 0 || dU2 > 0) ; - // Semiretta esterna al box dello Zmap + // Semiretta esterna al box dello Zmap quindi esterna anche allo Zmap if ( ! bTest) { dInLength = - 2 ; dOutLength = - 2 ; @@ -336,85 +201,65 @@ VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLen 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[0] - 1) ; - int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nNy[0] - 1) ; - int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nNx[0] - 1) ; - int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nNy[0] - 1) ; // Inizializzo distanze dInLength = INFINITO ; dOutLength = - INFINITO ; - // Variazioni - double dDeltaX = ptF.x - ptI.x ; - double dDeltaY = ptF.y - ptI.y ; + // Determino asse di spostamento maggiore + bool bOnX = ( abs( ptF.y - ptI.y) <= abs( ptF.x - ptI.x)) ; - // 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) { + // Movimento crescente su asse di movimento principale + if ( ( bOnX && ptF.x < ptI.x) || ( ! bOnX && ptF.y < ptI.y) ) + swap( ptI, ptF) ; - // 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_nNy[0] - 1) ; + // Pendenza + double dDeltaX = ( ptF.x - ptI.x) ; + double dDeltaY = ( ptF.y - ptI.y) ; + double dM = 0 ; + if ( bOnX && abs( dDeltaX) > EPS_SMALL) + dM = dDeltaY / dDeltaX ; + else if ( ! bOnX && abs( dDeltaY) > EPS_SMALL) + dM = dDeltaX / dDeltaY ; - // 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) ; - } - } + // Determinazione degli indici i j dei punti ptI e ptF + int nIi = Clamp( int( floor( ptI.x / m_dStep)), 0, m_nNx[nGrid] - 1) ; + int nIj = Clamp( int( floor( ptI.y / m_dStep)), 0, m_nNy[nGrid] - 1) ; + int nFi = Clamp( int( floor( ptF.x / m_dStep)), 0, m_nNx[nGrid] - 1) ; + int nFj = Clamp( int( floor( ptF.y / m_dStep)), 0, m_nNy[nGrid] - 1) ; + + // mi muovo + int i = nIi ; int j = nIj ; + while ( ( bOnX && i <= nFi) || ( ! bOnX && j <= nFj)) { + + // Eseguo controllo + double dU1, dU2 ; + if ( IntersRayDexel( ptP, vtV, nGrid, 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 ; + + // Calcolo spostamento (a destra o sopra) + if ( bOnX) { + double dMoveX = ( ( i + 1) * m_dStep - ptI.x) ; + double dMoveY = dMoveX * dM ; + double dY = ptI.y + dMoveY ; + int nNewJ = Clamp( int( floor( dY / m_dStep)), 0, m_nNy[nGrid] - 1) ; + if ( nNewJ != j) + j = nNewJ ; + else + ++ i ; + } + else { + double dMoveY = ( ( j + 1) * m_dStep - ptI.y) ; + double dMoveX = dMoveY * dM ; double dX = ptI.x + dMoveX ; - int OldI = i ; - i = Clamp( int( floor( dX / m_dStep)), 0, m_nNx[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) ; - } - } - } + int nNewI = Clamp( int( floor( dX / m_dStep)), 0, m_nNx[nGrid] - 1) ; + if ( nNewI != i) + i = nNewI ; + else + ++ j ; + } } // Se non abbiamo incontrato materiale diff --git a/VolTriZmapCreation.cpp b/VolTriZmapCreation.cpp index e554da0..12596b6 100644 --- a/VolTriZmapCreation.cpp +++ b/VolTriZmapCreation.cpp @@ -20,18 +20,17 @@ #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 bTriDex) +VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dLengthZ, double dPrec, bool bTriDex) { // Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo if ( dPrec < EPS_SMALL || dLengthX < EPS_SMALL || dLengthY < EPS_SMALL || dLengthZ < EPS_SMALL) - return false ; + return false ; // Il passo di discretizzazione non può essere inferiore a 100 * EPS_SMALL m_dStep = max( dPrec, 100 * EPS_SMALL) ; @@ -42,7 +41,7 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL // 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) ; @@ -51,12 +50,10 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL m_nNy[0] = static_cast ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; // Definisco il numero di blocchi lungo x e y - unsigned int nMinBlockNum = 1 ; - - m_nFracLin[0] = max( nMinBlockNum, + m_nFracLin[0] = max( 1u, m_nNx[0] / m_nDexNumPBlock + ( m_nNx[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; - m_nFracLin[1] = max( nMinBlockNum, + m_nFracLin[1] = max( 1u, m_nNy[0] / m_nDexNumPBlock + ( m_nNy[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; @@ -65,10 +62,9 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL // Se tridexel if ( bTriDex) { - m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ; m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ; - + m_nNx[1] = static_cast ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; m_nNy[1] = static_cast ( floor( ( dLengthZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; @@ -76,13 +72,13 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL m_nNy[2] = static_cast ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; // Definisco il numero di blocchi lungo z - m_nFracLin[2] = max( nMinBlockNum, + m_nFracLin[2] = max( 1u, m_nNy[1] / m_nDexNumPBlock + ( m_nNy[1] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; } + // altrimenti mono dexel else { - m_MapFrame[1].Set( ptO, Y_AX, Z_AX, X_AX) ; m_MapFrame[2].Set( ptO, Z_AX, X_AX, Y_AX) ; @@ -97,7 +93,7 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL } // Definizione della mappa - + // Creazione delle mappe // Calcolo del numero di celle per ogni mappa for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) @@ -128,13 +124,13 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL break ; case 1 : m_Values[i][j][0].vtMinN = - X_AX ; - m_Values[i][j][0].dMax = dLengthX ; + m_Values[i][j][0].dMax = dLengthX ; m_Values[i][j][0].vtMaxN = X_AX ; m_Values[i][j][0].nToolMax = 0 ; break ; case 2 : m_Values[i][j][0].vtMinN = - Y_AX ; - m_Values[i][j][0].dMax = dLengthY ; + m_Values[i][j][0].dMax = dLengthY ; m_Values[i][j][0].vtMaxN = Y_AX ; m_Values[i][j][0].nToolMax = 0 ; break ; @@ -142,24 +138,22 @@ VolZmap::Create( const Point3d& ptO, double dLengthX, double dLengthY, double dL } // Definizione delle limitazioni iniziali in Z per ogni mappa - for ( unsigned int i = 0 ; i < m_nMapNum ; ++ i) { - m_dMinZ[i] = 0 ; - switch ( i) { - case 0 : m_dMaxZ[i] = dLengthZ ; break ; - case 1 : m_dMaxZ[i] = dLengthX ; break ; - case 2 : m_dMaxZ[i] = dLengthY ; break ; - } - } + m_dMinZ[0] = 0 ; + m_dMaxZ[0] = dLengthZ ; + m_dMinZ[1] = 0 ; + m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ; + m_dMinZ[2] = 0 ; + m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ; - // Ridimensiono e setto il vettore dei blocchi a falso + // Dimensiono e setto il vettore dei blocchi a da ricalcolare m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ; - m_BlockToUpdate.resize( m_nNumBlock) ; for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount) m_BlockToUpdate[nCount] = true ; + // Dimensiono raccolta triangoli di feature tra blocchi m_InterBlockTria.resize( m_nNumBlock) ; - + // Aggiornamento dello stato m_nStatus = OK ; @@ -183,6 +177,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double // Determino i punti estremi del bounding box Point3d ptMapOrig, ptMapEnd ; SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ; + SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 0) ; // Sistema di riferimento mappa m_MapFrame[0].Set( ptMapOrig, X_AX, Y_AX, Z_AX) ; @@ -202,12 +197,10 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double m_Values[0].resize( m_nDim[0]) ; // Definisco il numero di blocchi lungo x e y - unsigned int nMinBlockNum = 1 ; - - m_nFracLin[0] = max( nMinBlockNum, + m_nFracLin[0] = max( 1u, m_nNx[0] / m_nDexNumPBlock + ( m_nNx[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; - m_nFracLin[1] = max( nMinBlockNum, + m_nFracLin[1] = max( 1u, m_nNy[0] / m_nDexNumPBlock + ( m_nNy[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; @@ -234,7 +227,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double m_Values[2].resize( m_nDim[2]) ; // Definisco il numero di blocchi lungo z - m_nFracLin[2] = max( nMinBlockNum, + m_nFracLin[2] = max( 1u, m_nNy[1] / m_nDexNumPBlock + ( m_nNy[1] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; } @@ -257,286 +250,229 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double m_nFracLin[2] = 1 ; } - // Determinazione e ridimensionamento dei dexel - // interni alla regione + // Metto in cache le curve di contorno della regione + POCRVVECTOR vpCrvs ; + INTVECTOR vnCompo ; + int nChunkNum = Surf.GetChunkCount() ; + for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) { + int nLoopNum = Surf.GetLoopCount( nChunk) ; + for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) { + ICurve* pCrv = Surf.GetLoop( nChunk, nLoop) ; + if ( pCrv != nullptr) { + vpCrvs.emplace_back( pCrv) ; + vnCompo.emplace_back( nChunk + 1) ; + } + } + } - // Griglia 0 + // Calcolo griglia 0=XY ( se tridexel anche griglia 2=ZX) for ( unsigned int i = 0 ; i < m_nNx[0] ; ++ i) { - - // Definisco la retta da intersecare con la regione + + // Definisco la retta diretta come Y da intersecare con la regione double dX = ( i + 0.5) * m_dStep ; - Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; + Point3d ptP0 = ptMapOrig + Vector3d( dX, 0, 0) ; CurveLine GridLine ; - GridLine.SetPVL( ptP0, Y_AX, dLengthY) ; + 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 + // Analizzo le parti in cui la retta è stata divisa + int nPart = int( IntersectionResults.size()) ; for ( int k = 0 ; k < nPart ; ++ k) { - - // Tipo di curva + + // Se la retta è interna alla regione o coincidente con parte della sua frontiera 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 - EPS_SMALL + 0.5)), 0, m_nNy[0] - 1) ; - int nEndJ = Clamp( int( floor( dt2 * dLengthY / m_dStep + EPS_SMALL - 0.5)), 0, m_nNy[0] - 1) ; + // Lunghezze dei tratti di retta corrente + double dLen1 = IntersectionResults[k].dParS * dLengthY ; + double dLen2 = IntersectionResults[k].dParE * dLengthY ; // Punti estremi della parte di retta corrente - Point3d ptP1 = ptP0 + dt1 * dLengthY * Y_AX ; - Point3d ptP2 = ptP0 + dt2 * dLengthY * Y_AX ; + Point3d ptP1 = ptP0 + dLen1 * Y_AX ; + Point3d ptP2 = ptP0 + dLen2 * Y_AX ; - // Determino il numero della componente connessa e le normali - int nCompo ; - Vector3d vtN1, vtN2 ; - - // Numero di componenti connesse - int nChunkNum = m_nConnectedCompoCount ; - - // Ciclo sulle componenti connesse - for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) { - - int nFind = 0 ; - - // Numero di loop della componente connessa - int nLoopNum = Surf.GetLoopCount( nChunk) ; - - // Ciclo sui loop della componente - for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) { - - PtrOwner< ICurve> pCurve( Surf.GetLoop( nChunk, nLoop)) ; - if ( IsNull( pCurve)) - continue ; - - double dP1 ; - if ( pCurve->GetParamAtPoint( ptP1, dP1, 10 * EPS_SMALL)) { - - Point3d ptTemp1 ; - Vector3d vtT1 ; - pCurve->GetPointTang( dP1, ICurve::FROM_MINUS, ptTemp1, vtT1) ; - - vtN1 = vtT1 ^ Z_AX ; - - nFind ++ ; - } - - double dP2 ; - if ( pCurve->GetParamAtPoint( ptP2, dP2, 10 * EPS_SMALL)) { - - Point3d ptTemp2 ; - Vector3d vtT2 ; - pCurve->GetPointTang( dP2, ICurve::FROM_MINUS, ptTemp2, vtT2) ; - - vtN2 = vtT2 ^ Z_AX ; - - nFind ++ ; - } - - // Se abbiamo trovato la componente - // connessa, usciamo dal ciclo. - if ( nFind == 2) { - - nCompo = nChunk + 1 ; - break ; - } + // Ricerca di questi punti sui contorni della regione, per avere le normali e il numero di componente connesso + int nFind = 0 ; + int nCompo = 0 ; + Vector3d vtN1 = - Y_AX ; Vector3d vtN2 = Y_AX ; + for ( size_t m = 0 ; m < vpCrvs.size() ; ++ m) { + // recupero la curva + ICurve* pCurve = vpCrvs[m] ; + // determino posizione primo punto su curva + double dP1 ; + if ( ( nFind & 1) == 0 && pCurve->GetParamAtPoint( ptP1, dP1, 10 * EPS_SMALL)) { + Point3d ptTemp1 ; + Vector3d vtT1 ; + pCurve->GetPointTang( dP1, ICurve::FROM_MINUS, ptTemp1, vtT1) ; + vtN1 = vtT1 ^ Z_AX ; + nFind += 1 ; } - // Se trovata componente esco dal ciclo - if ( nFind == 2) + // determino posizione secondo punto su curva + double dP2 ; + if ( ( nFind & 2) == 0 && pCurve->GetParamAtPoint( ptP2, dP2, 10 * EPS_SMALL)) { + Point3d ptTemp2 ; + Vector3d vtT2 ; + pCurve->GetPointTang( dP2, ICurve::FROM_MINUS, ptTemp2, vtT2) ; + vtN2 = vtT2 ^ Z_AX ; + nFind += 2 ; + } + // Se trovati entrambi gli estremi, esco dal ciclo + if ( nFind == 3) { + nCompo = vnCompo[m] ; break ; - } + } + } + // Verifico di aver trovato i punti sulle curve + if ( nFind != 3) + LOG_ERROR( GetEGkLogger(), "Error in VolZmap::CreateFromFlatRegion : point not on baundary") - // Ridimensiono e riempio i dexel + // Ridimensiono e riempio i dexel della griglia 0 + int nStartJ = Clamp( int( floor( dLen1 / m_dStep - EPS_SMALL + 0.5)), 0, m_nNy[0] - 1) ; + int nEndJ = Clamp( int( floor( dLen2 / m_dStep + EPS_SMALL - 0.5)), 0, m_nNy[0] - 1) ; for ( int j = nStartJ ; j <= nEndJ ; ++ j) { // Determino il dexel int nPos0 = j * m_nNx[0] + i ; - // Aggiungo il tratto al dexel vuoto m_Values[0][nPos0].resize( 1) ; - // Aggiorno i dati del tratto di dexel m_Values[0][nPos0][0].dMin = 0 ; - m_Values[0][nPos0][0].dMax = dDimZ ; - m_Values[0][nPos0][0].nToolMin = 0 ; m_Values[0][nPos0][0].vtMinN = - Z_AX ; + m_Values[0][nPos0][0].nToolMin = 0 ; + m_Values[0][nPos0][0].dMax = dDimZ ; m_Values[0][nPos0][0].vtMaxN = Z_AX ; m_Values[0][nPos0][0].nToolMax = 0 ; m_Values[0][nPos0][0].nCompo = nCompo ; } - - // Se tridexel riempio i singoli dexel della - // griglia 2 con gli intervalli + + // Se tridexel riempio i singoli dexel della griglia 2 con gli intervalli if ( bTriDex) { - - for ( size_t a = 0 ; a < m_nNx[2] ; ++ a) { - - size_t nPos2 = i * m_nNx[2] + a ; - - size_t nCurrentSize = m_Values[2][nPos2].size( ) ; - + for ( size_t n = 0 ; n < m_nNx[2] ; ++ n) { + size_t nPos2 = i * m_nNx[2] + n ; + size_t nCurrSize = m_Values[2][nPos2].size( ) ; // Aggiungo un tratto al dexel - m_Values[2][nPos2].resize( nCurrentSize + 1) ; - - // Aggiorno quote e numero di utensile al tratto di dexel - m_Values[2][nPos2][nCurrentSize].dMin = dt1 * dLengthY ; - m_Values[2][nPos2][nCurrentSize].nToolMin = 0 ; - m_Values[2][nPos2][nCurrentSize].dMax = dt2 * dLengthY ; - m_Values[2][nPos2][nCurrentSize].nToolMax = 0 ; - m_Values[2][nPos2][nCurrentSize].vtMinN = vtN1 ; - m_Values[2][nPos2][nCurrentSize].vtMaxN = vtN2 ; - - // Aggiorno il numero della componente connessa - m_Values[2][nPos2][nCurrentSize].nCompo = nCompo ; - } - } - } ///// Fine parte relativa a un segmento - } - } - - // Se tridexel resta la griglia 1 - if ( bTriDex) { - - for ( unsigned int i = 0 ; i < m_nNx[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_nNy[1] ; ++ j) { - - size_t nPos1 = j * m_nNx[1] + i ; - - size_t nCurrentSize = m_Values[1][nPos1].size( ) ; - - // Aggiungo un tratto al dexel - m_Values[1][nPos1].resize( nCurrentSize + 1) ; - - // Aggiorno quote e numero di utensile al tratto di dexel - m_Values[1][nPos1][nCurrentSize].dMin = dt1 * dLengthX ; - m_Values[1][nPos1][nCurrentSize].nToolMin = 0 ; - m_Values[1][nPos1][nCurrentSize].dMax = dt2 * dLengthX ; - m_Values[1][nPos1][nCurrentSize].nToolMax = 0 ; - - - Point3d ptP1 = ptP0 + dt1 * dLengthX * X_AX ; - Point3d ptP2 = ptP0 + dt2 * dLengthX * X_AX ; - - int nChunkNum = Surf.GetChunkCount() ; - - for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) { - - // Indice per ricerca della componente connessa - int nFind = 0 ; - - int nLoopNum = Surf.GetLoopCount( nChunk) ; - - for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) { - - PtrOwner< ICurve> pCurve( Surf.GetLoop( nChunk, nLoop)) ; - if ( IsNull( pCurve)) - continue ; - - double dP1 ; - if ( pCurve->GetParamAtPoint( ptP1, dP1, 10 * EPS_SMALL)) { - - Point3d ptTemp1 ; - Vector3d vtT1, vtN1 ; - pCurve->GetPointTang( dP1, ICurve::FROM_MINUS, ptTemp1, vtT1) ; - - vtN1 = vtT1 ^ Z_AX ; - // Aggiorno normale inferiore al tratto di dexel - m_Values[1][nPos1][nCurrentSize].vtMinN = vtN1 ; - - nFind ++ ; - } - - double dP2 ; - if ( pCurve->GetParamAtPoint( ptP2, dP2, 10 * EPS_SMALL)) { - - Point3d ptTemp2 ; - Vector3d vtT2, vtN2 ; - pCurve->GetPointTang( dP2, ICurve::FROM_MINUS, ptTemp2, vtT2) ; - - vtN2 = vtT2 ^ Z_AX ; - // Aggiorno normale superiore al tratto di dexel - m_Values[1][nPos1][nCurrentSize].vtMaxN = vtN2 ; - - nFind ++ ; - } - - // Se trovata componente esco dal ciclo - if ( nFind == 2) { - // Aggiorno il numero della componente connessa - m_Values[1][nPos1][nCurrentSize].nCompo = nChunk + 1 ; - } - } - - // Se trovata componente esco dal ciclo - if ( nFind == 2) - break ; - } + m_Values[2][nPos2].resize( nCurrSize + 1) ; + // Aggiorno i dati del tratto di dexel + m_Values[2][nPos2][nCurrSize].dMin = dLen1 ; + m_Values[2][nPos2][nCurrSize].vtMinN = vtN1 ; + m_Values[2][nPos2][nCurrSize].nToolMin = 0 ; + m_Values[2][nPos2][nCurrSize].dMax = dLen2 ; + m_Values[2][nPos2][nCurrSize].vtMaxN = vtN2 ; + m_Values[2][nPos2][nCurrSize].nToolMax = 0 ; + m_Values[2][nPos2][nCurrSize].nCompo = nCompo ; } } } } - } - + } + + // Se tridexel calcolo griglia 1=YZ + if ( bTriDex) { + + // ciclo sul lato orizzontale della griglia + for ( unsigned int i = 0 ; i < m_nNx[1] ; ++ i) { + + // Definisco la retta diretta come X da intersecare con la regione + double dY = ( i + 0.5) * m_dStep ; + Point3d ptP0 = ptMapOrig + Vector3d( 0, dY, 0) ; + CurveLine GridLine ; + GridLine.SetPVL( ptP0, X_AX, dLengthX) ; + + // Determino le intersezioni della retta con la regione + CRVCVECTOR IntersectionResults ; + Surf.GetCurveClassification( GridLine, IntersectionResults) ; + + // Analizzo le parti + int nPart = int( IntersectionResults.size()) ; + for ( int k = 0 ; k < nPart ; ++ k) { + + // Se la retta è interna alla regione o coincidente con parte della sua frontiera + int nType = IntersectionResults[k].nClass ; + if ( nType == CRVC_IN || nType == CRVC_ON_P || nType == CRVC_ON_M) { + + // Lunghezze dei tratti di retta + double dLen1 = IntersectionResults[k].dParS * dLengthX ; + double dLen2 = IntersectionResults[k].dParE * dLengthX ; + + // Punti estremi + Point3d ptP1 = ptP0 + dLen1 * X_AX ; + Point3d ptP2 = ptP0 + dLen2 * X_AX ; + + // Ricerca di questi punti sui contorni della regione, per avere le normali e il numero di componente connesso + int nFind = 0 ; + int nCompo = 0 ; + Vector3d vtN1 = -X_AX ; Vector3d vtN2 = X_AX ; + for ( size_t m = 0 ; m < vpCrvs.size() ; ++ m) { + // recupero la curva + ICurve* pCurve = vpCrvs[m] ; + // determino posizione primo punto su curva + double dP1 ; + if ( ( nFind & 1) == 0 && pCurve->GetParamAtPoint( ptP1, dP1, 10 * EPS_SMALL)) { + Point3d ptTemp1 ; Vector3d vtT1 ; + pCurve->GetPointTang( dP1, ICurve::FROM_MINUS, ptTemp1, vtT1) ; + vtN1 = vtT1 ^ Z_AX ; + nFind += 1 ; + } + // determino posizione secondo punto su curva + double dP2 ; + if ( ( nFind & 2) == 0 && pCurve->GetParamAtPoint( ptP2, dP2, 10 * EPS_SMALL)) { + Point3d ptTemp2 ; Vector3d vtT2 ; + pCurve->GetPointTang( dP2, ICurve::FROM_MINUS, ptTemp2, vtT2) ; + vtN2 = vtT2 ^ Z_AX ; + nFind += 2 ; + } + + // Se trovati entrambi gli estremi, esco dal ciclo + if ( nFind == 3) { + nCompo = vnCompo[m] ; + break ; + } + } + + // Verifico di aver trovato i punti sulle curve + if ( nFind != 3) + LOG_ERROR( GetEGkLogger(), "Error in VolZmap::CreateFromFlatRegion : point not on baundary") + + // aggiorno i dexel impilati + for ( size_t j = 0 ; j < m_nNy[1] ; ++ j) { + size_t nPos1 = j * m_nNx[1] + i ; + size_t nCurrSize = m_Values[1][nPos1].size() ; + // Aggiungo un tratto al dexel + m_Values[1][nPos1].resize( nCurrSize + 1) ; + // Assegno i dati + m_Values[1][nPos1][nCurrSize].dMin = dLen1 ; + m_Values[1][nPos1][nCurrSize].vtMinN = vtN1 ; + m_Values[1][nPos1][nCurrSize].nToolMin = 0 ; + m_Values[1][nPos1][nCurrSize].dMax = dLen2 ; + m_Values[1][nPos1][nCurrSize].vtMaxN = vtN2 ; + m_Values[1][nPos1][nCurrSize].nToolMax = 0 ; + m_Values[1][nPos1][nCurrSize].nCompo = nCompo ; + } + } + } + } + } + + // Definizione delle limitazioni iniziali in Z per ogni mappa m_dMinZ[0] = 0 ; m_dMaxZ[0] = dDimZ ; + m_dMinZ[1] = 0 ; + m_dMaxZ[1] = ( bTriDex ? dLengthX : 0) ; + m_dMinZ[2] = 0 ; + m_dMaxZ[2] = ( bTriDex ? dLengthY : 0) ; - if ( bTriDex) { - m_dMinZ[1] = 0 ; - m_dMaxZ[1] = dLengthX ; - m_dMinZ[2] = 0 ; - m_dMaxZ[2] = dLengthY ; - } - else { - m_dMinZ[1] = 0 ; - m_dMaxZ[1] = 0 ; - m_dMinZ[2] = 0 ; - m_dMaxZ[2] = 0 ; - } - - // Ridimensiono e setto il vettore dei blocchi a falso + // Dimensiono e setto il vettore dei blocchi a da ricalcolare m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ; - m_BlockToUpdate.resize( m_nNumBlock) ; for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount) m_BlockToUpdate[nCount] = true ; + // Dimensiono raccolta triangoli di feature tra blocchi m_InterBlockTria.resize( m_nNumBlock) ; - + // Aggiornamento dello stato m_nStatus = OK ; @@ -546,17 +482,18 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double //---------------------------------------------------------------------------- bool VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex) -{ +{ // Se la superficie non è chiusa non ha senso continuare if ( ! Surf.IsClosed()) return false ; - // Aggiorno la dimensione della mappa 1 o 3 + // Assegno la dimensione della mappa 1 o 3 m_nMapNum = ( bTriDex ? 3 : 1) ; // Determino il bounding box della TriMesh BBox3d SurfBBox ; Surf.GetLocalBBox( SurfBBox) ; + SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 100 * EPS_SMALL) ; // Determino i punti estremi del bounding box Point3d ptMapOrig, ptMapEnd ; @@ -569,15 +506,12 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex 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 ; - + Vector3d vtLen = ptMapEnd - ptMapOrig ; // 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[0] = static_cast ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; - m_nNy[0] = static_cast ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; + m_nNx[0] = static_cast ( floor( ( vtLen.x + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; + m_nNy[0] = static_cast ( floor( ( vtLen.y + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; m_nDim[0] = m_nNx[0] * m_nNy[0] ; @@ -585,12 +519,10 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex m_Values[0].resize( m_nDim[0]) ; // Definisco il numero di blocchi lungo x e y - unsigned int nMinBlockNum = 1 ; - - m_nFracLin[0] = max( nMinBlockNum, + m_nFracLin[0] = max( 1u, m_nNx[0] / m_nDexNumPBlock + ( m_nNx[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; - m_nFracLin[1] = max( nMinBlockNum, + m_nFracLin[1] = max( 1u, m_nNy[0] / m_nDexNumPBlock + ( m_nNy[0] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; @@ -599,17 +531,16 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex // Se Tridexel ridimensiono anche gli altri vettori if ( bTriDex) { - 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_nNx[1] = static_cast ( floor( ( dLengthY + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; - m_nNy[1] = static_cast ( floor( ( dLengthZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; + m_nNx[1] = static_cast ( floor( ( vtLen.y + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; + m_nNy[1] = static_cast ( floor( ( vtLen.z + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; m_nDim[1] = m_nNx[1] * m_nNy[1] ; - m_nNx[2] = static_cast ( floor( ( dLengthZ + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; - m_nNy[2] = static_cast ( floor( ( dLengthX + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; + m_nNx[2] = static_cast ( floor( ( vtLen.z + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; + m_nNy[2] = static_cast ( floor( ( vtLen.x + 0.5 * m_dStep + EPS_SMALL) / m_dStep)) ; m_nDim[2] = m_nNx[2] * m_nNy[2] ; @@ -617,12 +548,12 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex m_Values[2].resize( m_nDim[2]) ; // Definisco il numero di blocchi lungo z - m_nFracLin[2] = max( nMinBlockNum, + m_nFracLin[2] = max( 1u, m_nNy[1] / m_nDexNumPBlock + ( m_nNy[1] % m_nDexNumPBlock >= m_nDexNumPBlock / 2 ? 1 : 0)) ; } - else { + else { m_MapFrame[1].Set( ptMapOrig, Y_AX, Z_AX, X_AX) ; m_MapFrame[2].Set( ptMapOrig, Z_AX, X_AX, Y_AX) ; @@ -638,93 +569,15 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex m_nFracLin[2] = 1 ; } - // Oggetto per calcolo massivo intersezioni - IntersParLinesSurfTm intPLSTM( m_MapFrame[0], Surf) ; + // ciclo sulle griglie + for ( unsigned int g = 0 ; g < m_nMapNum ; ++ g) { - // Determinazione e ridimensionamento dei dexel interni alla trimesh - for ( unsigned int i = 0 ; i < m_nNx[0] ; ++ i) { - for ( unsigned int j = 0 ; j < m_nNy[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_nNx[0] + i ; - - bool bInside = false ; - Point3d ptIn ; - Vector3d vtInN ; - - 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 ; - - int nT = IntersectionResults[k].nT ; - int nF = Surf.GetFacetFromTria( nT) ; - - Surf.GetFacetNormal( nF, vtInN) ; - - bInside = true ; - } - - // esco dalla superficie trimesh - else if ( dCos > EPS_SMALL && bInside) { - - Point3d ptOut = IntersectionResults[k].ptI ; - - Vector3d vtOutN ; - - int nT = IntersectionResults[k].nT ; - int nF = Surf.GetFacetFromTria( nT) ; - - Surf.GetFacetNormal( nF, vtOutN) ; - - unsigned int nCurrentSize = unsigned int( m_Values[0][nPos].size()) ; - - // Aggiungo un tratto al dexel - m_Values[0][nPos].resize( nCurrentSize + 1) ; - - // Aggiorno dati del tratto di dexel - m_Values[0][nPos][nCurrentSize].dMin = ptIn.z - ptMapOrig.z ; - m_Values[0][nPos][nCurrentSize].dMax = ptOut.z - ptMapOrig.z ; - m_Values[0][nPos][nCurrentSize].vtMinN = vtInN ; - m_Values[0][nPos][nCurrentSize].vtMaxN = vtOutN ; - m_Values[0][nPos][nCurrentSize].nToolMin = 0 ; - m_Values[0][nPos][nCurrentSize].nToolMax = 0 ; - m_Values[0][nPos][nCurrentSize].nCompo = 0 ; - - - bInside = false ; - } - } - } - } - } - - if ( bTriDex) { - - IntersParLinesSurfTm intPLSTM1( m_MapFrame[1], Surf) ; + // Oggetto per calcolo massivo intersezioni + IntersParLinesSurfTm intPLSTM( m_MapFrame[g], Surf) ; // Determinazione e ridimensionamento dei dexel interni alla trimesh - for ( unsigned int i = 0 ; i < m_nNx[1] ; ++ i) { - for ( unsigned int j = 0 ; j < m_nNy[1] ; ++ j) { + for ( unsigned int i = 0 ; i < m_nNx[g] ; ++ i) { + for ( unsigned int j = 0 ; j < m_nNy[g] ; ++ j) { // Definisco la retta da intersecare con la trimesh double dX = ( i + 0.5) * m_dStep ; @@ -733,17 +586,17 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex // Determino le intersezioni della retta con la TriMesh ILSIVECTOR IntersectionResults ; - intPLSTM1.GetInters( ptP0, dLengthX, IntersectionResults) ; + intPLSTM.GetInters( ptP0, vtLen.v[(g+2)%3], IntersectionResults) ; int nInt = int( IntersectionResults.size()) ; - unsigned int nPos = j * m_nNx[1] + i ; + unsigned int nPos = j * m_nNx[g] + i ; bool bInside = false ; Point3d ptIn ; Vector3d vtInN ; - for ( int k = 0 ; k < nInt ; ++ k) { + for ( int k = 0 ; k < nInt ; ++ k) { int nIntType = IntersectionResults[k].nILTT ; @@ -754,121 +607,42 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex // entro nella superficie trimesh if ( dCos < - EPS_SMALL) { - + ptIn = IntersectionResults[k].ptI ; int nT = IntersectionResults[k].nT ; int nF = Surf.GetFacetFromTria( nT) ; - Surf.GetFacetNormal( nF, vtInN) ; + Surf.GetFacetNormal( nF, vtInN) ; bInside = true ; } // esco dalla superficie trimesh else if ( dCos > EPS_SMALL && bInside) { - + Point3d ptOut = IntersectionResults[k].ptI ; - Vector3d vtOutN ; - int nT = IntersectionResults[k].nT ; int nF = Surf.GetFacetFromTria( nT) ; - Surf.GetFacetNormal( nF, vtOutN) ; - - unsigned int nCurrentSize = unsigned int( m_Values[1][nPos].size()) ; - - // Aggiungo un tratto al dexel - m_Values[1][nPos].resize( nCurrentSize + 1) ; - - // Aggiorno dati del tratto di dexel - m_Values[1][nPos][nCurrentSize].dMin = ptIn.x - ptMapOrig.x ; - m_Values[1][nPos][nCurrentSize].dMax = ptOut.x - ptMapOrig.x ; - m_Values[1][nPos][nCurrentSize].vtMinN = vtInN ; - m_Values[1][nPos][nCurrentSize].vtMaxN = vtOutN ; - m_Values[1][nPos][nCurrentSize].nToolMin = 0 ; - m_Values[1][nPos][nCurrentSize].nToolMax = 0 ; - m_Values[1][nPos][nCurrentSize].nCompo = 0 ; - - bInside = false ; - } - } - } - } - } - - IntersParLinesSurfTm intPLSTM2( m_MapFrame[2], Surf) ; - - // Determinazione e ridimensionamento dei dexel interni alla trimesh - for ( unsigned int i = 0 ; i < m_nNx[2] ; ++ i) { - for ( unsigned int j = 0 ; j < m_nNy[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_nNx[2] + i ; - - bool bInside = false ; - Point3d ptIn ; - Vector3d vtInN ; - - 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 ; - - int nT = IntersectionResults[k].nT ; - int nF = Surf.GetFacetFromTria( nT) ; - - Surf.GetFacetNormal( nF, vtInN) ; - - bInside = true ; - } - - // esco dalla superficie trimesh - else if ( dCos > EPS_SMALL && bInside) { - - Point3d ptOut = IntersectionResults[k].ptI ; - Vector3d vtOutN ; - - int nT = IntersectionResults[k].nT ; - int nF = Surf.GetFacetFromTria( nT) ; - Surf.GetFacetNormal( nF, vtOutN) ; - unsigned int nCurrentSize = unsigned int( m_Values[2][nPos].size()) ; - + unsigned int nCurrentSize = unsigned int( m_Values[g][nPos].size()) ; + // Aggiungo un tratto al dexel - m_Values[2][nPos].resize( nCurrentSize + 1) ; + m_Values[g][nPos].resize( nCurrentSize + 1) ; // Aggiorno dati del tratto di dexel - m_Values[2][nPos][nCurrentSize].dMin = ptIn.y - ptMapOrig.y ; - m_Values[2][nPos][nCurrentSize].dMax = ptOut.y - ptMapOrig.y ; - m_Values[2][nPos][nCurrentSize].vtMinN = vtInN ; - m_Values[2][nPos][nCurrentSize].vtMaxN = vtOutN ; - m_Values[2][nPos][nCurrentSize].nToolMin = 0 ; - m_Values[2][nPos][nCurrentSize].nToolMax = 0 ; - m_Values[2][nPos][nCurrentSize].nCompo = 0 ; - + m_Values[g][nPos][nCurrentSize].dMin = ptIn.v[(g+2)%3] - ptMapOrig.v[(g+2)%3] ; + m_Values[g][nPos][nCurrentSize].dMax = ptOut.v[(g+2)%3] - ptMapOrig.v[(g+2)%3] ; + m_Values[g][nPos][nCurrentSize].vtMinN = vtInN ; + m_Values[g][nPos][nCurrentSize].vtMaxN = vtOutN ; + m_Values[g][nPos][nCurrentSize].nToolMin = 0 ; + m_Values[g][nPos][nCurrentSize].nToolMax = 0 ; + m_Values[g][nPos][nCurrentSize].nCompo = 0 ; + bInside = false ; } } @@ -877,33 +651,25 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex } } - // Assegno il minimo e massimo valore di Z della mappa + // Assegno il minimo e massimo valore di Z della mappa m_dMinZ[0] = 0 ; - m_dMaxZ[0] = dLengthZ ; + m_dMaxZ[0] = vtLen.z ; + m_dMinZ[1] = 0 ; + m_dMaxZ[1] = ( bTriDex ? vtLen.x : 0) ; + m_dMinZ[2] = 0 ; + m_dMaxZ[2] = ( bTriDex ? vtLen.y : 0) ; - if ( bTriDex) { - m_dMinZ[1] = 0 ; - m_dMaxZ[1] = dLengthX ; - m_dMinZ[2] = 0 ; - m_dMaxZ[2] = dLengthY ; - } - else { - m_dMinZ[1] = 0 ; - m_dMaxZ[1] = 0 ; - m_dMinZ[2] = 0 ; - m_dMaxZ[2] = 0 ; - } - - // Ridimensiono e setto il vettore dei blocchi a falso + // Dimensiono e setto il vettore dei blocchi a da ricalcolare m_nNumBlock = m_nFracLin[0] * m_nFracLin[1] * m_nFracLin[2] ; - m_BlockToUpdate.resize( m_nNumBlock) ; for ( unsigned int nCount = 0 ; nCount < m_nNumBlock ; ++ nCount) - m_BlockToUpdate[nCount] = true ; + m_BlockToUpdate[nCount] = true ; + // Dimensiono raccolta triangoli di feature tra blocchi m_InterBlockTria.resize( m_nNumBlock) ; - - m_nStatus = OK ; - return true ; -} \ No newline at end of file + // Aggiornamento dello stato + m_nStatus = OK ; + + return true ; +} diff --git a/VolZmap.h b/VolZmap.h index f4f94ce..ed94337 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -220,16 +220,13 @@ class VolZmap : public IVolZmap, public IGeoObjRW 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) const ; - bool IntersLineVoxel( const Point3d& ptP, const Vector3d& vtV, int nIndI, int nIndJ, int nIndK, - int& nFace1, int& nFace2, double& dU1, double& dU2) const ; - 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, + bool IntersLineBox( const Point3d& ptP, const Vector3d& vtV, const Point3d& ptMin, const Point3d& ptMax, + double& dU1, double& dU2) const ; + bool IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, double& dU1, double& dU2) ; + bool IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, 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) ; + bool IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ, + double& dU1, double& dU2) ; bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CylFrame, double dL, double dR, Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, @@ -249,8 +246,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW const Point3d& ptCenter, double dRad, Point3d& ptInt1, Point3d& ptInt2) ; bool IntersLineMyPolyhedron( const Point3d& ptLineSt, const Vector3d& vtLineDir, - const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaX, - Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) ; + const Frame3d& PolyFrame, double dLenX, double dLenY, double dLenZ, double dDeltaX, + Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2) ; // Funzioni di gestione dei blocchi bool GetBlockIJKFromN( int nBlock, int nIJK[]) const ;