EgtGeomKernel 1.6f4 :

- ApproxWithLines di curve con nuove opzioni
- semplificata CurveComposite
- completate IntersLineTria e IntersLineSurfTm
- aggiunta MakeConvex a PolyLine.
This commit is contained in:
Dario Sassi
2015-06-30 14:04:02 +00:00
parent 82195db8cc
commit b8bf9b2f21
10 changed files with 310 additions and 209 deletions
+10 -3
View File
@@ -1012,10 +1012,11 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLin
return false ;
// determino se approssimazione interna o esterna
bool bCCW = ( (( m_VtExtr * m_VtN) > - EPS_ZERO) ? ( m_dAngCenDeg > 0) : ( m_dAngCenDeg < 0)) ;
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
bool bCCW = ( (( vtExtr * m_VtN) > - EPS_ZERO) ? ( m_dAngCenDeg > 0) : ( m_dAngCenDeg < 0)) ;
bool bInside = true ;
if ( ( nType == APL_RIGHT && bCCW) ||
( nType == APL_LEFT && ! bCCW))
if ( ( ( nType == APL_RIGHT || nType == APL_RIGHT_CONVEX) && bCCW) ||
( ( nType == APL_LEFT || nType == APL_LEFT_CONVEX) && ! bCCW))
bInside = false ;
// eseguo approssimazione
@@ -1027,6 +1028,12 @@ CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, PolyLin
return false ;
}
// se necessario, sistemo per convessità dalla parte ammessa
if ( nType == APL_RIGHT_CONVEX || nType == APL_LEFT_CONVEX) {
if ( ! PL.MakeConvex( vtExtr, ( nType == APL_LEFT_CONVEX)))
return false ;
}
return true ;
}
+11 -3
View File
@@ -1331,13 +1331,21 @@ CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, Poly
dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ;
// se lineare con lato obbligato, gestione speciale
if ( nType == APL_LEFT || nType == APL_RIGHT) {
if ( nType == APL_LEFT || nType == APL_LEFT_CONVEX ||
nType == APL_RIGHT || nType == APL_RIGHT_CONVEX) {
// prima approssimazione lineare a 10 * Epsilon
if ( ! ApproxWithLines( 10 * EPS_SMALL, dAngTolDeg, APL_STD, PL))
return false ;
// eliminazione dei punti in tolleranza andando solo dalla parte ammessa
Vector3d vtN = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
return PL.ApproxOnSide( vtN, ( nType == APL_LEFT), dLinTol) ;
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
if ( ! PL.ApproxOnSide( vtExtr, ( nType == APL_LEFT), dLinTol))
return false ;
// se necessario, sistemo per convessità dalla parte ammessa
if ( nType == APL_RIGHT_CONVEX || nType == APL_LEFT_CONVEX) {
if ( ! PL.MakeConvex( vtExtr, ( nType == APL_LEFT_CONVEX)))
return false ;
}
return true ;
}
// inserisco il punto iniziale
+99 -182
View File
@@ -35,7 +35,7 @@ GEOOBJ_REGISTER( CRV_COMPO, NGE_C_CMP, CurveComposite) ;
//----------------------------------------------------------------------------
CurveComposite::CurveComposite( void)
: m_nStatus( TO_VERIFY), m_bClosed( false), m_VtExtr(), m_dThick(), m_nTempProp()
: m_nStatus( TO_VERIFY), m_VtExtr(), m_dThick(), m_nTempProp()
{
}
@@ -57,7 +57,6 @@ CurveComposite::Clear( void)
m_CrvSmplS.clear() ;
m_nStatus = TO_VERIFY ;
m_bClosed = false ;
m_VtExtr = V_NULL ;
m_dThick = 0 ;
m_nTempProp = 0 ;
@@ -193,10 +192,12 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
// se inserita alla fine
if ( bEndOrStart) {
// verifico sia in continuità con il finale attuale
if ( ! AreSamePointApprox( ptStart, m_PtEnd)) {
Point3d ptEnd ;
GetEndPoint( ptEnd) ;
if ( ! AreSamePointApprox( ptStart, ptEnd)) {
// se in tolleranza, modifico l'inizio dell'entità
if ( SqDist( ptStart, m_PtEnd) < ( dLinTol * dLinTol)) {
if ( ! pCrv->ModifyStart( m_PtEnd))
if ( SqDist( ptStart, ptEnd) < ( dLinTol * dLinTol)) {
if ( ! pCrv->ModifyStart( ptEnd))
return false ;
}
else
@@ -206,10 +207,12 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
// altrimenti inserita all'inizio
else {
// verifico sia in continuità con l'iniziale attuale
if ( ! AreSamePointApprox( ptEnd, m_PtStart)) {
Point3d ptStart ;
GetStartPoint( ptStart) ;
if ( ! AreSamePointApprox( ptEnd, ptStart)) {
// se in tolleranza, modifico la fine dell'entità
if ( SqDist( ptEnd, m_PtStart) < ( dLinTol * dLinTol)) {
if ( ! pCrv->ModifyEnd( m_PtStart))
if ( SqDist( ptEnd, ptStart) < ( dLinTol * dLinTol)) {
if ( ! pCrv->ModifyEnd( ptStart))
return false ;
}
else
@@ -218,29 +221,12 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
}
}
// se prima curva, assegno il punto iniziale o finale
if ( m_CrvSmplS.empty()) {
if ( bEndOrStart)
m_PtStart = ptStart ;
else
m_PtEnd = ptEnd ;
}
// inserisco la curva nella lista
if ( bEndOrStart)
m_CrvSmplS.push_back( ::Release( pCrv)) ;
else
m_CrvSmplS.push_front( ::Release( pCrv)) ;
// assegno il nuovo punto estremo
if ( bEndOrStart)
m_PtEnd = ptEnd ;
else
m_PtStart = ptStart ;
// aggiorno il flag di curva chiusa
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
// aggiorno lo stato
m_nStatus = OK ;
@@ -255,11 +241,14 @@ CurveComposite::Close( void)
if ( m_nStatus != OK)
return false ;
// se già chiusa, non faccio alcunché
if ( m_bClosed)
if ( IsClosed())
return true ;
// aggiungo la linea di chiusura
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
if ( ! pLine->Set( m_PtEnd, m_PtStart) ||
Point3d ptStart, ptEnd ;
if ( ! GetStartPoint( ptStart) ||
! GetEndPoint( ptEnd) ||
! pLine->Set( ptEnd, ptStart) ||
! AddSimpleCurve( Release( pLine)))
return false ;
// imposto ricalcolo della grafica
@@ -795,46 +784,11 @@ CurveComposite::Validate( void)
}
// aggiorno
m_nStatus = ( nCount > 0 ? OK : TO_VERIFY) ;
if ( m_nStatus == OK) {
m_CrvSmplS.front()->GetStartPoint( m_PtStart) ;
m_CrvSmplS.back()->GetEndPoint( m_PtEnd) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
}
else
m_bClosed = false ;
}
return ( m_nStatus == OK) ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::ValidateMoveStart( void)
{
// ci deve essere almeno una curva
if ( m_CrvSmplS.empty())
return false ;
// imposto punto iniziale e verifico curva chiusa
if ( ! m_CrvSmplS.front()->GetStartPoint( m_PtStart))
return false ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::ValidateMoveEnd( void)
{
// ci deve essere almeno una curva
if ( m_CrvSmplS.empty())
return false ;
// imposto punto finale e verifica curva chiusa
if ( ! m_CrvSmplS.back()->GetEndPoint( m_PtEnd))
return false ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::IsFlat( Plane3d& plPlane, double dToler) const
@@ -930,18 +884,31 @@ CurveComposite::IsFlat( Plane3d& plPlane, double dToler) const
return bFlat ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::IsClosed( void) const
{
// verifico lo stato
if ( m_nStatus != OK || m_CrvSmplS.empty())
return false ;
// ricavo punti iniziale e finale e li confronto
Point3d ptStart, ptEnd ;
return ( m_CrvSmplS.front()->GetStartPoint( ptStart) &&
m_CrvSmplS.back()->GetEndPoint( ptEnd) &&
AreSamePointApprox( ptStart, ptEnd)) ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::GetStartPoint( Point3d& ptStart) const
{
// verifico lo stato
if ( m_nStatus != OK)
if ( m_nStatus != OK || m_CrvSmplS.empty())
return false ;
// assegno il punto
ptStart = m_PtStart ;
return true ;
return m_CrvSmplS.front()->GetStartPoint( ptStart) ;
}
//----------------------------------------------------------------------------
@@ -949,13 +916,11 @@ bool
CurveComposite::GetEndPoint( Point3d& ptEnd) const
{
// verifico lo stato
if ( m_nStatus != OK)
if ( m_nStatus != OK || m_CrvSmplS.empty())
return false ;
// assegno il punto
ptEnd = m_PtEnd ;
return true ;
return m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
}
//----------------------------------------------------------------------------
@@ -995,6 +960,30 @@ CurveComposite::GetCentroid( Point3d& ptCen) const
return GetMidPoint( ptCen) ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::GetStartDir( Vector3d& vtDir) const
{
// verifico lo stato
if ( m_nStatus != OK || m_CrvSmplS.empty())
return false ;
// assegno il punto
return m_CrvSmplS.front()->GetStartDir( vtDir) ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::GetEndDir( Vector3d& vtDir) const
{
// verifico lo stato
if ( m_nStatus != OK || m_CrvSmplS.empty())
return false ;
// assegno il punto
return m_CrvSmplS.back()->GetEndDir( vtDir) ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::GetMidDir( Vector3d& vtDir) const
@@ -1039,7 +1028,7 @@ CurveComposite::GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& d
// il parametro U deve essere compreso tra 0 e m_nCounter (le curve chiuse sono cicliche)
if ( dU < ( 0 + EPS_PARAM)) {
// se chiusa e voglio valutare prima dell'inizio devo valutare prima della fine
if ( m_bClosed && nS == ICurve::FROM_MINUS)
if ( IsClosed() && nS == ICurve::FROM_MINUS)
dU = dMaxU ;
// altrimenti posso valutare solo dopo l'inizio
else {
@@ -1049,7 +1038,7 @@ CurveComposite::GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& d
}
else if ( dU > ( dMaxU - EPS_PARAM)) {
// se chiusa e voglio valutare dopo la fine devo valutare dopo l'inizio
if ( m_bClosed && nS == ICurve::FROM_PLUS)
if ( IsClosed() && nS == ICurve::FROM_PLUS)
dU = 0 ;
// altrimenti posso valutare solo prima della fine
else {
@@ -1268,6 +1257,13 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, int nType, P
dStartPar += 1 ;
}
// se necessario, sistemo per convessità dalla parte ammessa
if ( nType == APL_RIGHT_CONVEX || nType == APL_LEFT_CONVEX) {
Vector3d vtExtr = ( m_VtExtr.IsSmall() ? Z_AX : m_VtExtr) ;
if ( ! PL.MakeConvex( vtExtr, ( nType == APL_LEFT_CONVEX)))
return false ;
}
return true ;
}
@@ -1321,7 +1317,7 @@ CurveComposite::CopyParamRange( double dUStart, double dUEnd) const
// se il parametro start supera quello di end
if ( dUStart > dUEnd - EPS_PARAM) {
// se curva aperta, il trim la cancella completamente quindi non resta alcunchè
if ( ! m_bClosed)
if ( ! IsClosed())
return nullptr ;
// se curva chiusa, il trim si avvolge attorno al punto di giunzione
else
@@ -1361,16 +1357,12 @@ CurveComposite::Invert( void)
return false ;
// inverto le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Invert() ;
// inverto l'ordine della lista
reverse( m_CrvSmplS.begin(), m_CrvSmplS.end()) ;
// scambio punti iniziale e finale
swap( m_PtStart, m_PtEnd) ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -1425,9 +1417,6 @@ CurveComposite::ModifyStart( const Point3d& ptNewStart)
// modifico l'inizio di questa curva
if ( ! pCrv->ModifyStart( ptNewStart))
return false ;
// aggiorno il punto iniziale e il flag di curva chiusa
m_PtStart = ptNewStart ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -1449,9 +1438,6 @@ CurveComposite::ModifyEnd( const Point3d& ptNewEnd)
// modifico la fine di questa curva
if ( ! pCrv->ModifyEnd( ptNewEnd))
return false ;
// aggiorno il punto finale e il flag di curva chiusa
m_PtEnd = ptNewEnd ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -1465,8 +1451,7 @@ CurveComposite::TrimStartAtParam( double dUTrim)
{
// ciclo sulle diverse curve dall'inizio
double dUToTrim = dUTrim ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
// dominio parametrico della curva semplice
double dParStart, dParEnd ;
(*Iter)->GetDomain( dParStart, dParEnd) ;
@@ -1486,14 +1471,10 @@ CurveComposite::TrimStartAtParam( double dUTrim)
m_CrvSmplS.pop_front() ;
if ( m_CrvSmplS.empty())
return false ;
(*Iter)->GetStartPoint( m_PtStart) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
break ;
}
// altrimenti superata lunghezza ancora da tagliare (taglio già fatto al test sopra)
else {
(*Iter)->GetStartPoint( m_PtStart) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
break ;
}
}
@@ -1511,8 +1492,7 @@ CurveComposite::TrimEndAtParam( double dUTrim)
// ciclo sulle diverse curve dalla fine
bool bToErase = false ;
double dUToTrim = dUTrim ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
// dominio parametrico della curva semplice
double dParStart, dParEnd ;
(*Iter)->GetDomain( dParStart, dParEnd) ;
@@ -1530,9 +1510,6 @@ CurveComposite::TrimEndAtParam( double dUTrim)
}
// se lunghezza parametrica ancora da tagliare nulla (entro la tolleranza)
else if ( dUToTrim > - EPS_PARAM) {
// imposto punto finale e verifico curva chiusa
(*Iter)->GetEndPoint( m_PtEnd) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
// passo alla entità successiva
++ Iter ;
// dichiaro ingresso in zona da cancellare
@@ -1546,9 +1523,6 @@ CurveComposite::TrimEndAtParam( double dUTrim)
bToErase = true ;
continue ;
}
// imposto punto finale e verifica curva chiusa
(*Iter)->GetEndPoint( m_PtEnd) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
// passo alla entità successiva
++ Iter ;
// dichiaro ingresso in zona da cancellare
@@ -1575,7 +1549,7 @@ CurveComposite::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
// se il parametro start supera quello di end
if ( dUStartTrim > dUEndTrim - EPS_PARAM) {
// se curva aperta, il trim la cancella completamente quindi errore
if ( ! m_bClosed)
if ( ! IsClosed())
return false ;
// se curva chiusa, il trim interessa il punto di giunzione
else {
@@ -1619,8 +1593,7 @@ CurveComposite::TrimStartAtLen( double dLenTrim)
{
// ciclo sulle diverse curve dall'inizio
double dLenToTrim = dLenTrim ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
// lunghezza della curva
double dCrvLen ;
if ( ! (*Iter)->GetLength( dCrvLen))
@@ -1642,8 +1615,6 @@ CurveComposite::TrimStartAtLen( double dLenTrim)
m_CrvSmplS.pop_front() ;
if ( m_CrvSmplS.empty())
return false ;
(*Iter)->GetStartPoint( m_PtStart) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
break ;
}
// altrimenti superata lunghezza ancora da tagliare
@@ -1652,8 +1623,6 @@ CurveComposite::TrimStartAtLen( double dLenTrim)
m_nStatus = ERR ;
return false ;
}
(*Iter)->GetStartPoint( m_PtStart) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
break ;
}
}
@@ -1671,8 +1640,7 @@ CurveComposite::TrimEndAtLen( double dLenTrim)
// ciclo sulle diverse curve dalla fine
bool bToErase = false ;
double dLenToTrim = dLenTrim ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
double dCrvLen ;
// se non sono già nella zona da cancellare, aggiorno lunghezze
if ( ! bToErase) {
@@ -1695,9 +1663,6 @@ CurveComposite::TrimEndAtLen( double dLenTrim)
}
// se lunghezza ancora da tagliare nulla (entro la tolleranza)
else if ( dLenToTrim > - EPS_SMALL) {
// imposto punto finale e verifica curva chiusa
(*Iter)->GetEndPoint( m_PtEnd) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
// passo alla entità successiva
++ Iter ;
// dichiaro ingresso in zona da cancellare
@@ -1710,9 +1675,6 @@ CurveComposite::TrimEndAtLen( double dLenTrim)
m_nStatus = ERR ;
return false ;
}
// imposto punto finale e verifica curva chiusa
(*Iter)->GetEndPoint( m_PtEnd) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
// passo alla entità successiva
++ Iter ;
// dichiaro ingresso in zona da cancellare
@@ -1743,9 +1705,6 @@ CurveComposite::ExtendStartByLen( double dLenExt)
return false ;
}
// imposto punto iniziale e verifica curva chiusa
ValidateMoveStart() ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
@@ -1760,7 +1719,7 @@ CurveComposite::ExtendEndByLen( double dLenExt)
return false ;
// vado sulla fine
PCSD_ITER Iter = m_CrvSmplS.end() ;
auto Iter = m_CrvSmplS.end() ;
if ( Iter == m_CrvSmplS.begin())
return false ;
-- Iter ;
@@ -1773,9 +1732,6 @@ CurveComposite::ExtendEndByLen( double dLenExt)
return false ;
}
// imposto punto finale e verifica curva chiusa
ValidateMoveEnd() ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
@@ -1789,13 +1745,8 @@ CurveComposite::Translate( const Vector3d& vtMove)
m_OGrMgr.Reset() ;
// traslo le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Translate( vtMove) ;
// traslo i punti estremi
m_PtStart.Translate( vtMove) ;
m_PtEnd.Translate( vtMove) ;
for ( auto& pCrv : m_CrvSmplS)
pCrv->Translate( vtMove) ;
return true ;
}
@@ -1812,13 +1763,9 @@ CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAn
m_OGrMgr.Reset() ;
// ruoto le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
for ( auto& pCrv : m_CrvSmplS)
pCrv->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
// ruoto i punti estremi
m_PtStart.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
m_PtEnd.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
// ruoto il vettore estrusione
m_VtExtr.Rotate( vtAx, dCosAng, dSinAng) ;
@@ -1857,7 +1804,7 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
}
// scalo le singole curve
for ( PCSD_ITER Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ) {
for ( auto Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ) {
// eseguo la scalatura
bool bOk = (*Iter)->Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
// se tutto bene, passo alla prossima
@@ -1871,9 +1818,6 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
}
}
// scalo i punti estremi
m_PtStart.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
m_PtEnd.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
// scalo vettore estrusione, lo normalizzo e aggiusto spessore
m_VtExtr.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
double dLen = m_VtExtr.Len() ;
@@ -1898,13 +1842,9 @@ CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
m_OGrMgr.Reset() ;
// specchio le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Mirror( ptOn, vtNorm) ;
for ( auto& pCrv : m_CrvSmplS)
pCrv->Mirror( ptOn, vtNorm) ;
// specchio i punti estremi
m_PtStart.Mirror( ptOn, vtNorm) ;
m_PtEnd.Mirror( ptOn, vtNorm) ;
// specchio il vettore estrusione
m_VtExtr.Mirror( vtNorm) ;
@@ -1927,13 +1867,9 @@ CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
return false ;
// eseguo scorrimento delle singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Shear( ptOn, vtNorm, vtDir, dCoeff) ;
for ( auto& pCrv : m_CrvSmplS)
pCrv->Shear( ptOn, vtNorm, vtDir, dCoeff) ;
// eseguo scorrimento dei punti estremi
m_PtStart.Shear( ptOn, vtNorm, vtDir, dCoeff) ;
m_PtEnd.Shear( ptOn, vtNorm, vtDir, dCoeff) ;
// eseguo scorrimento del vettore estrusione, lo normalizzo e aggiusto spessore
m_VtExtr.Shear( vtNorm, vtDir, dCoeff) ;
double dLen = m_VtExtr.Len() ;
@@ -1957,13 +1893,10 @@ CurveComposite::ToGlob( const Frame3d& frRef)
m_OGrMgr.Reset() ;
// trasformo le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->ToGlob( frRef) ;
for ( auto& pCrv : m_CrvSmplS)
pCrv->ToGlob( frRef) ;
// trasformo i punti estremi e il vettore estrusione
m_PtStart.ToGlob( frRef) ;
m_PtEnd.ToGlob( frRef) ;
// trasformo il vettore estrusione
m_VtExtr.ToGlob( frRef) ;
return true ;
@@ -1981,13 +1914,10 @@ CurveComposite::ToLoc( const Frame3d& frRef)
m_OGrMgr.Reset() ;
// trasformo le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->ToLoc( frRef) ;
for ( auto& pCrv : m_CrvSmplS)
pCrv->ToLoc( frRef) ;
// trasformo i punti estremi e il vettore estrusione
m_PtStart.ToLoc( frRef) ;
m_PtEnd.ToLoc( frRef) ;
// trasformo il vettore estrusione
m_VtExtr.ToLoc( frRef) ;
return true ;
@@ -2009,14 +1939,10 @@ CurveComposite::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
m_OGrMgr.Reset() ;
// trasformo le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
(*Iter)->LocToLoc( frOri, frDest) ;
}
for ( auto& pCrv : m_CrvSmplS)
pCrv->LocToLoc( frOri, frDest) ;
// trasformo i punti estremi e il vettore estrusione
m_PtStart.LocToLoc( frOri, frDest) ;
m_PtEnd.LocToLoc( frOri, frDest) ;
// trasformo il vettore estrusione
m_VtExtr.LocToLoc( frOri, frDest) ;
return true ;
@@ -2063,6 +1989,8 @@ CurveComposite::GetNextCurve( void) const
return nullptr ;
// vado al successivo
if ( m_Iter == m_CrvSmplS.end())
return nullptr ;
++ m_Iter ;
// recupero la curva
@@ -2129,23 +2057,15 @@ CurveComposite::RemoveFirstOrLastCurve( bool bLast)
pCrv = *(m_CrvSmplS.rbegin()) ;
// la tolgo dalla lista
m_CrvSmplS.pop_back() ;
// aggiorno la curva composita
pCrv->GetStartPoint( m_PtEnd) ;
}
else {
// recupero la curva
pCrv = *(m_CrvSmplS.begin()) ;
// la tolgo dalla lista
m_CrvSmplS.pop_front() ;
// aggiorno la curva composita
pCrv->GetEndPoint( m_PtStart) ;
}
// eseguo mini verifica
m_nStatus = ( m_CrvSmplS.size() > 0 ? OK : TO_VERIFY) ;
if ( m_nStatus == OK)
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
else
m_bClosed = false ;
// assegno estrusione e spessore della curva composita
pCrv->SetExtrusion( m_VtExtr) ;
pCrv->SetThickness( m_dThick) ;
@@ -2160,8 +2080,9 @@ bool
CurveComposite::IsParamAtJoint( double dU) const
{
// se aperta e all'inizio o alla fine o lontano dagli interi non è giunzione
if ( ( ! m_bClosed && fabs( dU) < EPS_ZERO) ||
( ! m_bClosed && fabs( dU - double( m_CrvSmplS.size())) < EPS_ZERO) ||
bool bClosed = IsClosed() ;
if ( ( ! bClosed && fabs( dU) < EPS_ZERO) ||
( ! bClosed && fabs( dU - double( m_CrvSmplS.size())) < EPS_ZERO) ||
fabs( dU - (int) ( dU + EPS_ZERO)) > EPS_ZERO)
return false ;
else
@@ -2204,11 +2125,9 @@ CurveComposite::ArcsToBezierCurves( void)
if ( pCC == nullptr)
return false ;
// inserisco le curve prima dell'arco
int nParts = 0 ;
for ( PCSD_ITER Iter2 = pCC->m_CrvSmplS.begin() ; Iter2 != pCC->m_CrvSmplS.end() ; ++ Iter2) {
Iter = m_CrvSmplS.insert( Iter, (*Iter2)) ;
++ Iter ;
++ nParts ;
}
pCC->m_CrvSmplS.clear() ;
// elimino l'arco (e sposto l'iteratore alla curva precedente)
@@ -2250,12 +2169,10 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe
if ( pCC == nullptr)
return false ;
// inserisco le curve prima dell'originale
int nParts = 0 ;
PCSD_ITER Iter2 ;
for ( Iter2 = pCC->m_CrvSmplS.begin() ; Iter2 != pCC->m_CrvSmplS.end() ; ++ Iter2) {
Iter = m_CrvSmplS.insert( Iter, (*Iter2)) ;
++ Iter ;
++ nParts ;
}
pCC->m_CrvSmplS.clear() ;
// elimino l'arco (e sposto l'iteratore alla curva precedente)
+3 -11
View File
@@ -58,8 +58,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
public : // ICurve
virtual bool IsSimple( void) const { return false ; }
virtual bool IsClosed( void) const
{ return ( m_nStatus == OK && m_bClosed) ; }
virtual bool IsClosed( void) const ;
virtual bool IsFlat( Plane3d& plPlane, double dToler = EPS_SMALL) const ;
virtual bool GetStartPoint( Point3d& ptStart) const ;
virtual bool GetEndPoint( Point3d& ptEnd) const ;
@@ -67,10 +66,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
virtual bool GetCenterPoint( Point3d& ptCen) const
{ return GetMidPoint( ptCen) ; }
virtual bool GetCentroid( Point3d& ptCen) const ;
virtual bool GetStartDir( Vector3d& vtDir) const
{ return ::GetTang( *this, 0, FROM_PLUS, vtDir) ; }
virtual bool GetEndDir( Vector3d& vtDir) const
{ return ::GetTang( *this, double( m_CrvSmplS.size()), FROM_MINUS, vtDir) ; }
virtual bool GetStartDir( Vector3d& vtDir) const ;
virtual bool GetEndDir( Vector3d& vtDir) const ;
virtual bool GetMidDir( Vector3d& vtDir) const ;
virtual bool GetExtrusion( Vector3d& vtExtr) const
{ vtExtr = m_VtExtr ; return ( m_nStatus == OK) ; }
@@ -164,8 +161,6 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
private :
bool CopyFrom( const CurveComposite& ccSrc) ;
bool Validate( void) ;
bool ValidateMoveStart( void) ;
bool ValidateMoveEnd( void) ;
bool AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
bool AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ;
@@ -184,9 +179,6 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Status m_nStatus ; // stato
PCRVSMPL_DEQUE m_CrvSmplS ; // deque di curve semplici
Point3d m_PtStart ; // punto iniziale
Point3d m_PtEnd ; // punto finale
bool m_bClosed ; // flag per indicare che la curva è chiusa
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
double m_dThick ; // spessore
int m_nTempProp ; // proprietà temporanea
-3
View File
@@ -96,7 +96,6 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
if ( VerifyAndAdjustSamePoint( pCrv1, pCrv2, ccTemp) ||
VerifyAndAdjustInternalAngle( pCrv1, pCrv2, ccTemp) ||
VerifyAndAdjustExternalAngle( pCrv1, pCrv2, dDist, nType, ccTemp)) {
ccOffs.ValidateMoveEnd() ;
if ( ccTemp.GetCurveNumber() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
return false ;
}
@@ -121,8 +120,6 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
if ( VerifyAndAdjustSamePoint( pCrv1, pCrv2, ccTemp) ||
VerifyAndAdjustInternalAngle( pCrv1, pCrv2, ccTemp) ||
VerifyAndAdjustExternalAngle( pCrv1, pCrv2, dDist, nType, ccTemp)) {
ccOffs.ValidateMoveStart() ;
ccOffs.ValidateMoveEnd() ;
if ( ccTemp.GetCurveNumber() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
return false ;
}
BIN
View File
Binary file not shown.
+7 -3
View File
@@ -45,11 +45,15 @@ FontManager::SetCurrFont( const string& sFont, int nWeight, bool bItalic,
// lo cerco tra i font Nfe
if ( FileExtensionMatches( sFontName, "NFE")) {
// verifico che il font richiesto esista, altrimenti prendo il primo dello stesso tipo
// verifico che il font richiesto esista, altrimenti prendo default se Nfe
string sPath = m_sNfeFontDir + "\\" + sFontName ;
if ( ! ExistsFile( sPath)) {
if ( FindFirstFileEgt( m_sNfeFontDir + "\\*.Nfe", sFontName))
sPath = m_sNfeFontDir + "\\" + sFontName ;
sPath = m_sNfeFontDir + "\\" + m_sDefaultFont ;
// verifico esistenza, altrimenti prendo il primo dello stesso tipo
if ( ! ExistsFile( sPath)) {
if ( FindFirstFileEgt( m_sNfeFontDir + "\\*.Nfe", sFontName))
sPath = m_sNfeFontDir + "\\" + sFontName ;
}
}
// imposto il font corrente
m_bCurrNfeFont = true ;
+8 -1
View File
@@ -44,7 +44,14 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2) ;
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
double dU = ( ptInt - ptL) * vtDir ;
vInfo.emplace_back( dU, nT, ptInt) ;
double dCosDN = vtDir * Tria.GetN() ;
vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ;
}
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
double dU = ( ptInt - ptL) * vtDir ;
double dU2 = ( ptInt2 - ptL) * vtDir ;
double dCosDN = vtDir * Tria.GetN() ;
vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ;
}
nT = Stm.GetNextTriangle( nT, Tria) ;
}
+124 -3
View File
@@ -2,7 +2,7 @@
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : IntersLinePlane.cpp Data : 18.02.15 Versione : 1.6b7
// Contenuto : Implementazione della intersezione linea/piano.
// Contenuto : Implementazione della intersezione linea/triangolo.
//
//
//
@@ -14,9 +14,17 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "ProjPlane.h"
#include "CurveLine.h"
#include "IntersLineLine.h"
#include "/EgtDev/Include/EGkFrame3d.h"
#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
//----------------------------------------------------------------------------
static int IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Triangle3d& trTria,
Point3d& ptInt, Point3d& ptInt2) ;
//----------------------------------------------------------------------------
int
IntersLineTria( const Point3d& ptL1, const Point3d& ptL2, const Triangle3d& trTria,
@@ -61,7 +69,120 @@ IntersLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Tria
}
// se la linea giace nel piano del triangolo
else {
// !!!! DA FARE !!!!
return ILTT_NO ;
return IntersCoplanarLineTria( ptL, vtL, dLen, trTria, ptInt, ptInt2) ;
}
}
//----------------------------------------------------------------------------
int
IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Triangle3d& trTria,
Point3d& ptInt, Point3d& ptInt2)
{
// verifico se il segmento è completamente contenuto nel triangolo
ptInt = ptL ;
ptInt2 = ptL + vtL * dLen ;
int nPTT = PointInTria( ptInt, trTria) ;
int nPTT2 = PointInTria( ptInt2, trTria) ;
if ( nPTT != PTT_OUT && nPTT2 != PTT_OUT)
return ILTT_SEGM ;
// se segmento nullo, basta verificare la posizione del punto iniziale
if ( dLen < EPS_SMALL || vtL.IsSmall()) {
switch ( nPTT) {
case PTT_OUT :
return ILTT_NO ;
case PTT_VERT :
return ILTT_VERT ;
case PTT_EDGE :
return ILTT_EDGE ;
default :
return ILTT_IN ;
}
}
// definisco un riferimento coincidente con il piano del triangolo
Frame3d frRef ;
if ( ! frRef.Set( trTria.GetP( 0), trTria.GetN(), ( trTria.GetP( 1) - trTria.GetP( 0))))
return ILTT_NO ;
// esprimo il triangolo e il segmento in questo riferimento
Triangle3d trTriaL = trTria ;
trTriaL.ToLoc( frRef) ;
Point3d ptLL = ptL ;
ptLL.ToLoc( frRef) ;
Vector3d vtLL = vtL ;
vtLL.ToLoc( frRef) ;
// calcolo le intersezioni tra i lati del triangolo e il segmento
CurveLine LineLL ;
LineLL.Set( ptLL, ptLL + vtLL * dLen) ;
int nNumInt = 0 ;
IntCrvCrvInfo IntCCI[3] ;
for ( int i = 0 ; i < 3 ; ++ i) {
CurveLine LineTL ;
LineTL.Set( trTriaL.GetP( i), trTriaL.GetP( ( i + 1) % 3)) ;
IntersLineLine IntLL( LineLL, LineTL) ;
if ( IntLL.GetIntCrvCrvInfo( IntCCI[nNumInt]))
++ nNumInt ;
}
// se nessuna intersezione
if ( nNumInt == 0)
return ILTT_NO ;
// se una sola intersezione
else if ( nNumInt == 1) {
// punto di intersezione
Point3d ptIntL = IntCCI[0].IciA[0].ptI ;
ptInt = ptIntL ;
ptInt.ToGlob( frRef) ;
// se è l'inizio del segmento ( e il resto del segmento deve essere per forza esterno)
if ( AreSamePointApprox( ptIntL, LineLL.GetStart()))
return ( ( nPTT == PTT_VERT) ? ILTT_VERT : ILTT_EDGE) ;
// se è la fine del segmento ( e il resto del segmento deve essere per forza esterno)
else if ( AreSamePointApprox( ptIntL, LineLL.GetEnd()))
return ( ( nPTT2 == PTT_VERT) ? ILTT_VERT : ILTT_EDGE) ;
// altrimenti è un punto intermedio
else {
// se l'inizio è nel triangolo
if ( nPTT == PTT_IN) {
ptInt2 = ptInt ;
ptInt = ptL ;
}
// altrimenti è la fine nel triangolo
else
ptInt2 = ptL + vtL * dLen ;
return ILTT_SEGM ;
}
}
// se 2 intersezioni
else if ( nNumInt == 2) {
// punti di intersezione
Point3d ptIntL = IntCCI[0].IciA[0].ptI ;
ptInt = ptIntL ;
ptInt.ToGlob( frRef) ;
Point3d ptInt2L = IntCCI[1].IciA[0].ptI ;
ptInt2 = ptInt2L ;
ptInt2.ToGlob( frRef) ;
// se coincidono, deve essere un vertice
if ( AreSamePointApprox( ptIntL, ptInt2L))
return ILTT_VERT ;
// altrimenti è un tratto
else {
// le ordino secondo il verso positivo della linea
if ( ( ptInt - ptL) * vtL > ( ptInt2 - ptL) * vtL)
std::swap( ptInt, ptInt2) ;
return ILTT_SEGM ;
}
}
// altrimenti 3 intersezioni, una deve coincidere con un lato le altre due sono i suoi vertici
else {
for ( int i = 0 ; i < 3 ; ++ i) {
if ( IntCCI[i].bOverlap) {
// punti di intersezione
Point3d ptIntL = IntCCI[i].IciA[0].ptI ;
ptInt = ptIntL ;
ptInt.ToGlob( frRef) ;
Point3d ptInt2L = IntCCI[i].IciA[1].ptI ;
ptInt2 = ptInt2L ;
ptInt2.ToGlob( frRef) ;
return ILTT_SEGM_ON_EDGE ;
}
}
}
return ILTT_NO ;
}
+48
View File
@@ -835,6 +835,54 @@ PolyLine::ApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler)
return true ;
}
//----------------------------------------------------------------------------
bool
PolyLine::MakeConvex( const Vector3d& vtN, bool bLeftSide)
{
// ciclo i controlli finchè non ci sono rimozioni
bool bRemoved = true ;
while ( bRemoved) {
bRemoved = false ;
// se non ci sono almeno 3 punti, esco subito
if ( m_lUPoints.size() < 3)
return true ;
// punto precedente
auto precP = m_lUPoints.begin() ;
// punto corrente
auto currP = next( precP) ;
// punto successivo
auto nextP = next( currP) ;
// mentre esiste un successivo
while ( nextP != m_lUPoints.end()) {
// --- si verifica se possibile eliminare il punto corrente rimanendo dal lato voluto ---
// se lato sinistro e gira a sinistra o lato destro e gira a destra
double dCrossXY = ( ( currP->first - precP->first) ^ ( nextP->first - currP->first)) * vtN ;
if ( ( bLeftSide && dCrossXY > - EPS_ZERO) || ( ! bLeftSide && dCrossXY < EPS_ZERO)) {
// elimino il punto corrente
m_lUPoints.erase( currP) ;
// avanzo con corrente e successivo
currP = nextP ;
++ nextP ;
// dichiaro rimozione
bRemoved = true ;
continue ;
}
// non è stato eliminato alcunché : avanzo il terzetto di uno step
precP = currP ;
currP = nextP ;
++ nextP ;
}
// se rimasti due punti coincidenti, elimino il secondo
if ( m_lUPoints.size() == 2 &&
AreSamePointApprox( m_lUPoints.front().first, m_lUPoints.back().first)) {
m_lUPoints.pop_back() ;
return false ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
PolyLine::Invert( bool bInvertU)