diff --git a/VolZmap.h b/VolZmap.h index f782695..9da6256 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -50,6 +50,13 @@ struct IntersToCheck { typedef std::vector INTTOCHECKVEC ; +struct Neigh { // 6 7 8 + double nI ; // 3 s 5 + double nJ ; // 0 1 2 + int nN ; // n-esimo vicino di uno spillone : numerati così + Neigh( double _nI, double _nJ, int _nN) : nI( _nI), nJ( _nJ), nN( _nN) { ;} +}; + //---------------------------------------------------------------------------- class VolZmap : public IVolZmap, public IGeoObjRW { @@ -483,7 +490,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ; bool AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHECKVEC& vIntToCheck, const Point3d& ptMapOrig, const ISurfTriMesh& Surf, const IntersParLinesSurfTm& intPLSTM) ; - DBLDBLVECTOR GetNeighbours( int nG, int nI, int nJ, double dPar) ; + bool SearchMissingIntervals( int nMap, INTTOCHECKVEC& vIntToCheck) ; + std::vector GetNeighbours( int nG, int nI, int nJ, double dPar) ; // Funzioni per Offset di superfici bool InitVolZMapOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ; bool InitVolZMapThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ; diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp index 4327a79..0b10444 100644 --- a/VolZmapCreation.cpp +++ b/VolZmapCreation.cpp @@ -606,8 +606,10 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co if ( k > 0) { int z = k - 1 ; // controllo se l'intersezione corrente è coincidente con la precedente, per esempio se ILTT == 4 ( intersezione su un lato di un triangolo, quindi con 2 triangoli) + // controllo anche che le proiezioni delle normali abbiano lo stesso segno rispetto allo spillone if ( IntersectionResults[k].dU - IntersectionResults[z].dU < EPS_SMALL && - IntersectionResults[k].dCosDN - IntersectionResults[z].dCosDN < EPS_SMALL) + IntersectionResults[k].dCosDN - IntersectionResults[z].dCosDN < EPS_SMALL && + IntersectionResults[k].dCosDN * IntersectionResults[z].dCosDN > 0) continue ; } @@ -634,6 +636,10 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co Surf.GetFacetNormal( nF, vtInN) ; bInside = true ; + if ( k == nInt - 1) { + // se ho un ingresso ma è l'ultima intersezione vuol dire che è spaiata + vIntToCheck.emplace_back( IntersectionResults[k].ptI, vtInN, IntersectionResults[k].dU, nMap, i, j) ; + } } // esco dalla superficie trimesh @@ -677,6 +683,10 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co if ( bForceClosed) { if ( ! AdjustDexelThroughCracks( nMap, vtLen, vIntToCheck, ptMapOrig, Surf, intPLSTM)) return false ; + vIntToCheck.clear() ; + SearchMissingIntervals( nMap, vIntToCheck) ; + if ( ! AdjustDexelThroughCracks( nMap, vtLen, vIntToCheck, ptMapOrig, Surf, intPLSTM)) + return false ; } return true ; @@ -1048,30 +1058,30 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex return bCompleted ; } -DBLDBLVECTOR +vector VolZmap::GetNeighbours( int nG, int nI, int nJ, double dPar) { - DBLDBLVECTOR vNeigh ; + vector vNeigh ; // parto da in basso a sinistra e procedo per righe, saltando il punto corrente if ( nI > 0 && nJ > 0) - vNeigh.emplace_back( nI - dPar, nJ - dPar) ; + vNeigh.emplace_back( nI - dPar, nJ - dPar, 0) ; if ( nJ > 0) { - vNeigh.emplace_back( nI, nJ - dPar) ; + vNeigh.emplace_back( nI, nJ - dPar, 1) ; if ( nI < m_nNx[nG] - dPar) - vNeigh.emplace_back( nI + dPar, nJ - dPar) ; + vNeigh.emplace_back( nI + dPar, nJ - dPar, 2) ; } // passo alla fila contenente il punto corrente if ( nI > 0) - vNeigh.emplace_back( nI - dPar, nJ) ; + vNeigh.emplace_back( nI - dPar, nJ, 3) ; if ( nI < m_nNx[nG] - dPar) - vNeigh.emplace_back( nI + dPar, nJ) ; + vNeigh.emplace_back( nI + dPar, nJ, 5) ; // passo alla fila successiva a quella del corrente if ( nJ < m_nNy[nG] - dPar) { if ( nI > 0) - vNeigh.emplace_back( nI - dPar, nJ + dPar) ; - vNeigh.emplace_back( nI, nJ + dPar) ; - if ( nI < m_nNx[nG]) - vNeigh.emplace_back( nI + dPar, nJ + dPar) ; + vNeigh.emplace_back( nI - dPar, nJ + dPar, 6) ; + vNeigh.emplace_back( nI, nJ + dPar, 7) ; + if ( nI < m_nNx[nG] - dPar) + vNeigh.emplace_back( nI + dPar, nJ + dPar, 8) ; } return vNeigh ; } @@ -1095,103 +1105,112 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE for ( const auto& itc : vIntToCheck) { int nPos = itc.nJ * m_nNx[nG] + itc.nI ; double dPosRef = itc.ptInters.v[( nG + 2) % 3] ; - // controllo se esiste già un intervallo con un estremo quasi coincidente a quello segnalato - // ed entrambi sono entrate o uscite - bool bNeedToReconstruct = true ; - for ( const auto& data: m_Values[nG][nPos]) { - if ( (( abs( dPosRef - data.dMin) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMinN * vtAx) > 0)) || - (( abs( dPosRef - data.dMax) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMaxN * vtAx) > 0))) { - bNeedToReconstruct = false ; - break ; - } + bool bUseNeighInfo = true ; + // se il punto di intersezione passato non è valido vuol dire che non ho neanche un'intersezione spaiata da cui partire a cercare + bool bHaveRef = true ; + if ( ! isfinite( dPosRef)) { + bHaveRef = false ; + bUseNeighInfo = false ; } - if ( ! bNeedToReconstruct) - continue ; - DBLDBLVECTOR vNeigh = GetNeighbours( nG, itc.nI, itc.nJ, m_dStep) ; PNTVECTOR vNeighInters ; Vector3d vtMeanN = V_NULL ; - bool bSearchingInOrOut = itc.vtN * vtAx > 0 ; - bool bUseNeighInfo = true ; - for ( const auto& [i,j] : vNeigh) { - double dMinDist = INFINITO ; - double dCorrespInters = INFINITO ; - double dNearestPos = NAN ; - Vector3d vtNearestN ; - int nNeighPos = int( j) * m_nNx[nG] + int( i) ; - for ( const auto& data: m_Values[nG][nNeighPos]) { - double dDist1 = abs( dPosRef - data.dMin) ; - double dDist2 = abs( dPosRef - data.dMax) ; - if ( dDist1 < dMinDist || dDist2 < dMinDist) { - dMinDist = min( dDist1, dDist2) ; - - // se sto cercando un ingresso - if ( bSearchingInOrOut) { - if ( data.vtMaxN * vtAx < 0) { - dNearestPos = data.dMax ; - vtNearestN = data.vtMaxN ; - dCorrespInters = data.dMin ; - } - else if ( data.vtMinN * vtAx < 0) { - dNearestPos = data.dMin ; - vtNearestN = data.vtMinN ; - dCorrespInters = data.dMax ; - } - } - // se sto cercando un'uscita - else { - if ( data.vtMaxN * vtAx > 0) { - dNearestPos = data.dMax ; - vtNearestN = data.vtMaxN ; - dCorrespInters = data.dMin ; - } - else if ( data.vtMinN * vtAx > 0) { - dNearestPos = data.dMin ; - vtNearestN = data.vtMinN ; - dCorrespInters = data.dMax ; - } - } - } - } - // verifico che il dNearestPos sia effettivamente associato al tratto che sto cercando di ricostruire - // e non ad un altro presente sullo spillone corrente - bool bAddNearest = true ; + if ( bHaveRef) { + // controllo se esiste già un intervallo con un estremo quasi coincidente a quello segnalato + // ed entrambi sono entrate o uscite + bool bNeedToReconstruct = true ; for ( const auto& data: m_Values[nG][nPos]) { - double dDist1 = abs( dCorrespInters - data.dMin) ; - double dDist2 = abs( dCorrespInters - data.dMax) ; - if ( dDist1 < dMinDist || dDist2 < dMinDist) { - bAddNearest = false ; + if ( (( abs( dPosRef - data.dMin) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMinN * vtAx) > 0)) || + (( abs( dPosRef - data.dMax) < 10 * EPS_SMALL && ( itc.vtN * vtAx) * ( data.vtMaxN * vtAx) > 0))) { + bNeedToReconstruct = false ; break ; - } + } } + if ( ! bNeedToReconstruct) + continue ; + vector vNeigh = GetNeighbours( nG, itc.nI, itc.nJ, m_dStep) ; + bool bSearchingInOrOut = itc.vtN * vtAx > 0 ; + for ( const auto& [i, j, n] : vNeigh) { + double dMinDist = INFINITO ; + double dCorrespInters = INFINITO ; + double dNearestPos = NAN ; + Vector3d vtNearestN ; + int nNeighPos = int( j) * m_nNx[nG] + int( i) ; + for ( const auto& data : m_Values[nG][nNeighPos]) { + double dDist1 = abs( dPosRef - data.dMin) ; + double dDist2 = abs( dPosRef - data.dMax) ; + if ( dDist1 < dMinDist || dDist2 < dMinDist) { + dMinDist = min( dDist1, dDist2) ; - if ( bAddNearest && isfinite( dNearestPos)) { - // controllo anche che i punti non siano troppo lontani tra loro, altrimenti - // il piano calcolato potrebbe essere una media troppo grezza - double dMaxDist = 3 * m_dStep ; - const bool bTooFar = any_of( vNeighInters.begin(), vNeighInters.end(), - [ dNearestPos, dMaxDist]( const Point3d& pt) { - return abs( pt.z - dNearestPos) > dMaxDist ; - }) ; - double dAng ; - if ( ! bTooFar) { - // controllo anche che gli angoli delle normali non cambino troppo - // calcolo l'angolo con la media delle precedenti perché il valore oltre cui - // considero le normali diverse è grande - vtNearestN.GetAngle( vtMeanN, dAng) ; + // se sto cercando un ingresso + if ( bSearchingInOrOut) { + if ( data.vtMaxN * vtAx < 0) { + dNearestPos = data.dMax ; + vtNearestN = data.vtMaxN ; + dCorrespInters = data.dMin ; + } + else if ( data.vtMinN * vtAx < 0) { + dNearestPos = data.dMin ; + vtNearestN = data.vtMinN ; + dCorrespInters = data.dMax ; + } + } + // se sto cercando un'uscita + else { + if ( data.vtMaxN * vtAx > 0) { + dNearestPos = data.dMax ; + vtNearestN = data.vtMaxN ; + dCorrespInters = data.dMin ; + } + else if ( data.vtMinN * vtAx > 0) { + dNearestPos = data.dMin ; + vtNearestN = data.vtMinN ; + dCorrespInters = data.dMax ; + } + } + } } - bAddNearest = ! bTooFar && dAng < dAngSameFace ; - if ( bAddNearest) { - double dX = ( i + 0.5) * m_dStep ; - double dY = ( j + 0.5) * m_dStep ; - vNeighInters.emplace_back( dX, dY, dNearestPos) ; - vtMeanN += vtNearestN ; + // verifico che il dNearestPos sia effettivamente associato al tratto che sto cercando di ricostruire + // e non ad un altro presente sullo spillone corrente + bool bAddNearest = true ; + for ( const auto& data : m_Values[nG][nPos]) { + double dDist1 = abs( dCorrespInters - data.dMin) ; + double dDist2 = abs( dCorrespInters - data.dMax) ; + if ( dDist1 < dMinDist || dDist2 < dMinDist) { + bAddNearest = false ; + break ; + } } - else { - bUseNeighInfo = false ; - break ; + if ( bAddNearest && isfinite( dNearestPos)) { + // controllo anche che i punti non siano troppo lontani tra loro, altrimenti + // il piano calcolato potrebbe essere una media troppo grezza + double dMaxDist = 3 * m_dStep ; + const bool bTooFar = any_of( vNeighInters.begin(), vNeighInters.end(), + [dNearestPos, dMaxDist](const Point3d& pt) { + return abs( pt.z - dNearestPos) > dMaxDist ; + }) ; + double dAng ; + if ( ! bTooFar) { + // controllo anche che gli angoli delle normali non cambino troppo + // calcolo l'angolo con la media delle precedenti perché il valore oltre cui + // considero le normali diverse è grande + vtNearestN.GetAngle( vtMeanN, dAng) ; + } + bAddNearest = ! bTooFar && dAng < dAngSameFace ; + if ( bAddNearest) { + double dX = ( i + 0.5) * m_dStep ; + double dY = ( j + 0.5) * m_dStep ; + vNeighInters.emplace_back( dX, dY, dNearestPos) ; + vtMeanN += vtNearestN ; + } + else { + bUseNeighInfo = false ; + break ; + } } } } + vector vNewIntervals ; + bool bAddAllIntervals = false ; Point3d ptInt ; // se riesco uso i vicini per calcolare l'intersezione mancante if ( bUseNeighInfo) { @@ -1233,15 +1252,16 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE // se ciclando la raggiera non trovo un'intersezione valida allora potrei essermi spostato troppo poco dallo spillone originale e essere caduto ancora nella fessura // quindi ciclo nuovamente aumentando un poco la distanza dallo spillone originale ( comunque sempre meno della distanza m_dStep) for ( int c = 0 ; c < ssize( vSmallStep) ; ++c) { - DBLDBLVECTOR vSmallMoveNeigh = GetNeighbours( nG, itc.nI, itc.nJ, vSmallStep[c]) ; + vector vSmallMoveNeigh = GetNeighbours( nG, itc.nI, itc.nJ, vSmallStep[c]) ; for ( int n = 0 ; n < ssize( vSmallMoveNeigh) ; ++n) { - double dX = ( vSmallMoveNeigh[n].first + 0.5) * m_dStep ; - double dY = ( vSmallMoveNeigh[n].second + 0.5) * m_dStep ; + double dX = ( vSmallMoveNeigh[n].nI + 0.5) * m_dStep ; + double dY = ( vSmallMoveNeigh[n].nJ + 0.5) * m_dStep ; Point3d ptP0( dX, dY, 0) ; ILSIVECTOR IntersectionResults ; intPLSTM.GetInters( ptP0, vtLen.v[(nG+2)%3], IntersectionResults) ; // intervalli dalle intersezioni - vector vNewIntervals ; + vNewIntervals.clear() ; + DBLVECTOR vDiscardedInters ; bool bInside = false ; Vector3d vtInN ; Point3d ptIn ; @@ -1258,6 +1278,10 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE double dCos = IntersectionResults[i].dCosDN ; // entro nella superficie trimesh if ( dCos < - dCosSmall) { + if ( bInside) { + int k = i - 1 ; + vDiscardedInters.push_back( IntersectionResults[k].dU) ; + } ptIn = IntersectionResults[i].ptI ; int nT = IntersectionResults[i].nT ; @@ -1269,7 +1293,11 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE } // esco dalla superficie trimesh - else if ( dCos > dCosSmall && bInside) { + else if ( dCos > dCosSmall) { + if ( ! bInside) { + vDiscardedInters.push_back( IntersectionResults[i].dU) ; + continue ; + } Point3d ptOut = IntersectionResults[i].ptI ; int nT = IntersectionResults[i].nT ; @@ -1294,22 +1322,76 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE } } } - // controllo che abbia un intervallo in più rispetto a quelli di prima - if ( ssize( vNewIntervals) == ssize( m_Values[nG][nPos]) + 1) { - // dovrei verificare che quello in più sia effettivamente quello ricercato???? - double dMinDist = INFINITO ; - for ( const auto& data : vNewIntervals) { - if ( abs( data.dMin - dPosRef) < dMinDist) { - dMinDist = abs( data.dMin - dPosRef) ; - ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMax) ; - vtMeanN = data.vtMaxN ; - bFound = true ; + // controllo che abbia almeno un intervallo in più rispetto a quelli di prima + if ( ssize( vNewIntervals) > ssize( m_Values[nG][nPos])) { + // se avevo un punto disaccoppiato lo uso come riferimento + if ( itc.ptInters.IsValid()) { + // devo controllare se l'intervallo in più è quello che cercavo + // controllo anche tra le intersezioni scartate + double dMinDist = INFINITO ; + for ( const auto& data : vNewIntervals) { + if ( abs( data.dMin - dPosRef) < dMinDist) { + dMinDist = abs( data.dMin - dPosRef) ; + ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMax) ; + vtMeanN = data.vtMaxN ; + bFound = true ; + } + if ( abs( data.dMax - dPosRef) < dMinDist) { + dMinDist = abs( data.dMax - dPosRef) ; + ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMin) ; + vtMeanN = data.vtMinN ; + bFound = true ; + } } - if ( abs( data.dMax - dPosRef) < dMinDist) { - dMinDist = abs( data.dMax - dPosRef) ; - ptInt.Set( itc.nI + 0.5, itc.nJ + 0.5, data.dMin) ; - vtMeanN = data.vtMinN ; + for ( const auto& dU : vDiscardedInters) { + if ( abs( dU - dPosRef) < dMinDist) { + bFound = false ; + break ; + } + } + } + else { + // se non avevo intervalli sul corrente tengo tutto quello trovo + if ( ssize( m_Values[nG][nPos]) == 0) { bFound = true ; + bAddAllIntervals = true ; + } + else { + // altrimenti mi aspetto di aver attrvarsato due fessure e quindi di avere sullo spillone corrente un + // intervallo il cui inizio e fine corrispondono a inizio di un intervallo e fine del successivo + for ( int z = 0 ; z < ssize( vNewIntervals) - 1 ; ++z) { + Data& data = vNewIntervals[z] ; + Data& dataNext = vNewIntervals[z+1] ; + bool bSkipNext = false ; + for ( int w = 0 ; w < ssize( m_Values[nG][nPos]) ; ++w) { + Data& dataCurr = m_Values[nG][nPos][w] ; + if ( abs( data.dMin - dataCurr.dMin) < m_dStep && abs( dataNext.dMax - dataCurr.dMax) < m_dStep) { + m_Values[nG][nPos].emplace_back() ; + m_Values[nG][nPos].back().dMin = dataCurr.dMin; + m_Values[nG][nPos].back().dMax = data.dMax ; + m_Values[nG][nPos].back().vtMinN = dataCurr.vtMinN ; + m_Values[nG][nPos].back().vtMaxN = data.vtMaxN ; + m_Values[nG][nPos].back().nToolMin = 0 ; + m_Values[nG][nPos].back().nToolMax = 0 ; + m_Values[nG][nPos].back().nCompo = 0 ; + //secondo + m_Values[nG][nPos].emplace_back() ; + m_Values[nG][nPos].back().dMin = dataNext.dMin; + m_Values[nG][nPos].back().dMax = dataCurr.dMax ; + m_Values[nG][nPos].back().vtMinN = dataNext.vtMinN ; + m_Values[nG][nPos].back().vtMaxN = dataCurr.vtMaxN ; + m_Values[nG][nPos].back().nToolMin = 0 ; + m_Values[nG][nPos].back().nToolMax = 0 ; + m_Values[nG][nPos].back().nCompo = 0 ; + // cancello quello che era + m_Values[nG][nPos].erase( m_Values[nG][nPos].begin() + w) ; + bSkipNext = true ; + break ; + } + } + if ( bSkipNext) + ++z ; + } } } } @@ -1323,39 +1405,83 @@ VolZmap::AdjustDexelThroughCracks( int nG, const Vector3d& vtLen, const INTTOCHE if ( ! bFound) continue ; } - - double dMin, dMax ; - Vector3d vtMinN, vtMaxN ; - if ( itc.dU < ptInt.z) { - dMin = itc.dU ; - dMax = ptInt.z ; - vtMinN = itc.vtN ; - vtMaxN = vtMeanN ; + + + if ( ! bAddAllIntervals) { + double dMin, dMax ; + Vector3d vtMinN, vtMaxN ; + if ( itc.dU < ptInt.z) { + dMin = itc.dU ; + dMax = ptInt.z ; + vtMinN = itc.vtN ; + vtMaxN = vtMeanN ; + } + else { + dMin = ptInt.z ; + dMax = itc.dU ; + vtMinN = vtMeanN ; + vtMaxN = itc.vtN ; + } + //// prima di aggiungere il tratto verifico che non si sovrapponga con un tratto già presente + //for ( const auto& data: m_Values[nG][nPos]) { + // if ( ( dMin > data.dMin && dMin < data.dMax) || + // ( dMax > data.dMin && dMax < data.dMax) || + // ( dMin < data.dMin && dMax > data.dMax)) + // continue ; + //} + + m_Values[nG][nPos].emplace_back() ; + m_Values[nG][nPos].back().dMin = dMin; + m_Values[nG][nPos].back().dMax = dMax ; + m_Values[nG][nPos].back().vtMinN = vtMinN ; + m_Values[nG][nPos].back().vtMaxN = vtMaxN ; + m_Values[nG][nPos].back().nToolMin = 0 ; + m_Values[nG][nPos].back().nToolMax = 0 ; + m_Values[nG][nPos].back().nCompo = 0 ; } else { - dMin = ptInt.z ; - dMax = itc.dU ; - vtMinN = vtMeanN ; - vtMaxN = itc.vtN ; + for ( const auto& data: vNewIntervals) { + m_Values[nG][nPos].emplace_back() ; + m_Values[nG][nPos].back().dMin = data.dMin; + m_Values[nG][nPos].back().dMax = data.dMax ; + m_Values[nG][nPos].back().vtMinN = data.vtMinN ; + m_Values[nG][nPos].back().vtMaxN = data.vtMaxN ; + m_Values[nG][nPos].back().nToolMin = 0 ; + m_Values[nG][nPos].back().nToolMax = 0 ; + m_Values[nG][nPos].back().nCompo = 0 ; + } } - //// prima di aggiungere il tratto verifico che non si sovrapponga con un tratto già presente - //for ( const auto& data: m_Values[nG][nPos]) { - // if ( ( dMin > data.dMin && dMin < data.dMax) || - // ( dMax > data.dMin && dMax < data.dMax) || - // ( dMin < data.dMin && dMax > data.dMax)) - // continue ; - //} - - m_Values[nG][nPos].emplace_back() ; - m_Values[nG][nPos].back().dMin = dMin; - m_Values[nG][nPos].back().dMax = dMax ; - m_Values[nG][nPos].back().vtMinN = vtMinN ; - m_Values[nG][nPos].back().vtMaxN = vtMaxN ; - m_Values[nG][nPos].back().nToolMin = 0 ; - m_Values[nG][nPos].back().nToolMax = 0 ; - m_Values[nG][nPos].back().nCompo = 0 ; std::sort( m_Values[nG][nPos].begin(), m_Values[nG][nPos].end(), []( Data& a, Data& b) { return a.dMin < b.dMin ;}) ; } + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::SearchMissingIntervals( int nMap, INTTOCHECKVEC& vIntToCheck) +{ + + for ( int nI = 0 ; nI < m_nNx[nMap] ; ++nI) { + for ( int nJ = 0 ; nJ < m_nNy[nMap] ; ++nJ) { + int nPos = int( nJ) * m_nNx[nMap] + int( nI) ; + vector vNeigh = GetNeighbours( nMap, nI, nJ, 1) ; + for ( const auto& [i,j,n] : vNeigh) { + int nNeighPos = int( j) * m_nNx[nMap] + int( i) ; + if ( ssize( m_Values[nMap][nNeighPos]) > ssize( m_Values[nMap][nPos])) { + int nNeigh = 8 - n ; + auto itOpp = find_if( vNeigh.begin(), vNeigh.end(), [nNeigh]( const Neigh& a) { return a.nN == nNeigh ;}) ; + int nIndOpp = distance( begin( vNeigh), itOpp) ; + if ( itOpp != vNeigh.end()) { + int nOppNeighPos = int( vNeigh[nIndOpp].nJ) * m_nNx[nMap] + int( vNeigh[nIndOpp].nI) ; + if ( ssize( m_Values[nMap][nOppNeighPos]) == ssize( m_Values[nMap][nNeighPos])) { + vIntToCheck.emplace_back( P_INVALID, V_INVALID, double( NAN), nMap, nI, nJ) ; + break ; + } + } + } + } + } + } return true ; } \ No newline at end of file