EgtGeomKernel 1.6h4 :

- aggiunto metodo GetCrossOrOverlapIntersCount a SelfIntersCurve
- aggiunti metodi GetCrossIntersCount e GetCrossOrOverlapIntersCount a IntersCurveCurve
- allentati controlli sui loop delle regioni, ora possono toccarsi ma non attraversarsi in punti isolati
- aggiunte funzioni per operazioni booleante tra regioni Add, Subtract e Intersect.
This commit is contained in:
Dario Sassi
2015-08-22 13:48:19 +00:00
parent bab45eb4f3
commit b2db80edc9
12 changed files with 661 additions and 85 deletions
+113 -37
View File
@@ -116,16 +116,16 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
// porto la curva nel riferimento intrinseco
if ( ! pMyCrv->ToLoc( m_frF))
return false ;
// verifico non abbia auto-intersezioni
// verifico non abbia auto-intersezioni che si attraversano
SelfIntersCurve sInt( *pMyCrv) ;
if ( sInt.GetIntersCount() > 0)
if ( sInt.GetCrossOrOverlapIntersCount() > 0)
return false ;
// verifico che sia esterna alle curve esterne degli altri chunk
bool bOk = true ;
CRVCVECTOR ccClass ;
for ( auto i : m_vExtInd) {
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
if ( ccInt.GetNumInters() > 0 ||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
! ccInt.GetCurveClassification( 0, ccClass) ||
ccClass.empty() || ccClass[0].nClass != CRVC_OUT) {
bOk = false ;
@@ -138,7 +138,7 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
if ( binary_search( m_vExtInd.begin(), m_vExtInd.end(), i))
continue ;
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
if ( ccInt.GetNumInters() == 0 &&
if ( ccInt.GetCrossOrOverlapIntersCount() == 0 &&
ccInt.GetCurveClassification( 0, ccClass) &&
! ccClass.empty() && ccClass[0].nClass == CRVC_OUT) {
bOk = true ;
@@ -148,15 +148,30 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
if ( ! bOk)
return false ;
// assegno la curva come loop esterno
m_vpLoop.push_back( Release( pMyCrv)) ;
m_vExtInd.push_back( int( m_vpLoop.size()) - 1) ;
m_nStatus = OK ;
if ( MyAddExtLoop( Get( pMyCrv)))
Release( pMyCrv) ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFlatRegion::MyAddExtLoop( ICurve* pCrv)
{
try {
m_vpLoop.push_back( pCrv) ;
m_vExtInd.push_back( int( m_vpLoop.size()) - 1) ;
m_nStatus = OK ;
}
catch (...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFlatRegion::AddIntLoop( const ICurve& cCrv)
@@ -201,25 +216,40 @@ SurfFlatRegion::AddIntLoop( ICurve* pCrv)
pMyCrv->Invert() ;
// verifico non abbia auto-intersezioni
SelfIntersCurve sInt( *pMyCrv) ;
if ( sInt.GetIntersCount() > 0)
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]) ;
if ( ccInt.GetNumInters() > 0 ||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
! ccInt.GetCurveClassification( 0, ccClass) ||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
return false ;
}
// aggiungo la curva all'elenco dei loop
m_vpLoop.push_back( Release( pMyCrv)) ;
if ( MyAddIntLoop( Get( pMyCrv)))
Release( pMyCrv) ;
// imposto ricalcolo della grafica
ResetAuxSurf() ;
m_OGrMgr.Reset() ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFlatRegion::MyAddIntLoop( ICurve* pCrv)
{
try {
m_vpLoop.push_back( pCrv) ;
}
catch (...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
SurfFlatRegion*
SurfFlatRegion::Clone( void) const
@@ -831,7 +861,8 @@ SurfFlatRegion::GetAuxSurf( void) const
int j = 0 ;
ICurve* pLoop = GetMyLoop( i, j) ;
while ( pLoop != nullptr) {
if ( ! pLoop->ApproxWithLines( LIN_TOL_SFR, ANG_TOL_STD_DEG, ICurve::APL_STD, vPL[j]))
// approssimo con linee a destra per non avere problemi in punti di contatto tra esterni e interni
if ( ! pLoop->ApproxWithLines( LIN_TOL_SFR, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, vPL[j]))
return nullptr ;
pLoop = GetMyLoop( i, ++j) ;
}
@@ -888,8 +919,9 @@ SurfFlatRegion::CloneChunk( int nChunk) const
//----------------------------------------------------------------------------
bool
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
{
// la curva devono già essere nel riferimento intrinseco della regione
// verifico lo stato
if ( m_nStatus != OK || m_vpLoop.empty())
return false ;
@@ -900,18 +932,6 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
double dStart, dEnd ;
if ( ! Crv.GetDomain( dStart, dEnd))
return false ;
// curva in locale nel riferimento intrinseco
const ICurve* pCrvLoc = nullptr ;
PtrOwner<ICurve> pCopyCrv ;
if ( AreSameFrame( m_frF, GLOB_FRM))
pCrvLoc = &Crv ;
else {
pCopyCrv.Set( Crv.Clone()) ;
if ( IsNull( pCopyCrv))
return false ;
pCopyCrv->ToLoc( m_frF) ;
pCrvLoc = Get( pCopyCrv) ;
}
// intervalli totali delle diverse classi
Intervals inTIn, inTOut, inTOnP, inTOnM ;
@@ -925,7 +945,7 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
for ( int nLoop = 0 ; nLoop < GetLoopCount( nChunk) ; ++ nLoop) {
const ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
// intersezione
IntersCurveCurve ccInt( *pCrvLoc, *pLoop) ;
IntersCurveCurve ccInt( Crv, *pLoop) ;
// classificazione
CRVCVECTOR ccPart ;
if ( ! ccInt.GetCurveClassification( 0, ccPart))
@@ -936,16 +956,46 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
// IN è Remove degli altri
break ;
case CRVC_OUT :
inCOut.Add( ccOne.dParS, ccOne.dParE) ;
inCIn.Remove( ccOne.dParS, ccOne.dParE) ;
// intervallo standard
if ( ccOne.dParS < ccOne.dParE - EPS_PARAM) {
inCOut.Add( ccOne.dParS, ccOne.dParE) ;
inCIn.Subtract( ccOne.dParS, ccOne.dParE) ;
}
// intervallo che attraversa punto di chiusura della curva
else {
inCOut.Add( ccOne.dParS, dEnd) ;
inCOut.Add( dStart, ccOne.dParE) ;
inCIn.Subtract( ccOne.dParS, dEnd) ;
inCIn.Subtract( dStart, ccOne.dParE) ;
}
break ;
case CRVC_ON_P :
inCOnP.Add( ccOne.dParS, ccOne.dParE) ;
inCIn.Remove( ccOne.dParS, ccOne.dParE) ;
// intervallo standard
if ( ccOne.dParS < ccOne.dParE - EPS_PARAM) {
inCOnP.Add( ccOne.dParS, ccOne.dParE) ;
inCIn.Subtract( ccOne.dParS, ccOne.dParE) ;
}
// intervallo che attraversa punto di chiusura della curva
else {
inCOnP.Add( ccOne.dParS, dEnd) ;
inCOnP.Add( dStart, ccOne.dParE) ;
inCIn.Subtract( ccOne.dParS, dEnd) ;
inCIn.Subtract( dStart, ccOne.dParE) ;
}
break ;
case CRVC_ON_M :
inCOnM.Add( ccOne.dParS, ccOne.dParE) ;
inCIn.Remove( ccOne.dParS, ccOne.dParE) ;
// intervallo standard
if ( ccOne.dParS < ccOne.dParE - EPS_PARAM) {
inCOnM.Add( ccOne.dParS, ccOne.dParE) ;
inCIn.Subtract( ccOne.dParS, ccOne.dParE) ;
}
// intervallo che attraversa punto di chiusura della curva
else {
inCOnM.Add( ccOne.dParS, dEnd) ;
inCOnM.Add( dStart, ccOne.dParE) ;
inCIn.Subtract( ccOne.dParS, dEnd) ;
inCIn.Subtract( dStart, ccOne.dParE) ;
}
break ;
default : return false ;
}
@@ -953,13 +1003,13 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
}
// aggiorno gli intervalli di classificazione totali
// In, OnP e OnM vengono aggiornati per somma
inTIn.Union( inCIn) ;
inTOnP.Union( inCOnP) ;
inTOnM.Union( inCOnM) ;
inTIn.Add( inCIn) ;
inTOnP.Add( inCOnP) ;
inTOnM.Add( inCOnM) ;
// Out viene ricavato per differenza degli altri
inTOut.Difference( inCIn) ;
inTOut.Difference( inCOnP) ;
inTOut.Difference( inCOnM) ;
inTOut.Subtract( inCIn) ;
inTOut.Subtract( inCOnP) ;
inTOut.Subtract( inCOnM) ;
}
// ricostruisco la classificazione completa e la ordino
@@ -987,4 +1037,30 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass)
sort( ccClass.begin(), ccClass.end(),
[]( const CrvClass& a, const CrvClass& b) { return a.dParS < b.dParS ; }) ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const
{
// verifico lo stato
if ( m_nStatus != OK || m_vpLoop.empty())
return false ;
// verifico la curva
if ( &Crv == nullptr || ! Crv.IsValid())
return false ;
// curva in locale nel riferimento intrinseco
const ICurve* pCrvLoc = nullptr ;
PtrOwner<ICurve> pCopyCrv ;
if ( AreSameFrame( m_frF, GLOB_FRM))
pCrvLoc = &Crv ;
else {
pCopyCrv.Set( Crv.Clone()) ;
if ( IsNull( pCopyCrv))
return false ;
pCopyCrv->ToLoc( m_frF) ;
pCrvLoc = Get( pCopyCrv) ;
}
// esecuzione classificazione nel riferimento intrinseco
return MyGetCurveClassification( *pCrvLoc, ccClass) ;
}