EgtGeomKernel 2.1e1 :

- superficie rigata ora costruibile con metodo isoparametrica oppure minima distanza
- cambiato metodo di costruzione di superficie Swept
- al termine della costruzione di una superficie chiusa si aggiusta la normale in modo che punti all'esterno
- nelle PolyLine è possibile aggiungere punti anche prima dell'inizio
- migliorato calcolo centro con PCA di poligoni
- ora offset avanzato non dà errore con offset nullo ma copia la curva.
This commit is contained in:
Dario Sassi
2019-05-06 06:25:48 +00:00
parent ac23cb885d
commit 8cadda5d91
9 changed files with 655 additions and 313 deletions
+93 -20
View File
@@ -49,19 +49,37 @@ PolyLine::Clear( void)
//----------------------------------------------------------------------------
bool
PolyLine::AddUPoint( double dPar, const Point3d& ptP)
PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
{
// se il punto è uguale al precedente (ignoro parametro), non lo inserisco ma ok
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
++ m_nRejected ;
return true ;
// se da aggiungere in coda
if ( bEndOrStart) {
// se il punto è uguale all'ultimo (ignoro parametro), non lo inserisco ma ok
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
++ m_nRejected ;
return true ;
}
// eseguo inserimento
try {
m_lUPoints.emplace_back( ptP, dPar) ;
}
catch (...) {
return false ;
}
}
// eseguo inserimento
try {
m_lUPoints.emplace_back( ptP, dPar) ;
}
catch (...) {
return false ;
// altrimenti si aggiunge in testa
else {
// se il punto è uguale al primo (ignoro parametro), non lo inserisco ma ok
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.front().first)) {
++ m_nRejected ;
return true ;
}
// eseguo inserimento
try {
m_lUPoints.emplace_front( ptP, dPar) ;
}
catch (...) {
return false ;
}
}
return true ;
@@ -494,10 +512,10 @@ bool
PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) const
{
// cerco le componenti principali (tramite PCA)
Point3d ptP ;
Point3d ptP1, ptP2 ;
PointsPCA ptsPCA ;
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP))
ptsPCA.AddPoint( ptP) ;
for ( bool bFound = GetFirstLine( ptP1, ptP2) ; bFound ; bFound = GetNextLine( ptP1, ptP2))
ptsPCA.AddPoint( Media( ptP1, ptP2), Dist( ptP1, ptP2)) ;
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
nRank = ptsPCA.GetRank() ;
// se dimensione nulla, o non ci sono punti o sono tutti praticamente coincidenti
@@ -531,6 +549,7 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
Plane3d plPlane ;
plPlane.Set( ptCen, vtDir) ;
// Test each vertex to see if it is farther from plane than allowed max distance
Point3d ptP ;
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
double dDist = ( ( ptP - ORIG) * plPlane.GetVersN()) - plPlane.GetDist() ;
if ( abs( dDist) > dToler)
@@ -765,19 +784,19 @@ PolyLine::ApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler)
// *** polilinea chiusa : devo sistemare a cavallo dell'inizio/fine ***
// sposto l'inizio dalla parte opposta
MyChangeStartOnMiddle() ;
MyChangeStart( int( m_lUPoints.size() / 2)) ;
// rifaccio l'approssimazione con 3/4 della tolleranza ammessa
if ( ! MyApproxOnSide( vtN, bLeftSide, 0.75 * dToler))
return false ;
// risposto l'inizio dalla parte opposta, quindi lo porto vicino all'originale
MyChangeStartOnMiddle() ;
MyChangeStart( int( m_lUPoints.size() / 2)) ;
return true ;
}
//----------------------------------------------------------------------------
bool
PolyLine::MyChangeStartOnMiddle( void)
PolyLine::MyChangeStart( int nPos)
{
// solo per polilinee chiuse
if ( ! IsClosed())
@@ -785,7 +804,7 @@ PolyLine::MyChangeStartOnMiddle( void)
// cancello ultimo punto ( coincide con primo)
m_lUPoints.pop_back() ;
// sposto la metà iniziale dei punti alla fine
for ( size_t i = 0 ; i < m_lUPoints.size() / 2 ; ++ i)
for ( int i = 0 ; i < nPos ; ++ i)
m_lUPoints.splice( m_lUPoints.end(), m_lUPoints, m_lUPoints.begin()) ;
// aggiungo punto finale come copia dell'iniziale
m_lUPoints.push_back( m_lUPoints.front()) ;
@@ -916,12 +935,12 @@ PolyLine::MakeConvex( const Vector3d& vtN, bool bLeftSide)
// *** polilinea chiusa : devo sistemare a cavallo dell'inizio/fine ***
// sposto l'inizio dalla parte opposta
MyChangeStartOnMiddle() ;
MyChangeStart( int( m_lUPoints.size() / 2)) ;
// rifaccio la modifica
if ( ! MyMakeConvex( vtN, bLeftSide))
return false ;
// risposto l'inizio dalla parte opposta, quindi lo porto vicino all'originale
MyChangeStartOnMiddle() ;
MyChangeStart( int( m_lUPoints.size() / 2)) ;
return true ;
}
@@ -1195,3 +1214,57 @@ PolyLine::GetMinAreaRectangleXY( Point3d& ptCen, Vector3d& vtAx, double& dLen, d
return true ;
}
//----------------------------------------------------------------------------
bool
PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
{
// se vuota non faccio alcunché
if ( m_lUPoints.size() == 0)
return false ;
// determino le intersezioni dei lati con il piano
int nIntPos = - 1 ;
auto prevUP = m_lUPoints.begin() ;
double dPrevDist = ( prevUP->first - ORIG) * plPlane.GetVersN() - plPlane.GetDist() ;
auto currUP = next( prevUP) ;
while ( currUP != m_lUPoints.end()) {
// se non inizializzato e precedente in zona vietata, ne salvo l'indice
if ( nIntPos == -1 &&
( ( bInVsOut && dPrevDist > EPS_SMALL) ||
( ! bInVsOut && dPrevDist < - EPS_SMALL)))
nIntPos = int( distance( m_lUPoints.begin(), prevUP)) ;
// distanze del punto dal piano
double dCurrDist = ( currUP->first - ORIG) * plPlane.GetVersN() - plPlane.GetDist() ;
// se il lato attraversa il piano, inserisco il punto di intersezione nel poligono
if ( ( dPrevDist > EPS_SMALL && dCurrDist < - EPS_SMALL) ||
( dPrevDist < - EPS_SMALL && dCurrDist > EPS_SMALL)) {
double dCoeff = abs( dPrevDist) / ( abs( dPrevDist) + abs( dCurrDist)) ;
Point3d ptInt = Media( prevUP->first, currUP->first, dCoeff) ;
double dU = ( 1 - dCoeff) * prevUP->second + dCoeff * currUP->second ;
m_lUPoints.insert( currUP, { ptInt, dU}) ;
}
// passo al successivo
prevUP = currUP ;
currUP = next( currUP) ;
dPrevDist = dCurrDist ;
}
// se chiusa, sposto l'inizio su eventuale primo punto di intersezione con il piano
if ( IsClosed() && nIntPos != -1)
MyChangeStart( nIntPos) ;
// elimino i punti che non rispettano la posizione rispetto al piano
currUP = m_lUPoints.begin() ;
while ( currUP != m_lUPoints.end()) {
double dDist = ( currUP->first - ORIG) * plPlane.GetVersN() - plPlane.GetDist() ;
if ( ( bInVsOut && dDist > EPS_SMALL) ||
( ! bInVsOut && dDist < - EPS_SMALL)) {
currUP = m_lUPoints.erase( currUP) ;
}
else
currUP = next( currUP) ;
}
return true ;
}