diff --git a/SurfAux.cpp b/SurfAux.cpp index 75862f4..0bc73af 100644 --- a/SurfAux.cpp +++ b/SurfAux.cpp @@ -24,6 +24,13 @@ #include "/EgtDev/Include/EGkSurfAux.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EGkChainCurves.h" + + +#define SAVEMKUNIF_CRVS 0 +#if SAVEMKUNIF_CRVS + #include "/EgtDev/Include/EGkGeoObjSave.h" +#endif using namespace std ; @@ -530,6 +537,25 @@ NurbsToBezierSurface(const SNurbsSurfData& snData) return Release( pSrfBz) ; } +//---------------------------------------------------------------------------- +ICurveComposite* +GetRectangleCurve( const Point3d& ptStart, double dWidth, double dHeight) +{ + PolyLine PL ; + PL.AddUPoint( 0, ptStart) ; + PL.AddUPoint( 1, Point3d( ptStart.x + dWidth, ptStart.y)) ; + PL.AddUPoint( 2, Point3d( ptStart.x + dWidth, ptStart.y + dHeight, 0)) ; + PL.AddUPoint( 3, Point3d( ptStart.x , ptStart.y + dHeight, 0)) ; + PL.AddUPoint( 4, ptStart) ; + // creo la curva e la inserisco nel GDB + PtrOwner pCrvCompo( CreateCurveComposite()) ; + bool bOk = true ; + bOk = bOk && ! IsNull( pCrvCompo) ; + // inserisco i segmenti che uniscono i punti + bOk = bOk && pCrvCompo->FromPolyLine( PL) ; + return Release( pCrvCompo) ; +} + //---------------------------------------------------------------------------- bool MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, const DBLVECTOR& vV0, @@ -539,10 +565,13 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons bool bRescaledU = false ; bool bRescaledV = false ; int nSpanU = 1, nSpanV = 1 ; - PtrOwner pRescaledSfr( CreateSurfFlatRegion()) ; + ICRVCOMPOPOVECTOR vUniformedCurves ; + BOOLVECTOR vbUniform(2) ; + fill( vbUniform.begin(), vbUniform.end(), true) ; + DBLMATRIX mKnots(2) ; for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) { // vettore dei nodi - DBLVECTOR vU ; + DBLVECTOR& vU = mKnots[nDir] ; int nExtraKnots = 0 ; // controllo in U if ( nDir == 0) { @@ -581,45 +610,97 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons if ( b < (int)vU.size()) d1 = abs( vU[b] - vU[a]) ; } - if ( b != (int)vU.size()) { + if ( b != (int)vU.size()) + vbUniform[nDir] = false ; + } + // vettore delle curve di loop della regione di trim + ICRVCOMPOPOVECTOR vLoop ; + if ( ! vbUniform[0] || ! vbUniform[1]) { + for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++c) { + for ( int l = 0 ; l < pSfr->GetLoopCount( c); ++l) + vLoop.emplace_back( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ; + } + } + +#if SAVEMKUNIF_CRVS + //debug + vector vGeo ; + for( int i = 0 ; i < ssize( vLoop); ++i){ + vGeo.push_back(vLoop[i]->Clone()) ; + } + SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_loops.nge") ; + //debug +#endif + + for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) { + DBLVECTOR& vU = mKnots[nDir] ; + if ( ! vbUniform[nDir]) { nDir == 0 ? bRescaledU = true : bRescaledV = true ; - pRescaledSfr.Set( CreateSurfFlatRegion()) ; - if ( IsNull( pRescaledSfr)) - return false ; + // creo il vettore delle curve all'interno di una striscia + ICRVCOMPOPOVECTOR vCrvStrip ; for ( int p = 0 ; p < (int)vU.size() - 1 ; ++p) { - PtrOwner pSfr_copy( pSfr->Clone()) ; - if ( IsNull( pSfr_copy)) - return false ; double dLenStrip = abs( vU[p+1] - vU[p]) ; if ( dLenStrip < EPS_SMALL) continue ; // creo la maschera per tagliare la superficie originale e ottenere una striscia - PtrOwner pSfrTrim( CreateSurfFlatRegion()) ; + PtrOwner pTrimMask ; // ricavo la maschera del trim, con cui poi farò l'intersezione con la sfr iniziale - Vector3d vtTrim ; if ( nDir == 0) { - pSfrTrim.Set( GetSurfFlatRegionRectangle( dLenStrip, dScaleV + 2)) ; - vtTrim.Set( abs(vU[p] - vU.front()), - 1, 0) ; + Point3d ptStart( abs(vU[p] - vU.front()), - 1, 0) ; + pTrimMask.Set( GetRectangleCurve( ptStart, dLenStrip, dScaleV + 2)) ; } else{ - pSfrTrim.Set( GetSurfFlatRegionRectangle( dScaleU + 2, dLenStrip)) ; - vtTrim.Set( - 1, abs(vU[p] - vU.front()), 0) ; + Point3d ptStart( - 1, abs(vU[p] - vU.front()), 0) ; + pTrimMask.Set( GetRectangleCurve( ptStart, dScaleU + 2, dLenStrip)) ; } - pSfrTrim->Translate( vtTrim) ; - if ( ! pSfr_copy->Intersect( *pSfrTrim)) - return false ; + // qui potrei decidere di eliminare tutti i tratti dei loop paralleli alla direzione del parametro che sto analizzando ( e di valore coincidente a quello di un nodo) - // aggiungo la nuova striscia solo se è valida - if ( pSfr_copy->IsValid() ) { + for ( int l = 0 ; l < ssize( vLoop); ++l) { + #if SAVEMKUNIF_CRVS + //debug + vector vGeo ; + vGeo.push_back(pTrimMask->Clone()) ; + vGeo.push_back(vLoop[l]->Clone()) ; + SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_inters.nge") ; + //debug + #endif + IntersCurveCurve icc( *pTrimMask, *vLoop[l]) ; + CRVCVECTOR vCurveClass ; + icc.GetCurveClassification( 1, 10 * EPS_SMALL, vCurveClass) ; + for( int i = 0 ; i < ssize( vCurveClass); ++i) { + if( vCurveClass[i].nClass == CRVC_IN || vCurveClass[i].nClass == CRVC_ON_P || vCurveClass[i].nClass == CRVC_ON_M) + vCrvStrip.emplace_back( ConvertCurveToComposite( vLoop[l]->CopyParamRange( vCurveClass[i].dParS, vCurveClass[i].dParE))) ; + } + } + + #if SAVEMKUNIF_CRVS + //debug + vector vGeo ; + for( int i = 0 ; i < ssize( vCrvStrip); ++i){ + vGeo.push_back(vCrvStrip[i]->Clone()) ; + } + SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_strip.nge") ; + //debug + #endif + + // riscalo le curve nella striscia + if ( ! vCrvStrip.empty()) { + double dCoeffX = 1, dCoeffY = 1 ; + if ( nDir == 0) - pSfr_copy->Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ; - else - pSfr_copy->Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ; - - // prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo + dCoeffX = SBZ_TREG_COEFF / dLenStrip ; + else + dCoeffY = SBZ_TREG_COEFF / dLenStrip ; + for( int i = 0 ; i < ssize( vCrvStrip); ++i) { + if( ! IsNull( vCrvStrip[i])) + vCrvStrip[i]->Scale( GLOB_FRM, dCoeffX, dCoeffY, 1) ; + else + return false ; + } + // prima di riunire le curve al resto devo traslarle sul bordo destro della superificie che sto ricostruendo Point3d pt ; nDir == 0 ? pt.Set( abs(vU[p] - vU.front()), 0, 0) : pt.Set( 0,abs(vU[p] - vU.front()), 0) ; if ( nDir == 0) @@ -632,25 +713,78 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons vtJoin.Set( p * SBZ_TREG_COEFF - pt.x, 0, 0) ; else vtJoin.Set( 0, p * SBZ_TREG_COEFF - pt.y, 0) ; - pSfr_copy->Translate( vtJoin) ; - // se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET - if ( bRetry) - pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // OFFSET - if ( pRescaledSfr->IsValid()) { - if ( ! pRescaledSfr->Add( *pSfr_copy)) - return false ; + for( int i = 0 ; i < ssize( vCrvStrip); ++i) + vCrvStrip[i]->Translate( vtJoin) ; + + #if SAVEMKUNIF_CRVS + //debug + vector vGeo ; + for( int i = 0 ; i < ssize( vCrvStrip); ++i){ + vGeo.push_back(vCrvStrip[i]->Clone()) ; + } + SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_strip.nge") ; + //debug + #endif + + // faccio la chain con le curve delle striscie precedenti + + if ( ! vUniformedCurves.empty() || ! vCrvStrip.empty()) { + #if SAVEMKUNIF_CRVS + //debug + vector vGeo ; + for( int i = 0 ; i < ssize( vUniformedCurves); ++i){ + vGeo.push_back(vUniformedCurves[i]->Clone()) ; + } + SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_unif.nge") ; + //debug + #endif + + ChainCurves chainCrv ; + double dChainTol = 5 * EPS_SMALL ; + chainCrv.Init( false, dChainTol, max(ssize( vUniformedCurves), ssize(vCrvStrip))) ; + for ( int c = 0 ; c < ssize( vUniformedCurves) ; ++c) { + Point3d ptStart, ptEnd ; + Vector3d vtStart, vtEnd ; + vUniformedCurves[c]->GetStartPoint( ptStart) ; + vUniformedCurves[c]->GetEndPoint( ptEnd) ; + vUniformedCurves[c]->GetStartDir( vtStart) ; + vUniformedCurves[c]->GetEndDir( vtEnd) ; + chainCrv.AddCurve( 1 + c, ptStart, vtStart, ptEnd, vtEnd) ; + } + for ( int c = 0 ; c < ssize( vCrvStrip); ++c) { + Point3d ptStart, ptEnd ; + Vector3d vtStart, vtEnd ; + vCrvStrip[c]->GetStartPoint( ptStart) ; + vCrvStrip[c]->GetEndPoint( ptEnd) ; + vCrvStrip[c]->GetStartDir( vtStart) ; + vCrvStrip[c]->GetEndDir( vtEnd) ; + chainCrv.AddCurve( 1 + ssize( vUniformedCurves) + c, ptStart, vtStart, ptEnd, vtEnd) ; + } + INTVECTOR vIds ; + ICRVCOMPOPOVECTOR vNewCrv ; + int nCrvPrec = ssize( vUniformedCurves) ; + while ( chainCrv.GetChainFromNear( ORIG, false, vIds)) { + vNewCrv.emplace_back( CreateBasicCurveComposite()) ; + for ( int nId : vIds) { + nId -= 1 ; + if ( nId < nCrvPrec) + vNewCrv.back()->AddCurve( Release( vUniformedCurves[nId]), true, dChainTol) ; + else + vNewCrv.back()->AddCurve( Release( vCrvStrip[nId - ssize( vUniformedCurves)]), true, dChainTol) ; + } + } + // aggiorno le curve + vUniformedCurves.clear() ; + vUniformedCurves.swap( vNewCrv) ; } - else - pRescaledSfr.Set( pSfr_copy) ; } + vCrvStrip.clear() ; } if ( nDir == 0) { dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ; - if ( pRescaledSfr->IsValid()) { - if ( bRetry) - pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; //contro OFFSET - delete pSfr ; - pSfr = Release( pRescaledSfr) ; + if( ! vbUniform[1]) { + vLoop.swap( vUniformedCurves) ; + vUniformedCurves.clear() ; } } else @@ -658,12 +792,38 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons } } - if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) { - if ( bRetry) - pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET - delete pSfr ; - pSfr = Release( pRescaledSfr) ; + if ( ! vUniformedCurves.empty()) { + #if SAVEMKUNIF_CRVS + //debug + vector vGeo ; + for( int i = 0 ; i < ssize( vUniformedCurves); ++i){ + vGeo.push_back(vUniformedCurves[i]->Clone()) ; + } + SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_unif.nge") ; + //debug + #endif + + // controllo che tutte le curve siano chiuse, sennò vuol dire che ho perso qualche pezzo durante le intersezioni + for ( int i = 0 ; i < ssize( vUniformedCurves); ++i) { + if ( ! vUniformedCurves[i]->IsClosed()) + return false ; + } + + // creo una regione dalle curve riscalate + SurfFlatRegionByContours sfrRescaled ; + for ( int i = 0 ; i < ssize( vUniformedCurves); ++i) + sfrRescaled.AddCurve( Release( vUniformedCurves[i])) ; + + PtrOwner pRescaledSfr( sfrRescaled.GetSurf()) ; + if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) { + delete pSfr ; + pSfr = Release( pRescaledSfr) ; + } + else + return false ; } + else if( ! vbUniform[0] || ! vbUniform[1]) + return false ; if ( ! bRescaledU && ! bRescaledV) pSfr->Scale( GLOB_FRM, nSpanU / dScaleU * SBZ_TREG_COEFF, nSpanV / dScaleV * SBZ_TREG_COEFF, 1) ;