From d945d53ab59dfa83f8c6e02be5785532b903e2e8 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 27 Jan 2016 07:44:04 +0000 Subject: [PATCH] EgtGeomKernel : - correzione per memory leaks a offset semplice di curve composite - aggiunta creazione regione da curva ingrossata - collisione tra regioni estesa a contorni sia con curve composite sia con singola curva. --- CurveCompositeOffset.cpp | 55 +++++++++----------- SfrCreate.cpp | 110 +++++++++++++++++++++++++++++++++++++++ Simple CDSurfFrMove.cpp | 18 +++---- 3 files changed, 143 insertions(+), 40 deletions(-) diff --git a/CurveCompositeOffset.cpp b/CurveCompositeOffset.cpp index 32c96b9..88b553e 100644 --- a/CurveCompositeOffset.cpp +++ b/CurveCompositeOffset.cpp @@ -64,70 +64,65 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType) double dLenVertFirst = 0 ; double dLenVertLast = 0 ; // recupero la prima curva - ICurve* pCrv1 = ccCopy.RemoveFirstOrLastCurve( false) ; - if ( pCrv1 == nullptr) + PtrOwner pCrv1( ccCopy.RemoveFirstOrLastCurve( false)) ; + if ( IsNull( pCrv1)) return false ; // se la curva è una linea verticale in Z, passo alla successiva - if ( IsVerticalLine( pCrv1, &dLenVertFirst)) { - delete pCrv1 ; + if ( IsVerticalLine( Get( pCrv1), &dLenVertFirst)) { if ( bNoVertLine) return false ; - pCrv1 = ccCopy.RemoveFirstOrLastCurve( false) ; + pCrv1.Set( ccCopy.RemoveFirstOrLastCurve( false)) ; } // offset della prima curva - if ( pCrv1 == nullptr) + if ( IsNull( pCrv1)) return false ; - if ( ! pCrv1->SimpleOffset( dDist, nType)){ - delete pCrv1 ; + if ( ! pCrv1->SimpleOffset( dDist, nType)) return false ; - } - if ( ! ccOffs.AddSimpleCurve( pCrv1)) + ICurve* pCrvPrev = Get( pCrv1) ; + if ( ! ccOffs.AddSimpleCurve( Release( pCrv1))) return false ; // curve successive - ICurve* pCrv2 = ccCopy.RemoveFirstOrLastCurve( false) ; - while ( pCrv2 != nullptr) { + PtrOwner pCrv2( ccCopy.RemoveFirstOrLastCurve( false)) ; + while ( ! IsNull( pCrv2)) { // se la curva è una linea verticale in Z, passo alla successiva - if ( IsVerticalLine( pCrv2, &dLenVertLast)) { - delete pCrv2 ; + if ( IsVerticalLine( Get( pCrv2), &dLenVertLast)) { if ( bNoVertLine) return false ; - pCrv2 = ccCopy.RemoveFirstOrLastCurve( false) ; + pCrv2.Set( ccCopy.RemoveFirstOrLastCurve( false)) ; continue ; } // eseguo semplice offset - if ( ! pCrv2->SimpleOffset( dDist, nType)) { - delete pCrv2 ; + if ( ! pCrv2->SimpleOffset( dDist, nType)) return false ; - } // verifico relazione con la curva precedente e aggiungo eventuali curve intermedie CurveComposite ccTemp ; - if ( VerifyAndAdjustSamePoint( pCrv1, pCrv2, ccTemp) || - VerifyAndAdjustInternalAngle( pCrv1, pCrv2, ccTemp) || - VerifyAndAdjustExternalAngle( pCrv1, pCrv2, dDist, nType, ccTemp)) { + if ( VerifyAndAdjustSamePoint( pCrvPrev, Get( pCrv2), ccTemp) || + VerifyAndAdjustInternalAngle( pCrvPrev, Get( pCrv2), ccTemp) || + VerifyAndAdjustExternalAngle( pCrvPrev, Get( pCrv2), dDist, nType, ccTemp)) { if ( ccTemp.GetCurveCount() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp)) return false ; } // nessun caso è andato a buon fine, errore else return false ; - // inserisco nell'offset - if ( ! ccOffs.AddSimpleCurve( pCrv2)) - return false ; // aggiorno curva precedente - pCrv1 = pCrv2 ; + pCrvPrev = Get( pCrv2) ; + // inserisco nell'offset + if ( ! ccOffs.AddSimpleCurve( Release( pCrv2))) + return false ; // passo alla curva successiva - pCrv2 = ccCopy.RemoveFirstOrLastCurve( false) ; + pCrv2.Set( ccCopy.RemoveFirstOrLastCurve( false)) ; } // se originale chiuso, devo confrontare anche ultima e prima curva if ( bClosed && ccOffs.GetCurveCount() > 0) { // la curva successiva ora è la prima dell'offset - ICurve* pCrv2 = ccOffs.m_CrvSmplS.front() ; + ICurve* pCrvNext = ccOffs.m_CrvSmplS.front() ; // verifico relazione con la curva precedente e aggiungo eventuali curve intermedie CurveComposite ccTemp ; - if ( VerifyAndAdjustSamePoint( pCrv1, pCrv2, ccTemp) || - VerifyAndAdjustInternalAngle( pCrv1, pCrv2, ccTemp) || - VerifyAndAdjustExternalAngle( pCrv1, pCrv2, dDist, nType, ccTemp)) { + if ( VerifyAndAdjustSamePoint( pCrvPrev, pCrvNext, ccTemp) || + VerifyAndAdjustInternalAngle( pCrvPrev, pCrvNext, ccTemp) || + VerifyAndAdjustExternalAngle( pCrvPrev, pCrvNext, dDist, nType, ccTemp)) { if ( ccTemp.GetCurveCount() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp)) return false ; } diff --git a/SfrCreate.cpp b/SfrCreate.cpp index a2a3a95..f5952df 100644 --- a/SfrCreate.cpp +++ b/SfrCreate.cpp @@ -13,9 +13,11 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" +#include "CurveLine.h" #include "CurveArc.h" #include "CurveComposite.h" #include "SurfFlatRegion.h" +#include "GeoConst.h" #include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include @@ -106,6 +108,114 @@ GetSurfFlatRegionDisk( double dRadius) return Release( pSfr) ; } +//------------------------------------------------------------------------------- +ISurfFlatRegion* +GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids) +{ + // mi impossesso della curva + PtrOwner pCurve( pCrv) ; + if ( IsNull( pCurve)) + return nullptr ; + // la inserisco in una curva composita + PtrOwner pCompo1( CreateBasicCurveComposite()) ; + if ( IsNull( pCompo1) || ! pCompo1->AddCurve( Release( pCurve))) + return nullptr ; + // se distanza tra gli estremi minore di due volte il raggio la chiudo + Point3d ptStart, ptEnd ; + pCompo1->GetStartPoint( ptStart) ; + pCompo1->GetEndPoint( ptEnd) ; + if ( Dist( ptStart, ptEnd) <= 2 * dRadius) + pCompo1->Close() ; + // tipo di offset + int nOffsType = ( bSquareMids ? ICurve::OFF_EXTEND : ICurve::OFF_FILLET) ; + // se curva chiusa + if ( pCompo1->IsClosed()) { + // fondo le curve allineate + pCompo1->MergeCurves( LIN_TOL_SFR, ANG_TOL_STD_DEG) ; + // ne faccio una copia e la inverto + PtrOwner pCompo2( GetCurveComposite( pCompo1->Clone())) ; + if ( IsNull( pCompo2) || ! pCompo2->Invert()) + return nullptr ; + // per creare la regione + SurfFlatRegionByContours SfrCntr( false, false) ; + // offset della prima curva a destra del raggio + if ( pCompo1->SimpleOffset( dRadius, nOffsType)) + SfrCntr.AddCurve( Release( pCompo1)) ; + // offset della seconda curva a destra del raggio + if ( pCompo2->SimpleOffset( dRadius, nOffsType)) + SfrCntr.AddCurve( Release( pCompo2)) ; + // creo la regione + return SfrCntr.GetSurf() ; + } + // altrimenti + else { + // se richiesti estremi squadrati, la allungo del raggio alle due estremità + if ( bSquareEnds) { + pCompo1->ExtendStartByLen( dRadius) ; + pCompo1->ExtendEndByLen( dRadius) ; + } + // fondo le curve allineate + pCompo1->MergeCurves( LIN_TOL_SFR, ANG_TOL_STD_DEG) ; + // ne faccio una copia e la inverto + PtrOwner pCompo2( GetCurveComposite( pCompo1->Clone())) ; + if ( IsNull( pCompo2) || ! pCompo2->Invert()) + return nullptr ; + // offset della prima curva a destra del raggio + if ( ! pCompo1->SimpleOffset( dRadius, nOffsType)) + return nullptr ; + // offset della seconda curva a destra del raggio + if ( ! pCompo2->SimpleOffset( dRadius, nOffsType)) + return nullptr ; + // se estremi squadrati + if ( bSquareEnds) { + // aggiungo alla prima curva una linea che la unisca alla seconda + PtrOwner pLine( CreateBasicCurveLine()) ; + Point3d ptEnd1, ptStart2 ; + if ( IsNull( pLine) || + ! pCompo1->GetEndPoint( ptEnd1) || + ! pCompo2->GetStartPoint( ptStart2) || + ! pLine->Set( ptEnd1, ptStart2) || + ! pCompo1->AddCurve( Release( pLine))) + return nullptr ; + // unisco le due curve composite e le chiudo + if ( ! pCompo1->AddCurve( Release( pCompo2)) || ! pCompo1->Close()) + return nullptr ; + } + // altrimenti estremi arrotondati + else { + // aggiungo alla prima curva un arco che la unisca alla seconda + PtrOwner pArc1( CreateBasicCurveArc()) ; + Point3d ptEnd1, ptStart2 ; + Vector3d vtDirEnd1 ; + if ( IsNull( pArc1) || + ! pCompo1->GetEndPoint( ptEnd1) || + ! pCompo1->GetEndDir( vtDirEnd1) || + ! pCompo2->GetStartPoint( ptStart2) || + ! pArc1->Set2PVN( ptEnd1, ptStart2, vtDirEnd1, Z_AX) || + ! pCompo1->AddCurve( Release( pArc1))) + return nullptr ; + // aggiungo alla seconda curva un arco che la unisca alla prima + PtrOwner pArc2( CreateBasicCurveArc()) ; + Point3d ptEnd2, ptStart1 ; + Vector3d vtDirEnd2 ; + if ( IsNull( pArc2) || + ! pCompo2->GetEndPoint( ptEnd2) || + ! pCompo2->GetEndDir( vtDirEnd2) || + ! pCompo1->GetStartPoint( ptStart1) || + ! pArc2->Set2PVN( ptEnd2, ptStart1, vtDirEnd2, Z_AX) || + ! pCompo2->AddCurve( Release( pArc2))) + return nullptr ; + // unisco le due curve composite + if ( ! pCompo1->AddCurve( Release( pCompo2))) + return nullptr ; + } + // creo la regione + SurfFlatRegionByContours SfrCntr( false, false) ; + SfrCntr.AddCurve( Release( pCompo1)) ; + return SfrCntr.GetSurf() ; + } +} + //------------------------------------------------------------------------------- // Classe SurfFlatRegionByContours //------------------------------------------------------------------------------- diff --git a/Simple CDSurfFrMove.cpp b/Simple CDSurfFrMove.cpp index 4d665fc..b4d9dcc 100644 --- a/Simple CDSurfFrMove.cpp +++ b/Simple CDSurfFrMove.cpp @@ -124,14 +124,13 @@ MySimpleCDSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) const ICurve* pCrv1Loc = m_pRegM->GetMyLoop( j, 0) ; // verifico la collisione tra le entità dei loop esterni dei due chunk - // per ora solo curve composite const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ; const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ; int k = 0 ; - const ICurve* pCrv1 = pCompo1->GetFirstCurve() ; + const ICurve* pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetFirstCurve() : pCrv1Loc) ; while ( pCrv1 != nullptr) { int l = 0 ; - const ICurve* pCrv2 = pCompo2->GetFirstCurve() ; + const ICurve* pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetFirstCurve() : pCrv2Loc) ; while ( pCrv2 != nullptr) { SCollInfo scInfoCurr ; double dPrevLenXY = dNewLenXY ; @@ -153,10 +152,10 @@ MySimpleCDSurfFrMove::Translate( const Vector3d& vtDir, double& dLen) m_SCollInfo.nChunkF = i ; m_SCollInfo.nCrvF = l ; } - pCrv2 = pCompo2->GetNextCurve() ; + pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ; ++ l ; } - pCrv1 = pCompo1->GetNextCurve() ; + pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetNextCurve() : nullptr) ; ++ k ; } } @@ -224,18 +223,17 @@ MySimpleCDSurfFrMove::Rotate( const Point3d& ptCen, double& dAng) const ICurve* pCrv1Loc = m_pRegM->GetMyLoop( j, 0) ; // verifico la collisione tra le entità dei loop esterni dei due chunk - // per ora solo curve composite const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ; const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ; - const ICurve* pCrv1 = pCompo1->GetFirstCurve() ; + const ICurve* pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetFirstCurve() : pCrv1Loc) ; while ( pCrv1 != nullptr) { - const ICurve* pCrv2 = pCompo2->GetFirstCurve() ; + const ICurve* pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetFirstCurve() : pCrv2Loc) ; while ( pCrv2 != nullptr) { if ( ! RotateCurveNoCollisionCurve( pCrv1, pCrv2, ptCenL, dNewAng)) return false ; - pCrv2 = pCompo2->GetNextCurve() ; + pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ; } - pCrv1 = pCompo1->GetNextCurve() ; + pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetNextCurve() : nullptr) ; } } }