diff --git a/BBox3d.cpp b/BBox3d.cpp new file mode 100644 index 0000000..bc19d11 --- /dev/null +++ b/BBox3d.cpp @@ -0,0 +1,234 @@ +//---------------------------------------------------------------------------- +// EgalTech 2013-2013 +//---------------------------------------------------------------------------- +// File : BBox3d.cpp Data : 14.01.14 Versione : 1.5a3 +// Contenuto : Implementazione della classe axis aligned bounding box BBox3d. +// +// +// +// Modifiche : 14.01.14 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "\EgtDev\Include\EGkBBox3d.h" +#include "\EgtDev\Include\EGkFrame3d.h" +#include + +//---------------------------------------------------------------------------- +BBox3d::BBox3d( const Point3d ptP1, const Point3d ptP2) +{ + m_ptMin.Set( __min( ptP1.x, ptP2.x), __min( ptP1.y, ptP2.y), __min( ptP1.z, ptP2.z)) ; + m_ptMax.Set( __max( ptP1.x, ptP2.x), __max( ptP1.y, ptP2.y), __max( ptP1.z, ptP2.z)) ; +} + +//---------------------------------------------------------------------------- +void +BBox3d::Set( const Point3d ptP1, const Point3d ptP2) +{ + m_ptMin.Set( __min( ptP1.x, ptP2.x), __min( ptP1.y, ptP2.y), __min( ptP1.z, ptP2.z)) ; + m_ptMax.Set( __max( ptP1.x, ptP2.x), __max( ptP1.y, ptP2.y), __max( ptP1.z, ptP2.z)) ; +} + +//---------------------------------------------------------------------------- +bool +BBox3d::IsValid( void) const +{ + return ( m_ptMin.x < ( m_ptMax.x + EPS_SMALL) && + m_ptMin.y < ( m_ptMax.y + EPS_SMALL) && + m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ; +} + +//---------------------------------------------------------------------------- +void +BBox3d::Add( const Point3d& ptP) +{ + if ( ptP.x < m_ptMin.x) + m_ptMin.x = ptP.x ; + if ( ptP.y < m_ptMin.y) + m_ptMin.y = ptP.y ; + if ( ptP.z < m_ptMin.z) + m_ptMin.z = ptP.z ; + if ( ptP.x > m_ptMax.x) + m_ptMax.x = ptP.x ; + if ( ptP.y > m_ptMax.y) + m_ptMax.y = ptP.y ; + if ( ptP.z > m_ptMax.z) + m_ptMax.z = ptP.z ; +} + +//---------------------------------------------------------------------------- +void +BBox3d::Add( const BBox3d& b3B) +{ + if ( b3B.m_ptMin.x < m_ptMin.x) + m_ptMin.x = b3B.m_ptMin.x ; + if ( b3B.m_ptMin.y < m_ptMin.y) + m_ptMin.y = b3B.m_ptMin.y ; + if ( b3B.m_ptMin.z < m_ptMin.z) + m_ptMin.z = b3B.m_ptMin.z ; + if ( b3B.m_ptMax.x > m_ptMax.x) + m_ptMax.x = b3B.m_ptMax.x ; + if ( b3B.m_ptMax.y > m_ptMax.y) + m_ptMax.y = b3B.m_ptMax.y ; + if ( b3B.m_ptMax.z > m_ptMax.z) + m_ptMax.z = b3B.m_ptMax.z ; +} + +//---------------------------------------------------------------------------- +void +BBox3d::Expand( double dDelta) +{ + if ( IsValid()) { + m_ptMin -= Vector3d( dDelta, dDelta, dDelta) ; + m_ptMax += Vector3d( dDelta, dDelta, dDelta) ; + } +} + +//---------------------------------------------------------------------------- +void +BBox3d::Expand( double dDeltaX, double dDeltaY, double dDeltaZ) +{ + if ( IsValid()) { + m_ptMin -= Vector3d( dDeltaX, dDeltaY, dDeltaZ) ; + m_ptMax += Vector3d( dDeltaX, dDeltaY, dDeltaZ) ; + } +} + +//---------------------------------------------------------------------------- +bool +BBox3d::GetMinMax( Point3d& ptMin, Point3d& ptMax) const +{ + if ( ! IsValid()) + return false ; + ptMin = m_ptMin ; + ptMax = m_ptMax ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +BBox3d::GetCenterExtent( Point3d& ptCenter, Vector3d& vtExtent) const +{ + if ( ! IsValid()) + return false ; + ptCenter = 0.5 * ( m_ptMin + m_ptMax) ; + vtExtent = 0.5 * ( m_ptMin - m_ptMax) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +BBox3d::ToGlob( const Frame3d& frRef) +{ + // trasformo il minimo + Point3d ptMinGlob = m_ptMin ; + if ( ! ptMinGlob.ToGlob( frRef)) + return false ; + // trasformo i vettori dal Min al Max diretti come gli assi locali + Vector3d vtXGlob = ( m_ptMax.x - m_ptMin.x) * frRef.VersX() ; + Vector3d vtYGlob = ( m_ptMax.y - m_ptMin.y) * frRef.VersY() ; + Vector3d vtZGlob = ( m_ptMax.z - m_ptMin.z) * frRef.VersZ() ; + // calcolo il box trasformato + Set( ptMinGlob) ; + Add( ptMinGlob + vtXGlob) ; + Add( ptMinGlob + vtYGlob) ; + Add( ptMinGlob + vtZGlob) ; + Add( ptMinGlob + vtXGlob + vtYGlob) ; + Add( ptMinGlob + vtYGlob + vtZGlob) ; + Add( ptMinGlob + vtZGlob + vtXGlob) ; + Add( ptMinGlob + vtXGlob + vtYGlob + vtZGlob) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +BBox3d::ToLoc( const Frame3d& frRef) +{ + // trasformo il minimo + Point3d ptMinLoc = m_ptMin ; + if ( ! ptMinLoc.ToLoc( frRef)) + return false ; + // trasformo i vettori dal Min al Max diretti come gli assi globali + Vector3d vtXLoc = ( m_ptMax.x - m_ptMin.x) * + Vector3d( frRef.VersX().x, frRef.VersY().x, frRef.VersZ().x) ; + Vector3d vtYLoc = ( m_ptMax.y - m_ptMin.y) * + Vector3d( frRef.VersX().y, frRef.VersY().y, frRef.VersZ().y) ; + Vector3d vtZLoc = ( m_ptMax.z - m_ptMin.z) * + Vector3d( frRef.VersX().z, frRef.VersY().z, frRef.VersZ().z) ; + // calcolo il box trasformato + Set( ptMinLoc) ; + Add( ptMinLoc + vtXLoc) ; + Add( ptMinLoc + vtYLoc) ; + Add( ptMinLoc + vtZLoc) ; + Add( ptMinLoc + vtXLoc + vtYLoc) ; + Add( ptMinLoc + vtYLoc + vtZLoc) ; + Add( ptMinLoc + vtZLoc + vtXLoc) ; + Add( ptMinLoc + vtXLoc + vtYLoc + vtZLoc) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +BBox3d::Encloses( const Point3d& ptP) const +{ + return ( ptP.x >= m_ptMin.x && ptP.x <= m_ptMax.x && + ptP.y >= m_ptMin.y && ptP.y <= m_ptMax.y && + ptP.z >= m_ptMin.z && ptP.z <= m_ptMax.z) ; +} + +//---------------------------------------------------------------------------- +bool +BBox3d::Overlaps( const BBox3d& b3B) const +{ + if ( m_ptMax.x < b3B.m_ptMin.x || m_ptMin.x > b3B.m_ptMax.x) + return false ; + if ( m_ptMax.y < b3B.m_ptMin.y || m_ptMin.y > b3B.m_ptMax.y) + return false ; + if ( m_ptMax.z < b3B.m_ptMin.z || m_ptMin.z > b3B.m_ptMax.z) + return false ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const +{ + // verifico direttamente la sovrapposizione + if ( m_ptMax.x < b3B.m_ptMin.x || m_ptMin.x > b3B.m_ptMax.x) + return false ; + if ( m_ptMax.y < b3B.m_ptMin.y || m_ptMin.y > b3B.m_ptMax.y) + return false ; + if ( m_ptMax.z < b3B.m_ptMin.z || m_ptMin.z > b3B.m_ptMax.z) + return false ; + // calcolo il box intersezione + b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ; + b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ; + b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ; + b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ; + b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ; + b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ; + return true ; +} + +//---------------------------------------------------------------------------- +double +BBox3d::SqDistFromPoint( const Point3d& ptP) const +{ + double dSqDist = 0 ; + if ( ptP.x < m_ptMin.x) + dSqDist += ( m_ptMin.x - ptP.x) * ( m_ptMin.x - ptP.x) ; + else if ( ptP.x > m_ptMax.x) + dSqDist += ( ptP.x - m_ptMax.x) * ( ptP.x - m_ptMax.x) ; + if ( ptP.y < m_ptMin.y) + dSqDist += ( m_ptMin.y - ptP.y) * ( m_ptMin.y - ptP.y) ; + else if ( ptP.y > m_ptMax.y) + dSqDist += ( ptP.y - m_ptMax.y) * ( ptP.y - m_ptMax.y) ; + if ( ptP.z < m_ptMin.z) + dSqDist += ( m_ptMin.z - ptP.z) * ( m_ptMin.z - ptP.z) ; + else if ( ptP.z > m_ptMax.z) + dSqDist += ( ptP.z - m_ptMax.z) * ( ptP.z - m_ptMax.z) ; + return dSqDist ; +} diff --git a/CurveArc.cpp b/CurveArc.cpp index 16d1fd4..c0b2d80 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -23,6 +23,28 @@ using namespace std ; //---------------------------------------------------------------------------- GEOOBJ_REGISTER( CRV_ARC, "C_ARC", CurveArc) ; + +//---------------------------------------------------------------------------- +class ArcApproxer +{ + public : + ArcApproxer( double dLinTol, double dAngTolDeg, const CurveArc& arArc) ; + bool GetPoint( double& dU, Point3d& ptP) ; + + private : + Point3d m_PtCen ; + Vector3d m_VtN ; + double m_dRad ; + double m_dDeltaN ; + Vector3d m_vtA1 ; + Vector3d m_vtA2 ; + double m_dCosA ; + double m_dSinA ; + int m_nTotPnt ; + int m_nCurrPnt ; +} ; + + //---------------------------------------------------------------------------- CurveArc::CurveArc( void) : m_nStatus( TO_VERIFY), m_PtCen(), m_VtN(), m_VtS(), m_dRad( 0), m_dAngCenDeg( 0), m_dDeltaN( 0) @@ -172,6 +194,67 @@ CurveArc::Load( Scanner& TheScanner) return Validate() ; } +//---------------------------------------------------------------------------- +bool +CurveArc::GetLocalBBox( BBox3d& b3Loc) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // assegno il box in locale + b3Loc.Reset() ; + ArcApproxer aAppr( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, *this) ; + double dU ; + Point3d ptPos ; + while ( aAppr.GetPoint( dU, ptPos)) + b3Loc.Add( ptPos) ; + // espando per compensare l'approssimazione (solo nel piano dell'arco se possibile) + if ( m_VtN.IsXplus() || m_VtN.IsXminus()) + b3Loc.Expand( 0, LIN_TOL_APPROX, LIN_TOL_APPROX) ; + else if ( m_VtN.IsYplus() || m_VtN.IsYminus()) + b3Loc.Expand( LIN_TOL_APPROX, 0, LIN_TOL_APPROX) ; + else if ( m_VtN.IsZplus() || m_VtN.IsZminus()) + b3Loc.Expand( LIN_TOL_APPROX, LIN_TOL_APPROX, 0) ; + else + b3Loc.Expand( LIN_TOL_APPROX) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveArc::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // verifico validitą del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + // assegno il box nel riferimento + b3Ref.Reset() ; + ArcApproxer aAppr( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, *this) ; + double dU ; + Point3d ptPos ; + while ( aAppr.GetPoint( dU, ptPos)) { + ptPos.ToGlob( frRef) ; + b3Ref.Add( ptPos) ; + } + // espando per compensare l'approssimazione (solo nel piano dell'arco se possibile) + Vector3d vtNInRef = m_VtN ; + vtNInRef.ToGlob( frRef) ; + if ( vtNInRef.IsXplus() || vtNInRef.IsXminus()) + b3Ref.Expand( 0, LIN_TOL_APPROX, LIN_TOL_APPROX) ; + else if ( vtNInRef.IsYplus() || vtNInRef.IsYminus()) + b3Ref.Expand( LIN_TOL_APPROX, 0, LIN_TOL_APPROX) ; + else if ( vtNInRef.IsZplus() || vtNInRef.IsZminus()) + b3Ref.Expand( LIN_TOL_APPROX, LIN_TOL_APPROX, 0) ; + else + b3Ref.Expand( LIN_TOL_APPROX) ; + + return true ; +} + //---------------------------------------------------------------------------- bool CurveArc::Validate( void) @@ -278,64 +361,11 @@ CurveArc::GetLength( double& dLen) const bool CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const { - int i ; - int nStep ; - double dAngStepDeg ; - double dCosA ; - double dSinA ; - double dU ; - Point3d ptPos ; - Vector3d vtA1 ; - Vector3d vtA2 ; - Vector3d vtA1p ; - Vector3d vtA2p ; - - - // la curva deve essere validata - if ( m_nStatus != OK) - return false ; - - // limiti minimi su tolleranza e deviazione angolare - dLinTol = max( dLinTol, LIN_TOL_MIN) ; - dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; - - // determinazione dello step angolare - dAngStepDeg = sqrt( 8 * dLinTol / m_dRad) * RADTODEG ; - dAngStepDeg = min( dAngStepDeg, dAngTolDeg) ; - - // dall'angolo al centro ricavo il numero di passi - nStep = (int) ( fabs( m_dAngCenDeg) / dAngStepDeg + 0.999) ; - - // sistemo lo step (per il numero intero di passi) - dAngStepDeg = m_dAngCenDeg / nStep ; - - // versori di riferimento nel piano dell'arco - vtA1 = m_VtS ; - vtA2 = m_VtN ^ m_VtS ; - - // seno e coseno dell'angolo di step - dCosA = cos( dAngStepDeg * DEGTORAD) ; - dSinA = sin( dAngStepDeg * DEGTORAD) ; - - // primo punto - ptPos = m_PtCen + vtA1 * m_dRad ; - PL.AddUPoint( 0, ptPos) ; - - // ciclo per i punti successivi - for ( i = 1 ; i <= nStep ; ++ i) { - // parametro del punto - dU = i / (double) nStep ; - // nuovo valore versori - vtA1p = vtA1 ; - vtA2p = vtA2 ; - vtA1 = dCosA * vtA1p + dSinA * vtA2p ; - vtA2 = - dSinA * vtA1p + dCosA * vtA2p ; - // calcolo del punto - ptPos = m_PtCen + vtA1 * m_dRad ; - if ( fabs( m_dDeltaN) > EPS_ZERO) - ptPos += ( dU * m_dDeltaN) * m_VtN ; + ArcApproxer aAppr( dLinTol, dAngTolDeg, *this) ; + double dU ; + Point3d ptPos ; + while ( aAppr.GetPoint( dU, ptPos)) PL.AddUPoint( dU, ptPos) ; - } return true ; } @@ -588,3 +618,89 @@ CurveArc::ToLoc( const Frame3d& frRef) return true ; } + +//---------------------------------------------------------------------------- +// Oggetto locale per approssimazione di archi +//---------------------------------------------------------------------------- +ArcApproxer::ArcApproxer( double dLinTol, double dAngTolDeg, const CurveArc& arArc) +{ + int nStep ; + double dAngStepDeg ; + + + // inizializzazioni + m_nTotPnt = 0 ; + m_nCurrPnt = - 1 ; + + // la curva deve essere validata + if ( ! arArc.IsValid()) + return ; + + // limiti minimi su tolleranza e deviazione angolare + dLinTol = max( dLinTol, LIN_TOL_MIN) ; + dAngTolDeg = max( dAngTolDeg, ANG_TOL_MIN_DEG) ; + + // determinazione dello step angolare + dAngStepDeg = sqrt( 8 * dLinTol / arArc.GetRadius()) * RADTODEG ; + dAngStepDeg = min( dAngStepDeg, dAngTolDeg) ; + + // dall'angolo al centro ricavo il numero di passi + nStep = (int) ( fabs( arArc.GetAngCenter()) / dAngStepDeg + 0.999) ; + nStep = __max( nStep, 1) ; + + // sistemo lo step (per il numero intero di passi) + dAngStepDeg = arArc.GetAngCenter() / nStep ; + + // versori di riferimento nel piano dell'arco + m_vtA1 = arArc.GetStartVersor() ; + m_vtA2 = arArc.GetNormVersor() ^ arArc.GetStartVersor() ; + + // seno e coseno dell'angolo di step + m_dCosA = cos( dAngStepDeg * DEGTORAD) ; + m_dSinA = sin( dAngStepDeg * DEGTORAD) ; + + // salvo i dati + m_nTotPnt = nStep + 1 ; + m_PtCen = arArc.GetCenter() ; + m_VtN = arArc.GetNormVersor() ; + m_dRad = arArc.GetRadius() ; + m_dDeltaN = arArc.GetDeltaN() ; +} + +//---------------------------------------------------------------------------- +bool +ArcApproxer::GetPoint( double& dU, Point3d& ptP) +{ + Vector3d vtA1p ; + Vector3d vtA2p ; + + + // incremento indice punto corrente + ++ m_nCurrPnt ; + + // se oltrepassata la fine + if ( m_nCurrPnt >= m_nTotPnt) + return false ; + + // primo punto + if ( m_nCurrPnt == 0) { + dU = 0 ; + ptP = m_PtCen + m_vtA1 * m_dRad ; + return true ; + } + + // punti successivi + // calcolo parametro + dU = m_nCurrPnt / (double) ( m_nTotPnt - 1) ; + // nuovo valore versori + vtA1p = m_vtA1 ; + vtA2p = m_vtA2 ; + m_vtA1 = m_dCosA * vtA1p + m_dSinA * vtA2p ; + m_vtA2 = - m_dSinA * vtA1p + m_dCosA * vtA2p ; + // calcolo del punto + ptP = m_PtCen + m_vtA1 * m_dRad ; + if ( fabs( m_dDeltaN) > EPS_ZERO) + ptP += ( dU * m_dDeltaN) * m_VtN ; + + return true ; +} diff --git a/CurveArc.h b/CurveArc.h index a14ae19..ed932a6 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -27,6 +27,8 @@ class CurveArc : public ICurveArc virtual bool IsValid( void) const { return ( m_nStatus == OK) ; } virtual bool Save( std::ostream& osOut) const ; virtual bool Load( Scanner& TheScanner) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool Translate( const Vector3d& vtMove) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngRad) diff --git a/CurveBezier.cpp b/CurveBezier.cpp index f99684c..34d25aa 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -325,6 +325,41 @@ CurveBezier::Validate( void) return ( m_nStatus == OK) ; } +//---------------------------------------------------------------------------- +bool +CurveBezier::GetLocalBBox( BBox3d& b3Loc) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // assegno il box in locale + b3Loc.Reset() ; + for ( int i = 0 ; i <= m_nDeg ; ++ i) + b3Loc.Add( m_aPtCtrl[i]) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // verifico validitą del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + // assegno il box nel riferimento + b3Ref.Reset() ; + for ( int i = 0 ; i <= m_nDeg ; ++ i) { + Point3d ptTemp = m_aPtCtrl[i] ; + ptTemp.ToGlob( frRef) ; + b3Ref.Add( ptTemp) ; + } + + return true ; +} + //---------------------------------------------------------------------------- bool CurveBezier::GetStartPoint( Point3d& ptStart) const diff --git a/CurveBezier.h b/CurveBezier.h index 94532c4..0a390f5 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -29,6 +29,8 @@ class CurveBezier : public ICurveBezier virtual bool IsValid( void) const { return ( m_nStatus == OK) ; } virtual bool Save( std::ostream& osOut) const ; virtual bool Load( Scanner& TheScanner) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool Translate( const Vector3d& vtMove) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngRad) diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 9c4a67c..d5ab2a2 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -247,6 +247,59 @@ CurveComposite::Load( Scanner& TheScanner) return true ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::GetLocalBBox( BBox3d& b3Loc) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // inizializzo il box + b3Loc.Reset() ; + // ciclo sulle curve componenti + const ICurve* pCrvSmpl ; + pCrvSmpl = GetFirstCurve() ; + while ( pCrvSmpl != nullptr) { + BBox3d b3Crv ; + // recupero il box della curva + pCrvSmpl->GetLocalBBox( b3Crv) ; + // aggiorno il box + b3Loc.Add( b3Crv) ; + // passo alla curva successiva + pCrvSmpl = GetNextCurve() ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // verifico validitą del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + // inizializzo il box + b3Ref.Reset() ; + // ciclo sulle curve componenti + const ICurve* pCrvSmpl ; + pCrvSmpl = GetFirstCurve() ; + while ( pCrvSmpl != nullptr) { + BBox3d b3Crv ; + // recupero il box della curva + pCrvSmpl->GetBBox( frRef, b3Crv) ; + // aggiorno il box + b3Ref.Add( b3Crv) ; + // passo alla curva successiva + pCrvSmpl = GetNextCurve() ; + } + return true ; + + return true ; +} + //---------------------------------------------------------------------------- bool CurveComposite::Validate( void) diff --git a/CurveComposite.h b/CurveComposite.h index c58167f..7b1b7a3 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -31,6 +31,8 @@ class CurveComposite : public ICurveComposite virtual bool IsValid( void) const { return ( m_nStatus == OK) ; } virtual bool Save( std::ostream& osOut) const ; virtual bool Load( Scanner& TheScanner) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool Translate( const Vector3d& vtMove) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngRad) diff --git a/CurveLine.cpp b/CurveLine.cpp index c7c75b3..895c9a5 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -103,6 +103,39 @@ CurveLine::Load( Scanner& TheScanner) return Validate() ; } +//---------------------------------------------------------------------------- +bool +CurveLine::GetLocalBBox( BBox3d& b3Loc) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // assegno il box in locale + b3Loc.Set( m_PtStart, m_PtEnd) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +CurveLine::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + // verifico lo stato + if ( m_nStatus != OK) + return false ; + // verifico validitą del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + // porto gli estremi nel riferimento passato + Point3d ptFrStart = m_PtStart ; + ptFrStart.ToGlob( frRef) ; + Point3d ptFrEnd = m_PtEnd ; + ptFrEnd.ToGlob( frRef) ; + // assegno il box nel riferimento + b3Ref.Set( ptFrStart, ptFrEnd) ; + + return true ; +} + //---------------------------------------------------------------------------- bool CurveLine::Validate( void) diff --git a/CurveLine.h b/CurveLine.h index 4dc061f..4f6b252 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -27,6 +27,8 @@ class CurveLine : public ICurveLine virtual bool IsValid( void) const { return ( m_nStatus == OK) ; } virtual bool Save( std::ostream& osOut) const ; virtual bool Load( Scanner& TheScanner) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool Translate( const Vector3d& vtMove) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngRad) diff --git a/DistPointCrvAux.h b/DistPointCrvAux.h index 485fcaf..33ec500 100644 --- a/DistPointCrvAux.h +++ b/DistPointCrvAux.h @@ -19,8 +19,6 @@ //---------------------------------------------------------------------------- -static const double LIN_TOL_APPROX = 1 ; // tolleranza di approssimazione lineare -static const double ANG_TOL_APPROX_DEG = 45 ; // tolleranza di deviazione angolare per approx static const double MIN_LEN_CONT_MDPC = 1 ; // minima lunghezza di tratto continuo di minima distanza //---------------------------------------------------------------------------- diff --git a/DistPointCrvBezier.cpp b/DistPointCrvBezier.cpp index ced1d94..3d3385f 100644 --- a/DistPointCrvBezier.cpp +++ b/DistPointCrvBezier.cpp @@ -1,5 +1,5 @@ //---------------------------------------------------------------------------- -// EgalTech 2013-2013 +// EgalTech 2013-2014 //---------------------------------------------------------------------------- // File : DistPointCrvBezier.cpp Data : 02.01.14 Versione : 1.5a1 // Contenuto : Implementazione della classe distanza punto da curva di Bezier. diff --git a/DistPointCrvComposite.cpp b/DistPointCrvComposite.cpp new file mode 100644 index 0000000..1885d5d --- /dev/null +++ b/DistPointCrvComposite.cpp @@ -0,0 +1,121 @@ +//---------------------------------------------------------------------------- +// EgalTech 2013-2014 +//---------------------------------------------------------------------------- +// File : DistPointCrvCompo.cpp Data : 15.01.14 Versione : 1.5a4 +// Contenuto : Implementazione della classe distanza punto da curva Composita. +// +// +// +// Modifiche : 15.01.14 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "DistPointCrvComposite.h" +#include "DistPointCrvAux.h" + + +//---------------------------------------------------------------------------- +DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveComposite& CrvCompo) +{ + // distanza non calcolata + m_dDist = - 1 ; + + if ( ! CrvCompo.IsValid()) + return ; +#if 0 + // creo una polilinea di approssimazione + PolyLine PL ; + if ( ! CrvBez.ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, PL)) + return ; + + // cerco la minima distanza per la polilinea + MDCVECTOR vApproxMin ; + MDCVECTOR::iterator Iter ; + if ( ! CalcMinDistPointPolyLine( ptP, PL, vApproxMin)) + return ; + + // verifico presenza singolaritą agli estremi degli intervalli trovati + double dSingP ; + if ( CrvBez.GetSingularParam( dSingP) == 0) + dSingP = - 1 ; + for ( Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { + // imposto flag per singolaritą agli estremi + (*Iter).bParMinSing = fabs( (*Iter).dParMin - dSingP) < EPS_SMALL ; + (*Iter).bParMaxSing = fabs( (*Iter).dParMax - dSingP) < EPS_SMALL ; + } + + // raffino i punti trovati + double dPolishedPar ; + Point3d ptPolishedQ ; + for ( Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) { + // eseguo raffinamento + if ( PolishMinDistPointCurve( ptP, CrvBez, *Iter, dPolishedPar, ptPolishedQ)) { + (*Iter).dDist = Dist( ptP, ptPolishedQ) ; + (*Iter).dPar = dPolishedPar ; + (*Iter).ptQ = ptPolishedQ ; + } + else + (*Iter).dDist = INFINITO ; + } + + // determino i minimi raffinati da tenere + double dMinDist ; + if ( FilterMinDistPointCurve( ptP, CrvBez, vApproxMin, dMinDist, m_Info)) + m_dDist = dMinDist ; +#endif +} + +//---------------------------------------------------------------------------- +bool +DistPointCrvComposite::GetSqDist( double& dSqDist) +{ + if ( m_dDist < 0) + return false ; + + dSqDist = m_dDist * m_dDist ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +DistPointCrvComposite::GetDist( double& dDist) +{ + if ( m_dDist < 0) + return false ; + + dDist = m_dDist ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +DistPointCrvComposite::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) +{ + if ( m_dDist < 0) + return false ; + + if ( nInd < 0 || nInd >= (int) m_Info.size()) + return false ; + + ptMinDist = m_Info[nInd].ptQ ; + nFlag = m_Info[nInd].nFlag ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +DistPointCrvComposite::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) +{ + if ( m_dDist < 0) + return false ; + + if ( nInd < 0 || nInd >= (int) m_Info.size()) + return false ; + + dParam = m_Info[nInd].dPar ; + nFlag = m_Info[nInd].nFlag ; + return true ; +} diff --git a/DistPointCrvComposite.h b/DistPointCrvComposite.h new file mode 100644 index 0000000..cedd565 --- /dev/null +++ b/DistPointCrvComposite.h @@ -0,0 +1,42 @@ +//---------------------------------------------------------------------------- +// EgalTech 2013-2014 +//---------------------------------------------------------------------------- +// File : DistPointCrvCompo.h Data : 15.01.14 Versione : 1.5a4 +// Contenuto : Dichiarazione della classe distanza punto da curva Composita. +// +// +// +// Modifiche : 15.01.14 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +#pragma once + +#include "/EgtDev/Include/EGkCurveComposite.h" +#include "/EgtDev/Include/EGkDistPointCurve.h" + + +//----------------------------------------------------------------------------- +class DistPointCrvComposite +{ + friend class DistPointCurve ; + + public : + DistPointCrvComposite( const Point3d& ptP, const ICurveComposite& CrvCompo) ; + + public : + bool GetSqDist( double& dSqDist) ; + bool GetDist( double& dDist) ; + int GetNbrMinDist( void) { return m_Info.size() ; } + bool GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) ; + bool GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) ; + + private : + DistPointCrvComposite( void) ; + + private : + double m_dDist ; + MDPCIVECTOR m_Info ; +} ; + diff --git a/DistPointCurve.cpp b/DistPointCurve.cpp index 0a070b1..40d1eec 100644 --- a/DistPointCurve.cpp +++ b/DistPointCurve.cpp @@ -16,6 +16,7 @@ #include "DistPointLine.h" #include "DistPointArc.h" #include "DistPointCrvBezier.h" +#include "DistPointCrvComposite.h" #include "/EgtDev/Include/EGkDistPointCurve.h" @@ -85,7 +86,10 @@ DistPointCurve::CrvBezierCalculate( const Point3d& ptP, const ICurve& Curve) void DistPointCurve::CrvCompositeCalculate( const Point3d& ptP, const ICurve& Curve) { - //DistPointCrvComposite dstPtLn( ptP, *GetCurveComposite( &Curve)) ; + DistPointCrvComposite dstPtCCompo( ptP, *GetCurveComposite( &Curve)) ; + + m_dDist = dstPtCCompo.m_dDist ; + m_Info = dstPtCCompo.m_Info ; } //---------------------------------------------------------------------------- diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 7f3a014..d7aefc2 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index 5496ba2..acb8aa8 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -118,9 +118,11 @@ copy $(TargetPath) \EgtProg\Dll + + @@ -151,6 +153,7 @@ copy $(TargetPath) \EgtProg\Dll + @@ -185,6 +188,7 @@ copy $(TargetPath) \EgtProg\Dll + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 13211b0..f26d167 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -117,6 +117,12 @@ File di origine\Distanze + + File di origine\Base + + + File di origine\Distanze + @@ -287,6 +293,12 @@ File di intestazione + + File di intestazione + + + File di intestazione + diff --git a/Frame3d.cpp b/Frame3d.cpp index eff4ab0..b5c2454 100644 --- a/Frame3d.cpp +++ b/Frame3d.cpp @@ -13,15 +13,8 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" -#include "\EgtDev\Include\EGkGeoConst.h" #include "\EgtDev\Include\EGkFrame3d.h" -//---------------------------------------------------------------------------- -Frame3d::Frame3d( void) - : m_nType( TOP), m_nZType( TOP), m_ptOrig( ORIG), m_vtVersX( X_AX), m_vtVersY( Y_AX), m_vtVersZ( Z_AX) -{ -} - //---------------------------------------------------------------------------- bool Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX, @@ -203,6 +196,21 @@ Frame3d::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, doub return true ; } +//---------------------------------------------------------------------------- +bool +Frame3d::Invert( void) +{ + Frame3d frInv = GLOB_FRM ; + + + if ( frInv.ToLoc( *this)) { + *this = frInv ; + return true ; + } + else + return false ; +} + //---------------------------------------------------------------------------- bool Frame3d::ToGlob( const Frame3d& frRef) diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index cdc6fd1..cfb93ca 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -1136,6 +1136,7 @@ GdbExecutor::OutGroupScl( int nId, int nFlag) GdbIterator Iter ; + m_OutScl.Remark( "Start Group ---") ; // emetto dati gruppo if ( m_pGDB->GetGroupGlobFrame( nId, frFrame)) { nParentId = m_pGDB->GetParentId( nId) ; @@ -1146,7 +1147,14 @@ GdbExecutor::OutGroupScl( int nId, int nFlag) } else return false ; + // emetto eventuale box + if ( ( nFlag & 8) != 0) { + BBox3d b3Loc ; + if ( m_pGDB->GetLocalBBox( nId, b3Loc)) + m_OutScl.PutBBox( b3Loc) ; + } // emetto entitą gruppo + m_OutScl.Remark( "Entities :") ; Iter.SetGDB( m_pGDB) ; bNext = Iter.GoToFirstInGroup( nId) ; while ( bNext) { @@ -1161,6 +1169,7 @@ GdbExecutor::OutGroupScl( int nId, int nFlag) } bNext = Iter.GoToNext() ; } + m_OutScl.Remark( "End Group ---") ; return true ; } diff --git a/GdbGroup.cpp b/GdbGroup.cpp index b5fd467..91ed495 100644 --- a/GdbGroup.cpp +++ b/GdbGroup.cpp @@ -149,6 +149,38 @@ GdbGroup::Load( const string& sType, Scanner& TheScanner, int& nParentId) return true ; } +//---------------------------------------------------------------------------- +bool +GdbGroup::GetLocalBBox( BBox3d& b3Loc) const +{ + b3Loc.Reset() ; + const GdbNode* pGdbNode = GetFirstNode() ; + while ( pGdbNode != nullptr) { + BBox3d b3B ; + // voglio il box come appare nel frame del gruppo, quindi passo frame identitą + if ( pGdbNode->GetBBox( GLOB_FRM, b3B)) + b3Loc.Add( b3B) ; + pGdbNode = pGdbNode->GetNext() ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +GdbGroup::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + Frame3d frCurr = m_gfrFrame.m_frF * frRef ; + b3Ref.Reset() ; + const GdbNode* pGdbNode = GetFirstNode() ; + while ( pGdbNode != nullptr) { + BBox3d b3B ; + if ( pGdbNode->GetBBox( frCurr, b3B)) + b3Ref.Add( b3B) ; + pGdbNode = pGdbNode->GetNext() ; + } + return true ; +} + //---------------------------------------------------------------------------- bool GdbGroup::Translate( const Vector3d& vtMove) diff --git a/GdbGroup.h b/GdbGroup.h index 719fe80..58ecdec 100644 --- a/GdbGroup.h +++ b/GdbGroup.h @@ -29,6 +29,8 @@ class GdbGroup : public GdbNode virtual GdbGroup* Clone( int nId, IdManager& IdMgr) const ; virtual bool Save( std::ostream& osOut) const ; virtual bool Load( const std::string& sType, Scanner& TheScanner, int& nParentId) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool Translate( const Vector3d& vtMove) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) diff --git a/GdbNode.h b/GdbNode.h index 07bf436..974d2d1 100644 --- a/GdbNode.h +++ b/GdbNode.h @@ -16,7 +16,7 @@ #include #include "/EgtDev/Include/EGkGdbConst.h" #include "/EgtDev/Include/EGnScan.h" -#include "/EgtDev/Include/EGkPoint3d.h" +#include "/EgtDev/Include/EGkBBox3d.h" class GdbGroup ; @@ -30,6 +30,8 @@ class GdbNode virtual GdbNode* Clone( int nId, IdManager& IdMgr) const = 0 ; virtual bool Save( std::ostream& osOut) const = 0 ; virtual bool Load( const std::string& sType, Scanner& TheScanner, int& nParentId) = 0 ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const = 0 ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const = 0 ; virtual bool Translate( const Vector3d& vtMove) = 0 ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) = 0 ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngRad) = 0 ; diff --git a/GdbObj.cpp b/GdbObj.cpp index 55e25bb..07ba07a 100644 --- a/GdbObj.cpp +++ b/GdbObj.cpp @@ -120,6 +120,26 @@ GdbObj::Load( const std::string& sType, Scanner& TheScanner, int& nParentId) return m_pGeoObj->Load( TheScanner) ; } +//---------------------------------------------------------------------------- +bool +GdbObj::GetLocalBBox( BBox3d& b3Loc) const +{ + if ( m_pGeoObj != nullptr) + return m_pGeoObj->GetLocalBBox( b3Loc) ; + else + return false ; +} + +//---------------------------------------------------------------------------- +bool +GdbObj::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + if ( m_pGeoObj != nullptr) + return m_pGeoObj->GetBBox( frRef, b3Ref) ; + else + return false ; +} + //---------------------------------------------------------------------------- bool GdbObj::Translate( const Vector3d& vtMove) diff --git a/GdbObj.h b/GdbObj.h index 30f269d..0d698aa 100644 --- a/GdbObj.h +++ b/GdbObj.h @@ -26,6 +26,8 @@ class GdbObj : public GdbNode virtual GdbObj* Clone( int nId, IdManager& IdMgr) const ; virtual bool Save( std::ostream& osOut) const ; virtual bool Load( const std::string& sType, Scanner& TheScanner, int& nParentId) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool Translate( const Vector3d& vtMove) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ; virtual bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) diff --git a/GeoFrame3d.cpp b/GeoFrame3d.cpp index 496388f..7300a4f 100644 --- a/GeoFrame3d.cpp +++ b/GeoFrame3d.cpp @@ -124,3 +124,24 @@ GeoFrame3d::Load( Scanner& TheScanner) // imposto il riferimento return m_frF.Set( ptOrig, vtDirX, vtDirY, vtDirZ) ; } + +//---------------------------------------------------------------------------- +bool +GeoFrame3d::GetLocalBBox( BBox3d& b3Loc) const +{ + // reset del box (un riferimento non occupa posizioni nello spazio) + b3Loc.Reset() ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +GeoFrame3d::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + // verifico validitą del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + // reset del box (un riferimento non occupa posizioni nello spazio) + b3Ref.Reset() ; + return true ; +} diff --git a/GeoFrame3d.h b/GeoFrame3d.h index 09acc73..ea8aa28 100644 --- a/GeoFrame3d.h +++ b/GeoFrame3d.h @@ -27,6 +27,8 @@ class GeoFrame3d : public IGeoFrame3d virtual bool IsValid( void) const { return ( m_frF.GetType() != Frame3d::ERR) ; } virtual bool Save( std::ostream& osOut) const ; virtual bool Load( Scanner& TheScanner) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool GetFrame( Frame3d& frF) const { frF = m_frF ; return true ;} virtual bool Translate( const Vector3d& vtMove) diff --git a/GeoPoint3d.cpp b/GeoPoint3d.cpp index 2ec4476..95c74f8 100644 --- a/GeoPoint3d.cpp +++ b/GeoPoint3d.cpp @@ -93,3 +93,28 @@ GeoPoint3d::Load( Scanner& TheScanner) return true ; } + +//---------------------------------------------------------------------------- +bool +GeoPoint3d::GetLocalBBox( BBox3d& b3Loc) const +{ + // assegno il box in locale + b3Loc.Set( m_ptP) ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +GeoPoint3d::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + // verifico validitą del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + // porto il punto nel riferimento passato + Point3d ptP = m_ptP ; + ptP.ToGlob( frRef) ; + // assegno il box nel riferimento + b3Ref.Set( ptP) ; + + return true ; +} diff --git a/GeoPoint3d.h b/GeoPoint3d.h index 1bc6bc8..852c4f9 100644 --- a/GeoPoint3d.h +++ b/GeoPoint3d.h @@ -27,6 +27,8 @@ class GeoPoint3d : public IGeoPoint3d virtual bool IsValid( void) const { return true ; } virtual bool Save( std::ostream& osOut) const ; virtual bool Load( Scanner& TheScanner) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool GetPoint( Point3d& ptP) const { ptP = m_ptP ; return true ;} virtual bool Translate( const Vector3d& vtMove) diff --git a/GeoVector3d.cpp b/GeoVector3d.cpp index 0b9ef74..715ca37 100644 --- a/GeoVector3d.cpp +++ b/GeoVector3d.cpp @@ -92,3 +92,24 @@ GeoVector3d::Load( Scanner& TheScanner) return true ; } + +//---------------------------------------------------------------------------- +bool +GeoVector3d::GetLocalBBox( BBox3d& b3Loc) const +{ + // reset del box (un versore non occupa posizioni nello spazio) + b3Loc.Reset() ; + return true ; +} + +//---------------------------------------------------------------------------- +bool +GeoVector3d::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const +{ + // verifico validitą del frame + if ( frRef.GetType() == Frame3d::ERR) + return false ; + // reset del box (un versore non occupa posizioni nello spazio) + b3Ref.Reset() ; + return true ; +} diff --git a/GeoVector3d.h b/GeoVector3d.h index 1cad663..c598aed 100644 --- a/GeoVector3d.h +++ b/GeoVector3d.h @@ -27,6 +27,8 @@ class GeoVector3d : public IGeoVector3d virtual bool IsValid( void) const { return true ; } virtual bool Save( std::ostream& osOut) const ; virtual bool Load( Scanner& TheScanner) ; + virtual bool GetLocalBBox( BBox3d& b3Loc) const ; + virtual bool GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const ; virtual bool GetVector( Vector3d& vtV) const { vtV = m_vtV ; return true ;} virtual bool Translate( const Vector3d& vtMove) diff --git a/GeomDB.cpp b/GeomDB.cpp index 100f54c..c97c4be 100644 --- a/GeomDB.cpp +++ b/GeomDB.cpp @@ -405,6 +405,36 @@ GeomDB::GetParentId( int nId) return pGdbNode->GetParentId() ; } +//---------------------------------------------------------------------------- +bool +GeomDB::GetLocalBBox( int nId, BBox3d& b3Loc) const +{ + const GdbNode* pGdbNode ; + + + // recupero l'oggetto + if ( ( pGdbNode = (const_cast (this))->GetGdbNode( nId)) == nullptr) + return false ; + + // eseguo l'operazione + return pGdbNode->GetLocalBBox( b3Loc) ; +} + +//---------------------------------------------------------------------------- +bool +GeomDB::GetBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref) const +{ + const GdbNode* pGdbNode ; + + + // recupero l'oggetto + if ( ( pGdbNode = (const_cast (this))->GetGdbNode( nId)) == nullptr) + return false ; + + // eseguo l'operazione + return pGdbNode->GetBBox( frRef, b3Ref) ; +} + //---------------------------------------------------------------------------- int GeomDB::Copy( int nIdSou, int nIdDest, int nParentIdDest) diff --git a/GeomDB.h b/GeomDB.h index 391e69a..6c73ec4 100644 --- a/GeomDB.h +++ b/GeomDB.h @@ -44,6 +44,8 @@ class GeomDB : public IGeomDB virtual int GetParentId( int nId) ; virtual bool GetGlobFrame( int nId, Frame3d& frGlob) { return GetGroupGlobFrame( GetParentId( nId), frGlob) ; } + virtual bool GetLocalBBox( int nId, BBox3d& b3Loc) const ; + virtual bool GetBBox( int nId, const Frame3d& frRef, BBox3d& b3Ref) const ; virtual int Copy( int nIdSou, int nIdDest, int nParentIdDest) ; virtual bool Erase( int nId) ; virtual bool Translate( int nId, const Vector3d& vtMove) ; diff --git a/OutScl.cpp b/OutScl.cpp index 13a664f..58390fe 100644 --- a/OutScl.cpp +++ b/OutScl.cpp @@ -335,159 +335,84 @@ OutScl::NormalOrNone( const CrvPointDiffGeom& oDiffG) //---------------------------------------------------------------------------- bool -OutScl::PutCurve( const IGeoObj* pCurve, int nFlag) +OutScl::PutCurve( const IGeoObj* pGeoObj, int nFlag) { - if ( pCurve == nullptr) + bool bFound ; + PolyLine PL ; + const ICurve* pCurve ; + + + // recupero e controllo la curva + if ( ( pCurve = GetCurve( pGeoObj)) == nullptr) return false ; - switch ( pCurve->GetType()) { - case CRV_LINE : - return PutCurveLine( *GetCurveLine( pCurve), nFlag) ; - case CRV_ARC : - return PutCurveArc( *GetCurveArc( pCurve), nFlag) ; - case CRV_BEZ : - return PutCurveBez( *GetCurveBezier( pCurve), nFlag) ; - case CRV_COMPO : - return PutCurveCompo( *GetCurveComposite( pCurve), nFlag) ; - } - - return false ; -} - -//---------------------------------------------------------------------------- -bool -OutScl::PutCurveLine( const ICurveLine& CrvLine, int nFlag) -{ - bool bFound ; - double dU ; - PolyLine PL ; - CrvPointDiffGeom oDiffG ; - - - // scrittura della linea - Remark( "CurveLine") ; - Line2P( CrvLine.GetStart(), CrvLine.GetEnd()) ; - - // se richieste tangenti e curvature - if ( ( nFlag & 1) != 0) { - // ciclo per disegnare le derivate - Remark( "LineTangents+Der2") ; - for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) { - // ricavo il punto, la tangente, la normale e la curvatura - CrvLine.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; - // curvatura o tangente o niente - ArcCurvOrTgOrNone( oDiffG) ; - } - } - - // se richieste normali - if ( ( nFlag & 2) != 0) { - // ciclo per disegnare le normali - Remark( "LineNormals") ; - for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) { - // ricavo il punto, la tangente, la normale e la curvatura - CrvLine.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; - // curvatura o tangente o niente - NormalOrNone( oDiffG) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -OutScl::PutCurveArc( const ICurveArc& CrvArc, int nFlag) -{ - bool bFound ; - double dU ; - Point3d ptIni ; - Point3d ptFin ; - PolyLine PL ; - CrvPointDiffGeom oDiffG ; - - - // ciclo sui segmenti - Remark( "CurveArc") ; - CrvArc.ApproxWithLines( 0.1, 5, PL) ; - for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) { - Line2P( ptIni, ptFin) ; - } - - // se richieste tangenti e curvature - if ( ( nFlag & 1) != 0) { - // ciclo per disegnare le derivate - Remark( "ArcTangents+Der2") ; - for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) { - // ricavo il punto, la tangente, la normale e la curvatura - CrvArc.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; - // curvatura o tangente o niente - ArcCurvOrTgOrNone( oDiffG) ; - } - } - - // se richieste normali - if ( ( nFlag & 2) != 0) { - // ciclo per disegnare le normali - Remark( "ArcNormals") ; - for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) { - // ricavo il punto, la tangente, la normale e la curvatura - CrvArc.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; - // curvatura o tangente o niente - NormalOrNone( oDiffG) ; - } - } - - return true ; -} - -//---------------------------------------------------------------------------- -bool -OutScl::PutCurveBez( const ICurveBezier& CrvBez, int nFlag) -{ - bool bFound ; - double dU ; - Point3d ptIni ; - Point3d ptFin ; - PolyLine PL ; - CrvPointDiffGeom oDiffG ; - - - // se richiesto anche il poligono di controllo - if ( ( nFlag & 4) != 0) - PutPolygBez( CrvBez) ; - // ciclo per disegnare i segmenti - Remark( "BezierCurve") ; - CrvBez.ApproxWithLines( 0.1, 5, PL) ; - for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) { + Remark( "Curve") ; + Point3d ptIni ; + Point3d ptFin ; + pCurve->ApproxWithLines( 0.1, 5, PL) ; + for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) Line2P( ptIni, ptFin) ; - } // se richieste tangenti e curvature if ( ( nFlag & 1) != 0) { // ciclo per disegnare le derivate e le curvature - Remark( "BezierTangents+Der2") ; + Remark( "Curve:Tangents+Der2") ; + double dU ; for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) { // ricavo il punto, la tangente, la normale e la curvatura - CrvBez.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; + CrvPointDiffGeom oDiffG ; + pCurve->GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; // curvatura o tangente o niente ArcCurvOrTgOrNone( oDiffG) ; + // se punto con possibili discontinuitą + if ( oDiffG.nFlag == CrvPointDiffGeom::TO_VERIFY) { + // ricavo il punto, la tangente, la normale e la curvatura dall'intorno superiore + CrvPointDiffGeom oDiffGs ; + pCurve->GetPointDiffGeom( dU, ICurve::FROM_PLUS, oDiffGs) ; + // se ci sono delle discontinuitą + if ( ThereIsDiscontinuity( oDiffG, oDiffGs)) + // emetto curvatura o tangente o niente + ArcCurvOrTgOrNone( oDiffGs) ; + } } } // se richieste normali if ( ( nFlag & 2) != 0) { // ciclo per disegnare le derivate e le curvature - Remark( "BezierNormals") ; + Remark( "Curve:Normals") ; + double dU ; for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) { // ricavo il punto, la tangente, la normale e la curvatura - CrvBez.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; + CrvPointDiffGeom oDiffG ; + pCurve->GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; // curvatura o tangente o niente NormalOrNone( oDiffG) ; + // se punto con possibili discontinuitą + if ( oDiffG.nFlag == CrvPointDiffGeom::TO_VERIFY) { + // ricavo il punto, la tangente, la normale e la curvatura dall'intorno superiore + CrvPointDiffGeom oDiffGs ; + pCurve->GetPointDiffGeom( dU, ICurve::FROM_PLUS, oDiffGs) ; + // se ci sono delle discontinuitą + if ( ThereIsDiscontinuity( oDiffG, oDiffGs)) + // normale o niente + NormalOrNone( oDiffG) ; + } } } + // se curva di Bezier e richiesto anche il poligono di controllo + if ( pCurve->GetType() == CRV_BEZ && ( nFlag & 4) != 0) + PutPolygBez( *(GetCurveBezier( pCurve))) ; + + // se richiesto il box + if ( ( nFlag & 8) != 0) { + BBox3d b3B ; + if ( pCurve->GetLocalBBox( b3B)) + PutBBox( b3B) ; + } + return true ; } @@ -516,42 +441,29 @@ OutScl::PutPolygBez( const ICurveBezier& CrvBez) //---------------------------------------------------------------------------- bool -OutScl::PutCurveCompo( const ICurveComposite& CrvCompo, int nFlag) +OutScl::PutBBox( const BBox3d& b3B) { - bool bFound ; - double dU ; - Point3d ptIni ; - Point3d ptFin ; - PolyLine PL ; - CrvPointDiffGeom oDiffG ; - CrvPointDiffGeom oDiffGs ; + Point3d ptMin ; + Point3d ptMax ; - // ciclo per disegnare i segmenti - Remark( "CurveComposite") ; - CrvCompo.ApproxWithLines( 0.1, 5, PL) ; - for ( bFound = PL.GetFirstLine( ptIni, ptFin) ; bFound ; bFound = PL.GetNextLine( ptIni, ptFin)) { - Line2P( ptIni, ptFin) ; - } - // se richieste derivate e curvature - if ( ( nFlag & 1) != 0) { - // ciclo per disegnare le derivate e le curvature - Remark( "CompositeTangents+Der2") ; - for ( bFound = PL.GetFirstU( dU) ; bFound ; bFound = PL.GetNextU( dU)) { - // ricavo il punto, la tangente, la normale e la curvatura - CrvCompo.GetPointDiffGeom( dU, ICurve::FROM_MINUS, oDiffG) ; - // emetto curvatura o tangente o niente - ArcCurvOrTgOrNone( oDiffG) ; - // se punto con possibili discontinuitą - if ( oDiffG.nFlag == CrvPointDiffGeom::TO_VERIFY) { - // ricavo il punto, la tangente, la normale e la curvatura dall'intorno superiore - CrvCompo.GetPointDiffGeom( dU, ICurve::FROM_PLUS, oDiffGs) ; - // se ci sono delle discontinuitą - if ( ThereIsDiscontinuity( oDiffG, oDiffGs)) - // emetto curvatura o tangente o niente - ArcCurvOrTgOrNone( oDiffGs) ; - } - } + if ( b3B.GetMinMax( ptMin, ptMax)) { + Remark( "BoundingBox") ; + // giro a Zmin + Line2P( Point3d( ptMin.x, ptMin.y, ptMin.z), Point3d( ptMax.x, ptMin.y, ptMin.z)) ; + Line2P( Point3d( ptMax.x, ptMin.y, ptMin.z), Point3d( ptMax.x, ptMax.y, ptMin.z)) ; + Line2P( Point3d( ptMax.x, ptMax.y, ptMin.z), Point3d( ptMin.x, ptMax.y, ptMin.z)) ; + Line2P( Point3d( ptMin.x, ptMax.y, ptMin.z), Point3d( ptMin.x, ptMin.y, ptMin.z)) ; + // giro a Zmax + Line2P( Point3d( ptMin.x, ptMin.y, ptMax.z), Point3d( ptMax.x, ptMin.y, ptMax.z)) ; + Line2P( Point3d( ptMax.x, ptMin.y, ptMax.z), Point3d( ptMax.x, ptMax.y, ptMax.z)) ; + Line2P( Point3d( ptMax.x, ptMax.y, ptMax.z), Point3d( ptMin.x, ptMax.y, ptMax.z)) ; + Line2P( Point3d( ptMin.x, ptMax.y, ptMax.z), Point3d( ptMin.x, ptMin.y, ptMax.z)) ; + // giunzione tra i due giri + Line2P( Point3d( ptMin.x, ptMin.y, ptMin.z), Point3d( ptMin.x, ptMin.y, ptMax.z)) ; + Line2P( Point3d( ptMax.x, ptMin.y, ptMin.z), Point3d( ptMax.x, ptMin.y, ptMax.z)) ; + Line2P( Point3d( ptMax.x, ptMax.y, ptMin.z), Point3d( ptMax.x, ptMax.y, ptMax.z)) ; + Line2P( Point3d( ptMin.x, ptMax.y, ptMin.z), Point3d( ptMin.x, ptMax.y, ptMax.z)) ; } return true ; diff --git a/OutScl.h b/OutScl.h index e380823..3de3e8a 100644 --- a/OutScl.h +++ b/OutScl.h @@ -35,11 +35,8 @@ class OutScl bool SetPartLay( std::string sPart, std::string sLay) ; bool SetPartLayRef( std::string sPart, std::string sLay, const Frame3d& frFrame) ; bool PutCurve( const IGeoObj* pCurve, int nFlag) ; - bool PutCurveLine( const ICurveLine& CrvLine, int nFlag) ; - bool PutCurveArc( const ICurveArc& CrvArc, int nFlag) ; - bool PutCurveBez( const ICurveBezier& CrvBez, int nFlag) ; bool PutPolygBez( const ICurveBezier& CrvBez) ; - bool PutCurveCompo( const ICurveComposite& CrvCompo, int nFlag) ; + bool PutBBox( const BBox3d& b3B) ; private : bool Start( void) ;