diff --git a/ChainCurves.cpp b/ChainCurves.cpp index 766a9fe..2fd1499 100644 --- a/ChainCurves.cpp +++ b/ChainCurves.cpp @@ -16,6 +16,9 @@ #include "/EgtDev/Include/EgkChainCurves.h" #include "/EgtDev/Include/EgkGeomDB.h" #include "/EgtDev/Include/EgkCurve.h" +#include + +using namespace std ; //---------------------------------------------------------------------------- bool @@ -49,6 +52,10 @@ ChainCurves::AddCurve( int nId, const Point3d& ptStart, const Vector3d& vtStart, // li inserisco nel PointGrid3d m_PointGrid.InsertPoint( ptStart, nV) ; m_PointGrid.InsertPoint( ptEnd, - nV) ; + // verifico il valore di tolleranza rispetto alla distanza tra gli estremi dell'entità (ignoro curve chiuse) + double dDist = Dist( ptStart, ptEnd) ; + if ( dDist > EPS_SMALL && m_dToler > dDist / 2) + m_dToler = max( dDist / 2, EPS_SMALL) ; return true ; } diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 2e93bbb..237e2dd 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/IntersLineLine.cpp b/IntersLineLine.cpp index 6ec6aa9..0254c80 100644 --- a/IntersLineLine.cpp +++ b/IntersLineLine.cpp @@ -149,7 +149,8 @@ IntersLineLine::IntersFiniteLines( const ICurveLine& Line1, const ICurveLine& Li // flag per linee parallele bool bParallel = ( fabs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ; // flag per segmenti che si allontanano significativamente - bool bFarEnds = ( IsPointOutFatSegment( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) || + bool bFarEnds = ( ( fabs( dCrossXY) > sin( 1 * DEGTORAD) * ( dLen1XY * dLen2XY)) || + IsPointOutFatSegment( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) || IsPointOutFatSegment( ptE1, ptS2, vtDir2, dLen2XY, EPS_SMALL) || IsPointOutFatSegment( ptS2, ptS1, vtDir1, dLen1XY, EPS_SMALL) || IsPointOutFatSegment( ptE2, ptS1, vtDir1, dLen1XY, EPS_SMALL)) ; diff --git a/PolygonPlane.cpp b/PolygonPlane.cpp index d4e48f3..ba7da9b 100644 --- a/PolygonPlane.cpp +++ b/PolygonPlane.cpp @@ -72,7 +72,7 @@ PolygonPlane::Finalize( void) if ( m_dLenN < EPS_SMALL) { // lunghezza della normale (doppio dell'area del poligono) m_dLenN = m_vtN.Len() ; - if ( m_dLenN < EPS_SMALL) + if ( m_dLenN < SQ_EPS_SMALL) return false ; // normalizzo m_vtN /= m_dLenN ; diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index 324c1be..37ca734 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -1013,14 +1013,18 @@ SurfFlatRegion::GetAuxSurf( void) const return nullptr ; pLoop = GetMyLoop( i, ++j) ; } - // creo, setto la superficie trimesh ed elimino punti ripetuti - PtrOwner pChSTM( CreateBasicSurfTriMesh()) ; - if ( IsNull( pChSTM) || ! pChSTM->CreateByRegion( vPL) || ! pChSTM->DoCompacting()) - return nullptr ; - // porto la trimesh in globale al riferimento intrinseco - pChSTM->ToGlob( m_frF) ; - // inserisco questa trimesh in quella complessiva - pSTM->DoSewing( *pChSTM) ; + // se chunk abbastanza grande, creo la superficie trimesh relativa + double dArea ; + if ( vPL[0].GetAreaXY( dArea) && dArea > 100 * SQ_EPS_SMALL) { + // creo, setto la superficie trimesh ed elimino punti ripetuti + PtrOwner pChSTM( CreateBasicSurfTriMesh()) ; + if ( IsNull( pChSTM) || ! pChSTM->CreateByRegion( vPL) || ! pChSTM->DoCompacting()) + return nullptr ; + // porto la trimesh in globale al riferimento intrinseco + pChSTM->ToGlob( m_frF) ; + // inserisco questa trimesh in quella complessiva + pSTM->DoSewing( *pChSTM) ; + } } // la salvo m_pSTM = Release( pSTM) ; diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 512ac55..3d2d4dd 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -2314,7 +2314,7 @@ SurfTriMesh::AddBiTriangle( const int nIdVert[4]) //---------------------------------------------------------------------------- bool -SurfTriMesh::DoCompacting( void) +SurfTriMesh::DoCompacting( double dTol) { // imposto ricalcolo m_nStatus = ERR ; @@ -2339,7 +2339,7 @@ SurfTriMesh::DoCompacting( void) Point3d ptP = m_vVert[nId].ptP ; // se non c'è già un vertice con la stessa posizione lo inserisco nel grid int nAliasId ; - if ( ! VertGrid.Find( ptP, 2 * EPS_SMALL, nAliasId)) { + if ( ! VertGrid.Find( ptP, dTol, nAliasId)) { VertGrid.InsertPoint( ptP, nId) ; // salvo l'Id nel vettore di reindirizzo vVId.push_back( nId) ; @@ -2865,7 +2865,7 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) // classifico i vertici rispetto al piano for ( int i = 0 ; i < GetVertexSize() ; ++ i) { double dDist = DistPointPlane( m_vVert[i].ptP, plPlane) ; - if ( abs( dDist) < 2.1 * EPS_SMALL) { + if ( abs( dDist) < EPS_SMALL) { m_vVert[i].nTemp = 0 ; m_vVert[i].ptP -= plPlane.vtN * dDist ; } diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 07ff72b..dfbfa2d 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -139,7 +139,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW double dAngRot, double dStepRot) override ; bool CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx, double dAngRot, double dStepRot, double dMove) override ; - bool DoCompacting( void) override ; + bool DoCompacting( double dTol = EPS_SMALL) override ; bool DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther = GLOB_FRM) override ; int GetVertexCount( void) const override ; int GetTriangleCount( void) const override ; diff --git a/VolTriZmapCalculus.cpp b/VolTriZmapCalculus.cpp index e062f18..1bed074 100644 --- a/VolTriZmapCalculus.cpp +++ b/VolTriZmapCalculus.cpp @@ -74,7 +74,7 @@ VolZmap::IntersLineBox( const Point3d& ptP, const Vector3d& vtV, //---------------------------------------------------------------------------- bool -VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, double& dU1, double& dU2) +VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, double& dU1, double& dU2) const { // Punti estremi del box dello Zmap Point3d ptMin = ORIG ; @@ -86,7 +86,7 @@ VolZmap::IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, unsigned i //---------------------------------------------------------------------------- bool VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ, - double& dU1, double& dU2) + double& dU1, double& dU2) const { // Determino l'indice del dexel e il numero di suoi intervalli unsigned int nDexelPos = nJ * m_nNx[nGrid] + nI ; @@ -124,7 +124,7 @@ VolZmap::IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int //---------------------------------------------------------------------------- bool VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ, - double& dU1, double& dU2) + double& dU1, double& dU2) const { // Determino l'indice del dexel e il numero di suoi intervalli unsigned int nDexelPos = nJ * m_nNx[nGrid] + nI ; @@ -168,7 +168,7 @@ VolZmap::IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int n // 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) +VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLength, double& dOutLength) const { int nGrid = 0 ; @@ -278,7 +278,7 @@ VolZmap::GetDepth( const Point3d& ptPGlob, const Vector3d& vtDir, double& dInLen //---------------------------------------------------------------------------- bool -VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) +VolZmap::AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const { // BBox BBox3d b3Box( ORIG, ORIG + vtDiag) ; diff --git a/VolTriZmapVolume.cpp b/VolTriZmapVolume.cpp index 5c83a69..d0f6eda 100644 --- a/VolTriZmapVolume.cpp +++ b/VolTriZmapVolume.cpp @@ -905,6 +905,7 @@ VolZmap::MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& // Altri casi al momento non gestiti // return false ; } + m_nConnectedCompoCount = - 1 ; return true ; } diff --git a/VolZmap.cpp b/VolZmap.cpp index 27164f0..52db129 100644 --- a/VolZmap.cpp +++ b/VolZmap.cpp @@ -22,7 +22,6 @@ #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkStringUtils3d.h" - using namespace std ; //---------------------------------------------------------------------------- @@ -564,17 +563,468 @@ VolZmap::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) } //---------------------------------------------------------------------------- -bool -VolZmap::IsMapConnected( void) +int +VolZmap::GetPartCount( void) const { + if ( m_nConnectedCompoCount == - 1) { + const_cast(this)->CheckMapConnection() ; + return m_nConnectedCompoCount ; + } + else + return m_nConnectedCompoCount ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::CheckMapConnection( void) +{ + // Imposto il numero di componenti connesse a 0 + m_nConnectedCompoCount = 0 ; // Imposto a 0 tutti il valore del numero della componente // connessa di ciascun tratto di ciascun dexel. for ( size_t tMap = 0 ; tMap < m_nMapNum ; ++ tMap) { for ( size_t tDex = 0 ; tDex < m_nDim[tMap] ; ++ tDex) { for ( size_t tInt = 0 ; tInt < m_Values[tMap][tDex].size() ; ++ tInt) { + m_Values[tMap][tDex][tInt].nCompo = 0 ; + // Controlli sui tratti di dexel non incidenti su nodi del reticolo + if ( tMap == 0) { + // Z degli estremi del segmento + double dZMin = m_Values[tMap][tDex][tInt].dMin ; + double dZMax = m_Values[tMap][tDex][tInt].dMax ; + // Indici k dei voxels in cui cadono le Z + int nKmin = int( floor( ( dZMin - EPS_SMALL) / m_dStep - 0.5)) ; + int nKmax = int( floor( ( dZMax + EPS_SMALL) / m_dStep - 0.5)) ; + // Se cadono nello stesso voxel imposto a -1 il valore della componente connessa + if ( nKmax - nKmin == 0) + m_Values[tMap][tDex][tInt].nCompo = -1 ; + } + else if ( tMap == 1) { + // X degli estremi del segmento + double dXMin = m_Values[tMap][tDex][tInt].dMin ; + double dXMax = m_Values[tMap][tDex][tInt].dMax ; + // Indici i dei voxels in cui cadono le X + int nImin = int( floor( ( dXMin - EPS_SMALL) / m_dStep - 0.5)) ; + int nImax = int( floor( ( dXMax + EPS_SMALL) / m_dStep - 0.5)) ; + // Se cadono nello stesso voxel imposto a -1 il valore della componente connessa + if ( nImax - nImin == 0) + m_Values[tMap][tDex][tInt].nCompo = -1 ; + } + else { + // Y degli estremi del segmento + double dYMin = m_Values[tMap][tDex][tInt].dMin ; + double dYMax = m_Values[tMap][tDex][tInt].dMax ; + // Indici j dei voxels in cui cadono le X + int nJmin = int( floor( ( dYMin - EPS_SMALL) / m_dStep - 0.5)) ; + int nJmax = int( floor( ( dYMax + EPS_SMALL) / m_dStep - 0.5)) ; + // Se cadono nello stesso voxel imposto a -1 il valore della componente connessa + if ( nJmax - nJmin == 0) + m_Values[tMap][tDex][tInt].nCompo = -1 ; + } } } } + + // Ciclo sui dexel lungo Z + for ( size_t tI = 0 ; tI < m_nNx[0] ; ++ tI) { + for ( size_t tJ = 0 ; tJ < m_nNy[0] ; ++ tJ) { + // Numero del dexel lungo Z + size_t tDexZ = tJ * m_nNx[0] + tI ; + // Numero di intervalli nel dexel + size_t tStopIntZ = m_Values[0][tDexZ].size() ; + // Ciclo sugli intervalli del dexel + for ( size_t tIntZ = 0 ; tIntZ < tStopIntZ ; ++ tIntZ) { + + if ( m_Values[0][tDexZ][tIntZ].nCompo == 0) { + ++ m_nConnectedCompoCount ; + m_Values[0][tDexZ][tIntZ].nCompo = m_nConnectedCompoCount ; + // Espando in tutta la componente + // Segmento corrente + IntervalIndexes NewInt ; + NewInt.tMap = 0 ; + NewInt.tDex = tJ * m_nNx[0] + tI ; + NewInt.tInt = tIntZ ; + // Stack di segmenti + IntContaier IntervalsToProcess ; + // Aggiungo il segmento corrente + IntervalsToProcess.push( NewInt) ; + + // Processo gli intervalli trovati + while ( ! IntervalsToProcess.empty()) { + + switch ( IntervalsToProcess.top().tMap) { + case 0 : + ExpandFromZInterval( IntervalsToProcess) ; + break ; + case 1 : + ExpandFromXInterval( IntervalsToProcess) ; + break ; + case 2 : + ExpandFromYInterval( IntervalsToProcess) ; + break ; + } + } + } + // Se l'intervallo non attraversa un nodo o ha già + // un indice assegnato salto questa iterazione. + else + continue ; + } + } + } + return true ; } + +//---------------------------------------------------------------------------- +bool +VolZmap::ExpandFromXInterval( IntContaier& IntCont) +{ + // Copio i dati dell'intervallo corrente + IntervalIndexes CurrInterval = IntCont.top() ; + IntCont.pop() ; + size_t tDex = CurrInterval.tDex ; + size_t tGrIndex1 = CurrInterval.tDex % m_nNx[1] ; + size_t tGrIndex2 = CurrInterval.tDex / m_nNx[1] ; + size_t tInt = CurrInterval.tInt ; + // Quote estreme del segmento lungo X + double dMinX = m_Values[1][tDex][tInt].dMin ; + double dMaxX = m_Values[1][tDex][tInt].dMax ; + double dMinDX = max( floor( ( dMinX - EPS_SMALL) / m_dStep - 0.5), 0.) ; + double dMaxDX = max( floor( ( dMaxX + EPS_SMALL) / m_dStep - 0.5), 0.) ; + // Indici estremi dei dei dexel ortogonali + // che possono intersecare il segmento di partenza + size_t tStartI = min( size_t( dMinDX), size_t( m_nNx[0] - 1)) ; + size_t tStopI = min( size_t( dMaxDX), size_t( m_nNx[0] - 1)) ; + // Posizione YZ del dexel + double dY = ( tGrIndex1 + 0.5) * m_dStep ; + double dZ = ( tGrIndex2 + 0.5) * m_dStep ; + // Ciclo sugli indici dei dexel che potrebbero + // intersecare il segmento di partenza + for ( size_t tI = tStartI ; tI <= tStopI ; ++ tI) { + // Analizzo i dexel della griglia 0. + size_t tStopZ = m_Values[0][tGrIndex1 * m_nNx[0] + tI].size() ; + for ( size_t tIntZ = 0 ; tIntZ < tStopZ ; ++ tIntZ) { + // Estremi del dexel lunog Z + double dZmin = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMin ; + double dZmax = m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].dMax ; + // Se i segmenti si incrociano e il nuovo trovato non + // ha già un indice assegnato, assegno l'indice e + // aggiungo l'intervallo trovato allo stack. + if ( dZmin - EPS_SMALL < dZ && + dZmax + EPS_SMALL > dZ && + m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].nCompo == 0) { + m_Values[0][tGrIndex1 * m_nNx[0] + tI][tIntZ].nCompo = m_Values[1][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 0 ; + NewInterval.tDex = tGrIndex1 * m_nNx[0] + tI ; + NewInterval.tInt = tIntZ ; + IntCont.push( NewInterval) ; + } + } + // Analizzo i dexel della griglia 2 + size_t tStopY = m_Values[2][tI * m_nNx[2] + tGrIndex2].size() ; + for ( size_t tIntY = 0 ; tIntY < tStopY ; ++ tIntY) { + // Estremi del segmento del dexel lungo Y + double dYmin = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMin ; + double dYmax = m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].dMax ; + // Se i segmenti si incrociano e il nuovo trovato non + // ha già un indice assegnato, assegno l'indice e + // aggiungo l'intervallo trovato allo stack. + if ( dYmin - EPS_SMALL < dY && + dYmax + EPS_SMALL > dY && + m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].nCompo == 0) { + m_Values[2][tI * m_nNx[2] + tGrIndex2][tIntY].nCompo = m_Values[1][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 2 ; + NewInterval.tDex = tI * m_nNx[2] + tGrIndex2 ; + NewInterval.tInt = tIntY ; + IntCont.push( NewInterval) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ExpandFromYInterval( IntContaier& IntCont) +{ + // Copio i dati dell'intervallo corrente + IntervalIndexes CurrInterval = IntCont.top() ; + IntCont.pop() ; + size_t tDex = CurrInterval.tDex ; + size_t tGrIndex1 = CurrInterval.tDex % m_nNx[2] ; + size_t tGrIndex2 = CurrInterval.tDex / m_nNx[2] ; + size_t tInt = CurrInterval.tInt ; + // Quote estreme del segmento lungo Y + double dMinY = m_Values[2][tDex][tInt].dMin ; + double dMaxY = m_Values[2][tDex][tInt].dMax ; + double dMinDY = max( floor( ( dMinY - EPS_SMALL) / m_dStep - 0.5), 0.) ; + double dMaxDY = max( floor( ( dMaxY + EPS_SMALL) / m_dStep - 0.5), 0.) ; + // Indici estremi dei dei dexel ortogonali + // che possono intersecare il segmento di partenza + size_t tStartJ = min( size_t( dMinDY), size_t( m_nNy[0] - 1)) ; + size_t tStopJ = min( size_t( dMaxDY), size_t( m_nNy[0] - 1)) ; + // Posizione XZ del dexel + double dX = ( tGrIndex2 + 0.5) * m_dStep ; + double dZ = ( tGrIndex1 + 0.5) * m_dStep ; + // Ciclo sugli indici dei dexel che potrebbero + // intersecare il segmento di partenza + for ( size_t tJ = tStartJ ; tJ <= tStopJ ; ++ tJ) { + // Analizzo i dexel della griglia 0. + size_t tStopZ = m_Values[0][tJ * m_nNx[0] + tGrIndex2].size() ; + for ( size_t tIntZ = 0 ; tIntZ < tStopZ ; ++ tIntZ) { + // Estremi del dexel lunog Z + double dZmin = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMin ; + double dZmax = m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].dMax ; + // Se i segmenti si incrociano e il nuovo trovato non + // ha già un indice assegnato, assegno l'indice e + // aggiungo l'intervallo trovato allo stack. + if ( dZmin - EPS_SMALL < dZ && + dZmax + EPS_SMALL > dZ && + m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].nCompo == 0) { + m_Values[0][tJ * m_nNx[0] + tGrIndex2][tIntZ].nCompo = m_Values[2][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 0 ; + NewInterval.tDex = tJ * m_nNx[0] + tGrIndex2 ; + NewInterval.tInt = tIntZ ; + IntCont.push( NewInterval) ; + } + } + // Analizzo i dexel della griglia 1 + size_t tStopX = m_Values[1][tGrIndex1 * m_nNx[1] + tJ].size() ; + for ( size_t tIntX = 0 ; tIntX < tStopX ; ++ tIntX) { + // Estremi del segmento del dexel lungo X + double dXmin = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMin ; + double dXmax = m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].dMax ; + // Se i segmenti si incrociano e il nuovo trovato non + // ha già un indice assegnato, assegno l'indice e + // aggiungo l'intervallo trovato allo stack. + if ( dXmin - EPS_SMALL < dX && + dXmax + EPS_SMALL > dX && + m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].nCompo == 0) { + m_Values[1][tGrIndex1 * m_nNx[1] + tJ][tIntX].nCompo = m_Values[2][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 1 ; + NewInterval.tDex = tGrIndex1 * m_nNx[1] + tJ ; + NewInterval.tInt = tIntX ; + IntCont.push( NewInterval) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +VolZmap::ExpandFromZInterval( IntContaier& IntCont) +{ + // Copio i dati dell'intervallo corrente + IntervalIndexes CurrInterval = IntCont.top() ; + IntCont.pop() ; + size_t tDex = CurrInterval.tDex ; + size_t tGrIndex1 = CurrInterval.tDex % m_nNx[0] ; + size_t tGrIndex2 = CurrInterval.tDex / m_nNx[0] ; + size_t tInt = CurrInterval.tInt ; + // Quote estreme del segmento lungo Z + double dMinZ = m_Values[0][tDex][tInt].dMin ; + double dMaxZ = m_Values[0][tDex][tInt].dMax ; + double dMinDZ = max( floor( ( dMinZ - EPS_SMALL) / m_dStep - 0.5), 0.) ; + double dMaxDZ = max( floor( ( dMaxZ + EPS_SMALL) / m_dStep - 0.5), 0.) ; + // Indici estremi dei dexel ortogonali + // che possono intersecare il segmento di partenza + size_t tStartK = min( size_t( dMinDZ), size_t( m_nNy[1] - 1)) ; + size_t tStopK = min( size_t( dMaxDZ), size_t( m_nNy[1] - 1)) ; + // Posizione XY del dexel + double dX = ( tGrIndex1 + 0.5) * m_dStep ; + double dY = ( tGrIndex2 + 0.5) * m_dStep ; + // Ciclo sugli indici dei dexel che potrebbero + // intersecare il segmento di partenza + for ( size_t tK = tStartK ; tK <= tStopK ; ++ tK) { + // Analizzo i dexel della griglia 1. + size_t tStopX = m_Values[1][tK * m_nNx[1] + tGrIndex2].size() ; + for ( size_t tIntX = 0 ; tIntX < tStopX ; ++ tIntX) { + // Estremi del segmento del dexel lungo X + double dXmin = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMin ; + double dXmax = m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].dMax ; + // Se i segmenti si incrociano e il nuovo trovato non + // ha già un indice assegnato, assegno l'indice e + // aggiungo l'intervallo trovato allo stack. + if ( dXmin - EPS_SMALL < dX && + dXmax + EPS_SMALL > dX && + m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo == 0) { + m_Values[1][tK * m_nNx[1] + tGrIndex2][tIntX].nCompo = m_Values[0][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 1 ; + NewInterval.tDex = tK * m_nNx[1] + tGrIndex2 ; + NewInterval.tInt = tIntX ; + IntCont.push( NewInterval) ; + } + } + // Analizzo i dexel della griglia 2 + size_t tStopY = m_Values[2][tGrIndex1 * m_nNx[2] + tK].size() ; + for ( size_t tIntY = 0 ; tIntY < tStopY ; ++ tIntY) { + // Estremi del segmento del dexel lungo Y + double dYmin = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMin ; + double dYmax = m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].dMax ; + // Se i segmenti si incrociano e il nuovo trovato non + // ha già un indice assegnato, assegno l'indice e + // aggiungo l'intervallo trovato allo stack. + if ( dYmin - EPS_SMALL < dY && + dYmax + EPS_SMALL > dY && + m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo == 0) { + m_Values[2][tGrIndex1 * m_nNx[2] + tK][tIntY].nCompo = m_Values[0][tDex][tInt].nCompo ; + IntervalIndexes NewInterval ; + NewInterval.tMap = 2 ; + NewInterval.tDex = tGrIndex1 * m_nNx[2] + tK ; + NewInterval.tInt = tIntY ; + IntCont.push( NewInterval) ; + } + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +VolZmap* +VolZmap::ClonePart( int nPart) const +{ + + return nullptr ; + +#if 0 + // Se il vettore non è vuoto lo pulisco + if ( vMap.size() > 0) + vMap.resize( 0) ; + // Se il numero di componenti è + // indefinito, lo ricalcolo. + if ( m_nConnectedCompoCount == - 1) + IsMapConnected() ; + + // Se il numero di componenti è + // superiore a 1, creo più Zmap. + if ( m_nConnectedCompoCount > 1) + vMap.reserve( m_nConnectedCompoCount - 1) ; + else + return true ; + + // Ciclo sulle componenti connesse con indice superiore a uno + for ( int nC = 2 ; nC <= m_nConnectedCompoCount ; ++ nC) { + + VolZmap TempMap ; + TempMap.m_nConnectedCompoCount = 1 ; + TempMap.m_dStep = m_dStep ; + TempMap.m_nMapNum = m_nMapNum ; + + int nMinIndI, nMaxIndI, nMinIndJ, nMaxIndJ ; + + double dNewOx, dNewOy, dNewOz ; + // Ciclo sulle mappe + for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) { + + nMinIndI = m_nNx[nMap] ; + nMinIndJ = m_nNy[nMap] ; + nMaxIndI = 0 ; + nMaxIndJ = 0 ; + // Della componente connessa in questione calcolo + // indici i e j massimi e minimi. + for ( int nIndI = 0 ; nIndI < m_nNx[nMap] ; ++ nIndI) { + for ( int nIndJ = 0 ; nIndJ < m_nNy[nMap] ; ++ nIndJ) { + + int nDex = nIndJ * m_nNx[0] + nIndI ; + + for ( int nInt = 0 ; nInt < m_Values[nMap][nDex].size() ; ++ nInt) { + + if ( m_Values[nMap][nDex][nInt].nCompo == nC) { + + if ( nIndI < nMinIndI) + nMinIndI = nIndI ; + if ( nIndJ < nMinIndJ) + nMinIndJ = nIndJ ; + if ( nIndI > nMaxIndI) + nMaxIndI = nIndI ; + if ( nIndJ > nMaxIndJ) + nMaxIndJ = nIndJ ; + } + } + } + } + + TempMap.m_nNx[nMap] = nMaxIndI - nMinIndI + 1 ; + TempMap.m_nNy[nMap] = nMaxIndJ - nMinIndJ + 1 ; + TempMap.m_nDim[nMap] = TempMap.m_nNx[nMap] * TempMap.m_nNy[nMap] ; + TempMap.m_Values[nMap].resize( TempMap.m_nDim[nMap]) ; + TempMap.m_dMinZ[nMap] = m_dMaxZ[nMap] ; + TempMap.m_dMaxZ[nMap] = m_dMinZ[nMap] ; + + // Coordinate x,y dell'origine del sistema di riferimento + if ( nMap == 0) { + dNewOx = ( nMinIndI - 0.5) * m_dStep ; + dNewOy = ( nMinIndJ - 0.5) * m_dStep ; + dNewOz = TempMap.m_dMinZ[nMap] ; + } + if ( nMap == 1) { + + dNewOz = ( nMinIndJ - 0.5) * m_dStep ; + } + } + // Copio gli intervalli nella griglia del nuovo oggetto + // e li cancello da quella del vecchio. + for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) { + + for ( int nIndJ = 0 ; nIndJ < TempMap.m_nNy[nMap] ; ++ nIndJ) { + for ( int nIndI = 0 ; nIndI < TempMap.m_nNx[nMap] ; ++ nIndI) { + + int nNewDex = nIndJ * TempMap.m_nNx[nMap] + nIndI ; + int nOldDex = ( nIndJ + nMinIndJ) * m_nNx[nMap] + nIndI + nMinIndI ; + + for ( int nInt = 0 ; nInt < m_Values[nMap][nOldDex].size() ; ++ nInt) { + + if ( m_Values[nMap][nOldDex][nInt].nCompo == nC) { + + TempMap.m_Values[nMap][nNewDex].emplace_back( m_Values[nMap][nOldDex][nInt]) ; + m_Values[nMap][nOldDex].erase( m_Values[nMap][nOldDex].begin() + nInt) ; + + if ( m_Values[nMap][nOldDex][nInt].dMin < TempMap.m_dMinZ[nMap]) + TempMap.m_dMinZ[nMap] = m_Values[nMap][nOldDex][nInt].dMin ; + if ( m_Values[nMap][nOldDex][nInt].dMax > TempMap.m_dMaxZ[nMap]) + TempMap.m_dMaxZ[nMap] = m_Values[nMap][nOldDex][nInt].dMax ; + } + } + } + } + } + + // Definisco il numero di blocchi lungo x e y + TempMap.m_nFracLin[0] = max( 1u, + TempMap.m_nNx[0] / TempMap.m_nDexNumPBlock + + ( TempMap.m_nNx[0] % TempMap.m_nDexNumPBlock >= TempMap.m_nDexNumPBlock / 2 ? 1 : 0)) ; + TempMap.m_nFracLin[1] = max( 1u, + TempMap.m_nNy[0] / TempMap.m_nDexNumPBlock + + ( TempMap.m_nNy[0] % TempMap.m_nDexNumPBlock >= TempMap.m_nDexNumPBlock / 2 ? 1 : 0)) ; + + // Se vi sono tre griglie definisco il numero di blocchi lungo z + if ( TempMap.m_nMapNum > 1) + TempMap.m_nFracLin[2] = max( 1u, + TempMap.m_nNy[1] / TempMap.m_nDexNumPBlock + + ( TempMap.m_nNy[1] % TempMap.m_nDexNumPBlock >= TempMap.m_nDexNumPBlock / 2 ? 1 : 0)) ; + + // Sistema di riferimento + Point3d ptNewO( dNewOx, dNewOy, dNewOz) ; + TempMap.m_MapFrame[0].Set( ptNewO, X_AX, Y_AX, Z_AX) ; + + if ( TempMap.m_nMapNum > 1) { + + TempMap.m_MapFrame[1].Set( ptNewO, Y_AX, Z_AX, X_AX) ; + TempMap.m_MapFrame[2].Set( ptNewO, Z_AX, X_AX, Y_AX) ; + } + + vMap.emplace_back( TempMap) ; + } + return true ; +#endif +} diff --git a/VolZmap.h b/VolZmap.h index d7772fa..d9b6551 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -23,6 +23,7 @@ #include "/EgtDev/Include/ENkPolynomialRoots.h" #include "/EgtDev/Include/EgkIntersLinesurfTm.h" #include +#include //---------------------------------------------------------------------------- struct TriaStruct { @@ -81,6 +82,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dPrec, bool bTriDex) override ; bool GetAllTriangles( TRIA3DLIST& lstTria) const override ; int GetBlockCount( void) const override ; + int GetPartCount( void) const override ; bool GetTriangles( bool bAllBlocks, INTVECTOR& nModifiedBlocks, TRIA3DLISTVECTOR& vLstTria) const override ; bool GetDexelLines( int nDir, int nPos1, int nPos2, POLYLINELIST& lstPL) const override ; bool SetTolerances( double dLinTol, double dAngTolDeg = 90) override ; @@ -92,8 +94,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool SetChiselTool( const std::string& sToolName, double dH, double dW, double dTh) override ; bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Point3d& ptPe, const Vector3d& vtDe) override ; bool MillingStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs, const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) override ; - bool GetDepth( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) override ; - bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) override ; + bool GetDepth( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) const override ; + bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag) const override ; + VolZmap* ClonePart( int nPart) const override ; public : // IGeoObjRW virtual int GetNgeId( void) const ; @@ -228,11 +231,11 @@ class VolZmap : public IVolZmap, public IGeoObjRW // Intersezioni 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 IntersLineZMapBBox( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, double& dU1, double& dU2) const ; bool IntersLineDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ, - double& dU1, double& dU2) ; + double& dU1, double& dU2) const ; bool IntersRayDexel( const Point3d& ptP, const Vector3d& vtV, unsigned int nGrid, unsigned int nI, unsigned int nJ, - double& dU1, double& dU2) ; + double& dU1, double& dU2) const ; bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir, const Frame3d& CylFrame, double dL, double dR, Point3d& ptInt1, Point3d& ptInt2, Vector3d& vtN1, Vector3d& vtN2, @@ -272,9 +275,17 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool ProcessVoxContXZ( VoxelContainer& VoxContXZ, bool bPlus, TRIA3DLIST& lstTria) const ; bool Find( const VoxelContainer& VoxCont, int nI, int nJ, int nK, double dPos) const ; bool Remove( VoxelContainer& VoxCont, int nI, int nJ, int nK) const ; - // Connessione Zmap - bool IsMapConnected( void) ; + struct IntervalIndexes { + size_t tMap ; + size_t tDex ; + size_t tInt ; + } ; + typedef std::stack IntContaier ; + bool CheckMapConnection( void) ; + bool ExpandFromXInterval( IntContaier& IntCont) ; + bool ExpandFromYInterval( IntContaier& IntCont) ; + bool ExpandFromZInterval( IntContaier& IntCont) ; private : enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;