diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index 8c2a4f5..920a9e1 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index 6de2a81..d48ee68 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -321,10 +321,12 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
@@ -472,6 +474,7 @@ copy $(TargetPath) \EgtProg\Dll64
+
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index 8dd2118..249bad2 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -318,6 +318,12 @@
File di origine\Gdb
+
+ File di origine\Geo
+
+
+ File di origine\GeoInters
+
@@ -719,6 +725,9 @@
File di intestazione
+
+ File di intestazione
+
diff --git a/IntersArcArc.cpp b/IntersArcArc.cpp
index a6b4048..ca96ba7 100644
--- a/IntersArcArc.cpp
+++ b/IntersArcArc.cpp
@@ -80,6 +80,9 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
Point3d ptS2, ptE2 ;
if ( ! m_Arc2.GetStartPoint( ptS2) || ! m_Arc2.GetEndPoint( ptE2))
return ;
+ // determino se sono chiusi ( cerchi)
+ bool bClosed1 = AreSamePointApprox( ptS1, ptE1) ;
+ bool bClosed2 = AreSamePointApprox( ptS2, ptE2) ;
// calcolo del parametro di inizio dell'arco 2 nel riferimento dell'arco 1
double dUS2 ;
int nPosS2 ;
@@ -157,8 +160,8 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
m_bOverlaps = true ;
m_nNumInters = 1 ;
}
- // se il massimo di 2 coincide con il minimo di 1 nel secondo giro e 1 non completo -> un punto estremo
- if ( fabs( dTurnU - dU2max) * dU2L < EPS_SMALL && dTurnU < 1 - EPS_PARAM) {
+ // se il massimo di 2 coincide con il minimo di 1 nel secondo giro e 1 e 2 non completi -> un punto estremo
+ if ( fabs( dTurnU - dU2max) * dU2L < EPS_SMALL && ! bClosed1 && ! bClosed2) {
m_Info[m_nNumInters].IciA[0].dU = 0 ;
m_Info[m_nNumInters].IciB[0].dU = ( bEqVers ? 1 : 0) ;
m_Info[m_nNumInters].IciA[0].ptI = ptS1 ;
diff --git a/OffsetCurve.cpp b/OffsetCurve.cpp
index 21ee627..6f4fd6b 100644
--- a/OffsetCurve.cpp
+++ b/OffsetCurve.cpp
@@ -36,6 +36,8 @@ static bool VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2) ;
static bool VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, double dDist, int nType,
CurveComposite& ccAux) ;
static double GetMinDist( double dCoeff, ICurve* pCrv1, ICurve* pCrv2) ;
+static bool IsFillet( ICurve* pCrv, double dDist) ;
+static bool ModifyFillet( ICurve* pCrv, double dDist, int nType, CurveComposite& ccAux) ;
//----------------------------------------------------------------------------
@@ -54,16 +56,40 @@ OffsetCurve::~OffsetCurve( void)
bool
OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
{
- // verifico che la curva esista e si trovi nel piano XY o in uno ad esso parallelo
+ // verifico che la curva esista e sia piana
Plane3d plPlane ;
- if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane) ||
- ! ( plPlane.vtN.IsZplus() || plPlane.vtN.IsZminus()))
+ if ( pCrv == nullptr || ! pCrv->IsFlat( plPlane))
return false ;
+ // se esiste estrusione, verifico sia perpendicolare al piano della curva
+ Vector3d vtExtr ;
+ if ( pCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall()) {
+ if ( ! AreSameOrOppositeVectorApprox( plPlane.vtN, vtExtr))
+ return false ;
+ }
+ else
+ vtExtr = plPlane.vtN ;
- // creo una copia formata solo da rette e archi che giacciono nel piano XY (VtExtr è Z+)
+ // determino se necessario cambiare riferimento ( dal vettore estrusione)
+ bool bNeedRef = ( ! vtExtr.IsZplus()) ;
+
+ // creo una copia della curva
CurveComposite ccCopy ;
- if ( ! ccCopy.CopyFrom( pCrv) ||
- ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( 10 * EPS_SMALL, ANG_TOL_STD_DEG))
+ if ( ! ccCopy.CopyFrom( pCrv))
+ return false ;
+ ccCopy.SetExtrusion( vtExtr) ;
+
+ // se necessario cambio il riferimento
+ Frame3d frExtr ;
+ if ( bNeedRef) {
+ // calcolo il riferimento OCS con VtExtr come asse Z
+ if ( ! frExtr.Set( ORIG, vtExtr))
+ return false ;
+ // esprimo la curva in questo riferimento
+ ccCopy.ToLoc( frExtr) ;
+ }
+
+ // verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
+ if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( 10 * EPS_SMALL, ANG_TOL_STD_DEG))
return false ;
// verifico se curva chiusa e non forzata aperta
@@ -108,7 +134,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
vAngs.push_back( 0) ;
}
- // primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni
+ // primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni (sempre fillet)
CurveComposite ccCopy2 ;
if ( ! ccCopy2.CopyFrom( &ccCopy))
return false ;
@@ -119,27 +145,29 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
if ( IsNull( pCrv1))
return false ;
pCrv1->SetTempProp( nInd1) ;
- if ( ! pCrv1->SimpleOffset( dDist, nType) &&
- GetBasicCurveArc( Get( pCrv1))->MyExtendedOffset( dDist, true, nType))
+ if ( ! pCrv1->SimpleOffset( dDist, ICurve::OFF_FILLET) &&
+ GetBasicCurveArc( Get( pCrv1))->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, nType) &&
- GetBasicCurveArc( Get( pCrv2))->MyExtendedOffset( dDist, true, nType))
+ if ( ! pCrv2->SimpleOffset( dDist, ICurve::OFF_FILLET) &&
+ GetBasicCurveArc( Get( pCrv2))->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( Get( pCrv1), Get( pCrv2), vAngs[nInd1], dDist, nType, ccTemp) ;
+ bool bOk = VerifyAndAdjustExternalAngle( Get( pCrv1), Get( pCrv2), vAngs[nInd1], dDist, ICurve::OFF_FILLET, ccTemp) ;
// metto in lista curva precedente
m_CrvLst.push_back( Release( pCrv1)) ;
// se aggiunto qualcosa, lo metto in lista
if ( ccTemp.GetCurveCount() > 0) {
PtrOwner pCrv3( ccTemp.RemoveFirstOrLastCurve( false)) ;
- while ( ! IsNull( pCrv3))
+ while ( ! IsNull( pCrv3)) {
m_CrvLst.push_back( Release( pCrv3)) ;
+ pCrv3.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
+ }
}
// aggiorno curva precedente
++ nInd1 ;
@@ -159,12 +187,14 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
ICurve* pCrv2 = m_CrvLst.front() ;
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
CurveComposite ccTemp ;
- bool bOk = VerifyAndAdjustExternalAngle( pCrv1, pCrv2, vAngs[nInd1], dDist, nType, ccTemp) ;
+ bool bOk = VerifyAndAdjustExternalAngle( pCrv1, pCrv2, vAngs[nInd1], dDist, ICurve::OFF_FILLET, ccTemp) ;
// se aggiunto qualcosa, lo metto in lista
if ( ccTemp.GetCurveCount() > 0) {
PtrOwner pCrv3( ccTemp.RemoveFirstOrLastCurve( false)) ;
- while ( ! IsNull( pCrv3))
+ while ( ! IsNull( pCrv3)) {
m_CrvLst.push_back( Release( pCrv3)) ;
+ pCrv3.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
+ }
}
}
@@ -368,6 +398,48 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
++ iIter ;
}
+ // ottavo passo : se con smusso o estensione, sostituisco i fillet con questi
+ if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
+ for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) {
+ // processo le curve semplici della composita
+ CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
+ ICURVEPLIST CrvLst ;
+ PtrOwner pCrv( pCrvCo->RemoveFirstOrLastCurve( false)) ;
+ while ( ! IsNull( pCrv)) {
+ // se fillet lo trasformo in smusso o estensione
+ if ( IsFillet( Get( pCrv), dDist)) {
+ CurveComposite ccTemp ;
+ bool bOk = ModifyFillet( Get( pCrv), dDist, nType, ccTemp) ;
+ // metto in lista le curve risultanti
+ if ( ccTemp.GetCurveCount() > 0) {
+ PtrOwner pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
+ while ( ! IsNull( pCrv2)) {
+ CrvLst.push_back( Release( pCrv2)) ;
+ pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
+ }
+ }
+ }
+ // altrimenti salvo in lista
+ else
+ CrvLst.push_back( Release( pCrv)) ;
+ // passo alla curva successiva
+ pCrv.Set( pCrvCo->RemoveFirstOrLastCurve( false)) ;
+ }
+ // rimetto le curve nella composita
+ for ( auto pCrv : CrvLst) {
+ pCrvCo->AddCurve( pCrv) ;
+ }
+ // unisco tratti allineati
+ pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
+ }
+ }
+
+ // riporto il risultato nel riferimento originale
+ if ( bNeedRef) {
+ for ( auto pCrv : m_CrvLst)
+ pCrv->ToGlob( frExtr) ;
+ }
+
return true ;
}
@@ -692,4 +764,109 @@ GetMinDist( double dCoeff, ICurve* pCrv1, ICurve* pCrv2)
if ( ! dstPC.GetDist( dMinDist))
return 0 ;
return dMinDist ;
-}
\ No newline at end of file
+}
+
+//----------------------------------------------------------------------------
+bool
+IsFillet( ICurve* pCrv, double dDist)
+{
+ // deve essere un arco
+ if ( pCrv->GetType() != CRV_ARC)
+ return false ;
+ CurveArc* pArc = GetBasicCurveArc( pCrv) ;
+ // deve avere raggio uguale alla distanza di offset
+ if ( fabs( pArc->GetRadius() - fabs( dDist)) > EPS_SMALL)
+ return false ;
+ // deve essere CCW se offset a destra e CW se offset a sinistra
+ return ( pArc->GetAngCenter() * dDist > 0) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+ModifyFillet( ICurve* pCrv, double dDist, int nType, CurveComposite& ccAux)
+{
+ // la curva deve essere un arco
+ CurveArc* pArc = GetBasicCurveArc( pCrv) ;
+ if ( pArc == nullptr)
+ return false ;
+
+ // angolo al centro dell'arco
+ double dAngDeg = pArc->GetAngCenter() ;
+
+ // elimino dal tipo le parti estranee all'angolo esterno
+ nType &= ( ICurve::OFF_FILLET | ICurve::OFF_CHAMFER | ICurve::OFF_EXTEND) ;
+
+ // se l'angolo esterno supera il retto, offset extend diventa offset chamfer
+ if ( nType == ICurve::OFF_EXTEND && fabs( dAngDeg) > ANG_RIGHT + EPS_ANG_SMALL)
+ nType = ICurve::OFF_CHAMFER ;
+
+ // se angolo esterno molto piccolo, semplifico tutto
+ const double SMALL_EXT_ANG = 1.0 ;
+ bool bAngSmall = ( fabs( dAngDeg) < SMALL_EXT_ANG) ;
+ if ( bAngSmall)
+ nType = ICurve::OFF_EXTEND ;
+
+ switch ( nType) {
+ case ICurve::OFF_CHAMFER :
+ {
+ // lunghezza aggiuntiva in tangenza
+ double dLen = fabs( dDist) * tan( fabs( dAngDeg) / 4 * DEGTORAD) ;
+ // punti di costruzione smusso
+ Point3d ptP1, ptP1a, ptP2a, ptP2 ;
+ if ( ! pArc->GetStartPoint( ptP1) || ! pArc->GetEndPoint( ptP2))
+ return false ;
+ Vector3d vtDir1, vtDir2 ;
+ if ( ! pArc->GetStartDir( vtDir1) || ! pArc->GetEndDir( vtDir2))
+ return false ;
+ ptP1a = ptP1 + vtDir1 * dLen ;
+ ptP2a = ptP2 - vtDir2 * dLen ;
+ // aggiungo una nuova linea
+ PtrOwner pLine1( CreateBasicCurveLine()) ;
+ if ( IsNull( pLine1) || ! pLine1->Set( ptP1, ptP1a))
+ return false ;
+ if ( ! ccAux.AddCurve( Release( pLine1)))
+ return false ;
+ // tratto intermedio
+ PtrOwner pLine2( CreateBasicCurveLine()) ;
+ if ( IsNull( pLine2) || ! pLine2->Set( ptP1a, ptP2a))
+ return false ;
+ if ( ! ccAux.AddCurve( Release( pLine2)))
+ return false ;
+ // aggiungo una nuova linea
+ PtrOwner pLine3( CreateBasicCurveLine()) ;
+ if ( IsNull( pLine3) || ! pLine3->Set( ptP2a, ptP2))
+ return false ;
+ if ( ! ccAux.AddCurve( Release( pLine3)))
+ return false ;
+ return true ;
+ }
+ break ;
+ case ICurve::OFF_EXTEND :
+ {
+ // lunghezza aggiuntiva in tangenza
+ double dLen = fabs( dDist) * tan( fabs( dAngDeg) / 2 * DEGTORAD) ;
+ // punti di costruzione estensione
+ Point3d ptP1, ptPc, ptP2 ;
+ if ( ! pArc->GetStartPoint( ptP1) || ! pArc->GetEndPoint( ptP2))
+ return false ;
+ Vector3d vtDir1, vtDir2 ;
+ if ( ! pArc->GetStartDir( vtDir1) || ! pArc->GetEndDir( vtDir2))
+ return false ;
+ ptPc = ptP1 + vtDir1 * dLen ;
+ // aggiungo una nuova linea
+ PtrOwner pLine1( CreateBasicCurveLine()) ;
+ if ( IsNull( pLine1) || ! pLine1->Set( ptP1, ptPc))
+ return false ;
+ if ( ! ccAux.AddCurve( Release( pLine1)))
+ return false ;
+ // aggiungo una nuova linea
+ PtrOwner pLine2( CreateBasicCurveLine()) ;
+ if ( IsNull( pLine2) || ! pLine2->Set( ptPc, ptP2))
+ return false ;
+ if ( ! ccAux.AddCurve( Release( pLine2)))
+ return false ;
+ return true ;
+ }
+ }
+ return false ;
+}
diff --git a/RemoveCurveOverlaps.cpp b/RemoveCurveOverlaps.cpp
new file mode 100644
index 0000000..2a657a6
--- /dev/null
+++ b/RemoveCurveOverlaps.cpp
@@ -0,0 +1,158 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2015
+//----------------------------------------------------------------------------
+// File : RemoveCurveOverlaps.cpp Data : 02.11.15 Versione : 1.6K1
+// Contenuto : Implementazione rimozione sovrapposizioni di curva.
+//
+//
+//
+// Modifiche : 02.11.15 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "GeoConst.h"
+#include "CurveComposite.h"
+#include "RemoveCurveOverlaps.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
+#include "/EgtDev/Include/EGkIntervals.h"
+#include "/EgtDev/Include/EgtPointerOwner.h"
+#include
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+bool
+RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst)
+{
+ // Pulisco lista di ritorno
+ CrvLst.clear() ;
+
+ // Acquisisco la curva
+ PtrOwner pMyCrv( pCurve) ;
+
+ // Verifico validità curva
+ if ( IsNull( pMyCrv) || ! pMyCrv->IsValid())
+ return false ;
+
+ // Se nulla da rimuovere, non devo fare alcunché
+ if ( ! bRemoveSam && ! bRemoveCtr) {
+ CrvLst.push_back( Release( pMyCrv)) ;
+ return true ;
+ }
+
+ // --- la verifica ed eventuale rimozione va effettuata in un piano perpendicolare al vettore estrusione ---
+
+ // verifico il vettore estrusione
+ Vector3d vtExtr ;
+ pMyCrv->GetExtrusion( vtExtr) ;
+ bool bNeedRef = ( ! vtExtr.IsSmall() && ! vtExtr.IsZplus()) ;
+
+ // se necessario cambio il riferimento
+ Frame3d frExtr ;
+ if ( bNeedRef) {
+ // calcolo il riferimento OCS con VtExtr come asse Z
+ if ( ! frExtr.Set( ORIG, vtExtr))
+ return false ;
+ // esprimo la curva in questo riferimento
+ pMyCrv->ToLoc( frExtr) ;
+ }
+
+ // Calcolo le auto intersezioni
+ SelfIntersCurve sintC( *pMyCrv) ;
+ // se non ci sono sovrapposizioni, non devo fare alcunché
+ if ( ! sintC.GetOverlaps()) {
+ // riporto la curva nel riferimento originale
+ if ( bNeedRef)
+ pMyCrv->ToGlob( frExtr) ;
+ // la inserisco in lista
+ CrvLst.push_back( Release( pMyCrv)) ;
+ return true ;
+ }
+
+ // Determino intervallo complessivo della curva
+ double dStart, dEnd ;
+ if ( ! pMyCrv->GetDomain( dStart, dEnd))
+ return false ;
+ Intervals inOk( EPS_PARAM) ;
+ inOk.Set( dStart, dEnd) ;
+
+ // Tolgo le parti in sovrapposizione da eliminare
+ IntCrvCrvInfo iccInfo ;
+ for ( int i = 0 ; sintC.GetIntCrvCrvInfo( i, iccInfo) ; ++ i) {
+ // se sovrapposti
+ if ( iccInfo.bOverlap) {
+ // se equiversi e da eliminare, elimino solo uno dei due tratti
+ if ( iccInfo.bCBOverEq && bRemoveSam) {
+ inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
+ }
+ // se altrimenti controversi e da eliminare, elimino entrambi i tratti
+ else if ( ! iccInfo.bCBOverEq && bRemoveCtr) {
+ inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ;
+ inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
+ }
+ }
+ }
+
+ // Copio le parti da conservare
+ double dParS, dParE ;
+ bool bFound = inOk.GetFirst( dParS, dParE) ;
+ while ( bFound) {
+ ICurve* pCrv = pMyCrv->CopyParamRange( dParS, dParE) ;
+ if ( pCrv != nullptr) {
+ if ( pCrv->GetType() == CRV_COMPO)
+ CrvLst.push_back( pCrv) ;
+ else {
+ CurveComposite* pCrvCo = new( std::nothrow) CurveComposite ;
+ if ( pCrvCo != nullptr) {
+ pCrvCo->AddCurve( pCrv) ;
+ CrvLst.push_back( pCrvCo) ;
+ }
+ }
+ }
+ bFound = inOk.GetNext( dParS, dParE) ;
+ }
+
+ // Concateno i percorsi risultanti (senza cambiare verso)
+ for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) {
+ CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
+ // recupero punti iniziale e finale della curva
+ Point3d ptStart, ptEnd ;
+ pCrvCo->GetStartPoint( ptStart) ;
+ pCrvCo->GetEndPoint( ptEnd) ;
+ // ciclo sulle curve successive per verificare se possibile concatenamento
+ for ( auto iIter2 = next( iIter) ; iIter2 != CrvLst.end() ;) {
+ CurveComposite* pCrvCo2 = GetBasicCurveComposite( *iIter2) ;
+ // recupero punti iniziale e finale della curva
+ Point3d ptStart2, ptEnd2 ;
+ pCrvCo2->GetStartPoint( ptStart2) ;
+ pCrvCo2->GetEndPoint( ptEnd2) ;
+ // verifiche di concatenamento
+ if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL)) {
+ pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ;
+ CrvLst.erase( iIter2) ;
+ ptEnd = ptEnd2 ;
+ iIter2 = next( iIter) ;
+ }
+ else if ( AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
+ pCrvCo->AddCurve( pCrvCo2, false, 10 * EPS_SMALL) ;
+ CrvLst.erase( iIter2) ;
+ ptStart = ptStart2 ;
+ iIter2 = next( iIter) ;
+ }
+ else
+ ++ iIter2 ;
+ }
+ ++ iIter ;
+ }
+
+ // riporto la curva nel riferimento originale
+ if ( bNeedRef) {
+ for ( auto pCrv : CrvLst)
+ pCrv->ToGlob( frExtr) ;
+ }
+
+ return true ;
+}
\ No newline at end of file
diff --git a/RemoveCurveOverlaps.h b/RemoveCurveOverlaps.h
new file mode 100644
index 0000000..fa085de
--- /dev/null
+++ b/RemoveCurveOverlaps.h
@@ -0,0 +1,20 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2015
+//----------------------------------------------------------------------------
+// File : RemoveCurveOverlaps.h Data : 02.11.15 Versione : 1.6k1
+// Contenuto : Dichiarazione funzione rimozione sovrapposizioni curve.
+//
+//
+//
+// Modifiche : 02.11.15 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include "/EgtDev/Include/EGkCurve.h"
+
+
+//----------------------------------------------------------------------------
+bool RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst) ;
diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp
index b879d5d..9d72d98 100644
--- a/SurfFlatRegion.cpp
+++ b/SurfFlatRegion.cpp
@@ -18,6 +18,8 @@
#include "NgeWriter.h"
#include "NgeReader.h"
#include "CurveAux.h"
+#include "CurveComposite.h"
+#include "RemoveCurveOverlaps.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkUiUnits.h"
@@ -80,6 +82,28 @@ SurfFlatRegion::AddExtLoop( const ICurve& cCrv)
//----------------------------------------------------------------------------
bool
SurfFlatRegion::AddExtLoop( ICurve* pCrv)
+{
+ // rimuovo eventuali sovrapposizioni
+ ICURVEPLIST CrvLst ;
+ if ( ! RemoveCurveOverlaps( pCrv, true, true, CrvLst))
+ return false ;
+ // aggiungo le singole curve
+ bool bOk = true ;
+ for ( auto& pCrv : CrvLst) {
+ // se curva composita, unisco eventuali tratti allineati
+ CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
+ if ( pCrvCo != nullptr)
+ pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
+ // aggiungo il loop
+ if ( ! AddSimpleExtLoop( pCrv))
+ bOk = false ;
+ }
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
{
// acquisisco la curva
PtrOwner pMyCrv( pCrv) ;
@@ -116,7 +140,10 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
// porto la curva nel riferimento intrinseco
if ( ! pMyCrv->ToLoc( m_frF))
return false ;
- // verifico non abbia auto-intersezioni che si attraversano
+ Vector3d vtExtr ;
+ if ( pMyCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
+ pMyCrv->SetExtrusion( Z_AX) ;
+ // verifico non abbia auto-intersezioni che si attraversano o si sovrappongano
SelfIntersCurve sInt( *pMyCrv) ;
if ( sInt.GetCrossOrOverlapIntersCount() > 0)
return false ;
@@ -190,6 +217,28 @@ SurfFlatRegion::AddIntLoop( const ICurve& cCrv)
//----------------------------------------------------------------------------
bool
SurfFlatRegion::AddIntLoop( ICurve* pCrv)
+{
+ // rimuovo eventuali sovrapposizioni
+ ICURVEPLIST CrvLst ;
+ if ( ! RemoveCurveOverlaps( pCrv, true, true, CrvLst))
+ return false ;
+ // aggiungo le singole curve
+ bool bOk = true ;
+ for ( auto& pCrv : CrvLst) {
+ // se curva composita, unisco eventuali tratti allineati
+ CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
+ if ( pCrvCo != nullptr)
+ pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
+ // aggiungo il loop
+ if ( ! AddSimpleIntLoop( pCrv))
+ bOk = false ;
+ }
+ return bOk ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
{
// acquisisco la curva
PtrOwner pMyCrv( pCrv) ;
@@ -204,6 +253,9 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv)
// porto la curva nel riferimento intrinseco
if ( ! pMyCrv->ToLoc( m_frF))
return false ;
+ Vector3d vtExtr ;
+ if ( pMyCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
+ pMyCrv->SetExtrusion( Z_AX) ;
// verifico sia piana e il piano coincida con quello XY intrinseco
double dArea ;
Plane3d plPlane ;
diff --git a/SurfFlatRegion.h b/SurfFlatRegion.h
index 49f2845..8b99ab6 100644
--- a/SurfFlatRegion.h
+++ b/SurfFlatRegion.h
@@ -78,6 +78,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
virtual bool Add( const ISurfFlatRegion& Other) ;
virtual bool Subtract( const ISurfFlatRegion& Other) ;
virtual bool Intersect( const ISurfFlatRegion& Other) ;
+ virtual bool Offset( double dDist, int nType) ;
virtual const Vector3d& GetNormVersor( void) const
{ return m_frF.VersZ() ; }
virtual int GetChunkCount( void) const ;
@@ -110,7 +111,9 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
private :
bool CopyFrom( const SurfFlatRegion& clSrc) ;
+ bool AddSimpleExtLoop( ICurve* pCrv) ;
bool MyAddExtLoop( ICurve* pCrv) ;
+ bool AddSimpleIntLoop( ICurve* pCrv) ;
bool MyAddIntLoop( ICurve* pCrv) ;
int GetIndFromChunkLoop( int nChunk, int nLoop) const ;
bool GetChunkLoopFromInd( int nInd, int& nChunk, int& nLoop) const ;
diff --git a/SurfFlatRegionBooleans.cpp b/SurfFlatRegionBooleans.cpp
index be03dbc..82b3571 100644
--- a/SurfFlatRegionBooleans.cpp
+++ b/SurfFlatRegionBooleans.cpp
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
-// File : SurfFlatRegion.cpp Data : 18.08.15 Versione : 1.6h4
+// File : SurfFlatRegionBooleans.cpp Data : 18.08.15 Versione : 1.6h4
// Contenuto : Implementazione delle funzioni booleane per SurfFlatRegion.
//
//
@@ -158,7 +158,11 @@ SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
}
// creo una nuova regione a partire da questi loop
- PtrOwner pSfr( MyNewSurfFromLoops( vpLoop)) ;
+ PtrOwner pSfr ;
+ if ( vpLoop.size() == 0)
+ pSfr.Set( new SurfFlatRegion) ;
+ else
+ pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
if ( IsNull( pSfr))
return false ;
@@ -237,7 +241,11 @@ SurfFlatRegion::Intersect( const ISurfFlatRegion& Other)
}
// creo una nuova regione a partire da questi loop
- PtrOwner pSfr( MyNewSurfFromLoops( vpLoop)) ;
+ PtrOwner pSfr ;
+ if ( vpLoop.size() == 0)
+ pSfr.Set( new SurfFlatRegion) ;
+ else
+ pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
if ( IsNull( pSfr))
return false ;
diff --git a/SurfFlatRegionOffset.cpp b/SurfFlatRegionOffset.cpp
new file mode 100644
index 0000000..215185f
--- /dev/null
+++ b/SurfFlatRegionOffset.cpp
@@ -0,0 +1,98 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2015
+//----------------------------------------------------------------------------
+// File : SurfFlatRegionOffset.cpp Data : 01.11.15 Versione : 1.6k1
+// Contenuto : Implementazione della funzione offset per SurfFlatRegion.
+//
+//
+//
+// Modifiche : 01.11.15 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "SurfFlatRegion.h"
+#include "/EgtDev/Include/EgkOffsetCurve.h"
+#include "/EgtDev/Include/EgtPointerOwner.h"
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+bool
+SurfFlatRegion::Offset( double dDist, int nType)
+{
+ // recupero il numero dei chunk
+ int nChunk = GetChunkCount() ;
+ if ( nChunk == 0)
+ return false ;
+ // creo una nuova regione
+ PtrOwner pSfr( new SurfFlatRegion) ;
+ if ( IsNull( pSfr))
+ return false ;
+ // ciclo sui chunk
+ bool bFirstCurve = true ;
+ for ( int i = 0 ; i < nChunk ; ++ i) {
+ // ciclo sui loop di ogni chunk
+ int nLoop = GetLoopCount( i) ;
+ for ( int j = 0 ; j < nLoop ; ++ j) {
+ // recupero il loop
+ ICurve* pLoop = GetMyLoop( i, j) ;
+ if ( pLoop == nullptr)
+ return false ;
+ // ne eseguo l'offset
+ OffsetCurve OffsCrv ;
+ bool bOk = OffsCrv.Make( pLoop, dDist, nType) ;
+ // recupero le curve di offset
+ PtrOwner pOffs( OffsCrv.GetCurve()) ;
+ while ( bOk && ! IsNull( pOffs)) {
+ // se prima curva esterna in assoluto, è il primo contorno esterno della nuova regione
+ if ( bFirstCurve && j == 0) {
+ if ( ! pSfr->AddExtLoop( Release( pOffs)))
+ return false ;
+ bFirstCurve = false ;
+ }
+ // altrimenti aggiungo o sottraggo la regione della curva alla nuova regione
+ else if ( ! bFirstCurve) {
+ // se loop interno, inverto la curva
+ if ( j != 0)
+ pOffs->Invert() ;
+ // creo la regione
+ PtrOwner pSfr2( new SurfFlatRegion) ;
+ if ( IsNull( pSfr2) || ! pSfr2->AddExtLoop( Release( pOffs)))
+ return false ;
+ // se era loop esterno, lo aggiungo alla nuova regione
+ if ( j == 0) {
+ if ( ! pSfr->Add( *Get( pSfr2)))
+ return false ;
+ }
+ // altrimenti loop interno, lo sottraggo alla nuova regione
+ else {
+ if ( ! pSfr->Subtract( *Get( pSfr2)))
+ return false ;
+ }
+ }
+ // passo alla successiva
+ pOffs.Set( OffsCrv.GetCurve()) ;
+ }
+ }
+ }
+
+ // pulisco la superficie corrente
+ for ( auto& pLoop : m_vpLoop)
+ delete pLoop ;
+ m_vpLoop.clear() ;
+
+ // sposto i dati della nuova superficie in quella corrente
+ m_vExtInd = pSfr->m_vExtInd ;
+ m_vpLoop = pSfr->m_vpLoop ;
+ for ( auto& pLoop : pSfr->m_vpLoop)
+ pLoop = nullptr ;
+ m_nStatus = pSfr->m_nStatus ;
+
+ // imposto ricalcolo della grafica
+ ResetAuxSurf() ;
+ m_OGrMgr.Reset() ;
+ return true ;
+}
\ No newline at end of file