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:
+93
-20
@@ -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 ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user