diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index ed92303..6633396 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -2711,8 +2711,8 @@ GdbExecutor::ExecuteVolZmap( const string& sCmd2, const STRVECTOR& vsParams) else if ( sCmd2 == "COMP") { return ExecuteVolZmapCompact( vsParams) ; } - else if ( sCmd2 == "CHAIN") { - return ExecuteVolZmapChain( vsParams) ; + else if ( sCmd2 == "EDGES") { + return ExecuteVolZmapEdges( vsParams) ; } return false ; } @@ -3072,7 +3072,7 @@ GdbExecutor::ExecuteVolZmapCompact( const STRVECTOR& vsParams) //---------------------------------------------------------------------------- bool -GdbExecutor::ExecuteVolZmapChain(const STRVECTOR& vsParams) +GdbExecutor::ExecuteVolZmapEdges(const STRVECTOR& vsParams) { // Parametri : ZmapId, ParentId if ( vsParams.size() != 2) @@ -3087,7 +3087,7 @@ GdbExecutor::ExecuteVolZmapChain(const STRVECTOR& vsParams) if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frRef)) return false ; ICURVEPOVECTOR vpLoop ; - pZmap->GetFeatureChaines( vpLoop) ; + pZmap->GetEdges( vpLoop) ; bool bOk = true ; for ( int n = 0 ; n < int( vpLoop.size()) && bOk ; ++ n) { bOk = bOk && AddGeoObj( "$NN", vsParams[1], Release( vpLoop[n])) ; diff --git a/GdbExecutor.h b/GdbExecutor.h index c688d06..bd6d0a7 100644 --- a/GdbExecutor.h +++ b/GdbExecutor.h @@ -129,7 +129,7 @@ class GdbExecutor : public IGdbExecutor //bool VolZmapBBoxZmapIntersection( const STRVECTOR& vsParams) ; bool ExecuteVolZmapCut( const STRVECTOR& vsParams) ; bool ExecuteVolZmapCompact( const STRVECTOR& vsParams) ; - bool ExecuteVolZmapChain( const STRVECTOR& vsParams) ; + bool ExecuteVolZmapEdges( const STRVECTOR& vsParams) ; bool ExecuteIntersection( const std::string& sCmd2, const STRVECTOR& vsParams) ; bool LineDiscInters( const STRVECTOR& vsParams) ; bool RayDiscInters( const STRVECTOR& vsParams) ; diff --git a/VolZmap.h b/VolZmap.h index c410039..50cbd5f 100644 --- a/VolZmap.h +++ b/VolZmap.h @@ -71,6 +71,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW int GetBlockCount( void) const override ; int GetBlockUpdatingCounter( int nBlock) const override ; bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ; + bool GetEdges( ICURVEPOVECTOR& vpCurve) const override ; bool GetVolume( double& dVol) const override ; int GetPartCount( void) const override ; bool GetPartVolume( int nPart, double& dVol) const override ; @@ -93,7 +94,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW bool GetDepth( const Point3d& ptP, const Vector3d& vtD, double& dInLength, double& dOutLength, bool bExact) const override ; bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const override ; bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const override ; - bool GetFeatureChaines( ICURVEPOVECTOR& vpCurve) const ; bool AvoidBox( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist) const override ; bool AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist) const override ; bool AvoidCylinder( const Frame3d& frCyl, double dH, double dR, double dSafeDist) const override ; diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index 121876a..05209e8 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -1026,8 +1026,8 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const // Ciclo su tutti i voxel del blocco for ( int i = nLimits[0] ; i < nLimits[1] ; ++ i) { for ( int j = nLimits[2] ; j < nLimits[3] ; ++ j) { - for ( int k = nLimits[4] ; k < nLimits[5] ; ++ k) { - + for ( int k = nLimits[4] ; k < nLimits[5] ; ++ k) { + if ( m_nShape == BOX && ! IsVoxelOnBoxEdge( i, j, k)) continue ; // Classificazione dei vertici: interni o esterni al materiale @@ -2599,7 +2599,11 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel) c CurrTri.SetGrade( 0) ; // Setto le normali a ogni vertice CurrTri.SetVertexNorm( 1, it->second.Compo[nComp].CompVecField[nNextVert].vtVec) ; - CurrTri.SetVertexNorm( 2, it->second.Compo[nComp].CompVecField[nVert].vtVec) ; + CurrTri.SetVertexNorm( 2, it->second.Compo[nComp].CompVecField[nVert].vtVec) ; + // Setto i flag a false + CurrTri.SetEdgeFlag( 0, false) ; + CurrTri.SetEdgeFlag( 1, false) ; + CurrTri.SetEdgeFlag( 2, false) ; // Valido il triangolo if ( ! CurrTri.Validate( true)) CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) + CurrTri.GetVertexNorm( 2))) ; @@ -2661,8 +2665,12 @@ VolZmap::CreateSharpFeatureTriangle( int nBlock, const VoxelContainer& vVoxel) c // Setto le normali a ogni vertice CurrTri.SetVertexNorm( 1, itVox->second.Compo[nComp].CompVecField[nNextVert].vtVec) ; CurrTri.SetVertexNorm( 2, itVox->second.Compo[nComp].CompVecField[nVert].vtVec) ; + // Setto i flag a false + CurrTri.SetEdgeFlag( 0, false) ; + CurrTri.SetEdgeFlag( 1, false) ; + CurrTri.SetEdgeFlag( 2, false) ; // Valido il triangolo - if ( ! CurrTri.Validate(true)) + if ( ! CurrTri.Validate( true)) CurrTri.SetVertexNorm( 0, 0.5 * ( CurrTri.GetVertexNorm( 1) + CurrTri.GetVertexNorm( 2))); // Smisto i triangoli fra di frontiera e interni bool bTriOnBorder = IsTriangleOnBorder( CurrTri, nLimits, nVoxIJK) ; @@ -2917,6 +2925,13 @@ VolZmap::FlipEdgesII( int nBlock) const vTria1[nTri1].SetVertexNorm( 1, V_NULL) ; vTria2[nTri2].SetVertexNorm( 0, V_NULL) ; vTria2[nTri2].SetVertexNorm( 1, V_NULL) ; + // Valido i triangoli + vTria1[nTri1].Validate( true) ; + vTria2[nTri2].Validate( true) ; + // Setto i bFlags + if ( ! AreSameVectorApprox( vTria1[nTri1].GetN(), vTria2[nTri2].GetN())) { + vTria1[nTri1].SetEdgeFlag( 0, true) ; + } // Setto i triangoli come flippati SharpTria1.vbFlipped[nCompo1][nTri1] = true ; SharpTria2.vbFlipped[nCompo2][nTri2] = true ; @@ -2961,6 +2976,19 @@ VolZmap::FlipEdgesII( int nBlock) const // Assegno il colore ai triangoli vTria1[nTri1].SetGrade( nCol) ; vTria2[nTri2].SetGrade( nCol) ; + // Setto i flag dei vertici + double dDist02 = ( vTria1[nTri1].GetP( 0) - vTria1[nTri1].GetP( 2)).Len() + + ( vTria2[nTri2].GetP( 1) - vTria2[nTri2].GetP( 0)).Len() ; + double dDist20 = ( vTria1[nTri1].GetP( 1) - vTria1[nTri1].GetP( 0)).Len() + + ( vTria2[nTri2].GetP( 0) - vTria2[nTri2].GetP( 2)).Len() ; + if ( dDist02 > dDist20) { + vTria1[nTri1].SetEdgeFlag( 0, true) ; + vTria2[nTri2].SetEdgeFlag( 2, true) ; + } + else { + vTria1[nTri1].SetEdgeFlag( 2, true) ; + vTria2[nTri2].SetEdgeFlag( 0, true) ; + } } } } @@ -3182,6 +3210,14 @@ VolZmap::FlipEdgesBB() const m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetVertexNorm( 0, vtNormF) ; m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 1, vtNormL) ; m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetVertexNorm( 0, vtNormL) ; + // Valido i triangoli + m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].Validate( true) ; + m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].Validate( true) ; + // Setto i bFlags + if ( ! AreSameVectorApprox( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetN(), + m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetN())) { + m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetEdgeFlag( 0, true) ; + } // Setto i triangoli come flippati m_InterBlockSharpTria[tFB][tVFB].vbFlipped[tCmpF][tTriFB] = true ; m_InterBlockSharpTria[tLB][tVLB].vbFlipped[tCmpL][tTriLB] = true ; @@ -3229,6 +3265,23 @@ VolZmap::FlipEdgesBB() const // Assegno il colore ai triangoli m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetGrade( nCol) ; m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetGrade( nCol) ; + // Setto i flag dei vertici + double dDist02 = ( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 0) - + m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 2)).Len() + + ( m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 1) - + m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 0)).Len() ; + double dDist20 = ( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) - + m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 0)).Len() + + ( m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 0) - + m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 2)).Len() ; + if ( dDist02 > dDist20) { + m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetEdgeFlag( 0, true) ; + m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetEdgeFlag( 2, true) ; + } + else { + m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].SetEdgeFlag( 2, true) ; + m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].SetEdgeFlag( 0, true) ; + } } } } @@ -4457,181 +4510,134 @@ VolZmap::Remove( FlatVoxelContainer& VoxCont, int nI, int nJ, int nK) const //---------------------------------------------------------------------------- bool -VolZmap::GetFeatureChaines( ICURVEPOVECTOR& vpCurve) const +VolZmap::GetEdges( ICURVEPOVECTOR& vpCurve) const { // Garantisco grafica aggiornata UpdateTripleMapGraphics() ; - // Vettore delle curve di feature - vector vLine ; + // Vettore dei segmenti di feature (coppie di punti) + BIPNTVECTOR vBpt ; // Ciclo sui triangoli feature all'interno dei blocchi for ( int nBlock = 0 ; nBlock < m_nNumBlock ; ++ nBlock) { // Numero di voxel in cui si presentano sharp feature - int nVoxelNum = int( m_BlockSharpTria[nBlock].size()) ; + int nVoxelNum = int( m_BlockSharpTria[nBlock].size()) ; // Ciclo sui voxel con sharp feature - for ( int n1 = 0 ; n1 < nVoxelNum ; ++ n1) { - const SharpTriaStruct& SharpTria1 = m_BlockSharpTria[nBlock][n1] ; - for ( int n2 = n1 ; n2 < nVoxelNum ; ++ n2) { - const SharpTriaStruct& SharpTria2 = m_BlockSharpTria[nBlock][n2] ; - // Se non adiacenti o coincidenti vado oltre - if ( abs( SharpTria2.i - SharpTria1.i) > 1 || - abs( SharpTria2.j - SharpTria1.j) > 1 || - abs( SharpTria2.k - SharpTria1.k) > 1) - continue ; - // Ciclo sulle componenti connesse del primo voxel - int nNumCompo1 = int( SharpTria1.ptCompoVert.size()) ; - for ( int nCompo1 = 0 ; nCompo1 < nNumCompo1 ; ++ nCompo1) { - const TRIA3DEXVECTOR& vTria1 = SharpTria1.vCompoTria[nCompo1] ; - // Numero di triangoli della componente connessa - int nTriNum1 = int( vTria1.size()) ; - // Ciclo sulle componenti connesse del secondo voxel - int nNumCompo2 = int( SharpTria2.ptCompoVert.size()) ; - int nCompo2 = ( n1 == n2 ? nCompo1 + 1 : 0) ; - for ( ; nCompo2 < nNumCompo2 ; ++ nCompo2) { - const TRIA3DEXVECTOR& vTria2 = SharpTria2.vCompoTria[nCompo2] ; - // Numero di triangoli della componente connessa - int nTriNum2 = int( vTria2.size()) ; - for ( int nTri1 = 0 ; nTri1 < nTriNum1 ; ++ nTri1) { - for ( int nTri2 = 0 ; nTri2 < nTriNum2 ; ++ nTri2) { - // Punti che devono essere in comune fra i due triangoli - const Point3d& ptP10 = vTria1[nTri1].GetP( 0) ; - const Point3d& ptP11 = vTria1[nTri1].GetP( 1) ; - const Point3d& ptP20 = vTria2[nTri2].GetP( 0) ; - const Point3d& ptP21 = vTria2[nTri2].GetP( 1) ; - // I triangoli sono sono stati flippati - if ( AreSamePointEpsilon( ptP10, ptP21, EPS_ZERO) && - AreSamePointEpsilon( ptP11, ptP20, EPS_ZERO) && - ! AreSameVectorApprox( vTria1[nTri1].GetN(), vTria2[nTri2].GetN())) { - // Segmento che congiunge le sharp-features - CurveComposite cvLine ; - if ( cvLine.AddPoint( ptP10) && cvLine.AddLine( ptP11)) - vLine.emplace_back( cvLine) ; - } - } - } + for ( int n = 0 ; n < nVoxelNum ; ++ n) { + const SharpTriaStruct& SharpTria = m_BlockSharpTria[nBlock][n] ; + // Ciclo sulle componenti connesse del voxel + int nNumCompo = int( SharpTria.ptCompoVert.size()) ; + for ( int nCompo = 0 ; nCompo < nNumCompo ; ++ nCompo) { + const TRIA3DEXVECTOR& vTria = SharpTria.vCompoTria[nCompo] ; + // Numero di triangoli della componente connessa + int nTriNum = int( vTria.size()) ; + for ( int nTri = 0 ; nTri < nTriNum ; ++ nTri) { + // Il triangolo ha un lato sulla sharp-feature + if ( vTria[nTri].GetEdgeFlag( 0)) { + const Point3d& ptPS = vTria[nTri].GetP( 0) ; + const Point3d& ptPE = vTria[nTri].GetP( 1) ; + // Segmento sharp-feature + vBpt.emplace_back( ptPS, ptPE) ; } - } - } + else if ( vTria[nTri].GetEdgeFlag( 1)) { + const Point3d& ptPS = vTria[nTri].GetP( 1) ; + const Point3d& ptPE = vTria[nTri].GetP( 2) ; + // Segmento sharp-feature + vBpt.emplace_back( ptPS, ptPE) ; + } + else if ( vTria[nTri].GetEdgeFlag( 2)) { + const Point3d& ptPS = vTria[nTri].GetP( 2) ; + const Point3d& ptPE = vTria[nTri].GetP( 0) ; + // Segmento sharp-feature + vBpt.emplace_back( ptPS, ptPE) ; + } + } + } } } // Ciclo sui triangoli feature al confine tra blocchi - for ( int tFB = 0 ; tFB < m_nNumBlock ; ++ tFB) { - int nFBijk[3] ; - GetBlockIJKFromN( int( tFB), nFBijk) ; - for ( int tLB = tFB ; tLB < m_nNumBlock ; ++ tLB) { - int nLBijk[3] ; - GetBlockIJKFromN( int( tLB), nLBijk) ; - // Se i blocchi non sono adiacenti salto l'iterazione - if ( abs( nFBijk[0] - nLBijk[0]) > 1 || - abs( nFBijk[1] - nLBijk[1]) > 1 || - abs( nFBijk[2] - nLBijk[2]) > 1) - continue ; - // Numero di voxel nei blocchi correnti - int nVoxelNumFB = int( m_InterBlockSharpTria[tFB].size()) ; - int nVoxelNumLB = int( m_InterBlockSharpTria[tLB].size()) ; - // Ciclo sui voxel dei due blocchi - for ( int tVFB = 0 ; tVFB < nVoxelNumFB ; ++ tVFB) { - for ( int tVLB = 0 ; tVLB < nVoxelNumLB ; ++ tVLB) { - // Se i voxel non sono adiacenti salto l'iterazione - if ( abs( m_InterBlockSharpTria[tFB][tVFB].i - m_InterBlockSharpTria[tLB][tVLB].i) > 1 || - abs( m_InterBlockSharpTria[tFB][tVFB].j - m_InterBlockSharpTria[tLB][tVLB].j) > 1 || - abs( m_InterBlockSharpTria[tFB][tVFB].k - m_InterBlockSharpTria[tLB][tVLB].k) > 1) - continue ; - // Numero di componenti connesse dei voxel - int nCompoVFBNum = int( m_InterBlockSharpTria[tFB][tVFB].ptCompoVert.size()) ; - int nCompoVLBNum = int( m_InterBlockSharpTria[tLB][tVLB].ptCompoVert.size()) ; - // Ciclo sulle componenti connesse - for ( int tCmpF = 0 ; tCmpF < nCompoVFBNum ; ++ tCmpF) { - for ( int tCmpL = 0 ; tCmpL < nCompoVLBNum ; ++ tCmpL) { - // Numero di triangoli delle componenti connesse - int nTriFBNum = int( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF].size()) ; - int nTriLBNum = int( m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL].size()) ; - // Ciclo sui triangoli - for ( int tTriFB = 0 ; tTriFB < nTriFBNum ; ++ tTriFB) { - for ( int tTriLB = 0 ; tTriLB < nTriLBNum ; ++ tTriLB) { - // Punti che devono essere in comune fra i due triangoli - Point3d ptPF0 = m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 0) ; - Point3d ptPF1 = m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetP( 1) ; - Point3d ptPL0 = m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 0) ; - Point3d ptPL1 = m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetP( 1) ; - // I triangoli sono stati flippati - if ( AreSamePointEpsilon( ptPF0, ptPL1, EPS_ZERO) && - AreSamePointEpsilon( ptPF1, ptPL0, EPS_ZERO) && - ! AreSameVectorApprox( m_InterBlockSharpTria[tFB][tVFB].vCompoTria[tCmpF][tTriFB].GetN(), - m_InterBlockSharpTria[tLB][tVLB].vCompoTria[tCmpL][tTriLB].GetN())) { - // Segmento che congiunge le sharp-features - CurveComposite cvLine ; - if ( cvLine.AddPoint( ptPF0) && cvLine.AddLine( ptPF1)) - vLine.emplace_back( cvLine) ; - } - } - } - } + for ( int tB = 0 ; tB < m_nNumBlock ; ++ tB) { + // Numero di voxel nel blocco corrente + int nVoxelNum = int( m_InterBlockSharpTria[tB].size()) ; + // Ciclo sui voxel del blocco + for ( int tV = 0 ; tV < nVoxelNum ; ++ tV) { + // Numero di componenti connesse del voxel + int nCompoNum = int( m_InterBlockSharpTria[tB][tV].ptCompoVert.size()) ; + // Ciclo sulle componenti connesse + for ( int tC = 0 ; tC < nCompoNum ; ++ tC) { + // Numero di triangoli della componente connessa + int nTriNum = int( m_InterBlockSharpTria[tB][tV].vCompoTria[tC].size()) ; + // Ciclo sui triangoli + for ( int tT = 0 ; tT < nTriNum ; ++ tT) { + // Il triangolo ha un lato sulla sharp-feature + if ( m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetEdgeFlag( 0)) { + const Point3d& ptPS = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 0) ; + const Point3d& ptPE = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 1) ; + // Segmento sharp-feature + vBpt.emplace_back( ptPS, ptPE) ; } - } + else if ( m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetEdgeFlag( 1)) { + const Point3d& ptPS = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 1) ; + const Point3d& ptPE = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 2) ; + // Segmento sharp-feature + vBpt.emplace_back( ptPS, ptPE) ; + } + else if ( m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetEdgeFlag( 2)) { + const Point3d& ptPS = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 2) ; + const Point3d& ptPE = m_InterBlockSharpTria[tB][tV].vCompoTria[tC][tT].GetP( 0) ; + // Segmento sharp-feature + vBpt.emplace_back( ptPS, ptPE) ; + } + } } } } - - // Creo le curve - for ( int n = 0 ; n < int( vLine.size()) ; ++ n) { - bool bExpanded = false ; - int nNumSt = 0 ; - int nNumEn = 0 ; - int nMSt = - 1 ; - int nMEn = - 1 ; - Point3d ptSt, ptEn ; - vLine[n].GetStartPoint( ptSt) ; - vLine[n].GetEndPoint( ptEn) ; - for ( int m = 0 ; m < int( vLine.size()) ; ++ m) { - if ( m == n) - continue ; - Point3d ptStM, ptEnM ; - vLine[m].GetStartPoint( ptStM) ; - vLine[m].GetEndPoint( ptEnM) ; - if ( AreSamePointEpsilon( ptSt, ptStM, 100 * EPS_SMALL) || AreSamePointEpsilon( ptSt, ptEnM, 100 * EPS_SMALL)) { - nMSt = m ; - ++ nNumSt ; - } - if ( AreSamePointEpsilon( ptEn, ptStM, 100 * EPS_SMALL) || AreSamePointEpsilon( ptEn, ptEnM, 100 * EPS_SMALL)) { - nMEn = m ; - ++ nNumEn ; - } + + // Concateno le curve rispettando le biforcazioni + const double dToler = 20 * EPS_SMALL ; + ChainCurves chainC ; + chainC.Init( true, dToler, int( vBpt.size())) ; + for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) { + Vector3d vtDir = vBpt[i].second - vBpt[i].first ; + vtDir.Normalize() ; + if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir)) + return false ; + } + // recupero i percorsi concatenati + Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ; + INTVECTOR vId ; + while ( chainC.GetChainFromNear( ptNear, true, vId)) { + // creo una curva composita + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo)) + return false ; + // recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita + for ( int i = 0 ; i < int( vId.size()) ; ++ i) { + // creo un segmento di retta + int nInd = abs( vId[i]) - 1 ; + bool bInvert = ( vId[i] < 0) ; + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine) || ! pLine->Set( vBpt[nInd].first, vBpt[nInd].second)) + return false ; + if ( bInvert) + pLine->Invert() ; + // lo accodo alla composita + if ( ! pCrvCompo->AddCurve( Release( pLine), true, 1.1 * dToler) && + ! AreSamePointApprox( ptNear, ( bInvert ? vBpt[nInd].first : vBpt[nInd].second))) + return false ; + // aggiorno il prossimo near + ptNear = ( bInvert ? vBpt[nInd].first : vBpt[nInd].second) ; } - if ( nNumSt == 1) { - Point3d ptStM ; - vLine[nMSt].GetStartPoint( ptStM) ; - if ( AreSamePointEpsilon( ptSt, ptStM, 100 * EPS_SMALL)) - vLine[nMSt].Invert() ; - bool bAdded = vLine[n].AddCurve( vLine[nMSt], false) ; - vLine.erase( vLine.begin() + nMSt) ; - bExpanded = true ; - } - else if ( nNumEn == 1) { - Point3d ptEnM ; - vLine[nMEn].GetEndPoint( ptEnM) ; - if ( AreSamePointEpsilon( ptEn, ptEnM, 100 * EPS_SMALL)) - vLine[nMEn].Invert() ; - bool bAdded = vLine[n].AddCurve( vLine[nMEn]) ; - vLine.erase( vLine.begin() + nMEn) ; - bExpanded = true ; - } - if ( bExpanded) - -- n ; - nMSt = - 1 ; - nMEn = - 1 ; + // se lunghezza curva inferiore a 5 volte la tolleranza, la salto + double dCrvLen ; + if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5 * dToler) + continue ; + // unisco segmenti allineati + pCrvCompo->MergeCurves( dToler, ANG_TOL_STD_DEG) ; + // la salvo + vpCurve.emplace_back( Release( pCrvCompo)) ; } - for ( int n = 0 ; n < int( vLine.size()) ; ++ n) { - PtrOwner pCurve( vLine[n].Clone()) ; - if ( IsNull( pCurve)) - return false ; - pCurve->MergeCurves( EPS_SMALL, ANG_TOL_STD_DEG) ; - // Inserisco la curva composita nella raccolta da ritornare - vpCurve.emplace_back( Release( pCurve)) ; - } - return true ; }