EgtGeomKernel :
- modifiche per Regioni.
This commit is contained in:
+224
@@ -0,0 +1,224 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : AdjustLoops.cpp Data : 14.04.20 Versione : 2.2d2
|
||||
// Contenuto : Implementazione funzione di sistemazione curve chiuse per
|
||||
// poter formare loop validi.
|
||||
//
|
||||
//
|
||||
// Modifiche : 02.11.15 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "RemoveCurveSpikes.h"
|
||||
#include "AdjustLoops.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
{
|
||||
// Pulisco lista di ritorno
|
||||
CrvLst.clear() ;
|
||||
|
||||
// Acquisisco la curva
|
||||
PtrOwner<ICurve> pMyCrv( pCurve) ;
|
||||
|
||||
// Verifico validità curva
|
||||
if ( IsNull( pMyCrv) || ! pMyCrv->IsValid() || ! pMyCrv->IsClosed())
|
||||
return false ;
|
||||
|
||||
// --- 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 ci sono auto-intersezioni che si attraversano (anche con sovrapposizione), errore
|
||||
if ( sintC.GetCrossIntersCount() > 0)
|
||||
return false ;
|
||||
// se non ci sono auto-intersezioni che si toccano (anche con sovrapposizione), non devo fare alcunché
|
||||
if ( sintC.GetTouchIntersCount() == 0) {
|
||||
// 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, elimino solo uno dei due tratti
|
||||
if ( iccInfo.bCBOverEq) {
|
||||
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
|
||||
}
|
||||
// se altrimenti controversi, elimino entrambi i tratti
|
||||
else if ( ! iccInfo.bCBOverEq) {
|
||||
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[1].dU) ;
|
||||
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[1].dU) ;
|
||||
}
|
||||
}
|
||||
// altrimenti sono touch
|
||||
else {
|
||||
inOk.Subtract( iccInfo.IciA[0].dU, iccInfo.IciA[0].dU) ;
|
||||
inOk.Subtract( iccInfo.IciB[0].dU, iccInfo.IciB[0].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 e ignorando le curve già chiuse) :
|
||||
// primo ciclo con loop di due sole curve
|
||||
for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) {
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
||||
// recupero punti iniziale e finale della curva
|
||||
Point3d ptStart ; pCrvCo->GetStartPoint( ptStart) ;
|
||||
Point3d ptEnd ; pCrvCo->GetEndPoint( ptEnd) ;
|
||||
// se aperta, cerco di concatenarla
|
||||
if ( ! AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
|
||||
// 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 ; pCrvCo2->GetStartPoint( ptStart2) ;
|
||||
Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ;
|
||||
// se aperta, verifico se concatenabile alla principale
|
||||
if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) {
|
||||
if ( AreSamePointEpsilon( ptEnd, ptStart2, 10 * EPS_SMALL) &&
|
||||
AreSamePointEpsilon( ptEnd2, ptStart, 10 * EPS_SMALL)) {
|
||||
pCrvCo->AddCurve( pCrvCo2, true, 10 * EPS_SMALL) ;
|
||||
CrvLst.erase( iIter2) ;
|
||||
ptEnd = ptEnd2 ;
|
||||
iIter2 = next( iIter) ;
|
||||
}
|
||||
else
|
||||
++ iIter2 ;
|
||||
}
|
||||
else
|
||||
++ iIter2 ;
|
||||
}
|
||||
}
|
||||
++ iIter ;
|
||||
}
|
||||
// secondo ciclo con loop generici
|
||||
for ( auto iIter = CrvLst.begin() ; iIter != CrvLst.end() ;) {
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
||||
// recupero punti iniziale e finale della curva
|
||||
Point3d ptStart ; pCrvCo->GetStartPoint( ptStart) ;
|
||||
Point3d ptEnd ; pCrvCo->GetEndPoint( ptEnd) ;
|
||||
// se aperta, cerco di concatenarla
|
||||
if ( ! AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
|
||||
// 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 ; pCrvCo2->GetStartPoint( ptStart2) ;
|
||||
Point3d ptEnd2 ; pCrvCo2->GetEndPoint( ptEnd2) ;
|
||||
// se aperta, verifico se concatenabile alla principale
|
||||
if ( ! AreSamePointEpsilon( ptStart2, ptEnd2, 10 * EPS_SMALL)) {
|
||||
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 ;
|
||||
}
|
||||
else
|
||||
++ iIter2 ;
|
||||
}
|
||||
}
|
||||
++ iIter ;
|
||||
}
|
||||
|
||||
// riporto le curve nel riferimento originale
|
||||
if ( bNeedRef) {
|
||||
for ( auto pCrv : CrvLst)
|
||||
pCrv->ToGlob( frExtr) ;
|
||||
}
|
||||
// assegno il versore estrusione originale
|
||||
for ( auto pCrv : CrvLst)
|
||||
pCrv->SetExtrusion( vtExtr) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
||||
{
|
||||
// elimino eventuali sovrapposizioni e accostamenti
|
||||
if ( ! MyAdjustLoops( pCurve, CrvLst))
|
||||
return false ;
|
||||
// unisco eventuali tratti allineati ed elimino eventuali spikes
|
||||
for ( auto pCrv : CrvLst) {
|
||||
// se curva composita
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( pCrv) ;
|
||||
if ( pCrvCo != nullptr) {
|
||||
// unisco eventuali tratti allineati
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
// elimino eventuali spikes
|
||||
RemoveCurveSpikes( pCrvCo) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2015
|
||||
// EgalTech 2015-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : RemoveCurveOverlaps.h Data : 02.11.15 Versione : 1.6k1
|
||||
// Contenuto : Dichiarazione funzione rimozione sovrapposizioni curve.
|
||||
//
|
||||
// File : AdjustLoops.h Data : 14.04.20 Versione : 2.2d2
|
||||
// Contenuto : Dichiarazione funzione di sistemazione curve chiuse per
|
||||
// poter formare loop validi.
|
||||
//
|
||||
//
|
||||
// Modifiche : 02.11.15 DS Creazione modulo.
|
||||
@@ -17,4 +17,4 @@
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst) ;
|
||||
bool AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst) ;
|
||||
@@ -352,7 +352,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="FontOs.cpp" />
|
||||
<ClCompile Include="OffsetCurveOnX.cpp" />
|
||||
<ClCompile Include="Polygon3d.cpp" />
|
||||
<ClCompile Include="RemoveCurveOverlaps.cpp" />
|
||||
<ClCompile Include="AdjustLoops.cpp" />
|
||||
<ClCompile Include="RemoveCurveSpikes.cpp" />
|
||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||
<ClCompile Include="SfrCreate.cpp" />
|
||||
@@ -568,7 +568,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="NgeReader.h" />
|
||||
<ClInclude Include="ObjGraphicsMgr.h" />
|
||||
<ClInclude Include="FontOs.h" />
|
||||
<ClInclude Include="RemoveCurveOverlaps.h" />
|
||||
<ClInclude Include="AdjustLoops.h" />
|
||||
<ClInclude Include="RemoveCurveSpikes.h" />
|
||||
<ClInclude Include="SurfBezier.h" />
|
||||
<ClInclude Include="SurfFlatRegion.h" />
|
||||
|
||||
@@ -324,9 +324,6 @@
|
||||
<ClCompile Include="SurfFlatRegionOffset.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RemoveCurveOverlaps.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OffsetCurveOnX.cpp">
|
||||
<Filter>File di origine\GeoOffset</Filter>
|
||||
</ClCompile>
|
||||
@@ -414,8 +411,8 @@
|
||||
<ClCompile Include="SurfBezier.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="deCasteljau.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
<ClCompile Include="AdjustLoops.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -797,9 +794,6 @@
|
||||
<ClInclude Include="TextureData.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RemoveCurveOverlaps.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkOffsetCurveOnX.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
@@ -998,6 +992,12 @@
|
||||
<ClInclude Include="..\Include\EGkSurfBezier.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="deCasteljau.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AdjustLoops.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ class GeoObjRegister
|
||||
GetNgeIdPrivate() = nNgeId ;
|
||||
return true ; }
|
||||
static IGeoObj* Create( void)
|
||||
{ return new(nothrow) T ; }
|
||||
{ return new( std::nothrow) T ; }
|
||||
static int GetType( void)
|
||||
{ return GetTypePrivate() ; }
|
||||
static const std::string& GetKey( void)
|
||||
|
||||
+44
-12
@@ -473,7 +473,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
if ( i == 0 && ! bCrvAClosed)
|
||||
continue ;
|
||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||
m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ;
|
||||
m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ;
|
||||
}
|
||||
// se il tipo di allontanamento per la curva A non è definito
|
||||
if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) {
|
||||
@@ -492,14 +492,14 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
if ( i == 0 && ! bCrvBClosed)
|
||||
continue ;
|
||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||
m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
|
||||
m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
|
||||
}
|
||||
// se il tipo di allontanamento per la curva B non è definito
|
||||
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
||||
if ( i == m_nNumInters - 1 && ! bCrvBClosed)
|
||||
continue ;
|
||||
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
|
||||
m_Info[i].IciB[0].nNextTy = m_Info[j].IciB[0].nPrevTy ;
|
||||
m_Info[i].IciB[0].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ;
|
||||
}
|
||||
}
|
||||
// ripristino ordinamento su prima curva
|
||||
@@ -550,11 +550,12 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
else {
|
||||
// se il tipo di accostamento è non definito per la curva A
|
||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
||||
CCompoB, m_Info[i].IciB[0].dU, nType)) {
|
||||
// aggiorno il tipo di accostamento della curva A alla curva B
|
||||
// se autointersezione con spike
|
||||
double dDeltaU = abs( m_Info[i].IciA[0].dU - m_Info[i].IciB[0].dU) ;
|
||||
if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) {
|
||||
// è punta di spike
|
||||
int nType = ICCT_SPK ;
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
@@ -562,13 +563,29 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
else
|
||||
m_Info[i].IciB[0].nNextTy = nType ;
|
||||
}
|
||||
// caso standard
|
||||
else {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
||||
CCompoB, m_Info[i].IciB[0].dU, nType)) {
|
||||
// aggiorno il tipo di accostamento della curva A alla curva B
|
||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[0].nNextTy = nType ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se il tipo di allontanamento è non definito per la curva A
|
||||
if ( m_Info[i].IciA[1].nNextTy == ICCT_NULL) {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS,
|
||||
CCompoB, m_Info[i].IciB[1].dU, nType)) {
|
||||
// se autointersezione con spike
|
||||
double dDeltaU = abs( m_Info[i].IciA[1].dU - m_Info[i].IciB[1].dU) ;
|
||||
if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) {
|
||||
// è punta di spike
|
||||
int nType = ICCT_SPK ;
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[1].nNextTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
@@ -577,6 +594,21 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
else
|
||||
m_Info[i].IciB[1].nPrevTy = nType ;
|
||||
}
|
||||
// caso standard
|
||||
else {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS,
|
||||
CCompoB, m_Info[i].IciB[1].dU, nType)) {
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[1].nNextTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[1].nPrevTy = nType ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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 <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
RemoveCurveOverlaps( ICurve* pCurve, bool bRemoveSam, bool bRemoveCtr, ICURVEPLIST& CrvLst)
|
||||
{
|
||||
// Pulisco lista di ritorno
|
||||
CrvLst.clear() ;
|
||||
|
||||
// Acquisisco la curva
|
||||
PtrOwner<ICurve> 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 le curve nel riferimento originale
|
||||
if ( bNeedRef) {
|
||||
for ( auto pCrv : CrvLst)
|
||||
pCrv->ToGlob( frExtr) ;
|
||||
}
|
||||
// assegno il versore estrusione originale
|
||||
for ( auto pCrv : CrvLst)
|
||||
pCrv->SetExtrusion( vtExtr) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -177,6 +177,7 @@ SelfIntersCurve::GetCrossIntersCount( void)
|
||||
// se con sovrapposizione
|
||||
if ( m_Info[i].bOverlap) {
|
||||
if ( m_Info[i].IciA[0].nPrevTy != m_Info[i].IciA[1].nNextTy &&
|
||||
m_Info[i].IciA[0].nPrevTy != ICCT_SPK && m_Info[i].IciA[1].nNextTy != ICCT_SPK &&
|
||||
m_Info[i].IciA[0].nPrevTy != ICCT_NULL && m_Info[i].IciA[1].nNextTy != ICCT_NULL)
|
||||
++ nCrossIntersCount ;
|
||||
}
|
||||
@@ -207,6 +208,29 @@ SelfIntersCurve::GetCrossOrOverlapIntersCount( void)
|
||||
return nCrossOverIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SelfIntersCurve::GetTouchIntersCount( void)
|
||||
{
|
||||
int nTouchIntersCount = 0 ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||
// se con sovrapposizione
|
||||
if ( m_Info[i].bOverlap) {
|
||||
if ( ( m_Info[i].IciA[0].nPrevTy == m_Info[i].IciA[1].nNextTy ||
|
||||
m_Info[i].IciA[0].nPrevTy == ICCT_SPK || m_Info[i].IciA[1].nNextTy == ICCT_SPK) &&
|
||||
m_Info[i].IciA[0].nPrevTy != ICCT_NULL && m_Info[i].IciA[1].nNextTy != ICCT_NULL)
|
||||
++ nTouchIntersCount ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( m_Info[i].IciA[0].nPrevTy == m_Info[i].IciA[0].nNextTy &&
|
||||
m_Info[i].IciA[0].nPrevTy != ICCT_NULL && m_Info[i].IciA[0].nNextTy != ICCT_NULL)
|
||||
++ nTouchIntersCount ;
|
||||
}
|
||||
}
|
||||
return nTouchIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
|
||||
+45
-30
@@ -19,8 +19,7 @@
|
||||
#include "NgeReader.h"
|
||||
#include "CurveAux.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "RemoveCurveOverlaps.h"
|
||||
#include "RemoveCurveSpikes.h"
|
||||
#include "AdjustLoops.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
@@ -100,20 +99,11 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
|
||||
pMyCrv->SetThickness( 0) ;
|
||||
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
||||
ICURVEPLIST CrvLst ;
|
||||
if ( ! RemoveCurveOverlaps( Release( pMyCrv), true, true, CrvLst))
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst))
|
||||
return false ;
|
||||
// aggiungo le singole curve
|
||||
bool bOk = true ;
|
||||
for ( auto& pSingCrv : CrvLst) {
|
||||
// se curva composita
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( pSingCrv) ;
|
||||
if ( pCrvCo != nullptr) {
|
||||
// unisco eventuali tratti allineati
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
// elimino eventuali spikes
|
||||
RemoveCurveSpikes( pCrvCo) ;
|
||||
}
|
||||
// aggiungo il loop
|
||||
if ( ! AddSimpleExtLoop( pSingCrv))
|
||||
bOk = false ;
|
||||
}
|
||||
@@ -253,20 +243,11 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv)
|
||||
pMyCrv->SetThickness( 0) ;
|
||||
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
||||
ICURVEPLIST CrvLst ;
|
||||
if ( ! RemoveCurveOverlaps( Release( pMyCrv), true, true, CrvLst))
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst))
|
||||
return false ;
|
||||
// aggiungo le singole curve
|
||||
bool bOk = true ;
|
||||
for ( auto& pSingCrv : CrvLst) {
|
||||
// se curva composita
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( pSingCrv) ;
|
||||
if ( pCrvCo != nullptr) {
|
||||
// unisco eventuali tratti allineati
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
// elimino eventuali spikes
|
||||
RemoveCurveSpikes( pCrvCo) ;
|
||||
}
|
||||
// aggiungo il loop
|
||||
if ( ! AddSimpleIntLoop( pSingCrv))
|
||||
bOk = false ;
|
||||
}
|
||||
@@ -307,17 +288,39 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
||||
SelfIntersCurve sInt( *pMyCrv) ;
|
||||
if ( sInt.GetCrossOrOverlapIntersCount() > 0)
|
||||
return false ;
|
||||
// verifico non abbia intersezioni e non sia esterna ai loop già definiti del medesimo chunk
|
||||
CRVCVECTOR ccClass ;
|
||||
for ( int i = m_vExtInd.back() ; i < int( m_vpLoop.size()) ; ++ i) {
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||
// ricerca del chunk in cui andrebbe inserito
|
||||
int nChunk = -1 ;
|
||||
for ( int i = 0 ; i < int( m_vExtInd.size()) ; ++ i) {
|
||||
// verifica rispetto al loop esterno
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[m_vExtInd[i]]) ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
return false ;
|
||||
continue ;
|
||||
// verifica rispetto ai loop interni
|
||||
bool bOk = true ;
|
||||
int nLoopCnt = GetLoopCount( i) ;
|
||||
for ( int j = 0 ; j < nLoopCnt ; ++ j) {
|
||||
int k = m_vExtInd[i] + j ;
|
||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[k]) ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 0, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( bOk) {
|
||||
nChunk = i ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( nChunk == -1)
|
||||
return false ;
|
||||
// aggiungo la curva all'elenco dei loop
|
||||
if ( MyAddIntLoop( pMyCrv))
|
||||
if ( MyAddIntLoop( pMyCrv, nChunk))
|
||||
Release( pMyCrv) ;
|
||||
// imposto ricalcolo della grafica
|
||||
ResetAuxSurf() ;
|
||||
@@ -327,10 +330,22 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::MyAddIntLoop( ICurve* pCrv)
|
||||
SurfFlatRegion::MyAddIntLoop( ICurve* pCrv, int nChunk)
|
||||
{
|
||||
try {
|
||||
m_vpLoop.push_back( pCrv) ;
|
||||
// se da aggiungere all'ultimo chunk
|
||||
if ( nChunk == -1)
|
||||
m_vpLoop.push_back( pCrv) ;
|
||||
// altrimenti aggiungo al chunck indicato
|
||||
else {
|
||||
int nLoopCnt = GetLoopCount( nChunk) ;
|
||||
if ( nLoopCnt == 0)
|
||||
return false ;
|
||||
int nOffset = m_vExtInd[nChunk] + nLoopCnt ;
|
||||
m_vpLoop.insert( m_vpLoop.begin() + nOffset, pCrv) ;
|
||||
for ( int i = nChunk + 1 ; i < int( m_vExtInd.size()) ; ++ i)
|
||||
++ m_vExtInd[i] ;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
return false ;
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
bool AddSimpleExtLoop( ICurve* pCrv) ;
|
||||
bool MyAddExtLoop( ICurve* pCrv) ;
|
||||
bool AddSimpleIntLoop( ICurve* pCrv) ;
|
||||
bool MyAddIntLoop( ICurve* pCrv) ;
|
||||
bool MyAddIntLoop( ICurve* pCrv, int nChunk) ;
|
||||
int GetIndFromChunkLoop( int nChunk, int nLoop) const ;
|
||||
bool GetChunkLoopFromInd( int nInd, int& nChunk, int& nLoop) const ;
|
||||
ICurve* GetMyLoop( int nInd) const ; // indice nel vettore di tutti i loop
|
||||
|
||||
@@ -443,7 +443,7 @@ SurfFlatRegion::MyNewSurfFromLoops( PCRV_DEQUE& vpLoop)
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
continue ;
|
||||
// lo inserisco
|
||||
if ( pSfr->MyAddIntLoop( vpLoop[l])) {
|
||||
if ( pSfr->MyAddIntLoop( vpLoop[l], -1)) {
|
||||
vpLoop[l] = nullptr ;
|
||||
vArea[k].first = - 1 ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user