diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index b310e6e..0aefca9 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/GeoConst.h b/GeoConst.h index 30c8a3f..2c1726d 100644 --- a/GeoConst.h +++ b/GeoConst.h @@ -49,7 +49,7 @@ const double BEZARC_ANG_CEN_MAX = 90 ; //----------------- Costanti per superfici TriMesh --------------------------- // tolleranza lineare standard -const double STM_STD_LIN_TOL = 0.1 ; +const double STM_STD_LIN_TOL = EPS_SMALL/*0.1*/ ; // angolo limite per definire un edge che è contorno di poligono const double STM_STD_BOUNDARY_ANG = 0.1 ; // angolo limite per mediare le normali in un vertice diff --git a/OffsetCurve.cpp b/OffsetCurve.cpp index 69ed9e1..e67f5ac 100644 --- a/OffsetCurve.cpp +++ b/OffsetCurve.cpp @@ -178,17 +178,25 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) if ( IsNull( pCrv1)) return false ; pCrv1->SetTempProp( nInd1) ; - if ( ! pCrv1->SimpleOffset( dDist, ICurve::OFF_FILLET) && - GetBasicCurveArc( pCrv1)->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET)) - pCrv1->SetTempProp( - nInd1) ; + if ( ! pCrv1->SimpleOffset( dDist, ICurve::OFF_FILLET)) { + CurveArc* pArc = GetBasicCurveArc( pCrv1) ; + if ( pArc == nullptr) + return false ; + if ( pArc->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET)) + pCrv1->SetTempProp( - nInd1) ; + } // curve successive PtrOwner pCrv2( ccCopy2.RemoveFirstOrLastCurve( false)) ; while ( ! IsNull( pCrv2)) { // eseguo semplice offset pCrv2->SetTempProp( nInd1 + 1) ; - if ( ! pCrv2->SimpleOffset( dDist, ICurve::OFF_FILLET) && - GetBasicCurveArc( pCrv2)->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET)) - pCrv2->SetTempProp( - (nInd1 + 1)) ; + if ( ! pCrv2->SimpleOffset( dDist, ICurve::OFF_FILLET)) { + CurveArc* pArc = GetBasicCurveArc( pCrv2) ; + if ( pArc == nullptr) + return false ; + if ( pArc->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET)) + pCrv2->SetTempProp( - ( nInd1 + 1)) ; + } // verifico relazione con la curva precedente e aggiungo eventuali curve intermedie CurveComposite ccTemp ; bool bOk = VerifyAndAdjustExternalAngle( pCrv1, pCrv2, vAngs[nInd1], dDist, ICurve::OFF_FILLET, ccTemp) ; diff --git a/PolyLine.cpp b/PolyLine.cpp index 88c31ca..4875cf9 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -22,6 +22,8 @@ #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkPlane3d.h" #include "/EgtDev/Include/EGnStringUtils.h" +#include "/EgtDev/Include/EgtNumUtils.h" +#include "/EgtDev/Include/EGkPolygon3d.h" using namespace std ; @@ -1296,3 +1298,324 @@ PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut) return true ; } + +//---------------------------------------------------------------------------- +/*static*/ bool +ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop, double dTol) +{ + // Rinomino la lista di punti della PolyLine. + PNTULIST& LoopList = Loop.GetUPointList() ; + // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso più vicino al punto. + double dMinSqDist = DBL_MAX ; + auto itMinDist = LoopList.end() ; + auto itSt = LoopList.begin() ; + auto itEn = itSt ; + ++ itEn ; + for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn) { + // Estremi del segmento corrente del loop + Point3d ptSegSt = itSt->first ; + Point3d ptSegEn = itEn->first ; + // Distanza del punto dal segmento del loop + DistPointLine dDistCalc( ptNewStart, ptSegSt, ptSegEn) ; + double dSqDist ; + dDistCalc.GetSqDist( dSqDist) ; + if ( dSqDist < dMinSqDist) { + dMinSqDist = dSqDist ; + itMinDist = itSt ; + } + } + // Se il punto non sta sul loop, errore + if ( dMinSqDist > dTol * dTol) + return false ; + // Se il punto non sta su un vertice del segmento, lo aggiungo. Altrimenti non devo fare nulla. + auto itNewPointSt = LoopList.begin() ; + auto itNext = itMinDist ; + ++ itNext ; + bool bOnStart = AreSamePointApprox( ptNewStart, itMinDist->first) ; + bool bOnEnd = AreSamePointApprox( ptNewStart, itNext->first) ; + itNewPointSt = LoopList.emplace( itNext, ptNewStart, 0) ; + // Sposto i punti precedenti in coda. + bool bStartRemoved = false ; + auto it = LoopList.begin() ; + while ( it != itNewPointSt) { + if ( bStartRemoved) { + LoopList.emplace_back( it->first, it->second) ; + } + bStartRemoved = true ; + it = LoopList.erase( it) ; + } + // Se il punto inserito non coincide con l'inizio del segmento chiudo il loop. + if ( ! bOnStart) { + LoopList.emplace_back( ptNewStart, 0) ; + // Se coincide con la fine tolgo il punto di fine che diviene inutile. + if ( bOnEnd) { + //LoopList.erase( itNext) ; + auto itNewStart = LoopList.begin() ; + ++ itNewStart ; + LoopList.erase( itNewStart) ; + } + } + + return true ; +} + +//---------------------------------------------------------------------------- +// nSegNum 0-based +/*static*/ bool +PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& nSegNum, double& dParOnSeg, double dTol) +{ + // Rinomino la lista di punti della PolyLine. + /*const*/ PNTULIST& LoopList = Loop.GetUPointList() ; + // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso più vicino al punto. + nSegNum = - 1 ; + double dMinSqDist = DBL_MAX ; + int nS = 0 ; + auto itMinDistSt = LoopList.end() ; + auto itMinDistEn = itMinDistSt ; + auto itSt = LoopList.begin() ; + auto itEn = itSt ; + ++ itEn ; + for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn, ++ nS) { + // Estremi del segmento corrente del loop + Point3d ptSegSt = itSt->first ; + Point3d ptSegEn = itEn->first ; + // Distanza del punto dal segmento del loop + DistPointLine dDistCalc( ptPoint, ptSegSt, ptSegEn) ; + double dSqDist ; + dDistCalc.GetSqDist( dSqDist) ; + if ( dSqDist < dMinSqDist) { + nSegNum = nS ; + dMinSqDist = dSqDist ; + itMinDistSt = itSt ; + itMinDistEn = itEn ; + } + } + // Se il punto non sta sul loop, lo segnalo. + if ( dMinSqDist > dTol * dTol) + return false ; + // Calcolo il parametro lungo il segmento. + Vector3d vtSeg = itMinDistEn->first - itMinDistSt->first ; + double dSegLen = vtSeg.Len() ; + if ( dSegLen < EPS_SMALL) + return false ; + vtSeg /= dSegLen ; + dParOnSeg = Clamp( ( ptPoint - itMinDistSt->first) * vtSeg, 0., dSegLen) ; + return true ; +} + +//---------------------------------------------------------------------------- +/*static*/ bool +IsPointInsidePolyLine( const Point3d& ptP, /*const*/ PolyLine& plPoly) +{ + // Se la PolyLine non è chiusa, il punto non può essere interno. + if ( ! plPoly.IsClosed()) + return false ; + // Lista dei punti + /*const*/ PNTULIST& List = plPoly.GetUPointList() ; + // Ciclo sui segmenti della PolyLine per cercarne il tratto più vicino al punto. + double dMinSqDist = DBL_MAX ; + Point3d ptMinDist ; + auto itMinDistSt = List.end() ; + auto itSt = List.begin() ; + auto itEn = itSt ; + ++ itEn ; + for ( ; itSt != List.end() && itEn != List.end() ; ++ itSt, ++ itEn) { + // Estremi del segmento corrente del loop + Point3d ptSegSt = itSt->first ; + Point3d ptSegEn = itEn->first ; + // Distanza del punto dal segmento del loop + DistPointLine dDistCalc( ptP, ptSegSt, ptSegEn) ; + double dSqDist ; + dDistCalc.GetSqDist( dSqDist) ; + if ( dSqDist < dMinSqDist) { + dMinSqDist = dSqDist ; + dDistCalc.GetMinDistPoint( ptMinDist) ; + itMinDistSt = itSt ; + } + } + // Termine del segmento di minima distanza. + auto itMinDistEn = itMinDistSt ; + ++ itMinDistEn ; + // Punto di minima distanza nell'estremo iniziale del segento + if ( AreSamePointApprox( ptMinDist, itMinDistSt->first)) { + auto itPrevSt = List.begin() ; + if ( itMinDistSt == List.begin()) { + auto itAuxNext = itPrevSt ; + ++ ( ++ itAuxNext) ; + for ( ; itAuxNext != List.end() ; ++ itPrevSt, ++ itAuxNext) + ; + } + else { + auto itAuxNext = itPrevSt ; + ++ itAuxNext ; + for (; itAuxNext != itMinDistSt; ++itPrevSt, ++itAuxNext) + ; + } + Vector3d vtPrevTan = itMinDistSt->first - itPrevSt->first ; + vtPrevTan.Normalize() ; + Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; + vtTan.Normalize() ; + Polygon3d AuxPolygon ; + AuxPolygon.FromPolyLine( plPoly) ; + Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; + Vector3d vtPrevOut = vtPrevTan ^ vtPolyNorm ; + Vector3d vtOut = vtTan ^ vtPolyNorm ; + // Caso concavo + if ( vtTan * vtPrevOut > 0) { + Vector3d vtTest = ptP - ptMinDist ; + if ( vtTest * vtPrevOut < 0 || vtTest * vtOut < 0) + return true ; + } + // Caso convesso + else { + Vector3d vtTest = ptP - ptMinDist ; + if ( vtTest * vtPrevOut < 0 && vtTest * vtOut < 0) + return true ; + } + } + // Punto di minima distanza nell'estremo finale del segento + else if ( AreSamePointApprox( ptMinDist, itMinDistEn->first)) { + auto itNextEn = itMinDistEn ; + ++ itNextEn ; + if ( itNextEn == List.end()) { + itNextEn = List.begin() ; + ++ itNextEn ; + } + Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; + vtTan.Normalize() ; + Vector3d vtNextTan = itNextEn->first - itMinDistEn->first ; + vtNextTan.Normalize() ; + Polygon3d AuxPolygon ; + AuxPolygon.FromPolyLine( plPoly) ; + Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; + Vector3d vtOut = vtTan ^ vtPolyNorm ; + Vector3d vtNextOut = vtNextTan ^ vtPolyNorm ; + // Caso concavo + if ( vtNextTan * vtOut > 0) { + Vector3d vtTest = ptP - ptMinDist ; + if ( vtTest * vtOut < 0 || vtTest * vtNextOut < 0) + return true ; + } + // Caso convesso + else { + Vector3d vtTest = ptP - ptMinDist ; + if ( vtTest * vtOut < 0 && vtTest * vtNextOut < 0) + return true ; + } + } + // Punto di minima distanza interno al segmeno + else { + Vector3d vtP = ptP - itMinDistSt->first ; + Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; + vtTan.Normalize() ; + Polygon3d AuxPolygon ; + AuxPolygon.FromPolyLine( plPoly) ; + Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; + Vector3d vtOut = vtTan ^ vtPolyNorm ; + vtP -= ( vtP * vtTan) * vtTan ; + if ( vtP * vtOut < - EPS_SMALL) + return true ; + } + return false ; +} + +//---------------------------------------------------------------------------- +bool +DistPointPolyLine( const Point3d& ptP, const PolyLine& plPoly, double& dPointPolyLineDist) +{ + if ( plPoly.GetPointNbr() == 0) + return false ; + dPointPolyLineDist = DBL_MAX ; + Point3d ptSt, ptEn ; + bool bContinue = plPoly.GetFirstPoint( ptSt) && plPoly.GetNextPoint( ptEn) ; + while ( bContinue) { + double dPoinLineDist ; + DistPointLine PointLineDistCalc( ptP, ptSt, ptEn) ; + PointLineDistCalc.GetDist( dPoinLineDist) ; + if ( dPoinLineDist < dPointPolyLineDist) + dPointPolyLineDist = dPoinLineDist ; + ptSt = ptEn ; + bContinue = plPoly.GetNextPoint( ptEn) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +/*static*/ bool +SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine& Loop1, PolyLine& Loop2, double dTol) +{ + // Rinomino la lista di punti della PolyLine. + /*const*/ PNTULIST& LoopList = Loop.GetUPointList() ; + // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso più vicino al punto. + double dMinSqDist = DBL_MAX ; + auto itMinDistSt = LoopList.end() ; + auto itSt = LoopList.begin() ; + auto itEn = itSt ; + ++ itEn ; + for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn) { + // Estremi del segmento corrente del loop + Point3d ptSegSt = itSt->first ; + Point3d ptSegEn = itEn->first ; + // Distanza del punto dal segmento del loop + DistPointLine dDistCalc( ptPoint, ptSegSt, ptSegEn) ; + double dSqDist ; + dDistCalc.GetSqDist( dSqDist) ; + if ( dSqDist < dMinSqDist) { + dMinSqDist = dSqDist ; + itMinDistSt = itSt ; + } + } + // Se il punto non sta sul loop, lo segnalo. + if ( dMinSqDist > dTol * dTol) + return false ; + // Se il punto di stop sta su un vertice non devo aggiungerlo e il + // punto di stop sarà uno degli estremi del segmento su cui giace. + auto itStop = itMinDistSt ; + auto itNext = itMinDistSt ; + ++ itNext ; + if ( AreSamePointApprox( ptPoint, itStop->first)) + ; + else if ( AreSamePointApprox( ptPoint, itNext->first)) + itStop = itNext ; + else { + itStop = LoopList.emplace( itNext, ptPoint, 0.) ; + } + // Creo i due loop + PNTULIST& LoopList1 = Loop1.GetUPointList() ; + PNTULIST& LoopList2 = Loop2.GetUPointList() ; + for ( auto it = LoopList.begin() ; it != itStop ; ++ it) { + LoopList1.emplace_back( it->first, it->second) ; + } + LoopList1.emplace_back( itStop->first, itStop->second) ; + for ( auto it = itStop ; it != LoopList.end() ; ++ it) { + LoopList2.emplace_back( it->first, it->second) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +/*static*/ bool +AddPolyLineToPolyLine( PolyLine& Poly, PolyLine& PolyToAdd, double dTol) +{ + // Se la PolyLine a cui devo aggiungere l'altra è chiusa, non posso aggiungere nulla. + if ( Poly.IsClosed()) + return false ; + // Se la PolyLina che devo aggiungere è vuota, ho finito. + PNTULIST& PolyToAddList = PolyToAdd.GetUPointList() ; + if ( int( PolyToAddList.size()) == 0) + return true ; + // Se Poly non è vuota e la sua fine non coincide con l'inizio di PolyToAdd, non è possibile aggiungere nulla. + Point3d ptLast ; + Poly.GetLastPoint( ptLast) ; + auto it = PolyToAddList.begin() ; + if ( Poly.GetPointNbr() != 0 && ! AreSamePointEpsilon( it->first, ptLast, dTol)) + return false ; + /*if ( Poly.GetPointNbr() == 0) + Poly.AddUPoint( 0., it->first) ; + ++ it ;*/ + // Aggiungo i punti. + for ( ; it != PolyToAddList.end() ; ++ it) { + Poly.AddUPoint( 0., it->first) ; + } + return true ; +} \ No newline at end of file diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 2a21bec..86b3e85 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -41,7 +41,7 @@ GEOOBJ_REGISTER( SRF_TRIMESH, NGE_S_TRM, SurfTriMesh) ; SurfTriMesh::SurfTriMesh( void) : m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dBoundaryAng( STM_STD_BOUNDARY_ANG), m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bOriented( false), m_bClosed( false), m_bFaceted( false), - m_nTimeStamp( 0), m_nTempProp( 0), m_nMaxTFlag( 0), m_nParts( -1), m_pHGrd3d( nullptr) + m_nTimeStamp( 0), m_nTempProp( 0), m_nMaxTFlag( 0), m_nParts( -1), m_pHGrd3d( nullptr), m_pPGrd3d( nullptr) { m_dCosBndAng = cos( m_dBoundaryAng * DEGTORAD) ; m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ; @@ -51,15 +51,17 @@ SurfTriMesh::SurfTriMesh( void) SurfTriMesh::~SurfTriMesh( void) { ResetHashGrids3d() ; + ResetPointGrid3d() ; } //---------------------------------------------------------------------------- bool SurfTriMesh::Init( int nNumVert, int nNumTria, int nNumFacet) { - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // se superficie vuota if ( nNumVert == 0 && nNumTria == 0 && nNumFacet == 0) return true ; @@ -97,6 +99,7 @@ SurfTriMesh::Clear( void) m_vTria.clear() ; m_vFacet.clear() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; m_nMaxTFlag = 0 ; m_nParts = -1 ; return true ; @@ -110,10 +113,19 @@ SurfTriMesh::AddVertex( const Point3d& ptVert) m_nStatus = TO_VERIFY ; m_nParts = - 1 ; m_OGrMgr.Reset() ; - ResetHashGrids3d() ; + // Verifico che il punto non sia distante meno di epsilon da un altro già esistente. + Point3d ptAddingPoint ; + VerifyPointGrid3d() ; + int nNearestId ; + if ( m_pPGrd3d->FindNearest( ptVert, EPS_SMALL, nNearestId)) + GetVertex( nNearestId, ptAddingPoint) ; + else + ptAddingPoint = ptVert ; // inserisco il vertice try { m_vVert.emplace_back( ptVert) ;} catch(...) { return SVT_NULL ;} + // Inserisco il vertice nella griglia + m_pPGrd3d->InsertPoint( ptVert, int( m_vVert.size() - 1)) ; // ne determino l'indice return int( m_vVert.size() - 1) ; } @@ -181,6 +193,7 @@ SurfTriMesh::AddTriangle( const int nIdVert[3], int nTFlag) m_nParts = - 1 ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // inserisco il triangolo try { m_vTria.emplace_back( nIdVert, nTFlag) ;} catch(...) { return SVT_NULL ;} @@ -198,6 +211,7 @@ SurfTriMesh::SetTriangle( int nInd, const StmTria& tT) m_nStatus = TO_VERIFY ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // recupero la dimensione originale int nPrevSize = int( m_vTria.size()) ; // determino la dimensione necessaria @@ -1195,11 +1209,12 @@ SurfTriMesh::Save( NgeWriter& ngeOut) const bool SurfTriMesh::Load( NgeReader& ngeIn) { - // imposto ricalcolo della grafica, della connessione e di hashgrids3d + // imposto ricalcolo della grafica, della connessione e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; m_nMaxTFlag = 0 ; m_nParts = -1 ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // leggo la prossima linea ( 2 parametri : dLinTol e dSmoothAng) // tolleranza lineare di costruzione double dLinTol ; @@ -1719,8 +1734,9 @@ SurfTriMesh::PackTriangles( void) // se non c'è stata compattazione, esco if ( nFirstFree == SVT_NULL) return true ; - // Invalido HashGrid + // Invalido HashGrid e Pointgrid ResetHashGrids3d() ; + ResetPointGrid3d() ; // lunghezza vettore indici triangoli int nTIdSize = int( vTId.size()) ; // aggiorno gli indici ai triangoli dai vertici @@ -1861,6 +1877,7 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) m_nStatus = ERR ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // verifico se la polilinea è chiusa bool bClosed = PL.IsClosed() ; @@ -1931,6 +1948,7 @@ SurfTriMesh::CreateByPointCurve( const Point3d& ptP, const PolyLine& PL) m_nStatus = ERR ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // costruisco la mesh int nVertNbr = 1 + PL.GetPointNbr() ; @@ -1978,6 +1996,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nR m_nStatus = ERR ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // se rigata a minima distanza tra le due curve if ( nRuledType == RLT_MINDIST) { @@ -2559,6 +2578,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve m_nStatus = ERR ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // verifico se la polilinea è chiusa bool bClosed = MyPL.IsClosed() ; @@ -2752,6 +2772,7 @@ SurfTriMesh::DoCompacting( double dTol) m_nStatus = ERR ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // definisco un Grid per i vertici della superficie PointGrid3d VertGrid ; @@ -2839,6 +2860,7 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther) m_nStatus = ERR ; m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // definisco un Grid per i vertici delle due superfici PointGrid3d VertGrid ; @@ -2966,9 +2988,10 @@ SurfTriMesh::Translate( const Vector3d& vtMove) if ( m_nStatus != OK) return false ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // traslo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -2991,9 +3014,10 @@ SurfTriMesh::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, if ( vtAx.IsSmall()) return false ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // ruoto i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -3128,9 +3152,10 @@ SurfTriMesh::Mirror( const Point3d& ptOn, const Vector3d& vtNorm) if ( vtNorm.IsSmall()) return false ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // specchio i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) @@ -3161,9 +3186,10 @@ SurfTriMesh::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& if ( vtNorm.IsSmall() || vtDir.IsSmall()) return false ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // eseguo scorrimento dei vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -3193,9 +3219,10 @@ SurfTriMesh::ToGlob( const Frame3d& frRef) if ( frRef.GetType() == Frame3d::ERR) return false ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // trasformo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -3224,9 +3251,10 @@ SurfTriMesh::ToLoc( const Frame3d& frRef) if ( frRef.GetType() == Frame3d::ERR) return false ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // trasformo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -3259,9 +3287,10 @@ SurfTriMesh::LocToLoc( const Frame3d& frOri, const Frame3d& frDest) if ( AreSameFrame( frOri, frDest)) return true ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // trasformo i vertici for ( int i = 0 ; i < GetVertexSize() ; ++ i) { @@ -3286,9 +3315,10 @@ SurfTriMesh::Invert( void) if ( m_nStatus != OK) return false ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; // inverto i triangoli for ( int i = 0 ; i < GetTriangleSize() ; ++ i) @@ -3539,34 +3569,11 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) PtrOwner pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ; if ( IsNull( pReg)) return false ; - ////////////////////////////////////////// double dArea; Plane3d plFacetPlane; vLoopVec[0].IsClosedAndFlat( plFacetPlane, dArea) ; - /*if (!AreSameVectorApprox(plFacetPlane.GetVersN(), Y_AX)) { - INTVECTOR vT ; - GetAllTriaInFacet( nF, vT) ; - for ( auto& nT : vT) - m_vTria[nT].nTempPart = - 1 ; - continue; - }*/ - - BBox3d b3Box( Point3d( 650, -96.5, 2.5), Point3d(653,-95.5,3.5)); - BBox3d b3RegBox; - pReg->GetLocalBBox(b3RegBox); - if (/*b3Box.Overlaps(b3RegBox)*/nF == 136) - int mimi = 0; - if (/*nF == 1349 ||*/ nF == 1350) { - /*INTVECTOR vT ; - GetAllTriaInFacet( nF, vT) ; - for ( auto& nT : vT) - m_vTria[nT].nTempPart = - 1 ; - continue;*/ - int qq = 0; - } - ////////////////////////////////////////// LineFacetClassVector IntersLinePart ; - int nIntType = IntersFacetPlane( vLoopVec, plPlane, IntersLinePart); /*IntersFacetPlane(*pReg, vLoopVec[0], plPlane, IntersLinePart);*/ + int nIntType = IntersFacetPlane( vLoopVec, plPlane, IntersLinePart) ; /*IntersFacetPlane(*pReg, vLoopVec[0], plPlane, IntersLinePart);*/ if ( nIntType == FacetPlaneIntersType::FPI_CUT) { for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) { // Salvo intersezione per la faccia. @@ -3583,7 +3590,7 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) INTVECTOR vT ; GetAllTriaInFacet( nF, vT) ; for ( auto& nT : vT) - m_vTria[nT].nTempPart = plFacetPlane.GetVersN() * plPlane.GetVersN() > 0. ? 2 : - 2 ;/*pReg->GetNormVersor() * plPlane.GetVersN() > 0. ? 2 : - 2 ;*/ + m_vTria[nT].nTempPart = plFacetPlane.GetVersN() * plPlane.GetVersN() > 0. ? 2 : - 2 ; /*pReg->GetNormVersor() * plPlane.GetVersN() > 0. ? 2 : - 2 ;*/ } else if ( nIntType == FacetPlaneIntersType::FPI_INN) { INTVECTOR vT ; @@ -3616,7 +3623,9 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) if ( m_vTria[nT].nTempPart == - 1 || m_vTria[nT].nTempPart == - 2 || ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2)) RemoveTriangle( nT) ; - return AdjustVertices() && DoCompacting() ; + if ( AdjustVertices() && DoCompacting() ) + RemoveTJunctions(); + return AdjustVertices() && DoCompacting() ; #endif } @@ -3664,6 +3673,45 @@ SurfTriMesh::VerifyHashGrids3d( void) const return true ; } +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//---------------------------------------------------------------------------- +void +SurfTriMesh::ResetPointGrid3d( void) const +{ + if ( m_pPGrd3d != nullptr) { + delete m_pPGrd3d ; + m_pPGrd3d = nullptr ; + } +} + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::VerifyPointGrid3d( void) const +{ + // Se già calcolato, non devo fare altro + if ( m_pPGrd3d != nullptr) + return true ; + // Alloco + m_pPGrd3d = new PointGrid3d ; + if ( m_pPGrd3d == nullptr) + return false ; + // Riempio + m_pPGrd3d->Init( 100) ; + Point3d ptPV ; + int nV = GetFirstVertex( ptPV) ; + while ( nV != SVT_NULL) + { + if ( ! m_pPGrd3d->InsertPoint( ptPV, nV)) { + ResetPointGrid3d() ; + return false ; + } + nV = GetNextVertex( nV, ptPV) ; + } + + return true ; +} +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //---------------------------------------------------------------------------- bool SurfTriMesh::GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const @@ -3759,9 +3807,10 @@ SurfTriMesh::RemovePart( int nPart) // Aggiorno il numero di componenti m_nParts = nPartsOld - 1 ; - // imposto ricalcolo della grafica e di hashgrids3d + // imposto ricalcolo della grafica e di hashgrids3d e poingrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; return true ; } diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 1528759..4af5812 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -18,6 +18,7 @@ #include "GeoObjRW.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkHashGrids3d.h" +#include "/EgtDev/Include/EGkPointGrid3d.h" #include #include @@ -229,7 +230,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool CopyFrom( const IGeoObj* pGObjSrc) override ; bool Init( int nNumVert, int nNumTria, int nNumFacet = 0) override ; void SetLinearTolerance( double dLinTol) override - { m_dLinTol = std::max( dLinTol, EPS_SMALL) ; } + { m_dLinTol = EPS_SMALL/*std::max( dLinTol, EPS_SMALL)*/ ; } /////////////////////////////////////////////////////////////// void SetBoundaryAngle( double dBoundaryAngDeg) override { m_dBoundaryAng = std::max( dBoundaryAngDeg, EPS_ANG_SMALL) ; m_dCosBndAng = cos( m_dBoundaryAng * DEGTORAD) ; @@ -383,6 +384,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ; void ResetHashGrids3d( void) const ; bool VerifyHashGrids3d( void) const ; + void ResetPointGrid3d( void) const ; + bool VerifyPointGrid3d( void) const ; bool VerifyConnection( void) const ; bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ; bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ; @@ -395,7 +398,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA, const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB, LineFacetClassVector& IntersLinePart) ; - bool ItersectTriMeshFacets( SurfTriMesh& Other) ; + bool IntersectTriMeshFacets( SurfTriMesh& Other) ; bool RetriangulateFacetPieces( const PieceMap& NewFacet, const INTERSEDGEMAP& EdgeInterLineMap, const INTERSEDGEMAP& EdgeEdgeLineMap) ; @@ -432,16 +435,17 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW int m_nMaxTFlag ; // massimo valore dei TFlag dei triangoli mutable int m_nParts ; // numero di parti connesse (-1 se da calcolare) mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento - mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d + mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d + mutable PointGrid3d* m_pPGrd3d ; // Point Grid 3d nel suo riferimento } ; //---------------------------------------------------------------------------- -static bool ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop) ; -// nSegNum 0-based -static bool PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& nSegNum, double& dParOnSeg) ; -static bool IsPointInsidePolyLine( const Point3d& ptP, /*const*/ PolyLine& plPoly) ; -static bool SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine& Loop1, PolyLine& Loop2) ; -static bool AddPolyLineToPolyLine(PolyLine& Poly, PolyLine& PolyToAdd) ; +//static bool ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop) ; +//// nSegNum 0-based +//static bool PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& nSegNum, double& dParOnSeg) ; +//static bool IsPointInsidePolyLine( const Point3d& ptP, /*const*/ PolyLine& plPoly) ; +//static bool SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine& Loop1, PolyLine& Loop2) ; +//static bool AddPolyLineToPolyLine(PolyLine& Poly, PolyLine& PolyToAdd) ; //----------------------------------------------------------------------------- inline SurfTriMesh* CreateBasicSurfTriMesh( void) diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index a66ae09..64dfe29 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -20,7 +20,7 @@ #include "Triangulate.h" #include "GeoConst.h" #include "IntersLineLine.h" -#include "/EgtDev/Include/EgtNumUtils.h" +//#include "/EgtDev/Include/EgtNumUtils.h" #include "/EgtDev/Include/EgkCurve.h" #include "/EgtDev/Include/EgkDistPointCurve.h" #include "/EgtDev/Include/EgkDistPointTria.h" @@ -1765,8 +1765,9 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) SurfB.m_vTria[nTB].nETempFlag[1] = 0 ; SurfB.m_vTria[nTB].nETempFlag[2] = 0 ; } - // Resetto e ricalcolo la HashGrid della superficie B + // Resetto e ricalcolo la HashGrid e Pointgrid della superficie B SurfB.ResetHashGrids3d() ; + SurfB.ResetPointGrid3d() ; for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) { // Se il triangolo A non è valido, continuo Triangle3d trTriaA ; @@ -2015,8 +2016,9 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) // Triangoli sovrapposti if ( bContinue) { int nTriaNum2A = GetTriangleSize() ; - // Resetto e ricalcolo la HashGrid della superficie B + // Resetto e ricalcolo la HashGrid e Pointgrid della superficie B SurfB.ResetHashGrids3d() ; + SurfB.ResetPointGrid3d() ; for ( int nTA = 0 ; nTA < nTriaNum2A ; ++ nTA) { // Se il triangolo A non è valido, continuo Triangle3d trTriaA ; @@ -2089,6 +2091,8 @@ SurfTriMesh::RemoveTJunctions(void) { //PerformanceCounter Counter ; + if ( GetPartCount() < 0) + return false ; // Vettore di indici dei vertici sui lati del triangolo corrente INTMATRIX vvIndexMatrix( m_vTria.size()) ; // Ciclo sui triangoli della superficie @@ -2106,8 +2110,10 @@ SurfTriMesh::RemoveTJunctions(void) GetAllTriaOverlapBox( b3Tria, vNearTria) ; // Ciclo sui lati del triangolo for ( int nSeg = 0 ; nSeg < 3 ; ++ nSeg) { - // aggiungo alla riga della matrice il vertice iniziale del lato + // Aggiungo alla riga della matrice il vertice iniziale del lato vIndexRow.emplace_back( m_vTria[nT].nIdVert[nSeg]) ; + if ( m_vTria[nT].nIdAdjac[nSeg] != SVT_NULL && m_vTria[nT].nIdAdjac[nSeg] != SVT_DEL) + continue ; int nPrevSize = int( vIndexRow.size()) ; // recupero la geometria del lato Point3d ptSegSt = trTria.GetP( nSeg) ; @@ -2128,8 +2134,15 @@ SurfTriMesh::RemoveTJunctions(void) GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], ptVert) ; double dProj = ( ptVert - ptSegSt) * vtSeg ; double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ; - if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < SQ_EPS_TRIA_H) { - vIndexRow.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ; + if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < 10000 * SQ_EPS_TRIA_H && m_vTria[nT].nPart == m_vTria[vNearTria[nI]].nPart) { + int nCandidateId = m_vTria[vNearTria[nI]].nIdVert[nVert] ; + int nY ; + for ( nY = 0 ; nY < int( vIndexRow.size()) ; ++ nY) { + if ( vIndexRow[nY] == nCandidateId) + break ; + } + if ( nY == int( vIndexRow.size())) + vIndexRow.emplace_back( nCandidateId) ; } } } @@ -2148,26 +2161,28 @@ SurfTriMesh::RemoveTJunctions(void) for ( int nT = 0 ; nT < int( vvIndexMatrix.size()) ; ++ nT) { if ( vvIndexMatrix[nT].size() > 3) { - PolyLine Polygon ; + // Vettore contenente tutti i punti di contorno sul triangolo + PNTVECTOR vP ; for ( int nV = 0 ; nV < int( vvIndexMatrix[nT].size()) ; ++ nV) { - Point3d ptPt; + Point3d ptPt ; GetVertex( vvIndexMatrix[nT][nV], ptPt) ; - Polygon.AddUPoint( 0., ptPt) ; + vP.emplace_back( ptPt) ; } - Polygon.Close() ; - PNTVECTOR vPt ; - INTVECTOR vTr ; - if ( Triangulate().Make( Polygon, vPt, vTr)) { - // Rimuovo il triangolo originale e salvo il suo flag + // Salvo il colore del triangolo, ne calcolo il baricentro e lo cancello. + Triangle3d trTria ; + if ( GetTriangle( nT, trTria) && trTria.Validate( true)) { int nTFlag = m_vTria[nT].nTFlag ; + Point3d ptBar = ( trTria.GetP( 0) + trTria.GetP( 1) + trTria.GetP( 2)) / 3 ; + int nBarIndex = AddVertex( ptBar) ; RemoveTriangle( nT) ; - // Inserisco i nuovi triangoli che lo sostituiscono e asegno loro lo stesso flag - for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { - int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; - int nNewId[3] = { AddVertex( vPt[nNewTriaVertId[0]]), - AddVertex( vPt[nNewTriaVertId[1]]), - AddVertex( vPt[nNewTriaVertId[2]])} ; - AddTriangle( nNewId, nTFlag) ; + int nContourPointNum = int( vP.size()) ; + for ( int nP = 0 ; nP < nContourPointNum ; ++ nP) { + int nNewId[3] = { nBarIndex, + AddVertex( vP[nP]), + AddVertex( vP[( nP + 1) % nContourPointNum])} ; + int nTempNewTriaId = AddTriangle( nNewId, nTFlag) ; + if ( ! IsValidSvt( nTempNewTriaId)) + ; } } } @@ -2175,7 +2190,7 @@ SurfTriMesh::RemoveTJunctions(void) return true ; } - + //---------------------------------------------------------------------------- bool SurfTriMesh::RemoveCaps(void) @@ -2433,7 +2448,7 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other) //Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ; //SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ; //IntersectTriMeshTriangle( SurfB) ; - ItersectTriMeshFacets( SurfB) ; + IntersectTriMeshFacets( SurfB) ; IdentifyParts() ; SurfB.IdentifyParts() ; int nTriaNumA = GetTriangleSize() ; @@ -2455,12 +2470,13 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other) } } bool bOk = ( AdjustVertices() && DoCompacting()) ; - //bOk && RemoveTripleTriangles() ; - //bOk = bOk && ( AdjustVertices() && DoCompacting()) ; + ////bOk && RemoveTripleTriangles() ; + ////bOk = bOk && ( AdjustVertices() && DoCompacting()) ; bOk && RemoveTJunctions() ; bOk = bOk && ( AdjustVertices() && DoCompacting()) ; - //Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ; + ////Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ; return bOk ; + //return RemoveTJunctions() ; } //---------------------------------------------------------------------------- @@ -3043,247 +3059,6 @@ TrimLineWithExtPolygon( const CurveLine& cvLine, const POLYLINEVECTOR& vContourV return true ; } -//---------------------------------------------------------------------------- -static bool -ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop) -{ - // Rinomino la lista di punti della PolyLine. - PNTULIST& LoopList = Loop.GetUPointList() ; - // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso più vicino al punto. - double dMinSqDist = DBL_MAX ; - auto itMinDist = LoopList.end() ; - auto itSt = LoopList.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptNewStart, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - dMinSqDist = dSqDist ; - itMinDist = itSt ; - } - } - // Se il punto non sta sul loop, errore - if ( dMinSqDist > 100 * SQ_EPS_SMALL) - return false ; - // Se il punto non sta su un vertice del segmento, lo aggiungo. Altrimenti non devo fare nulla. - auto itNewPointSt = LoopList.begin() ; - auto itNext = itMinDist ; - ++ itNext ; - bool bOnStart = AreSamePointApprox( ptNewStart, itMinDist->first) ; - bool bOnEnd = AreSamePointApprox( ptNewStart, itNext->first) ; - itNewPointSt = LoopList.emplace( itNext, ptNewStart, 0) ; - // Sposto i punti precedenti in coda. - bool bStartRemoved = false ; - auto it = LoopList.begin() ; - while ( it != itNewPointSt) { - if ( bStartRemoved) { - LoopList.emplace_back( it->first, it->second) ; - } - bStartRemoved = true ; - it = LoopList.erase( it) ; - } - // Se il punto inserito non coincide con l'inizio del segmento chiudo il loop. - if ( ! bOnStart) { - LoopList.emplace_back( ptNewStart, 0) ; - // Se coincide con la fine tolgo il punto di fine che diviene inutile. - if ( bOnEnd) { - //LoopList.erase( itNext) ; - auto itNewStart = LoopList.begin() ; - ++ itNewStart ; - LoopList.erase( itNewStart) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -// nSegNum 0-based -static bool -PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& nSegNum, double& dParOnSeg) -{ - // Rinomino la lista di punti della PolyLine. - /*const*/ PNTULIST& LoopList = Loop.GetUPointList() ; - // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso più vicino al punto. - nSegNum = - 1 ; - double dMinSqDist = DBL_MAX ; - int nS = 0 ; - auto itMinDistSt = LoopList.end() ; - auto itMinDistEn = itMinDistSt ; - auto itSt = LoopList.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn, ++ nS) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptPoint, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - nSegNum = nS ; - dMinSqDist = dSqDist ; - itMinDistSt = itSt ; - itMinDistEn = itEn ; - } - } - // Se il punto non sta sul loop, lo segnalo. - if ( dMinSqDist > 100 * SQ_EPS_SMALL) - return false ; - // Calcolo il parametro lungo il segmento. - Vector3d vtSeg = itMinDistEn->first - itMinDistSt->first ; - double dSegLen = vtSeg.Len() ; - if ( dSegLen < EPS_SMALL) - return false ; - vtSeg /= dSegLen ; - dParOnSeg = Clamp( ( ptPoint - itMinDistSt->first) * vtSeg, 0., dSegLen) ; - return true ; -} - -//---------------------------------------------------------------------------- -static bool -IsPointInsidePolyLine( const Point3d& ptP, /*const*/ PolyLine& plPoly) -{ - // Se la PolyLine non è chiusa, il punto non può essere interno. - if ( ! plPoly.IsClosed()) - return false ; - // Lista dei punti - /*const*/ PNTULIST& List = plPoly.GetUPointList() ; - // Ciclo sui segmenti della PolyLine per cercarne il tratto più vicino al punto. - double dMinSqDist = DBL_MAX ; - Point3d ptMinDist ; - auto itMinDistSt = List.end() ; - auto itSt = List.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != List.end() && itEn != List.end() ; ++ itSt, ++ itEn) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptP, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - dMinSqDist = dSqDist ; - dDistCalc.GetMinDistPoint( ptMinDist) ; - itMinDistSt = itSt ; - } - } - // Termine del segmento di minima distanza. - auto itMinDistEn = itMinDistSt ; - ++ itMinDistEn ; - // Punto di minima distanza nell'estremo iniziale del segento - if ( AreSamePointApprox( ptMinDist, itMinDistSt->first)) { - auto itPrevSt = List.begin() ; - if ( itMinDistSt == List.begin()) { - auto itAuxNext = itPrevSt ; - ++ ( ++ itAuxNext) ; - for ( ; itAuxNext != List.end() ; ++ itPrevSt, ++ itAuxNext) - ; - } - else { - auto itAuxNext = itPrevSt ; - ++ itAuxNext ; - for (; itAuxNext != itMinDistSt; ++itPrevSt, ++itAuxNext) - ; - } - Vector3d vtPrevTan = itMinDistSt->first - itPrevSt->first ; - vtPrevTan.Normalize() ; - Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; - vtTan.Normalize() ; - Polygon3d AuxPolygon ; - AuxPolygon.FromPolyLine( plPoly) ; - Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; - Vector3d vtPrevOut = vtPrevTan ^ vtPolyNorm ; - Vector3d vtOut = vtTan ^ vtPolyNorm ; - // Caso concavo - if ( vtTan * vtPrevOut > 0) { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtPrevOut < 0 || vtTest * vtOut < 0) - return true ; - } - // Caso convesso - else { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtPrevOut < 0 && vtTest * vtOut < 0) - return true ; - } - } - // Punto di minima distanza nell'estremo finale del segento - else if ( AreSamePointApprox( ptMinDist, itMinDistEn->first)) { - auto itNextEn = itMinDistEn ; - ++ itNextEn ; - if ( itNextEn == List.end()) { - itNextEn = List.begin() ; - ++ itNextEn ; - } - Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; - vtTan.Normalize() ; - Vector3d vtNextTan = itNextEn->first - itMinDistEn->first ; - vtNextTan.Normalize() ; - Polygon3d AuxPolygon ; - AuxPolygon.FromPolyLine( plPoly) ; - Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; - Vector3d vtOut = vtTan ^ vtPolyNorm ; - Vector3d vtNextOut = vtNextTan ^ vtPolyNorm ; - // Caso concavo - if ( vtNextTan * vtOut > 0) { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtOut < 0 || vtTest * vtNextOut < 0) - return true ; - } - // Caso convesso - else { - Vector3d vtTest = ptP - ptMinDist ; - if ( vtTest * vtOut < 0 && vtTest * vtNextOut < 0) - return true ; - } - } - // Punto di minima distanza interno al segmeno - else { - Vector3d vtP = ptP - itMinDistSt->first ; - Vector3d vtTan = itMinDistEn->first - itMinDistSt->first ; - vtTan.Normalize() ; - Polygon3d AuxPolygon ; - AuxPolygon.FromPolyLine( plPoly) ; - Vector3d vtPolyNorm = AuxPolygon.GetVersN() ; - Vector3d vtOut = vtTan ^ vtPolyNorm ; - vtP -= ( vtP * vtTan) * vtTan ; - if ( vtP * vtOut < - EPS_SMALL) - return true ; - } - return false ; -} - -//---------------------------------------------------------------------------- -bool -DistPointPolyLine( const Point3d& ptP, const PolyLine& plPoly, double& dPointPolyLineDist) -{ - if ( plPoly.GetPointNbr() == 0) - return false ; - dPointPolyLineDist = DBL_MAX ; - Point3d ptSt, ptEn ; - bool bContinue = plPoly.GetFirstPoint( ptSt) && plPoly.GetNextPoint( ptEn) ; - while ( bContinue) { - double dPoinLineDist ; - DistPointLine PointLineDistCalc( ptP, ptSt, ptEn) ; - PointLineDistCalc.GetDist( dPoinLineDist) ; - if ( dPoinLineDist < dPointPolyLineDist) - dPointPolyLineDist = dPoinLineDist ; - ptSt = ptEn ; - bContinue = plPoly.GetNextPoint( ptEn) ; - } - return true ; -} - //---------------------------------------------------------------------------- // Una faccia di una trimesh ha una sola componente connessa. // Si assume che i loop siano corretti e rispettino tale proprietà. @@ -3327,98 +3102,6 @@ DistPointFacet( const Point3d& ptP, /*const*/ POLYLINEVECTOR& vPolyVec, double& return true ; } -//---------------------------------------------------------------------------- -static bool -SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine& Loop1, PolyLine& Loop2) -{ - // Rinomino la lista di punti della PolyLine. - /*const*/ PNTULIST& LoopList = Loop.GetUPointList() ; - // Ciclo sui segmenti del loop per cercare il tratto del loop chiuso più vicino al punto. - double dMinSqDist = DBL_MAX ; - auto itMinDistSt = LoopList.end() ; - auto itSt = LoopList.begin() ; - auto itEn = itSt ; - ++ itEn ; - for ( ; itSt != LoopList.end() && itEn != LoopList.end() ; ++ itSt, ++ itEn) { - // Estremi del segmento corrente del loop - Point3d ptSegSt = itSt->first ; - Point3d ptSegEn = itEn->first ; - // Distanza del punto dal segmento del loop - DistPointLine dDistCalc( ptPoint, ptSegSt, ptSegEn) ; - double dSqDist ; - dDistCalc.GetSqDist( dSqDist) ; - if ( dSqDist < dMinSqDist) { - dMinSqDist = dSqDist ; - itMinDistSt = itSt ; - } - } - // Se il punto non sta sul loop, lo segnalo. - if ( dMinSqDist > 100 * SQ_EPS_SMALL) - return false ; - // Se il punto di stop sta su un vertice non devo aggiungerlo e il - // punto di stop sarà uno degli estremi del segmento su cui giace. - auto itStop = itMinDistSt ; - auto itNext = itMinDistSt ; - ++ itNext ; - if ( AreSamePointApprox( ptPoint, itStop->first)) - ; - else if ( AreSamePointApprox( ptPoint, itNext->first)) - itStop = itNext ; - else { - itStop = LoopList.emplace( itNext, ptPoint, 0.) ; - } - // Creo i due loop - PNTULIST& LoopList1 = Loop1.GetUPointList() ; - PNTULIST& LoopList2 = Loop2.GetUPointList() ; - for ( auto it = LoopList.begin() ; it != itStop ; ++ it) { - LoopList1.emplace_back( it->first, it->second) ; - } - LoopList1.emplace_back( itStop->first, itStop->second) ; - for ( auto it = itStop ; it != LoopList.end() ; ++ it) { - LoopList2.emplace_back( it->first, it->second) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -static bool -AddPolyLineToPolyLine( PolyLine& Poly, PolyLine& PolyToAdd) -{ - // Se la PolyLine a cui devo aggiungere l'altra è chiusa, non posso aggiungere nulla. - if ( Poly.IsClosed()) - return false ; - // Se la PolyLina che devo aggiungere è vuota, ho finito. - PNTULIST& PolyToAddList = PolyToAdd.GetUPointList() ; - if ( int( PolyToAddList.size()) == 0) - return true ; - // Se Poly non è vuota e la sua fine non coincide con l'inizio di PolyToAdd, non è possibile aggiungere nulla. - Point3d ptLast ; - Poly.GetLastPoint( ptLast) ; - auto it = PolyToAddList.begin() ; - if ( Poly.GetPointNbr() != 0 && ! AreSamePointEpsilon( it->first, ptLast, 10 * EPS_SMALL)) - return false ; - /*if ( Poly.GetPointNbr() == 0) - Poly.AddUPoint( 0., it->first) ; - ++ it ;*/ - // Aggiungo i punti. - for ( ; it != PolyToAddList.end() ; ++ it) { - Poly.AddUPoint( 0., it->first) ; - } - return true ; -} - -//---------------------------------------------------------------------------- -struct PositionOnPolyLine { - int nIndexInVec ; - int nSegNum ; - double dParOnSeg ; - PositionOnPolyLine( int nIndex, int nSeg, double dPar) { - nIndexInVec = nIndex ; - nSegNum = nSeg ; - dParOnSeg = dPar ; - } -} ; - //---------------------------------------------------------------------------- bool SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet) @@ -3529,14 +3212,14 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet for ( int nLoop = 0 ; nLoop < int( vNewPieces[nPart].vPieceLoop.size()) && int( vLoopIndexes.size()) < 2 ; ++ nLoop) { int nSegNum ; double dParOnSeg ; - if ( PointPositionOnPolyLine( cvOpenChain[nLastChainNum][0].ptSt, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg)) { + if ( PointPositionOnPolyLine( cvOpenChain[nLastChainNum][0].ptSt, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { vLoopIndexes.emplace_back( nLoop) ; if ( vLoopIndexes.size() > 1) { swap( vLoopIndexes[0], vLoopIndexes[1]) ; } } if ( PointPositionOnPolyLine( cvOpenChain[nLastChainNum][cvOpenChain[nLastChainNum].size() - 1].ptEn, - vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg)) { + vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { vLoopIndexes.emplace_back( nLoop) ; } } @@ -3546,7 +3229,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet // La catena finisce sul loop ove inizia. Divido la nuova parte. if ( vLoopIndexes[0] == vLoopIndexes[1]) { // Cambio inizio al loop iniziale. - ChangePolyLineStart( cvOpenChain[nLastChainNum].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]]) ; + ChangePolyLineStart( cvOpenChain[nLastChainNum].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]], 9 * EPS_SMALL) ; // Divido il loop della parte // Loop1 PolyLine NewLoop1 ; @@ -3560,12 +3243,12 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet PolyLine SplitLoop1, SplitLoop2 ; SplitPolyLineAtPoint( cvOpenChain[nLastChainNum][0].ptSt, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]], - SplitLoop1, SplitLoop2) ; + SplitLoop1, SplitLoop2, 9 * EPS_SMALL) ; // Aggiungo i punti precedenti il punto di frattura nella in NewLoop1. - AddPolyLineToPolyLine( NewLoop1, SplitLoop1) ; + AddPolyLineToPolyLine( NewLoop1, SplitLoop1, 10 * EPS_SMALL) ; // Loop2 PolyLine NewLoop2 ; - AddPolyLineToPolyLine( NewLoop2, SplitLoop2) ; + AddPolyLineToPolyLine( NewLoop2, SplitLoop2, 10 * EPS_SMALL) ; // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = int( cvOpenChain[nLastChainNum].size()) - 1 ; m >= 0 ; -- m) { NewLoop2.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptEn) ; @@ -3664,37 +3347,31 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet else { INTVECTOR vChainIndex ; vChainIndex.emplace_back( nLastChainNum) ; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - int nIter = 0; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + int nIter = 0 ; while ( vLoopIndexes.back() != vLoopIndexes[0] && nIter == 0) { // Cambio inizio del loop corrente in modo che il punto di inizio sia il punto finale dell'ultima catena trovata. - ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()]) ; + ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()], 9 * EPS_SMALL) ; // Cerco catene che iniziano sul loop coorente vector vChainStartingOnLoop ; for ( int nCh = 0 ; nCh < nLastChainNum ; ++ nCh) { int nSegNum ; double dParOnSeg ; - if ( PointPositionOnPolyLine( cvOpenChain[nCh][0].ptSt, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()], nSegNum, dParOnSeg)) { + if ( PointPositionOnPolyLine( cvOpenChain[nCh][0].ptSt, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { vChainStartingOnLoop.emplace_back( PositionOnPolyLine(nCh, nSegNum, dParOnSeg)) ; } } // Ordino le catene secondo la vicinanza lungo il loop del loro punto d'inizio al punto d'inizio del loop stesso. sort( vChainStartingOnLoop.begin(), vChainStartingOnLoop.end(), [] ( PositionOnPolyLine Ch1, PositionOnPolyLine Ch2) { - if ( Ch1.nSegNum/*nIndexInVec*/ < Ch2.nSegNum/*nIndexInVec*/) + if ( Ch1.nSegNum < Ch2.nSegNum) return true ; - else if ( Ch1.nSegNum/*nIndexInVec*/ == Ch2.nSegNum/*nIndexInVec*/) + else if ( Ch1.nSegNum == Ch2.nSegNum) return Ch1.dParOnSeg < Ch2.dParOnSeg ; else return false ; } ) ; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ nIter ; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Cerco la prima catena che non termina sul loop corrente. for ( int n = 0 ; n < int( vChainStartingOnLoop.size()) ; ++ n) { - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - bool bFound = false; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool bFound = false ; // Indice della catena e indice del segmento finale int nCh = vChainStartingOnLoop[n].nIndexInVec ; int nLastLineIndex = int( cvOpenChain[nCh].size()) - 1 ; @@ -3709,25 +3386,21 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet double dParOnSeg ; // La catena termina su questo loop diverso da quello corrente. if ( nLoop != vLoopIndexes.back() && - PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg)) { - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg, 9 * EPS_SMALL)) { nIter = 0 ; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Salvo l'indice della catena e quello del loop. vChainIndex.emplace_back( nCh) ; vLoopIndexes.emplace_back( nLoop) ; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bFound = true; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// break ; } } - if ( nLoop == nLoopNum/* 77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777 */ || bFound) + if ( nLoop == nLoopNum || bFound) break ; } } // Cambio inizio al loop iniziale. - ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]]) ; + ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]], 9 * EPS_SMALL) ; // Divido i loop della parte. POLYLINEVECTOR vPolySecondPartVec ; PolyLine NewLoop1 ; @@ -3742,16 +3415,16 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet PolyLine SplitLoop1, SplitLoop2 ; SplitPolyLineAtPoint( cvOpenChain[vChainIndex[( n + 1) % int( vChainIndex.size())]][0].ptSt, vNewPieces[nPart].vPieceLoop[vLoopIndexes[n + 1]], - SplitLoop1, SplitLoop2) ; + SplitLoop1, SplitLoop2, 9 * EPS_SMALL) ; // Aggiungo i punti precedenti il punto di frattura in NewLoop1. - AddPolyLineToPolyLine( NewLoop1, SplitLoop1) ; + AddPolyLineToPolyLine( NewLoop1, SplitLoop1, 10 * EPS_SMALL) ; // Salvo la parte dopo il punto di frattura in un apposito vettore. vPolySecondPartVec.emplace_back( SplitLoop2) ; } PolyLine NewLoop2 ; for ( int n = int( vChainIndex.size()) - 1 ; n >= 0 ; -- n) { // Aggiungo i punti successivi il punto di frattura in NewLoop2. - AddPolyLineToPolyLine( NewLoop2, vPolySecondPartVec[n]) ; + AddPolyLineToPolyLine( NewLoop2, vPolySecondPartVec[n], 10 * EPS_SMALL) ; // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = int( cvOpenChain[vChainIndex[n]].size()) - 1 ; m >= 0 ; -- m) { NewLoop2.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptEn) ; @@ -4030,7 +3703,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet double dLongPos = ( ptInnPoint - ptSt) * vtSeg ; if ( dDist < 10 * EPS_SMALL && dLongPos > 0. && dLongPos < dSegLen) { POINTU NewPointU ; - NewPointU.first = ptInnPoint ; + NewPointU.first = ptSt + ( ( ptInnPoint - ptSt) * vtSeg) * vtSeg ; NewPointU.second = dLongPos ; if ( ! bIsFirst) vPointWithOrder.emplace_back( NewPointU) ; @@ -4535,8 +4208,8 @@ SplitPolyLineContour( const POLYLINEVECTOR& vContourVec, POLYLINEVECTOR& vContou AuxPoly.AddUPoint( 0, vPointsVec[nP]) ; // Cambio origine al contorno e lo divido. vContourVec1.emplace_back() ; vContourVec2.emplace_back() ; - if ( ChangePolyLineStart( vPointsVec[nSplitI], AuxPoly) && - SplitPolyLineAtPoint( vPointsVec[nSplitJ], AuxPoly, vContourVec1[0], vContourVec2[0])) { + if ( ChangePolyLineStart( vPointsVec[nSplitI], AuxPoly, 9 * EPS_SMALL) && + SplitPolyLineAtPoint( vPointsVec[nSplitJ], AuxPoly, vContourVec1[0], vContourVec2[0], 9 * EPS_SMALL)) { // Chiudo i contorni. vContourVec1[0].AddUPoint( 0, vPointsVec[nSplitI]) ; vContourVec2[0].AddUPoint( 0, vPointsVec[nSplitJ]) ; @@ -4801,11 +4474,11 @@ SurfTriMesh::RetriangulateFacetPieces( const PieceMap& NewFacet, //---------------------------------------------------------------------------- bool -SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) +SurfTriMesh::IntersectTriMeshFacets( SurfTriMesh& Other) { //////////////////////////////////////////////////////////////////////////////////////////////////////// static int nTime = 0; nTime++; - if (nTime == 37) + if (nTime == 14) nTime = 0; //////////////////////////////////////////////////////////////////////////////////////////////////////// SurfTriMesh& SurfB = Other ; @@ -4848,7 +4521,7 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) RegionA.GetLocalBBox( b3BoxA) ; INTVECTOR vNearTria ; SurfB.GetAllTriaOverlapBox( b3BoxA, vNearTria) ; - // Determino le facce a cui appartengono i tirangoli che cadono nel box + // Determino le facce a cui appartengono i triangoli che cadono nel box INTVECTOR vFacetIndexesB ; for ( int& nT : vNearTria) { int nF = SurfB.GetFacetFromTria(nT) ; @@ -5454,8 +5127,9 @@ SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) // Gestione triangoli sovrapposti if ( bOk) { int nTriaNum2A = GetTriangleSize() ; - // Resetto e ricalcolo la HashGrid della superficie B + // Resetto e ricalcolo la HashGrid e PointGrid della superficie B SurfB.ResetHashGrids3d() ; + SurfB.ResetPointGrid3d() ; for ( int nTA = 0 ; nTA < nTriaNum2A ; ++ nTA) { // Se il triangolo A non è valido, continuo Triangle3d trTriaA ; diff --git a/SurfTriMeshFaceting.cpp b/SurfTriMeshFaceting.cpp index c467009..6e4a664 100644 --- a/SurfTriMeshFaceting.cpp +++ b/SurfTriMeshFaceting.cpp @@ -114,7 +114,7 @@ SurfTriMesh::UpdateTriaFaceting( int nRefT, int nFacet, const Plane3d& plPlane, } if ( nV == SVT_NULL) return false ; - double dTol = max( min( m_dLinTol, 20 * EPS_SMALL), 2 * EPS_SMALL) ; + double dTol = max( min( m_dLinTol, 20 * EPS_SMALL), /*2 **/ EPS_SMALL) ; //////////////////////////////////////////////////// if ( ! PointInPlaneEpsilon( m_vVert[m_vTria[nT].nIdVert[nV]].ptP, plPlane, dTol)) return true ; // il triangolo fa parte della faccia @@ -413,7 +413,7 @@ SurfTriMesh::GetFacetLoops( int nF, POLYLINEVECTOR& vPL) const for ( int i = 0 ; i < int( vPL.size()) ; ++ i) { Plane3d plPlane ; double dArea ; - if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea, 100 * EPS_SMALL)) + if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea, /*100 **/ EPS_SMALL)) return false ; // se loop esterno if ( vtN * plPlane.GetVersN() > 0) { @@ -712,9 +712,10 @@ SurfTriMesh::RemoveFacet( int nF) if ( ! DoCompacting()) return false ; - // dichiaro necessità ricalcolo della grafica e di hashgrids3d + // dichiaro necessità ricalcolo della grafica e di hashgrids3d e pointgrid3d m_OGrMgr.Reset() ; ResetHashGrids3d() ; + ResetPointGrid3d() ; return true ; }