diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 626707f..164c94b 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -40,7 +40,6 @@ #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Extern/Eigen/Dense" -#include "EgtDev/Include/EGkGeoObjSave.h" using namespace std ; @@ -49,6 +48,7 @@ GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ; static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposite* pCrvU0, ICurveComposite* pCrvU1) ; static bool ParametrizeByLen( const ICurveComposite* pCurve, DBLVECTOR& vParam) ; +static bool BuildCommonParam( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam) ; //---------------------------------------------------------------------------- SurfBezier::SurfBezier( void) @@ -4769,8 +4769,24 @@ ParametrizeByLen( const ICurveComposite* pCurve, DBLVECTOR& vParam) //---------------------------------------------------------------------------- static bool -FindCommonParametrization( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam) +BuildCommonParam( const DBLMATRIX& mParam, DBLVECTOR& vCommonParam) { + // aggiungo tutti gli end delle sottocurve + Intervals iInt ; + iInt.Set( 0, 1) ; + for ( int i = 0 ; i < int( mParam.size()) ; ++i) { + for ( int j = 0 ; j < int(mParam[i].size()) - 1 ; ++j) { + iInt.Add( mParam[i][j], mParam[i][j+1]) ; + } + } + + //// NON FUNZIONANO COSì GLI INTERVALSS!!!!!!/////////////////////////// + // + //// controllo che non ce ne siano di troppo vicini + //// in tal caso elimino il secondo + //for ( ) { + // iInt. + //} return true ; } diff --git a/Tree.cpp b/Tree.cpp index da1abbf..4a8bb23 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -282,7 +282,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi // se richiesto divido preliminarmente le patches m_vnParents.clear() ; bool bIsPlanar = m_pSrfBz->IsPlanar() ; - if( ! bIsPlanar) { + if( ! bIsPlanar || m_bMulti) { if ( m_bSplitPatches && ( nSpanU > 1 || nSpanV > 1)) { int nId = -1 ; // se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo @@ -698,6 +698,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) // suddivido lo spazio parametrico con divisioni a metà su uno dei due parametri int nCToSplit = -1 ; Cell* pcToSplit = &m_mTree[nCToSplit] ; + bool bIsPlanar = m_pSrfBz->IsPlanar() ; if ( ! m_bBilinear) { while ( nCToSplit != -2 && pcToSplit->IsProcessed() == false) { // controllo che la cella non sia già stata preliminarmente splittata @@ -767,35 +768,60 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) // posso guardare la distanza tra le due diagonali bool bTwist = false ; Point3d ptP00, ptP10, ptP11, ptP01 ; - // distanza reale tra i vertici della cella + // i vertici della cella ptP00 = m_mVert[nCToSplit][0] ; ptP10 = m_mVert[nCToSplit][1] ; ptP11 = m_mVert[nCToSplit][2] ; ptP01 = m_mVert[nCToSplit][3] ; - // serve una valutazione più fine, sennò approssimo la superficie in modo troppo grossolano DistLineLine dll( ptP00, ptP11, ptP10, ptP01, true, true) ; double dDist = 0 ; dll.GetDist( dDist) ; - if ( dDist > max(dCurvU, dCurvV) && dDist > EPS_SMALL) { - bTwist = true ; - // devo decidere in quale direzione splittare - // dovrei capire in quale delle due direzioni è più torta la superficie - Vector3d vtU0 = ptP10 - ptP00 ; - Vector3d vtU1 = ptP11 - ptP01 ; - double dAngU ; - bool bDetU = false ; - vtU0.GetRotation( vtU1, vtU0 ^ vtU1, dAngU, bDetU) ; - Vector3d vtV0 = ptP01 - ptP00 ; - Vector3d vtV1 = ptP11 - ptP10 ; - double dAngV ; - bool bDetV = false ; - // faccio la get rotation tra le coppie vettori, usando come asse il loro prodotto vettoriale per ottenere la rotazione tra i due lati - // splitto nella direzione perpendicolare alla coppia di vettori più torti tra loro. - vtV0.GetRotation( vtV1, vtV0 ^ vtV1, dAngV, bDetV) ; - if ( dAngU > dAngV) - dCurvV = dDist ; - else - dCurvU = dDist ; + if ( dDist > max(dCurvU, dCurvV) || dDist < 5 * EPS_SMALL) { + bool bFlat = false ; + // controllo se la cella è twistata di 180 gradi e quindi piatta + Triangle3d tria1, tria2 ; + tria1.Set( ptP00, ptP10, ptP11) ; tria1.Validate( true) ; + tria2.Set( ptP00, ptP11, ptP01) ; tria2.Validate( true) ; + if( AreOppositeVectorEpsilon(tria1.GetN(), tria2.GetN(), 5 * EPS_SMALL)) { + bTwist = true ; + bFlat = true ; + } + // controllo che la cella non sia piatta + if( ! bTwist) { + PolyLine plCell ; + plCell.AddUPoint(0,ptP00) ; + plCell.AddUPoint(1,ptP10) ; + plCell.AddUPoint(2,ptP11) ; + double dU = (pcToSplit->GetTopRight().x + pcToSplit->GetBottomLeft().x) / (SBZ_TREG_COEFF * 2) ; + double dV = (pcToSplit->GetTopRight().y + pcToSplit->GetBottomLeft().y) / (SBZ_TREG_COEFF * 2) ; + Point3d ptCen ; m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptCen) ; + plCell.AddUPoint(3,ptCen) ; + plCell.AddUPoint(4,ptP01) ; + plCell.Close() ; + Plane3d plPlane ; double dArea = 0 ; + bFlat = plCell.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ; + } + if( ! bFlat) { + bTwist = true ; + // devo decidere in quale direzione splittare + // dovrei capire in quale delle due direzioni è più torta la superficie + Vector3d vtU0 = ptP10 - ptP00 ; + Vector3d vtU1 = ptP11 - ptP01 ; + double dAngU ; + bool bDetU = false ; + vtU0.GetRotation( vtU1, vtU0 ^ vtU1, dAngU, bDetU) ; + Vector3d vtV0 = ptP01 - ptP00 ; + Vector3d vtV1 = ptP11 - ptP10 ; + double dAngV ; + bool bDetV = false ; + // faccio la get rotation tra le coppie vettori, usando come asse il loro prodotto vettoriale per ottenere la rotazione tra i due lati + // splitto nella direzione perpendicolare alla coppia di vettori più torti tra loro. + vtV0.GetRotation( vtV1, vtV0 ^ vtV1, dAngV, bDetV) ; + if ( dAngU > dAngV) + dCurvV = dDist ; + else + dCurvU = dDist ; + } } // per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza @@ -978,7 +1004,6 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } // bilineare else { - bool bIsPlanar = m_pSrfBz->IsPlanar() ; while ( nCToSplit != -2 && pcToSplit->IsProcessed() == false) { if ( pcToSplit->IsLeaf()) { // vertici della cella