EgtGeomKernel 2.1i1 :

- migliorie a ChainCurves
- aggiunta GetFeatureChaines a VolZmap.
This commit is contained in:
Dario Sassi
2019-09-12 07:43:35 +00:00
parent e79caee914
commit bd1efafbc0
7 changed files with 398 additions and 44 deletions
+178 -36
View File
@@ -32,6 +32,10 @@ ChainCurves::Init( bool bAllowInvert, double dToler, int nCrvNbrHint)
m_vCrvData.reserve( nCrvNbrHint) ;
const double DIM_CELL = 10.0 ;
m_PointGrid.Init( 2 * nCrvNbrHint, DIM_CELL) ;
m_bFromNear = false ;
m_vForkData.clear() ;
m_bIsFork = false ;
m_vFork.clear() ;
return true ;
}
@@ -61,6 +65,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
{
// pulisco il risultato
vIds.clear() ;
m_bFromNear = true ;
m_bIsFork = false ;
m_vFork.clear() ;
@@ -68,28 +73,56 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
int nStart ;
INTVECTOR vStart ;
if ( ! m_PointGrid.FindNearest( ptStart, vStart) ||
! ChooseStart( ptStart, vStart, nStart))
! ChooseStart( ptStart, vStart, nStart)) {
m_bFromNear = false ;
return false ;
}
// recupero indice e verso
int nId = abs( nStart) - 1 ;
bool bEquiv = true ;
// tolgo dal grid
RemoveEntityFromGrid( nId) ;
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
bool bSkip = false ;
if ( bHaltOnFork) {
auto iIter = GetForkPoint( m_vCrvData[nId].ptEnd) ;
if ( iIter != m_vForkData.end()) {
m_bIsFork = true ;
m_vFork.insert( m_vFork.end(), iIter->vnFork.begin(), iIter->vnFork.end()) ;
bSkip = true ;
}
}
// concateno dopo la fine dell'entità di partenza
INTVECTOR vIdsAfter ;
bool bClosed ;
if ( ! GetChainFromPoint( m_vCrvData[nId].ptEnd, m_vCrvData[nId].vtEnd,
m_vCrvData[nId].ptStart, bHaltOnFork, vIdsAfter, bClosed))
bool bClosed = false ;
if ( ! bSkip && ! GetChainFromPoint( m_vCrvData[nId].ptEnd, m_vCrvData[nId].vtEnd,
m_vCrvData[nId].ptStart, bHaltOnFork, vIdsAfter, bClosed)) {
m_bFromNear = false ;
return false ;
}
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
bool bRevSkip = false ;
if ( bHaltOnFork) {
auto iIter = GetForkPoint( m_vCrvData[nId].ptStart) ;
if ( iIter != m_vForkData.end()) {
m_bIsFork = true ;
m_vFork.insert( m_vFork.end(), iIter->vnFork.begin(), iIter->vnFork.end()) ;
bRevSkip = true ;
}
}
// se non ho già chiuso l'anello, concateno prima dell'inizio dell'entità di partenza
INTVECTOR vIdsBefore ;
if ( ! bClosed) {
bool bRevClosed ;
if ( ! GetReverseChainFromPoint( m_vCrvData[nId].ptStart, m_vCrvData[nId].vtStart,
m_vCrvData[nId].ptEnd, bHaltOnFork, vIdsBefore, bRevClosed))
if ( ! bRevSkip && ! GetReverseChainFromPoint( m_vCrvData[nId].ptStart, m_vCrvData[nId].vtStart,
m_vCrvData[nId].ptEnd, bHaltOnFork, vIdsBefore, bRevClosed)) {
m_bFromNear = false ;
return false ;
}
// inverto l'ordine
reverse( vIdsBefore.begin(), vIdsBefore.end()) ;
}
@@ -100,6 +133,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
AddToChain( nId, bEquiv, vIds) ;
vIds.insert( vIds.end(), vIdsAfter.begin(), vIdsAfter.end()) ;
m_bFromNear = false ;
return true ;
}
@@ -112,8 +146,10 @@ ChainCurves::GetChainFromPoint( const Point3d& ptStart, const Vector3d& vtStart,
// pulisco il risultato
vIds.clear() ;
bStopped = false ;
m_bIsFork = false ;
m_vFork.clear() ;
if ( ! m_bFromNear) {
m_bIsFork = false ;
m_vFork.clear() ;
}
// concateno in senso normale
Point3d ptCurr = ptStart ;
@@ -121,7 +157,7 @@ ChainCurves::GetChainFromPoint( const Point3d& ptStart, const Vector3d& vtStart,
int nNext ;
INTVECTOR vNext ;
while ( m_PointGrid.Find( ptCurr, m_dToler, vNext) &&
ChooseNext( vtCurr, vNext, bHaltOnFork, nNext)) {
ChooseNext( ptCurr, vtCurr, vNext, bHaltOnFork, nNext)) {
// recupero indice e verso
int nId = abs( nNext) - 1 ;
bool bEquiv = ( nNext > 0) ;
@@ -137,6 +173,15 @@ ChainCurves::GetChainFromPoint( const Point3d& ptStart, const Vector3d& vtStart,
bStopped = true ;
break ;
}
// se devo fermarmi su biforcazione, verifico se sono su vecchia biforcazione
if ( bHaltOnFork) {
auto iIter = GetForkPoint( ptCurr) ;
if ( iIter != m_vForkData.end()) {
m_bIsFork = true ;
m_vFork.insert( m_vFork.end(), iIter->vnFork.begin(), iIter->vnFork.end()) ;
break ;
}
}
}
return true ;
@@ -151,8 +196,10 @@ ChainCurves::GetReverseChainFromPoint( const Point3d& ptStart, const Vector3d& v
// pulisco il risultato
vIds.clear() ;
bStopped = false ;
m_bIsFork = false ;
m_vFork.clear() ;
if ( ! m_bFromNear) {
m_bIsFork = false ;
m_vFork.clear() ;
}
// concateno in senso invertito
Point3d ptCurr = ptStart ;
@@ -160,7 +207,7 @@ ChainCurves::GetReverseChainFromPoint( const Point3d& ptStart, const Vector3d& v
int nPrev ;
INTVECTOR vPrev ;
while ( m_PointGrid.Find( ptCurr, m_dToler, vPrev) &&
ChoosePrev( vtCurr, vPrev, bHaltOnFork, nPrev)) {
ChoosePrev( ptCurr, vtCurr, vPrev, bHaltOnFork, nPrev)) {
// recupero indice e verso
int nId = abs( nPrev) - 1 ;
bool bEquiv = ( nPrev < 0) ;
@@ -176,6 +223,15 @@ ChainCurves::GetReverseChainFromPoint( const Point3d& ptStart, const Vector3d& v
bStopped = true ;
break ;
}
// se devo fermarmi su biforcazione, verifico se sono su vecchia biforcazione
if ( bHaltOnFork) {
auto iIter = GetForkPoint( ptCurr) ;
if ( iIter != m_vForkData.end()) {
m_bIsFork = true ;
m_vFork.insert( m_vFork.end(), iIter->vnFork.begin(), iIter->vnFork.end()) ;
break ;
}
}
}
return true ;
@@ -244,23 +300,56 @@ ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int&
//----------------------------------------------------------------------------
bool
ChainCurves::ChooseNext( const Vector3d& vtCurr, const INTVECTOR& vNext, bool bHaltOnFork, int& nNext)
ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vNext, bool bHaltOnFork, int& nNext)
{
// cerco la direzione più vicina
int nI = - 1 ;
int nF = 0 ;
double dProScaMax = - 1.1 ;
for ( int i = 0 ; i < int( vNext.size()) ; ++ i) {
INTVECTOR vMyNext = vNext ;
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
int nM = -1 ;
Point3d ptRef ;
double dSqMinDist = m_dToler * m_dToler ;
for ( int i = 0 ; i < int( vMyNext.size()) ; ++ i) {
// recupero indice e verso
int nId = abs( vNext[i]) - 1 ;
bool bEquiv = ( vNext[i] > 0) ;
int nId = abs( vMyNext[i]) - 1 ;
bool bEquiv = ( vMyNext[i] > 0) ;
// determino minima distanza
double dSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
if ( dSqDist < dSqMinDist) {
ptRef = ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart) ;
dSqMinDist = dSqDist ;
nM = i ;
}
}
for ( int i = 0 ; i < int( vMyNext.size()) ; ++ i) {
// salto l'entità più vicina
if ( i == nM)
continue ;
// recupero indice e verso
int nId = abs( vMyNext[i]) - 1 ;
bool bEquiv = ( vMyNext[i] > 0) ;
// verifico se più vicino al più vicino
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
if ( dRefSqDist < dCurrSqDist)
vMyNext[i] = 0 ;
}
// cerco la direzione più vicina
int nI = -1 ;
int nF = 0 ;
INTVECTOR vFork ;
double dProScaMax = - 1.1 ;
for ( int i = 0 ; i < int( vMyNext.size()) ; ++ i) {
// salto gli scartati
if ( vMyNext[i] == 0)
continue ;
// recupero indice e verso
int nId = abs( vMyNext[i]) - 1 ;
bool bEquiv = ( vMyNext[i] > 0) ;
// incremento contatore indice entità tra cui scegliere
++ nF ;
vFork.push_back( vMyNext[i]) ;
// se vietata inversione, salto se controverso
if ( ! m_bAllowInvert && ! bEquiv)
continue ;
// incremento contatore indice entità tra cui scegliere
++ nF ;
if ( bHaltOnFork)
m_vFork.push_back( vNext[i]) ;
// determino scarto angolare
Vector3d vtDir = ( bEquiv ? m_vCrvData[nId].vtStart : - m_vCrvData[nId].vtEnd) ;
double dProSca = vtCurr * vtDir ;
@@ -276,37 +365,76 @@ ChainCurves::ChooseNext( const Vector3d& vtCurr, const INTVECTOR& vNext, bool bH
return false ;
}
// se biforcazione, aggiungo il punto nel vettore relativo
if ( nF > 1) {
if ( GetForkPoint( ptCurr) == m_vForkData.end())
m_vForkData.emplace_back( ptCurr, vFork) ;
}
// se richiesto arresto su biforcazione e trovata biforcazione
if ( bHaltOnFork && nF > 1) {
m_bIsFork = true ;
m_vFork.insert( m_vFork.end(), vFork.begin(), vFork.end()) ;
return false ;
}
// altrimenti assegno il migliore
nNext = vNext[nI] ;
m_bIsFork = false ;
nNext = vMyNext[nI] ;
return true ;
}
//----------------------------------------------------------------------------
bool
ChainCurves::ChoosePrev( const Vector3d& vtCurr, const INTVECTOR& vPrev, bool bHaltOnFork, int& nPrev)
ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vPrev, bool bHaltOnFork, int& nPrev)
{
INTVECTOR vMyPrev = vPrev ;
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
int nM = -1 ;
Point3d ptRef ;
double dSqMinDist = m_dToler * m_dToler ;
for ( int i = 0 ; i < int( vMyPrev.size()) ; ++ i) {
// recupero indice e verso
int nId = abs( vMyPrev[i]) - 1 ;
bool bEquiv = ( vMyPrev[i] < 0) ;
// determino minima distanza
double dSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
if ( dSqDist < dSqMinDist) {
ptRef = ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd) ;
dSqMinDist = dSqDist ;
nM = i ;
}
}
for ( int i = 0 ; i < int( vMyPrev.size()) ; ++ i) {
// salto l'entità più vicina
if ( i == nM)
continue ;
// recupero indice e verso
int nId = abs( vMyPrev[i]) - 1 ;
bool bEquiv = ( vMyPrev[i] < 0) ;
// verifico se più vicino al più vicino
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
if ( dRefSqDist < dCurrSqDist)
vMyPrev[i] = 0 ;
}
// cerco la direzione più vicina
int nI = - 1 ;
int nF = 0 ;
double dProScaMax = - 1.1 ;
for ( int i = 0 ; i < int( vPrev.size()) ; ++ i) {
INTVECTOR vFork ;
for ( int i = 0 ; i < int( vMyPrev.size()) ; ++ i) {
// salto gli scartati
if ( vMyPrev[i] == 0)
continue ;
// recupero indice e verso
int nId = abs( vPrev[i]) - 1 ;
bool bEquiv = ( vPrev[i] < 0) ;
int nId = abs( vMyPrev[i]) - 1 ;
bool bEquiv = ( vMyPrev[i] < 0) ;
// incremento contatore indice entità tra cui scegliere
++ nF ;
vFork.push_back( vMyPrev[i]) ;
// se vietata inversione, salto se controverso
if ( ! m_bAllowInvert && ! bEquiv)
continue ;
// incremento contatore indice entità tra cui scegliere
++ nF ;
if ( bHaltOnFork)
m_vFork.push_back( vPrev[i]) ;
// determino scarto angolare
Vector3d vtDir = ( bEquiv ? m_vCrvData[nId].vtEnd : - m_vCrvData[nId].vtStart) ;
double dProSca = vtCurr * vtDir ;
@@ -322,15 +450,21 @@ ChainCurves::ChoosePrev( const Vector3d& vtCurr, const INTVECTOR& vPrev, bool bH
return false ;
}
// se biforcazione, aggiungo il punto nel vettore relativo
if ( nF > 1) {
if ( GetForkPoint( ptCurr) == m_vForkData.end())
m_vForkData.emplace_back( ptCurr, vFork) ;
}
// se richiesto arresto su biforcazione e trovata biforcazione
if ( bHaltOnFork && nF > 1) {
m_bIsFork = true ;
m_vFork.insert( m_vFork.end(), vFork.begin(), vFork.end()) ;
return false ;
}
// altrimenti assegno il migliore
nPrev = vPrev[nI] ;
m_bIsFork = false ;
nPrev = vMyPrev[nI] ;
return true ;
}
@@ -352,3 +486,11 @@ ChainCurves::GetForkIds( INTVECTOR& vForkIds)
}
return true ;
}
//----------------------------------------------------------------------------
ChainCurves::FDV_CONST_ITER
ChainCurves::GetForkPoint( const Point3d& ptP)
{
return ( find_if( m_vForkData.begin(), m_vForkData.end(),
[&]( const ForkData& frkData) { return AreSamePointEpsilon( frkData.ptFork, ptP, m_dToler) ; })) ;
}