diff --git a/CurveAux.cpp b/CurveAux.cpp index dc2b391..4c6d624 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -525,6 +525,7 @@ NurbsCurveCanonicalize( CNurbsData& cnData) // se periodica if ( cnData.bPeriodic || ! cnData.bClamped) { // se la curva è peridica verifco che effettivamente ci sia un numero di punti ripetituti uguale al grado della curva + // wrap della curva su se stessa if ( cnData.bPeriodic ) { bool bRepetead = true ; for ( int i = 0 ; i < cnData.nDeg ; ++i) { @@ -557,6 +558,18 @@ NurbsCurveCanonicalize( CNurbsData& cnData) } } + // qui aggiungo un controllo se la curva è collassata in un punto ( ho un polo), lascio stare + bool bCollapsed = true ; + Point3d ptFirst = cnData.vCP.front() ; + for( int i = 1 ; i < int( cnData.vCP.size()) ; ++i) { + if ( ! AreSamePointApprox( ptFirst, cnData.vCP[i])) { + bCollapsed = false ; + break ; + } + } + if ( bCollapsed) + return true ; + // va trasformata in non-periodica (clamped) // bisogna aumentare la molteplicità dei nodi u_p-1 e u_(m-p+1) fino ad arrivare al grado della nurbs // e poi scartare nodi e punti fuori dalla regione clamped ( al di fuori della regione u_p-1 -> u_(m-p+1)) diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 0e5cd91..87568ca 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -3112,6 +3112,8 @@ SurfBezier::GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge) con ICurveComposite* SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const { + if ( m_mCCEdge.size() == 0) + GetAuxSurf() ; // questa funzione dà per scontato che la superficie NON sia trimmata if ( nEdge < 0 || nEdge > 3 || m_bTrimmed) return nullptr ; @@ -3218,25 +3220,26 @@ SurfBezier::IsPlanar( void) const PolyLine plApprox ; pCCEdge->ApproxWithLines( 0.01, 15, 0, plApprox) ; Plane3d plPlane ; - if ( ! plApprox.IsFlat( plPlane, EPS_SMALL)) + if ( ! plApprox.IsFlat( plPlane, 2 * EPS_SMALL)) return false ; // in questo caso se è grado 1 in U e V e ho un unica Patch allora sono sicuro sia piana if ( m_nDegU == 1 && m_nSpanU == 1 && m_nDegV == 1 && m_nSpanV == 1) // questa condizione da sola non è sufficiente ( posso avere superfici torte anche se i lati sono segmenti) return true ; - int nCount = int(plApprox.GetUPointList().size()) ; + double dULast ; plApprox.GetLastU( dULast) ; + ++ dULast ; // altrimenti devo verificare anche all'interno della superficie, prendendo dei punti campione DBLVECTOR vSampling { 0.2, 0.4, 0.6, 0.8} ; for ( double i : vSampling) { for ( double j : vSampling) { Point3d ptBez ; - GetPointD1D2( i * m_nSpanU, j * m_nSpanV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_PLUS, ptBez) ; - if ( plApprox.AddUPoint( nCount, ptBez)) - ++ nCount ; + GetPointD1D2( i * m_nSpanU, j * m_nSpanV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez) ; + if ( plApprox.AddUPoint( dULast, ptBez)) + ++ dULast ; } } plPlane.Reset() ; - if ( plApprox.IsFlat( plPlane, EPS_SMALL)) + if ( plApprox.IsFlat( plPlane, 2 * EPS_SMALL)) return true ; // nel dubbio restituisco false