diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index f256780..8d9b362 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/IntersCrvCompoCrvCompo.cpp b/IntersCrvCompoCrvCompo.cpp index dd98918..dac0154 100644 --- a/IntersCrvCompoCrvCompo.cpp +++ b/IntersCrvCompoCrvCompo.cpp @@ -118,7 +118,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, } // ordino le intersezioni secondo l'ordine crescente del parametro della prima curva - stable_sort( m_Info.begin(), m_Info.end(), SortGreater) ; + stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ; // se auto-intersezione, elimino le seconde copie di una stessa intersezione if ( bAutoInters) { @@ -377,7 +377,46 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, } } - // verifico se sono rimaste delle intersezioni di tipo non definito e cerco di risolverle + // verifico se sono rimaste delle intersezioni di tipo non definito sulla curva A e cerco di risolverle per continuità + for ( int i = 0 ; i < m_nNumInters ; ++ i) { + // se il tipo di accostamento per la curva A non è definito + if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) { + if ( i == 0 && ! bCrvAClosed) + continue ; + int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ; + m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ; + } + // se il tipo di allontanamento per la curva A non è definito + if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) { + if ( i == m_nNumInters - 1 && ! bCrvAClosed) + continue ; + int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ; + m_Info[i].IciA[0].nNextTy = m_Info[j].IciA[0].nPrevTy ; + } + } + + // verifico se sono rimaste delle intersezioni di tipo non definito sulla curva B e cerco di risolverle per continuità + stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ; + for ( int i = 0 ; i < m_nNumInters ; ++ i) { + // se il tipo di accostamento per la curva B non è definito + if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) { + if ( i == 0 && ! bCrvBClosed) + continue ; + int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ; + m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ; + } + // se il tipo di allontanamento per la curva B non è definito + if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) { + if ( i == m_nNumInters - 1 && ! bCrvBClosed) + continue ; + int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ; + m_Info[i].IciB[0].nNextTy = m_Info[j].IciB[0].nPrevTy ; + } + } + // ripristino ordinamento su prima curva + stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ; + + // verifico se sono rimaste delle intersezioni di tipo non definito e cerco di risolverle studiando gli intorni for ( int i = 0 ; i < m_nNumInters ; ++ i) { // in assenza di overlap if ( ! m_Info[i].bOverlap) { @@ -591,7 +630,7 @@ IntersCrvCompoCrvCompo::EraseOtherInfo( int& nIndCurr, int& nIndOther) //---------------------------------------------------------------------------- bool -SortGreater( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) +SortGreaterA( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) { double dU1, dU2 ; // determino il primo termine del confronto @@ -618,6 +657,35 @@ SortGreater( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) return ( dU2 > dU1 + EPS_PARAM) ; } +//---------------------------------------------------------------------------- +bool +SortGreaterB( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) +{ + double dU1, dU2 ; + // determino il primo termine del confronto + dU1 = aInfo1.IciB[0].dU ; + if ( aInfo1.bOverlap) { + // caso normale + if ( aInfo1.IciB[0].dU < aInfo1.IciB[1].dU) + dU1 = 0.5 * ( aInfo1.IciB[0].dU + aInfo1.IciB[1].dU) ; + // a cavallo di fine / inizio + else + dU1 = aInfo1.IciB[0].dU + SPAN_PARAM ; + } + // determino il secondo termine del confronto + dU2 = aInfo2.IciB[0].dU ; + if ( aInfo2.bOverlap) { + // caso normale + if ( aInfo2.IciB[0].dU < aInfo2.IciB[1].dU) + dU2 = 0.5 * ( aInfo2.IciB[0].dU + aInfo2.IciB[1].dU) ; + // a cavallo di fine / inizio + else + dU2 = aInfo2.IciB[0].dU + SPAN_PARAM ; + } + + return ( dU2 > dU1 + EPS_PARAM) ; +} + //---------------------------------------------------------------------------- bool OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& CurveB) diff --git a/IntersCrvCompoCrvCompo.h b/IntersCrvCompoCrvCompo.h index 6a98f41..ee5d0ff 100644 --- a/IntersCrvCompoCrvCompo.h +++ b/IntersCrvCompoCrvCompo.h @@ -52,6 +52,7 @@ class IntersCrvCompoCrvCompo //----------------------------------------------------------------------------- // Per ordinare le info di intersezione secondo il parametro crescente (con stable_sort) -bool SortGreater( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) ; +bool SortGreaterA( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) ; +bool SortGreaterB( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) ; // Per tener conto di intersezioni con parti non manifold bool OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& CurveB) ; diff --git a/IntersCurveCurve.cpp b/IntersCurveCurve.cpp index c4e8f7a..862f226 100644 --- a/IntersCurveCurve.cpp +++ b/IntersCurveCurve.cpp @@ -453,7 +453,7 @@ IntersCurveCurve::SwapInfoAB( ICCIVECTOR& Info, int IndCrvOrd) } } // ordino le intersezioni secondo l'ordine crescente del parametro della prima curva - stable_sort( Info.begin(), Info.end(), SortGreater) ; + stable_sort( Info.begin(), Info.end(), SortGreaterA) ; // verifiche su intersezioni in zone non-manifold OrderNonManifoldInters( Info, *(m_pCurve[IndCrvOrd]), *(m_pCurve[1-IndCrvOrd])) ; return true ; diff --git a/IntersLineLine.cpp b/IntersLineLine.cpp index 7092c79..b7437b6 100644 --- a/IntersLineLine.cpp +++ b/IntersLineLine.cpp @@ -161,7 +161,7 @@ IntersLineLine::IntersFiniteLines( const ICurveLine& Line1, const ICurveLine& Li m_Info.IciA[0].dU = CrossXY( ( ptS2 - ptS1), vtDir2) / dCrossXY ; m_Info.IciB[0].dU = CrossXY( ( ptS2 - ptS1), vtDir1) / dCrossXY ; // verifica posizione intersezione su prima linea - int nPos1 = ICurve::PP_NULL ; // fuori + int nPos1 = ICurve::PP_NULL ; // fuori if ( ( m_Info.IciA[0].dU * vtDir1).IsSmall()) nPos1 = ICurve::PP_START ; // vicino a inizio else if ( (( 1 - m_Info.IciA[0].dU) * vtDir1).IsSmall()) diff --git a/VolZmap.cpp b/VolZmap.cpp index 0ad9b72..cb46688 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -905,16 +905,16 @@ VolZmap::ClonePart( int nPart) const // Se è definita una sola griglia non sono definibili le parti, errore if ( m_nMapNum == 1) return nullptr ; - // Se è richiesta una componente fuori intervallo restituisco nullptr. + // Se è richiesta una componente fuori intervallo, errore if ( nPart < 0 || nPart >= m_nConnectedCompoCount) return nullptr ; // Se il numero di componenti è indefinito, lo ricalcolo. if ( m_nConnectedCompoCount == - 1) const_cast(this)->CheckMapConnection() ; - // Se non vi sono componenti restituisco nullptr. + // Se non vi sono componenti, errore if ( m_nConnectedCompoCount == 0) return nullptr ; - + // Creo nuovo oggetto Zmap PtrOwner pVolume( CreateBasicVolZmap()) ; if ( IsNull( pVolume)) return nullptr ; @@ -924,31 +924,28 @@ VolZmap::ClonePart( int nPart) const pVolume->m_nMapNum = m_nMapNum ; // Minimi e massimi indici i,j della componente per le tre griglie - int nMinIndI[3] ; - int nMaxIndI[3] ; - int nMinIndJ[3] ; - int nMaxIndJ[3] ; + int nMinIndI[N_MAPS] ; + int nMaxIndI[N_MAPS] ; + int nMinIndJ[N_MAPS] ; + int nMaxIndJ[N_MAPS] ; // Coordinate dell'origine del sistema di riferimento // del nuovo Zmap double dNewOx, dNewOy, dNewOz ; // Ciclo sulle mappe for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) { - nMinIndI[nMap] = m_nNx[nMap] ; nMinIndJ[nMap] = m_nNy[nMap] ; nMaxIndI[nMap] = 0 ; nMaxIndJ[nMap] = 0 ; - // Della componente connessa in questione calcolo - // indici i e j massimi e minimi. + pVolume->m_dMinZ[nMap] = m_dMaxZ[nMap] ; + pVolume->m_dMaxZ[nMap] = m_dMinZ[nMap] ; + // Della componente connessa in questione calcolo indici i e j massimi e minimi. + // Inoltre cerco la minima e massima Z. for ( int nIndI = 0 ; nIndI < int( m_nNx[nMap]) ; ++ nIndI) { for ( int nIndJ = 0 ; nIndJ < int( m_nNy[nMap]) ; ++ nIndJ) { - int nDex = nIndJ * m_nNx[nMap] + nIndI ; - for ( int nInt = 0 ; nInt < int( m_Values[nMap][nDex].size()) ; ++ nInt) { - if ( m_Values[nMap][nDex][nInt].nCompo == nPart + 1) { - if ( nIndI < nMinIndI[nMap]) nMinIndI[nMap] = nIndI ; if ( nIndJ < nMinIndJ[nMap]) @@ -957,55 +954,98 @@ VolZmap::ClonePart( int nPart) const nMaxIndI[nMap] = nIndI ; if ( nIndJ > nMaxIndJ[nMap]) nMaxIndJ[nMap] = nIndJ ; + if ( m_Values[nMap][nDex][nInt].dMin < pVolume->m_dMinZ[nMap]) + pVolume->m_dMinZ[nMap] = m_Values[nMap][nDex][nInt].dMin ; + if ( m_Values[nMap][nDex][nInt].dMax > pVolume->m_dMaxZ[nMap]) + pVolume->m_dMaxZ[nMap] = m_Values[nMap][nDex][nInt].dMax ; } } } } + } + for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) { + if ( nMinIndI[nMap] > 0) + -- nMinIndI[nMap] ; + if ( nMaxIndI[nMap] < int( m_nNx[nMap]) - 1) + ++ nMaxIndI[nMap] ; + if ( nMinIndJ[nMap] > 0) + -- nMinIndJ[nMap] ; + if ( nMaxIndJ[nMap] < int( m_nNy[nMap]) - 1) + ++ nMaxIndJ[nMap] ; pVolume->m_nNx[nMap] = nMaxIndI[nMap] - nMinIndI[nMap] + 1 ; pVolume->m_nNy[nMap] = nMaxIndJ[nMap] - nMinIndJ[nMap] + 1 ; pVolume->m_nDim[nMap] = pVolume->m_nNx[nMap] * pVolume->m_nNy[nMap] ; pVolume->m_Values[nMap].resize( pVolume->m_nDim[nMap]) ; - pVolume->m_dMinZ[nMap] = m_dMaxZ[nMap] ; - pVolume->m_dMaxZ[nMap] = m_dMinZ[nMap] ; } - // Copio gli intervalli nella griglia del nuovo oggetto - for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) { - - for ( int nIndJ = 0 ; nIndJ < int( pVolume->m_nNy[nMap]) ; ++ nIndJ) { - for ( int nIndI = 0 ; nIndI < int( pVolume->m_nNx[nMap]) ; ++ nIndI) { - - int nNewDex = nIndJ * pVolume->m_nNx[nMap] + nIndI ; - int nOldDex = ( nIndJ + nMinIndJ[nMap]) * m_nNx[nMap] + nIndI + nMinIndI[nMap] ; - - for ( int nInt = 0 ; nInt < int( m_Values[nMap][nOldDex].size()) ; ++ nInt) { - - if ( m_Values[nMap][nOldDex][nInt].nCompo == nPart + 1) { - - pVolume->m_Values[nMap][nNewDex].emplace_back( m_Values[nMap][nOldDex][nInt]) ; - pVolume->m_Values[nMap][nNewDex][pVolume->m_Values[nMap][nNewDex].size() - 1].nCompo = 1 ; - - if ( m_Values[nMap][nOldDex][nInt].dMin < pVolume->m_dMinZ[nMap]) - pVolume->m_dMinZ[nMap] = m_Values[nMap][nOldDex][nInt].dMin ; - if ( m_Values[nMap][nOldDex][nInt].dMax > pVolume->m_dMaxZ[nMap]) - pVolume->m_dMaxZ[nMap] = m_Values[nMap][nOldDex][nInt].dMax ; - } + // Copio gli intervalli nelle griglie del nuovo oggetto: + // Griglia 0 + for ( int nIndJ = 0 ; nIndJ < int( pVolume->m_nNy[0]) ; ++ nIndJ) { + for ( int nIndI = 0 ; nIndI < int( pVolume->m_nNx[0]) ; ++ nIndI) { + int nNewDex = nIndJ * pVolume->m_nNx[0] + nIndI ; + int nOldDex = ( nIndJ + nMinIndJ[0]) * m_nNx[0] + nIndI + nMinIndI[0] ; + for ( int nInt = 0 ; nInt < int( m_Values[0][nOldDex].size()) ; ++ nInt) { + if ( m_Values[0][nOldDex][nInt].nCompo == nPart + 1) { + pVolume->m_Values[0][nNewDex].emplace_back( m_Values[0][nOldDex][nInt]) ; + pVolume->m_Values[0][nNewDex].back().nCompo = 1 ; } } } } + // Griglia 1 + for ( int nIndJ = 0 ; nIndJ < int( pVolume->m_nNy[1]) ; ++ nIndJ) { + for ( int nIndI = 0 ; nIndI < int( pVolume->m_nNx[1]) ; ++ nIndI) { + int nNewDex = nIndJ * pVolume->m_nNx[1] + nIndI ; + int nOldDex = ( nIndJ + nMinIndJ[1]) * m_nNx[1] + nIndI + nMinIndI[1] ; + for ( int nInt = 0 ; nInt < int( m_Values[1][nOldDex].size()) ; ++ nInt) { + if ( m_Values[1][nOldDex][nInt].nCompo == nPart + 1) { + pVolume->m_Values[1][nNewDex].emplace_back( m_Values[1][nOldDex][nInt]) ; + pVolume->m_Values[1][nNewDex].back().nCompo = 1 ; + } + } + } + } + // Griglia 2 + for ( int nIndJ = 0 ; nIndJ < int( pVolume->m_nNy[2]) ; ++ nIndJ) { + for ( int nIndI = 0 ; nIndI < int( pVolume->m_nNx[2]) ; ++ nIndI) { + int nNewDex = nIndJ * pVolume->m_nNx[2] + nIndI ; + int nOldDex = ( nIndJ + nMinIndJ[2]) * m_nNx[2] + nIndI + nMinIndI[2] ; + for ( int nInt = 0 ; nInt < int( m_Values[2][nOldDex].size()) ; ++ nInt) { + if ( m_Values[2][nOldDex][nInt].nCompo == nPart + 1) { + pVolume->m_Values[2][nNewDex].emplace_back( m_Values[2][nOldDex][nInt]) ; + pVolume->m_Values[2][nNewDex].back().nCompo = 1 ; + } + } + } + } + // Coordinate x,y dell'origine del sistema di riferimento dNewOx = nMinIndI[0] * m_dStep ; dNewOy = nMinIndJ[0] * m_dStep ; dNewOz = nMinIndJ[1] * m_dStep ; - //dNewOz = pVolume->m_dMinZ[0] ; - - // Porto i dexel nel nuovo sistema di riferimento + + // Porto i dexel nel nuovo sistema di riferimento e le quote estreme Z. Non c'è bisogno di trasformare le normali, + // infatti i sistemi di riferimento in gioco differiscono al più per una traslazione. for ( int nMap = 0 ; nMap < int( m_nMapNum) ; ++ nMap) { - for ( int nDex = 0 ; nDex < int( pVolume->m_nDim[nMap]) ; ++ nDex) { + // Quote estreme Z + switch ( nMap) { + case 0 : + pVolume->m_dMinZ[nMap] -= dNewOz ; + pVolume->m_dMaxZ[nMap] -= dNewOz ; + break ; + case 1 : + pVolume->m_dMinZ[nMap] -= dNewOx ; + pVolume->m_dMaxZ[nMap] -= dNewOx ; + break ; + case 2 : + pVolume->m_dMinZ[nMap] -= dNewOy ; + pVolume->m_dMaxZ[nMap] -= dNewOy ; + break ; + } + // Dexel + for ( int nDex = 0 ; nDex < int( pVolume->m_nDim[nMap]) ; ++ nDex) { for ( int nInt = 0 ; nInt < int( pVolume->m_Values[nMap][nDex].size()) ; ++ nInt) { - switch ( nMap) { case 0 : pVolume->m_Values[nMap][nDex][nInt].dMin -= dNewOz ; @@ -1024,7 +1064,7 @@ VolZmap::ClonePart( int nPart) const } } - // Definisco il numero di blocchi lungo x,y e z + // Definisco il numero di blocchi lungo x, y e z pVolume->m_nFracLin[0] = max( 1u, pVolume->m_nNx[0] / pVolume->m_nDexNumPBlock + ( pVolume->m_nNx[0] % pVolume->m_nDexNumPBlock >= pVolume->m_nDexNumPBlock / 2 ? 1 : 0)) ; @@ -1038,7 +1078,7 @@ VolZmap::ClonePart( int nPart) const // Dimensiono il vettore dei blocchi pVolume->m_nNumBlock = pVolume->m_nFracLin[0] * pVolume->m_nFracLin[1] * pVolume->m_nFracLin[2] ; pVolume->m_BlockToUpdate.resize( pVolume->m_nNumBlock) ; - // Setto tutti i blocchi come da ricalcolare (per quanto riguarda la grafica) + // Setto tutti i blocchi come da aggiornare per la grafica for ( unsigned int nCount = 0 ; nCount < pVolume->m_nNumBlock ; ++ nCount) pVolume->m_BlockToUpdate[nCount] = true ; @@ -1053,6 +1093,7 @@ VolZmap::ClonePart( int nPart) const // Setto lo stato del nuovo Solido pVolume->m_nStatus = m_nStatus ; + // Restituisco il nuovo solido return Release( pVolume) ; }