EgtGeomKernel 1.5l1 :

- aggiornamento a VS2013
- migliorato SimpleOffset e implementato anche per CurveComposite
- il lato di offset ora viene dal segno dello spostamento ( + a destra, - a sinistra)
- il vettore estrusione ora è la normale al piano di offset (se non c'è uso Z+)
- aggiunto a tutte le entità geometriche membro m_nTempProp intero temporaneo
- migliorata DistPointCrvBezier e DistPointArc
- corretta IntersLineArc con linee che non giacciono nel piano XY
- corretta ModifyStart di CurveArc
- a PolyArc aggiunto metodo ParamLinearTransform
- aggiunta gestione riferimento di griglia (CPlane).
This commit is contained in:
Dario Sassi
2014-12-17 15:03:29 +00:00
parent 9347e52d18
commit 3e8e7e2e2a
41 changed files with 1227 additions and 271 deletions
+11 -8
View File
@@ -1,13 +1,13 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : Angle.cpp Data : 14.07.14 Versione : 1.5g2
// File : Angle.cpp Data : 16.12.14 Versione : 1.5l1
// Contenuto : Implementazione funzioni per gestione angoli.
//
//
//
// Modifiche : 14.07.14 DS Creazione modulo.
//
// 16.12.14 DS Aumentata robustezza AngleInSpan.
//
//----------------------------------------------------------------------------
@@ -51,12 +51,15 @@ MediaAngle( double dAng1Deg, double dAng2Deg, double dCoeff)
bool
AngleInSpan( double dAngDeg, double dAngRefDeg, double dAngSpanDeg)
{
double dAngDiffDeg = DiffAngle( dAngDeg, dAngRefDeg) ;
// differenza dalla posizione a metà dell'intervallo angolare
double dAngDiffDeg = DiffAngle( dAngDeg, dAngRefDeg + 0.5 * dAngSpanDeg) ;
// se intervallo nullo, anche differenza deve essere nulla
if ( fabs( dAngSpanDeg) < EPS_ANG_ZERO)
return ( fabs( dAngDiffDeg) < EPS_ANG_SMALL) ;
else if ( dAngSpanDeg > 0)
return ( dAngDiffDeg > - EPS_ANG_SMALL && dAngDiffDeg < dAngSpanDeg + EPS_ANG_SMALL) ;
else
return ( dAngDiffDeg < EPS_ANG_SMALL && dAngDiffDeg > dAngSpanDeg - EPS_ANG_SMALL) ;
// deve essere non oltre metà intervallo dal suo centro
else {
double dHalfAngSpanDeg = fabs( 0.5 * dAngSpanDeg) ;
return ( dAngDiffDeg > - dHalfAngSpanDeg - EPS_ANG_SMALL &&
dAngDiffDeg < dHalfAngSpanDeg + EPS_ANG_SMALL) ;
}
}
+4 -4
View File
@@ -210,8 +210,8 @@ GetArcPntDirTgArc( const Point3d& ptP, double dDirStartDeg, const ICurveArc& crv
Point3d ptP1 = ptP + vtOrtho * crvArc.GetRadius() ;
PtrOwner<ICurve> pCrv1( GetArc2PD( ptP1, crvArc.GetCenter(), dDirStartDeg)) ;
bool bOk1 = ( ! IsNull( pCrv1)) ;
// compenso lo spostamento
bOk1 = bOk1 && pCrv1->Offset( crvArc.GetRadius(), ICurve::OFF_RIGHT) ;
// compenso lo spostamento ( più -> offset a destra)
bOk1 = bOk1 && pCrv1->SimpleOffset( crvArc.GetRadius()) ;
// verifico se il punto di tangenza sta sull'arco
Point3d ptEnd1 ;
bOk1 = bOk1 && pCrv1->GetEndPoint( ptEnd1) && crvArc.IsPointOn( ptEnd1) ;
@@ -220,8 +220,8 @@ GetArcPntDirTgArc( const Point3d& ptP, double dDirStartDeg, const ICurveArc& crv
Point3d ptP2 = ptP - vtOrtho * crvArc.GetRadius() ;
PtrOwner<ICurve> pCrv2( GetArc2PD( ptP2, crvArc.GetCenter(), dDirStartDeg)) ;
bool bOk2 = ( ! IsNull( pCrv2)) ;
// compenso lo spostamento
bOk2 = bOk2 && pCrv2->Offset( crvArc.GetRadius(), ICurve::OFF_LEFT) ;
// compenso lo spostamento ( meno -> offset a sinistra)
bOk2 = bOk2 && pCrv2->SimpleOffset( - crvArc.GetRadius()) ;
// verifico se il punto di tangenza sta sull'arco
Point3d ptEnd2 ;
bOk2 = bOk2 && pCrv2->GetEndPoint( ptEnd2) && crvArc.IsPointOn( ptEnd2) ;
+3 -3
View File
@@ -78,11 +78,11 @@ CalcLinePointTgCircle( const Point3d& ptP, const Point3d& ptCen, double dRad, BI
bool
FindPointOnArc( const CurveArc& crvArc, const Vector3d& vtDirP, const Point3d& ptNear, Point3d& ptP)
{
// calcolo i due punti e verifico se stanno sull'arco
// calcolo i due punti e verifico se stanno sull'arco (anche come angolo)
Point3d ptPa = crvArc.GetCenter() + vtDirP * crvArc.GetRadius() ;
bool bPaOn = crvArc.IsPointOn( ptPa) ;
bool bPaOn = crvArc.IsPointOn( ptPa) && crvArc.IsPointInSector( ptPa) ;
Point3d ptPb = crvArc.GetCenter() - vtDirP * crvArc.GetRadius() ;
bool bPbOn = crvArc.IsPointOn( ptPb) ;
bool bPbOn = crvArc.IsPointOn( ptPb) && crvArc.IsPointInSector( ptPb) ;
// se nessuno valido
if ( ! bPaOn && ! bPbOn)
return false ;
+44 -60
View File
@@ -56,7 +56,7 @@ class ArcApproxer
//----------------------------------------------------------------------------
CurveArc::CurveArc( void)
: m_nStatus( TO_VERIFY), m_PtCen(), m_VtN(), m_VtS(), m_dRad(),
m_dAngCenDeg(), m_dDeltaN(), m_VtExtr(), m_dThick()
m_dAngCenDeg(), m_dDeltaN(), m_VtExtr(), m_dThick(), m_nTempProp()
{
}
@@ -523,6 +523,7 @@ CurveArc::CopyFrom( const CurveArc& caSrc)
return true ;
m_VtExtr = caSrc.m_VtExtr ;
m_dThick = caSrc.m_dThick ;
m_nTempProp = caSrc.m_nTempProp ;
return Set( caSrc.m_PtCen, caSrc.m_VtN, caSrc.m_dRad,
caSrc.m_VtS, caSrc.m_dAngCenDeg, caSrc.m_dDeltaN) ;
}
@@ -690,7 +691,7 @@ CurveArc::Validate( void)
// eseguo il controllo
m_nStatus = ( ( m_VtN.IsNormalized() && m_VtS.IsNormalized() &&
AreOrthoApprox( m_VtN, m_VtS) &&
m_dRad > EPS_ZERO && fabs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
m_dRad > EPS_SMALL && fabs( m_dAngCenDeg) > EPS_ANG_ZERO) ? OK : ERR) ;
}
return ( m_nStatus == OK) ;
@@ -938,6 +939,7 @@ CurveArc::GetParamAtLength( double dLen, double& dU) const
bool
CurveArc::IsPointOn( const Point3d& ptP, double dTol) const
{
// verifico la distanza
double dSqDist ;
dTol = max( dTol, EPS_ZERO) ;
return ( DistPointArc( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ;
@@ -977,8 +979,13 @@ CurveArc::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const
if ( m_nStatus != OK)
return false ;
// se l'arco non ha direzione normale coincidente con Z, approssimo con rette
if ( ! m_VtN.IsZplus() && ! m_VtN.IsZminus()) {
// determinazione versore normale al piano di riferimento
Vector3d vtNref = Z_AX ;
if ( ! m_VtExtr.IsSmall())
vtNref = m_VtExtr ;
// se l'arco non ha direzione normale coincidente con il versore del piano, approssimo con rette
if ( ! AreSameOrOppositeVectorApprox( m_VtN, vtNref)) {
ArcApproxer aAppr( dLinTol, dAngTolDeg, true, *this) ;
double dU ;
Point3d ptPos ;
@@ -994,7 +1001,8 @@ CurveArc::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const
int nArcs = int( ceil( fabs( m_dAngCenDeg) / MAX_ANG_ARC_BULGE)) ;
nArcs = max( nArcs, 1) ;
double dBulge = tan( m_dAngCenDeg / ( 4 * nArcs) * DEGTORAD) ;
if ( m_VtN.IsZminus())
// se direzioni opposte, senso di rotazione contrario
if ( m_VtN * vtNref < 0)
dBulge = - dBulge ;
// inserisco i punti di inizio di ogni arco
for ( int i = 0 ; i < nArcs ; ++ i) {
@@ -1074,24 +1082,25 @@ CurveArc::Invert( void)
//----------------------------------------------------------------------------
bool
CurveArc::Offset( double dDist, int nSide, int nType)
CurveArc::SimpleOffset( double dDist, int nType)
{
// la curva deve essere validata
if ( m_nStatus != OK)
return false ;
// la normale deve coincidere con l'asse Z (l'offset è sempre nel piano XY)
if ( ! ( m_VtN.IsZplus() || m_VtN.IsZminus()))
// determinazione versore normale al piano di offset
Vector3d vtNref = Z_AX ;
if ( ! m_VtExtr.IsSmall())
vtNref = m_VtExtr ;
// la normale deve coincidere con il versore del piano di offset
if ( ! AreSameOrOppositeVectorApprox( m_VtN, vtNref))
return false ;
// calcolo il nuovo raggio e lo valido
bool bCCW = ( ( m_dAngCenDeg > 0 && m_VtN.z > 0) ||
( m_dAngCenDeg < 0 && m_VtN.z < 0)) ;
double dNewRad ;
if ( ( bCCW && nSide != OFF_LEFT) || ( ! bCCW && nSide == OFF_LEFT))
dNewRad = m_dRad + dDist ;
else
dNewRad = m_dRad - dDist ;
bool bCCW = ( ( m_dAngCenDeg > 0 && m_VtN * vtNref > 0) ||
( m_dAngCenDeg < 0 && m_VtN * vtNref < 0)) ;
double dNewRad = m_dRad + ( bCCW ? + dDist : - dDist) ;
if ( dNewRad < EPS_SMALL)
return false ;
@@ -1112,51 +1121,14 @@ CurveArc::ModifyStart( const Point3d& ptNewStart)
if ( m_nStatus != OK)
return false ;
// calcolo il riferimento intrinseco dell'arco (DirNorm->Z e DirStart->X)
Frame3d frIntr ;
if ( ! frIntr.Set( m_PtCen, m_VtN, m_VtS))
return false ;
// determino vecchio e nuovo punto iniziale nel riferimento intrinsseco
Point3d ptOldStart ;
GetStartPoint( ptOldStart) ;
Point3d ptOldStartIntr = ptOldStart ;
ptOldStartIntr.ToLoc( frIntr) ;
Point3d ptStartIntr = ptNewStart ;
ptStartIntr.ToLoc( frIntr) ;
// se coincidono nel piano XY, è cambiato solo il deltaN e il centro
if ( SqDistXY( ptOldStartIntr, ptStartIntr) < EPS_SMALL * EPS_SMALL) {
m_dDeltaN -= ptStartIntr.z - ptOldStartIntr.z ;
m_PtCen += ( ptNewStart - ptOldStart) ;
}
// altrimenti, calcolo un arco ausiliario nel riferimento intrinseco con i nuovi dati
else {
Point3d ptEndIntr ;
GetEndPoint( ptEndIntr) ;
ptEndIntr.ToLoc( frIntr) ;
double dOldAngCenDeg = m_dAngCenDeg ;
CurveArc arcAux ;
if ( ! arcAux.Set2PD( ptStartIntr, ptEndIntr, ( m_dAngCenDeg > 0 ? ANG_RIGHT : - ANG_RIGHT)))
return false ;
// aggiorno i dati dell'arco con quelli appena calcolati
m_PtCen = arcAux.m_PtCen ;
m_PtCen.ToGlob( frIntr) ;
m_VtN = arcAux.m_VtN ;
m_VtN.ToGlob( frIntr) ;
m_VtS = arcAux.m_VtS ;
m_VtS.ToGlob( frIntr) ;
m_dRad = arcAux.m_dRad ;
// se elica, devo avere un numero di giri vicino ai precedenti
if ( fabs( dOldAngCenDeg) >= ANG_FULL - EPS_ANG_ZERO)
m_dAngCenDeg = AngleNearAngle( arcAux.m_dAngCenDeg, dOldAngCenDeg) ;
else
m_dAngCenDeg = arcAux.m_dAngCenDeg ;
m_dDeltaN = arcAux.m_dDeltaN ;
}
// inverto l'arco
Invert() ;
// modifico la fine dell'arco invertito
bool bOk = ModifyEnd( ptNewStart) ;
// re-inverto
Invert() ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
return bOk ;
}
//----------------------------------------------------------------------------
@@ -1178,7 +1150,7 @@ CurveArc::ModifyEnd( const Point3d& ptNewEnd)
Point3d ptEndIntr = ptNewEnd ;
ptEndIntr.ToLoc( frIntr) ;
// se coincidono nel piano XY, è cambiato solo il deltaN
if ( SqDistXY( ptOldEndIntr, ptEndIntr) < EPS_SMALL * EPS_SMALL) {
if ( SqDistXY( ptOldEndIntr, ptEndIntr) < EPS_ZERO * EPS_ZERO) {
m_dDeltaN += ptEndIntr.z - ptOldEndIntr.z ;
}
// altrimenti, calcolo un arco ausiliario nel riferimento intrinseco con i nuovi dati
@@ -1591,6 +1563,18 @@ CurveArc::InvertN( void)
return true ;
}
//----------------------------------------------------------------------------
bool
CurveArc::IsPointInSector( const Point3d& ptP) const
{
// verifico sia compreso nell'angolo al centro
bool bDet ;
double dAngDeg ;
if ( ! m_VtS.GetRotation( ( ptP - m_PtCen), m_VtN, dAngDeg, bDet) || ! bDet)
return false ;
return AngleInSpan( dAngDeg, 0, m_dAngCenDeg) ;
}
//----------------------------------------------------------------------------
bool
CurveArc::CalcPointAngle( const Point3d& ptP, double& dAngDeg) const
+10 -1
View File
@@ -49,6 +49,10 @@ class CurveArc : public ICurveArc, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // ICurve
virtual bool IsSimple( void) const
@@ -93,7 +97,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
virtual bool Invert( void) ;
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET) ;
virtual bool SimpleOffset( double dDist, int nType = OFF_FILLET) ;
virtual bool ModifyStart( const Point3d& ptNewStart) ;
virtual bool ModifyEnd( const Point3d& ptNewEnd) ;
virtual bool SetExtrusion( const Vector3d& vtExtr)
@@ -129,6 +133,9 @@ class CurveArc : public ICurveArc, public IGeoObjRW
{ return ( IsFlat() && IsClosed()) ; }
virtual bool IsInPlaneXY( void) const
{ return ( m_VtN.IsZplus()) ; }
virtual bool IsInPlanePerpExtr( void) const
{ return ( ( m_VtExtr.IsSmall() && m_VtN.IsZplus()) ||
AreSameVectorApprox( m_VtExtr, m_VtN)) ; }
virtual const Point3d& GetCenter( void) const
{ return m_PtCen ; }
virtual const Vector3d& GetNormVersor( void) const
@@ -141,6 +148,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
{ return m_dAngCenDeg ; }
virtual double GetDeltaN( void) const
{ return m_dDeltaN ; }
virtual bool IsPointInSector( const Point3d& ptP) const ;
virtual bool CalcPointAngle( const Point3d& ptP, double& dAngDeg) const ;
virtual bool CalcPointParamPosiz( const Point3d& ptP, double& dU, int& nPos) const ;
virtual bool InvertN( void) ;
@@ -183,6 +191,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
double m_dDeltaN ; // variazione di quota lungo VtN della fine rispetto all'inizio
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
double m_dThick ; // spessore
int m_nTempProp ; // proprietà temporanea
} ;
//-----------------------------------------------------------------------------
+114 -12
View File
@@ -82,6 +82,55 @@ IsEndParam( const ICurve& crvC, double dPar)
return true ;
}
//----------------------------------------------------------------------------
bool
MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve)
{
// verifico che il parametro sia accettabile
if ( ! Curve.IsValidParam( dU, nSide))
return false ;
// determino un incremento piccolo ma valido del parametro U
double dDeltaU = 1000 * EPS_PARAM ;
Point3d ptPos ;
Vector3d vtDer1 ;
if ( Curve.GetPointD1D2( dU, nSide, ptPos, &vtDer1)) {
double dDer1 = vtDer1.LenXY() ;
if ( dDer1 > EPS_ZERO)
dDeltaU = 10 * EPS_SMALL / dDer1 ;
}
// cerco di spostarmi per evitare eventuali problemi di tangenza
if ( nSide == ICurve::FROM_MINUS) {
double dUm = dU - dDeltaU ;
if ( ! Curve.IsValidParam( dUm, nSide)) {
if ( Curve.IsClosed()) {
double dStart, dEnd ;
Curve.GetDomain( dStart, dEnd) ;
dUm = ( dEnd - dStart) - dDeltaU ;
}
else
dUm = dU ;
}
dU = dUm ;
return true ;
}
else { // nSide == ICurve::FROM_PLUS
double dUm = dU + dDeltaU ;
if ( ! Curve.IsValidParam( dUm, nSide)) {
if ( Curve.IsClosed()) {
double dStart, dEnd ;
Curve.GetDomain( dStart, dEnd) ;
dUm = dStart + dDeltaU ;
}
else
dUm = dU ;
}
dU = dUm ;
return true ;
}
}
//----------------------------------------------------------------------------
bool
GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang)
@@ -224,6 +273,34 @@ CurveDump( const ICurve& crvC, string& sOut, const char* szNewLine)
return true ;
}
//----------------------------------------------------------------------------
bool
CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv)
{
// verifico puntatori
if ( pSouCrv == nullptr || pDestCrv == nullptr)
return false ;
// eseguo copia
Vector3d vtExtr ;
pSouCrv->GetExtrusion( vtExtr) ;
pDestCrv->SetExtrusion( vtExtr) ;
return true ;
}
//----------------------------------------------------------------------------
bool
CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv)
{
// verifico puntatori
if ( pSouCrv == nullptr || pDestCrv == nullptr)
return false ;
// eseguo copia
double dThick = 0 ;
pSouCrv->GetThickness( dThick) ;
pDestCrv->SetThickness( dThick) ;
return true ;
}
//----------------------------------------------------------------------------
ICurve*
ArcToBezierCurve( const ICurve* pCrv)
@@ -242,7 +319,6 @@ ArcToBezierCurve( const ICurve* pCrv)
// restituisco la curva
return Release( pCrvBez) ;
}
// altrimenti curva composita di Bezier
else {
// creo la curva composita
@@ -265,6 +341,9 @@ ArcToBezierCurve( const ICurve* pCrv)
if ( ! pCrvCompo->AddCurve( Release( pCrvBez)))
return false ;
}
// copio estrusione e spessore
CopyExtrusion( pArc, Get( pCrvCompo)) ;
CopyThickness( pArc, Get( pCrvCompo)) ;
// restituisco la curva
return Release( pCrvCompo) ;
}
@@ -277,29 +356,52 @@ CurveToNoArcsCurve( const ICurve* pCrv)
// verifico validità curva
if ( pCrv == nullptr)
return nullptr ;
// preparo puntatore a nuova curva
PtrOwner<ICurve> pCrvNew ;
// se arco, devo trasformarlo in curva di Bezier (semplice o composta)
if ( pCrv->GetType() == CRV_ARC) {
pCrvNew.Set( ArcToBezierCurve( pCrv)) ;
if ( IsNull( pCrvNew))
return nullptr ;
return ArcToBezierCurve( pCrv) ;
}
// se curva composita, devo trasformarla in composita senza archi
else if ( pCrv->GetType() == CRV_COMPO) {
PtrOwner<ICurveComposite> pCopyCC( GetCurveComposite( pCrv->Clone())) ;
PtrOwner<CurveComposite> pCopyCC( GetBasicCurveComposite( pCrv->Clone())) ;
if ( IsNull( pCopyCC) || ! pCopyCC->ArcsToBezierCurves())
return nullptr ;
pCrvNew.Set( Release( pCopyCC)) ;
return Release( pCopyCC) ;
}
// altrimenti devo solo copiarla
else {
pCrvNew.Set( pCrv->Clone()) ;
if ( IsNull( pCrvNew))
return nullptr ;
return pCrv->Clone() ;
}
}
return Release( pCrvNew) ;
//----------------------------------------------------------------------------
ICurve*
CurveToArcsPerpExtrCurve( const ICurve* pCrv, double dLinTol, double dAngTolDeg)
{
// verifico validità curva
if ( pCrv == nullptr)
return nullptr ;
// se arco in piano non perpendicolare ad estrusione o curva di Bezier trasformo
if ( ( pCrv->GetType() == CRV_ARC && ! GetBasicCurveArc(pCrv)->IsInPlanePerpExtr()) ||
pCrv->GetType() == CRV_BEZ) {
// creo un poliarco
PolyArc PA ;
if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PA))
return nullptr ;
// creo una nuova curva composita a partire dal poliarco
PtrOwner<CurveComposite> pCopyCC( CreateBasicCurveComposite()) ;
if ( IsNull( pCopyCC))
return nullptr ;
if ( ! pCopyCC->FromPolyArc( PA))
return nullptr ;
// copio estrusione e spessore
CopyExtrusion( pCrv, Get( pCopyCC)) ;
CopyThickness( pCrv, Get( pCopyCC)) ;
return Release( pCopyCC) ;
}
// altrimenti devo solo copiarla
else {
return pCrv->Clone() ;
}
}
//----------------------------------------------------------------------------
+3
View File
@@ -20,7 +20,10 @@ bool IsClosed( const ICurve& crvC) ;
bool IsValidParam( const ICurve& crvC, double dPar, ICurve::Side nSide) ;
bool IsStartParam( const ICurve& crvC, double dPar) ;
bool IsEndParam( const ICurve& crvC, double dPar) ;
bool MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve) ;
bool GetTang( const ICurve& crvC, double dU, ICurve::Side nS, Vector3d& vtTang) ;
bool GetPointTang( const ICurve& crvC, double dU, ICurve::Side nS, Point3d& ptPos, Vector3d& vtTang) ;
bool GetPointDiffGeom( const ICurve& crvC, double dU, ICurve::Side nS, CrvPointDiffGeom& oDiffG) ;
bool CurveDump( const ICurve& crvC, std::string& sOut, const char* szNewLine) ;
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
+42 -2
View File
@@ -40,7 +40,7 @@ GEOOBJ_REGISTER( CRV_BEZ, NGE_C_BEZ, CurveBezier) ;
//----------------------------------------------------------------------------
CurveBezier::CurveBezier( void)
: m_nStatus( TO_VERIFY), m_nDeg(), m_bRat( false), m_dParSing( -2),
m_nDimArr(), m_aPtCtrl( nullptr), m_aWeCtrl( nullptr), m_VtExtr(), m_dThick()
m_nDimArr(), m_aPtCtrl( nullptr), m_aWeCtrl( nullptr), m_VtExtr(), m_dThick(), m_nTempProp()
{
}
@@ -235,6 +235,10 @@ CurveBezier::FromArc( const ICurveArc& crArc)
SetControlPoint( 3, ptEnd, 1) ;
}
// copio estrusione e spessore
crArc.GetExtrusion( m_VtExtr) ;
crArc.GetThickness( m_dThick) ;
return true ;
}
@@ -322,6 +326,7 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
return false ;
m_VtExtr = cbSrc.m_VtExtr ;
m_dThick = cbSrc.m_dThick ;
m_nTempProp = cbSrc.m_nTempProp ;
for ( int i = 0 ; i <= m_nDeg ; ++ i) {
m_aPtCtrl[i] = cbSrc.m_aPtCtrl[i] ;
if ( cbSrc.m_bRat)
@@ -1375,6 +1380,34 @@ CurveBezier::FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart,
bool
CurveBezier::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const
{
// se estrusione definita e diversa da Z+
if ( ! m_VtExtr.IsSmall() && ! m_VtExtr.IsZplus()) {
// devo portarmi in un piano perpendicolare all'estrusione per costruirvi gli archi
Frame3d frExtr ;
if ( ! frExtr.Set( ORIG, m_VtExtr))
return false ;
// copio la curva e la porto nel riferimento di estrusione
CurveBezier crvAux ;
if ( ! crvAux.CopyFrom( *this))
return false ;
crvAux.ToLoc( frExtr) ;
// approssimo
bool bOk = crvAux.ApproxWithArcsXY( dLinTol, dAngTolDeg, PA) ;
// porto il risultato nel riferimento originale
PA.ToGlob( frExtr) ;
return bOk ;
}
// l'estrusione è secondo Z+, pertanto sono già nel piano XY
else
return ApproxWithArcsXY( dLinTol, dAngTolDeg, PA) ;
}
//----------------------------------------------------------------------------
bool
CurveBezier::ApproxWithArcsXY( double dLinTol, double dAngTolDeg, PolyArc& PA) const
{
// si creano gli archi nel piano XY
// pulisco il poliarco
PA.Clear() ;
@@ -1439,12 +1472,19 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
// se in tolleranza
if ( dMaxDist <= dLinTol) {
// lo inserisco nel poliarco ed esco
// creo un nuovo poliarco
PolyArc PA2 ;
if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PA2))
return false ;
// aggiusto la parametrizzazione
double dUStart, dUEnd ;
PL.GetFirstU( dUStart) ;
PL.GetLastU( dUEnd) ;
PA2.ParamLinearTransform( dUStart, dUEnd) ;
// accodo all'esistente
if ( ! PA.Join( PA2))
return false ;
// esco
return true ;
}
}
+9 -3
View File
@@ -51,6 +51,10 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // ICurve
virtual bool IsSimple( void) const { return true ; }
@@ -94,8 +98,8 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
virtual bool Invert( void) ;
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET)
{ return false ; }
virtual bool SimpleOffset( double dDist, int nType = OFF_FILLET)
{ return false ; } // l'offset di crvBezier non è crvBezier tranne in casi molto particolari
virtual bool ModifyStart( const Point3d& ptNewStart) ;
virtual bool ModifyEnd( const Point3d& ptNewEnd) ;
virtual bool SetExtrusion( const Vector3d& vtExtr)
@@ -154,7 +158,8 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
double& dUIni, double& dUFin) const ;
bool FlatOrSplit( int nLev, const CurveBezier& crvBez, double dParStart, double dParEnd,
double dLinTol, double dAngTolDeg, PolyLine& PL) const ;
bool BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
bool ApproxWithArcsXY(double dLinTol, double dAngTolDeg, PolyArc& PA) const;
bool BiArcOrSplit(int nLev, PolyLine& PL, double dLinTol, double dAngTolDeg, PolyArc& PA) const;
bool ToPowerBase( PolynomialPoint3d& pol3P) const ;
bool ToPowerBase( PolynomialPoint3d& pol3Num, Polynomial& polDen) const ;
@@ -176,6 +181,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
double m_aStWeCtrl[ST_PTC] ; // array predefinito di 4 pesi di controllo
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
double m_dThick ; // spessore
int m_nTempProp ; // proprietà temporanea
} ;
//-----------------------------------------------------------------------------
+198 -46
View File
@@ -33,7 +33,7 @@ GEOOBJ_REGISTER( CRV_COMPO, NGE_C_CMP, CurveComposite) ;
//----------------------------------------------------------------------------
CurveComposite::CurveComposite( void)
: m_nStatus( TO_VERIFY), m_nCounter(), m_bClosed( false), m_VtExtr(), m_dThick()
: m_nStatus( TO_VERIFY), m_nCounter(), m_bClosed( false), m_VtExtr(), m_dThick(), m_nTempProp()
{
}
@@ -48,7 +48,7 @@ bool
CurveComposite::Clear( void)
{
// ciclo di pulizia
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
delete (*Iter) ;
@@ -59,6 +59,7 @@ CurveComposite::Clear( void)
m_bClosed = false ;
m_VtExtr = V_NULL ;
m_dThick = 0 ;
m_nTempProp = 0 ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -122,19 +123,12 @@ CurveComposite::AddCurve( ICurve* pCrv, bool bEndOrStart, double dLinTol)
if ( ! AddSimpleCurve( pCrv, bEndOrStart, dLinTol))
return false ;
}
// altrimenti curva composta, devo aggiungere le singole curve semplici
// altrimenti curva composita, devo aggiungere le singole curve semplici
else {
// puntatore alla curva composita originaria
// riloco le curve dalla composita sorgente alla corrente
CurveComposite* pCrvCompo = dynamic_cast<CurveComposite*>( pCrv) ;
if ( pCrvCompo == nullptr)
if ( ! AddCurveByRelocate( *pCrvCompo, bEndOrStart, dLinTol))
return false ;
// recupero le curve componenti e le inserisco nella lista
ICurve* pSmplCrv ;
while ( ( pSmplCrv = pCrvCompo->RemoveFirstOrLastCurve( ! bEndOrStart)) != nullptr) {
// inserisco la curva
if ( ! AddSimpleCurve( pSmplCrv, bEndOrStart, dLinTol))
return false ;
}
// cancello la curva composita originaria
delete pCrvCompo ;
}
@@ -145,6 +139,28 @@ CurveComposite::AddCurve( ICurve* pCrv, bool bEndOrStart, double dLinTol)
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart, double dLinTol)
{
// verifica curva
if ( &ccSrc == nullptr)
return false ;
// recupero le curve componenti e le inserisco nella lista
ICurve* pSmplCrv ;
while ( ( pSmplCrv = ccSrc.RemoveFirstOrLastCurve( ! bEndOrStart)) != nullptr) {
// inserisco la curva
if ( ! AddSimpleCurve( pSmplCrv, bEndOrStart, dLinTol))
return false ;
}
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinTol)
@@ -162,8 +178,9 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
if ( ! pCrv->IsSimple())
return false ;
// annullo l'estrusione
// annullo l'estrusione e lo spessore
pCrv->SetExtrusion( V_NULL) ;
pCrv->SetThickness( 0) ;
// recupero i punti iniziali e finali della curva
Point3d ptStart, ptEnd ;
@@ -489,6 +506,8 @@ CurveComposite::CopyFrom( const IGeoObj* pGObjSrc)
const ICurve* pCrv = GetCurve( pGObjSrc) ;
if ( pCrv != nullptr) {
Clear() ;
pCrv->GetExtrusion( m_VtExtr) ;
pCrv->GetThickness( m_dThick) ;
return AddCurve( *pCrv) ;
}
// altrimenti errroe
@@ -504,7 +523,8 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
Clear() ;
m_VtExtr = ccSrc.m_VtExtr ;
m_dThick = ccSrc.m_dThick ;
PCRVSMPL_DEQUE::const_iterator Iter ;
m_nTempProp = ccSrc.m_nTempProp ;
PCSD_CONST_ITER Iter ;
for ( Iter = ccSrc.m_CrvSmplS.begin() ; Iter != ccSrc.m_CrvSmplS.end() ; ++Iter) {
if ( ! AddCurve( **Iter))
return false ;
@@ -512,6 +532,25 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::RelocateFrom( CurveComposite& ccSrc)
{
if ( &ccSrc == this)
return true ;
Clear() ;
m_VtExtr = ccSrc.m_VtExtr ;
m_dThick = ccSrc.m_dThick ;
m_nTempProp = ccSrc.m_nTempProp ;
for ( ICurve* pCrv = ccSrc.RemoveFirstOrLastCurve( false) ;
pCrv != nullptr ;
pCrv = ccSrc.RemoveFirstOrLastCurve( false)) {
if ( ! AddSimpleCurve( pCrv))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
GeoObjType
CurveComposite::GetType( void) const
@@ -704,7 +743,7 @@ CurveComposite::Validate( void)
Point3d ptStart ;
// ciclo su tutte le curve
int nCount = 0 ;
PCRVSMPL_DEQUE::const_iterator Iter ;
PCSD_CONST_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
// verifico validità della curva e sua semplicità
if ( ! (*Iter)->IsValid() || (*Iter)->GetType() == CRV_COMPO) {
@@ -739,6 +778,34 @@ CurveComposite::Validate( void)
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
@@ -976,7 +1043,7 @@ CurveComposite::GetLength( double& dLen) const
// ciclo di calcolo
dLen = 0 ;
PCRVSMPL_DEQUE::const_iterator Iter ;
PCSD_CONST_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
double dLenCrvSmpl ;
if ( (*Iter)->GetLength( dLenCrvSmpl))
@@ -1003,7 +1070,7 @@ CurveComposite::GetLengthAtParam( double dU, double& dLen) const
// ciclo di calcolo
dLen = 0 ;
double dUToGo = dU ;
PCRVSMPL_DEQUE::const_iterator Iter ;
PCSD_CONST_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
// dominio parametrico della curva semplice
double dParStart, dParEnd ;
@@ -1052,7 +1119,7 @@ CurveComposite::GetParamAtLength( double dLen, double& dU) const
// ciclo di calcolo
dU = 0 ;
double dLenToGo = dLen ;
PCRVSMPL_DEQUE::const_iterator Iter ;
PCSD_CONST_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
// lunghezza della curva semplice
double dCrvLen ;
@@ -1107,7 +1174,7 @@ CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL
// eseguo approssimazione
double dStartPar = 0 ;
PolyLine PLSmpl ;
PCRVSMPL_DEQUE::const_iterator Iter ;
PCSD_CONST_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
// recupero approssimazione per curva semplice
if ( ! (*Iter)->ApproxWithLines( dLinTol, dAngTolDeg, PLSmpl))
@@ -1136,11 +1203,18 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA)
// eseguo approssimazione
double dStartPar = 0 ;
PolyArc PASmpl ;
PCRVSMPL_DEQUE::const_iterator Iter ;
PCSD_CONST_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
ICurve* pCrv = (*Iter) ;
// assegno estrusione e spessore della curva composita
pCrv->SetExtrusion( m_VtExtr) ;
pCrv->SetThickness( m_dThick) ;
// recupero approssimazione per curva semplice
if ( ! (*Iter)->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
if ( ! pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, PASmpl))
return false ;
// ripristino estrusione e spessore della curva semplice (annullandoli)
pCrv->SetExtrusion( V_NULL) ;
pCrv->SetThickness( 0) ;
// la accodo opportunamente a quella della curva composita
if ( ! PA.Join( PASmpl, dStartPar))
return false ;
@@ -1148,6 +1222,9 @@ CurveComposite::ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA)
dStartPar += 1 ;
}
// assegno estrusione della curva composita
PA.SetExtrusion( m_VtExtr) ;
return true ;
}
@@ -1202,7 +1279,7 @@ CurveComposite::Invert( void)
return false ;
// inverto le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Invert() ;
@@ -1218,6 +1295,35 @@ CurveComposite::Invert( void)
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::SimpleOffset( double dDist, int nType)
{
// --- l'offset va effettuato in un piano perpendicolare al vettore estrusione ---
// verifico il vettore estrusione
bool bNeedRef = ( ! m_VtExtr.IsSmall() && ! m_VtExtr.IsZplus()) ;
// se necessario cambio il riferimento
Frame3d frExtr ;
if ( bNeedRef) {
// calcolo il riferimento OCS con VtExtr come asse Z
if ( ! frExtr.Set( ORIG, m_VtExtr))
return false ;
// esprimo la curva in questo riferimento
ToLoc( frExtr) ;
}
// eseguo l'offset nel piano XY
bool bOk = SimpleOffsetXY( dDist, nType) ;
// riporto la curva nel riferimento originale
if ( bNeedRef)
ToGlob( frExtr) ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::ModifyStart( const Point3d& ptNewStart)
@@ -1273,7 +1379,7 @@ CurveComposite::TrimStartAtParam( double dUTrim)
{
// ciclo sulle diverse curve dall'inizio
double dUToTrim = dUTrim ;
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
// dominio parametrico della curva semplice
double dParStart, dParEnd ;
@@ -1321,7 +1427,7 @@ CurveComposite::TrimEndAtParam( double dUTrim)
// ciclo sulle diverse curve dalla fine
bool bToErase = false ;
double dUToTrim = dUTrim ;
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
// dominio parametrico della curva semplice
double dParStart, dParEnd ;
@@ -1382,11 +1488,6 @@ CurveComposite::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
if ( dUStartTrim < - EPS_PARAM || dUStartTrim > m_nCounter + EPS_PARAM ||
dUEndTrim < - EPS_PARAM || dUEndTrim > m_nCounter + EPS_PARAM)
return false ;
#if 0
// verifico che i trim non cancellino interamente la curva
if ( dUStartTrim > dUEndTrim - EPS_PARAM)
return false ;
#endif
// se il parametro start supera quello di end
if ( dUStartTrim > dUEndTrim - EPS_PARAM) {
// se curva aperta, il trim la cancella completamente quindi errore
@@ -1434,7 +1535,7 @@ CurveComposite::TrimStartAtLen( double dLenTrim)
{
// ciclo sulle diverse curve dall'inizio
double dLenToTrim = dLenTrim ;
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
// lunghezza della curva
double dCrvLen ;
@@ -1448,6 +1549,8 @@ CurveComposite::TrimStartAtLen( double dLenTrim)
Iter ++ ;
m_CrvSmplS.pop_front() ;
m_nCounter -- ;
if ( m_nCounter == 0)
return false ;
}
// se lunghezza ancora da tagliare nulla (entro la tolleranza)
else if ( dLenToTrim > - EPS_SMALL) {
@@ -1486,7 +1589,7 @@ CurveComposite::TrimEndAtLen( double dLenTrim)
// ciclo sulle diverse curve dalla fine
bool bToErase = false ;
double dLenToTrim = dLenTrim ;
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ;) {
double dCrvLen ;
// se non sono già nella zona da cancellare, aggiorno lunghezze
@@ -1561,8 +1664,7 @@ CurveComposite::ExtendStartByLen( double dLenExt)
}
// imposto punto iniziale e verifica curva chiusa
(*m_CrvSmplS.begin())->GetStartPoint( m_PtStart) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
ValidateMoveStart() ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -1578,7 +1680,7 @@ CurveComposite::ExtendEndByLen( double dLenExt)
return false ;
// vado sulla fine
PCRVSMPL_DEQUE::iterator Iter = m_CrvSmplS.end() ;
PCSD_ITER Iter = m_CrvSmplS.end() ;
if ( Iter == m_CrvSmplS.begin())
return false ;
-- Iter ;
@@ -1592,8 +1694,7 @@ CurveComposite::ExtendEndByLen( double dLenExt)
}
// imposto punto finale e verifica curva chiusa
(*m_CrvSmplS.begin())->GetEndPoint( m_PtEnd) ;
m_bClosed = ( AreSamePointApprox( m_PtStart, m_PtEnd)) ;
ValidateMoveEnd() ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -1608,7 +1709,7 @@ CurveComposite::Translate( const Vector3d& vtMove)
m_OGrMgr.Reset() ;
// traslo le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Translate( vtMove) ;
@@ -1631,7 +1732,7 @@ CurveComposite::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAn
m_OGrMgr.Reset() ;
// ruoto le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
@@ -1662,7 +1763,7 @@ CurveComposite::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, dou
}
// scalo le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
// eseguo la scalatura
if ( ! (*Iter)->Scale( frRef, dCoeffX, dCoeffY, dCoeffZ))
@@ -1696,7 +1797,7 @@ CurveComposite::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
m_OGrMgr.Reset() ;
// specchio le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Mirror( ptOn, vtNorm) ;
@@ -1725,7 +1826,7 @@ CurveComposite::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector
return false ;
// eseguo scorrimento delle singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->Shear( ptOn, vtNorm, vtDir, dCoeff) ;
@@ -1755,7 +1856,7 @@ CurveComposite::ToGlob( const Frame3d& frRef)
m_OGrMgr.Reset() ;
// trasformo le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->ToGlob( frRef) ;
@@ -1779,7 +1880,7 @@ CurveComposite::ToLoc( const Frame3d& frRef)
m_OGrMgr.Reset() ;
// trasformo le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter)
(*Iter)->ToLoc( frRef) ;
@@ -1807,7 +1908,7 @@ CurveComposite::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
m_OGrMgr.Reset() ;
// trasformo le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
(*Iter)->LocToLoc( frOri, frDest) ;
}
@@ -1990,7 +2091,7 @@ bool
CurveComposite::ArcsToBezierCurves( void)
{
// verifico le singole curve
PCRVSMPL_DEQUE::iterator Iter ;
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
// se arco, devo trasformare in una o più curve di Bezier
if ( (*Iter)->GetType() == CRV_ARC) {
@@ -2011,7 +2112,7 @@ CurveComposite::ArcsToBezierCurves( void)
return false ;
// inserisco le curve prima dell'arco
int nParts = 0 ;
PCRVSMPL_DEQUE::iterator Iter2 ;
PCSD_ITER Iter2 ;
for ( Iter2 = pCC->m_CrvSmplS.begin() ; Iter2 != pCC->m_CrvSmplS.end() ; ++ Iter2) {
Iter = m_CrvSmplS.insert( Iter, (*Iter2)) ;
++ Iter ;
@@ -2034,3 +2135,54 @@ CurveComposite::ArcsToBezierCurves( void)
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg)
{
// verifico le singole curve
PCSD_ITER Iter ;
for ( Iter = m_CrvSmplS.begin() ; Iter != m_CrvSmplS.end() ; ++Iter) {
// se arco in piano non perpendicolare ad estrusione o curva di Bezier trasformo
if ( ( (*Iter)->GetType() == CRV_ARC && ! GetBasicCurveArc((*Iter))->IsInPlanePerpExtr()) ||
(*Iter)->GetType() == CRV_BEZ) {
// eseguo trasformazione
PtrOwner<ICurve> pNewCrv( CurveToArcsPerpExtrCurve( (*Iter), dLinTol, dAngTolDeg)) ;
if ( IsNull( pNewCrv))
return false ;
// se risultato è singola curva
if ( pNewCrv->IsSimple()) {
// elimino l'arco e lo sostituisco con la curva di Bezier
delete (*Iter) ;
(*Iter) = Release( pNewCrv) ;
}
// altrimenti è una curva composita
else {
CurveComposite* pCC = GetBasicCurveComposite( Get( pNewCrv)) ;
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() ;
pCC->m_nCounter = 0 ;
// elimino l'arco (e sposto l'iteratore alla curva precedente)
delete (*Iter) ;
Iter = m_CrvSmplS.erase( Iter) ;
-- Iter ;
// aggiorno il numero di curve
m_nCounter += nParts - 1 ;
}
}
}
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
}
+16 -4
View File
@@ -51,6 +51,10 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // ICurve
virtual bool IsSimple( void) const { return false ; }
@@ -93,8 +97,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
virtual bool Invert( void) ;
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET)
{ return false ; }
virtual bool SimpleOffset( double dDist, int nType = OFF_FILLET) ;
virtual bool ModifyStart( const Point3d& ptNewStart) ;
virtual bool ModifyEnd( const Point3d& ptNewEnd) ;
virtual bool SetExtrusion( const Vector3d& vtExtr)
@@ -130,6 +133,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
virtual ICurve* RemoveFirstOrLastCurve( bool bLast = true) ;
virtual bool ChangeStartPoint( double dU) ;
virtual bool ArcsToBezierCurves( void) ;
virtual bool ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDeg) ;
public : // IGeoObjRW
virtual int GetNgeId( void) const ;
@@ -145,18 +149,25 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
{ if ( ! CopyFrom( ccSrc))
LOG_ERROR( GetEGkLogger(), "CurveComposite : copy error")
return *this ; }
bool RelocateFrom( CurveComposite& ccSrc) ;
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 ;
bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET) ;
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
private :
typedef std::deque<ICurve*> PCRVSMPL_DEQUE ;
typedef std::deque<ICurve*> PCRVSMPL_DEQUE ;
typedef PCRVSMPL_DEQUE::iterator PCSD_ITER ;
typedef PCRVSMPL_DEQUE::const_iterator PCSD_CONST_ITER ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
@@ -168,7 +179,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
bool m_bClosed ; // flag per indicare che la curva è chiusa
Vector3d m_VtExtr ; // vettore estrusione (normalmente coincide con m_VtN)
double m_dThick ; // spessore
mutable PCRVSMPL_DEQUE::const_iterator m_Iter ; // iteratore
int m_nTempProp ; // proprietà temporanea
mutable PCSD_CONST_ITER m_Iter ; // iteratore
} ;
//-----------------------------------------------------------------------------
+508
View File
@@ -0,0 +1,508 @@
//----------------------------------------------------------------------------
// EgalTech 2013-2013
//----------------------------------------------------------------------------
// File : CurveCompositeOffset.cpp Data : 07.12.14 Versione : 1.5l1
// Contenuto : Metodi per offset semplice della classe CCurveComposite.
//
//
//
// Modifiche : 07.12.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveComposite.h"
#include "CurveLine.h"
#include "CurveArc.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EgkCurve.h"
#include "/EgtDev/Include/EgkIntersCurveCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
static const int TP_IS_VERT_LINE = 1 ;
//----------------------------------------------------------------------------
static bool IsVerticalLine( const ICurve* pCrv, double* pdLenZ) ;
static bool VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
static bool VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
static bool VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType,
CurveComposite& ccAux) ;
static bool AddFirstLastVerticalLines( CurveComposite& ccOffs, double dLenVertFirst, double dLenVertLast) ;
static bool MediaInternalAngleDeltaZ( CurveComposite& ccOffs) ;
//----------------------------------------------------------------------------
bool
CurveComposite::SimpleOffsetXY( double dDist, int nType)
{
// creo una copia formata solo da rette e archi che giacciono nel piano XY (VtExtr è Z+)
CurveComposite ccCopy ;
if ( ! ccCopy.CopyFrom( *this) ||
! ccCopy.ArcsBezierCurvesToArcsPerpExtr( 10 * EPS_SMALL, ANG_TOL_STD_DEG))
return false ;
// determino se vietate linee verticali (perpendicolari a piano offset)
bool bNoVertLine = (( nType & ICurve::OFF_NO_VERTICAL) != 0) ;
// determino se richiesti angoli interni con deltaZ mediata
bool bMedIntDz = (( nType & ICurve::OFF_MEDIA_INTDZ) != 0) ;
// verifico se curva chiusa
bool bClosed = ccCopy.IsClosed() && ( nType & ICurve::OFF_FORCE_OPEN) == 0 ;
// creo la curva di offset
CurveComposite ccOffs ;
ccOffs.m_VtExtr = m_VtExtr ;
ccOffs.m_dThick = m_dThick ;
// eseguo l'offset ( estraggo entità dalla copia, le modifiche e le inserisco nell'offset)
// lunghezze di eventuali linee verticali iniziale e finale
double dLenVertFirst = 0 ;
double dLenVertLast = 0 ;
// recupero la prima curva
ICurve* pCrv1 = ccCopy.RemoveFirstOrLastCurve( false) ;
// se la curva è una linea verticale in Z, passo alla successiva
if ( IsVerticalLine( pCrv1, &dLenVertFirst)) {
delete pCrv1 ;
if ( bNoVertLine)
return false ;
pCrv1 = ccCopy.RemoveFirstOrLastCurve( false) ;
}
// offset della prima curva
if ( pCrv1 == nullptr ||
! pCrv1->SimpleOffset( dDist, nType) ||
! ccOffs.AddSimpleCurve( pCrv1))
return false ;
// curve successive
ICurve* pCrv2 = ccCopy.RemoveFirstOrLastCurve( false) ;
while ( pCrv2 != nullptr) {
// se la curva è una linea verticale in Z, passo alla successiva
if ( IsVerticalLine( pCrv2, &dLenVertLast)) {
delete pCrv2 ;
if ( bNoVertLine)
return false ;
pCrv2 = ccCopy.RemoveFirstOrLastCurve( false) ;
continue ;
}
// eseguo semplice offset
if ( ! pCrv2->SimpleOffset( dDist, nType))
return false ;
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
CurveComposite ccTemp ;
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 ;
}
// nessun caso è andato a buon fine, errore
else
return false ;
// inserisco nell'offset
if ( ! ccOffs.AddSimpleCurve( pCrv2))
return false ;
// aggiorno curva precedente
pCrv1 = pCrv2 ;
// passo alla curva successiva
pCrv2 = ccCopy.RemoveFirstOrLastCurve( false) ;
}
// se originale chiuso, devo confrontare anche ultima e prima curva
if ( bClosed && ccOffs.GetCurveNumber() > 0) {
// la curva successiva ora è la prima dell'offset
ICurve* pCrv2 = ccOffs.m_CrvSmplS.front() ;
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
CurveComposite ccTemp ;
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 ;
}
// nessun caso è andato a buon fine, errore
else
return false ;
}
// se originale aperto, devo rimettere eventuali lineee verticali iniziale e finale
if ( ! bClosed && ccOffs.GetCurveNumber() > 0 &&
! AddFirstLastVerticalLines( ccOffs, dLenVertFirst, dLenVertLast))
return false ;
// se richiesti angoli interni con Z mediata, verifico e sistemo
if ( bMedIntDz && ! MediaInternalAngleDeltaZ( ccOffs))
return false ;
// sposto le curve dall'offset alla composita attuale
return RelocateFrom( ccOffs) ;
}
//----------------------------------------------------------------------------
bool
IsVerticalLine( const ICurve* pCrv, double* pdLenZ)
{
// verifico sia una linea
const CurveLine* pLine = GetBasicCurveLine( pCrv) ;
if ( pLine == nullptr)
return false ;
// verifico sia diretta come l'asse Z
if ( AreSamePointXYApprox( pLine->GetStart(), pLine->GetEnd())) {
if ( pdLenZ != nullptr)
*pdLenZ = pLine->GetEnd().z - pLine->GetStart().z ;
return true ;
}
else {
if ( pdLenZ != nullptr)
*pdLenZ = 0 ;
return false ;
}
}
//----------------------------------------------------------------------------
bool
VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
{
// verifica dei puntatori
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
return false ;
// pulisco la curva ausiliaria
ccAux.Clear() ;
// calcolo dei punti estremi (finale per prima curva, iniziale per seconda)
Point3d ptP1, ptP2 ;
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
return false ;
// verifica distanza tra estremi
if ( ! AreSamePointXYEpsilon( ptP1, ptP2, 10 * EPS_SMALL))
return false ;
// se punti quasi coincidenti in Z
if ( fabs( ptP1.z - ptP2.z) < 10 * EPS_SMALL) {
// se coincidono esattamente, va bene così
if ( AreSamePointExact( ptP1, ptP2))
return true ;
// sono in tolleranza, ma devo ricongiungere gli estremi
Point3d ptMid = 0.5 * ( ptP1 + ptP2) ;
return ( pCrv1->ModifyEnd( ptMid) && pCrv2->ModifyStart( ptMid)) ;
}
// devo allineare i punti in XY e aggiungere un tratto verticale
else {
// facio coincidere gli estremi in XY
Point3d ptP1a = 0.5 * ( ptP1 + ptP2) ;
ptP1a.z = ptP1.z ;
Point3d ptP2a = 0.5 * ( ptP1 + ptP2) ;
ptP2a.z = ptP2.z ;
if ( ! pCrv1->ModifyEnd( ptP1a) || ! pCrv2->ModifyStart( ptP2a))
return false ;
// aggiungo una retta in Z
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptP1a, ptP2a))
return false ;
return ccAux.AddCurve( Release( pCrv)) ;
}
}
//----------------------------------------------------------------------------
bool
VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
{
// verifica dei puntatori
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
return false ;
// pulisco la curva ausiliaria
ccAux.Clear() ;
// calcolo l'intersezione tra le due curve
IntersCurveCurve intCC( *pCrv1, *pCrv2) ;
if ( intCC.GetNumInters() == 0)
return false ;
// prendo l'intersezione più vicina al punto medio tra gli estremi delle curve
Point3d ptP1, ptP2 ;
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
return false ;
Point3d ptMid = 0.5 * ( ptP1 + ptP2) ;
Point3d ptNew1, ptNew2 ;
if ( ! intCC.GetIntersPointNearTo( 0, ptMid, ptNew1) ||
! intCC.GetIntersPointNearTo( 1, ptMid, ptNew2))
return false ;
// se punti coincidenti in Z
if ( fabs( ptNew1.z - ptNew2.z) < EPS_SMALL) {
// modifico le due curve sul punto medio
Point3d ptNew = 0.5 * ( ptNew1 + ptNew2) ;
return ( pCrv1->ModifyEnd( ptNew) && pCrv2->ModifyStart( ptNew)) ;
}
// altrimenti
else {
// modifico le due curve sui rispettivi punti di intersezione
if ( ! pCrv1->ModifyEnd( ptNew1) || ! pCrv2->ModifyStart( ptNew2))
return false ;
// aggiungo una retta in Z
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptNew1, ptNew2))
return false ;
pCrv->SetTempProp( TP_IS_VERT_LINE) ;
return ccAux.AddCurve( Release( pCrv)) ;
}
}
//----------------------------------------------------------------------------
bool
VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType,
CurveComposite& ccAux)
{
// verifica dei puntatori
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
return false ;
// pulisco la curva ausiliaria
ccAux.Clear() ;
// elimino dal tipo le parti estranee all'angolo esterno
nType &= ( ICurve::OFF_FILLET | ICurve::OFF_CHAMFER | ICurve::OFF_EXTEND) ;
// calcolo direzioni tangenti sull'estremo in comune
Vector3d vtDir1, vtDir2 ;
if ( ! pCrv1->GetEndDir( vtDir1) || ! pCrv2->GetStartDir( vtDir2))
return false ;
// verifico se presente componente in Z
bool bDZ1 = fabs( vtDir1.z) > EPS_ANG_ZERO ;
bool bDZ2 = fabs( vtDir2.z) > EPS_ANG_ZERO ;
// le porto nel piano XY
vtDir1.z = 0 ;
vtDir2.z = 0 ;
if ( ! vtDir1.Normalize() || ! vtDir2.Normalize())
return false ;
// calcolo l'angolo di rotazione dalla prima direzione alla seconda
double dAngDeg ;
if ( ! vtDir1.GetAngleXY( vtDir2, dAngDeg))
return false ;
// se vicino all'angolo piatto, si devono ricalcolare usando le curve originali e spostandosi un poco
if ( fabs( dAngDeg) > ( ANG_STRAIGHT - EPS_ANG_SMALL)) {
// ritorno alle curve originali
PtrOwner<ICurve> pCrvOri1( pCrv1->Clone()) ;
PtrOwner<ICurve> pCrvOri2( pCrv2->Clone()) ;
if ( IsNull( pCrvOri1) || ! pCrvOri1->SimpleOffset( - dDist, nType))
return false ;
if ( IsNull( pCrvOri2) || ! pCrvOri2->SimpleOffset( - dDist, nType))
return false ;
// eseguo calcolo spostato su curve originali
Point3d ptDummy ;
double dU1 = 1 ;
double dU2 = 0 ;
if ( ! MoveParamToAvoidTg( dU1, ICurve::FROM_MINUS, *pCrvOri1) ||
! pCrvOri1->GetPointTang( dU1, ICurve::FROM_MINUS, ptDummy, vtDir1) ||
! MoveParamToAvoidTg( dU2, ICurve::FROM_PLUS, *pCrvOri2) ||
! pCrvOri2->GetPointTang( dU2, ICurve::FROM_PLUS, ptDummy, vtDir2))
return false ;
if ( ! vtDir1.GetAngleXY( vtDir2, dAngDeg))
return false ;
}
// verifico sia angolo esterno (accetto se entità quasi esattamente sovrapposto)
if ( fabs( dAngDeg) < ( ANG_STRAIGHT - 10 * EPS_ANG_ZERO) &&
( ( dDist < 0 && dAngDeg > 0) ||
( dDist > 0 && dAngDeg < 0)))
return false ;
// se l'angolo esterno supera il retto, offset extend diventa offset chamfer
if ( nType == ICurve::OFF_EXTEND && fabs( dAngDeg) > ANG_RIGHT + EPS_ANG_SMALL)
nType = ICurve::OFF_CHAMFER ;
// congiungo le due curve
switch ( nType) {
case ICurve::OFF_FILLET :
{
Point3d ptP1, ptP2 ;
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
return false ;
double dAngStart ;
vtDir1.ToSpherical( nullptr, nullptr, &dAngStart) ;
PtrOwner<CurveArc> pCrv( CreateBasicCurveArc()) ;
if ( IsNull( pCrv) || ! pCrv->Set2PD( ptP1, ptP2, dAngStart))
return false ;
// restituisco la curva
return ccAux.AddCurve( Release( pCrv)) ;
}
break ;
case ICurve::OFF_CHAMFER :
{
// lunghezza aggiuntiva in tangenza
double dLen = dDist * tan( fabs( dAngDeg) / 4 * DEGTORAD) ;
// punti di costruzione smusso
Point3d ptP1, ptP1a, ptP2a, ptP2 ;
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
return false ;
ptP1a = ptP1 + vtDir1 * dLen ;
ptP2a = ptP2 - vtDir2 * dLen ;
// se sull'angolo c'era un dislivello (linea verticale eliminata)
double dDeltaZ = ptP2.z - ptP1.z ;
if ( fabs( dDeltaZ) > EPS_SMALL) {
ptP1a.z += dDeltaZ / 4 ;
ptP2a.z -= dDeltaZ / 4 ;
bDZ1 = true ;
bDZ2 = true ;
}
// se prima c'è linea senza DZ posso allungarla
if ( pCrv1->GetType() == CRV_LINE && ! bDZ1)
pCrv1->ModifyEnd( ptP1a) ;
// altrimenti, devo aggiungere una nuova linea
else {
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptP1, ptP1a))
return false ;
if ( ! ccAux.AddCurve( Release( pCrv)))
return false ;
}
// tratto intermedio
{
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptP1a, ptP2a))
return false ;
if ( ! ccAux.AddCurve( Release( pCrv)))
return false ;
}
// se dopo c'è linea senza DZ posso allungarla
if ( pCrv2->GetType() == CRV_LINE && ! bDZ2)
pCrv2->ModifyStart( ptP2a) ;
// altrimenti, devo aggiungere una nuova linea
else {
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptP2a, ptP2))
return false ;
if ( ! ccAux.AddCurve( Release( pCrv)))
return false ;
}
return true ;
}
break ;
case ICurve::OFF_EXTEND :
{
// lunghezza aggiuntiva in tangenza
double dLen = dDist * tan( fabs( dAngDeg) / 2 * DEGTORAD) ;
// punti di costruzione estensione
Point3d ptP1, ptPc, ptP2 ;
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
return false ;
ptPc = ptP1 + vtDir1 * dLen ;
// se sull'angolo c'era un dislivello (linea verticale eliminata)
double dDeltaZ = ptP2.z - ptP1.z ;
if ( fabs( dDeltaZ) > EPS_SMALL) {
ptPc.z += dDeltaZ / 2 ;
bDZ1 = true ;
bDZ2 = true ;
}
// se prima c'è linea senza DZ posso allungarla
if ( pCrv1->GetType() == CRV_LINE && ! bDZ1)
pCrv1->ModifyEnd( ptPc) ;
// altrimenti, devo aggiungere una nuova linea
else {
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptP1, ptPc))
return false ;
if ( ! ccAux.AddCurve( Release( pCrv)))
return false ;
}
// se dopo c'è linea senza DZ posso allungarla
if ( pCrv2->GetType() == CRV_LINE && ! bDZ2)
pCrv2->ModifyStart( ptPc) ;
// altrimenti, devo aggiungere una nuova linea
else {
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptPc, ptP2))
return false ;
if ( ! ccAux.AddCurve( Release( pCrv)))
return false ;
}
return true ;
}
}
return false ;
}
//----------------------------------------------------------------------------
bool
AddFirstLastVerticalLines( CurveComposite& ccOffs, double dLenVertFirst, double dLenVertLast)
{
// se richiesto inserimento prima retta verticale
if ( fabs( dLenVertFirst) > EPS_SMALL) {
Point3d ptP2 ;
if ( ! ccOffs.GetStartPoint( ptP2))
return false ;
Point3d ptP1 = ptP2 ;
ptP1.z -= dLenVertFirst ;
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptP1, ptP2))
return false ;
if ( ! ccOffs.AddCurve( Release( pCrv), false))
return false ;
}
// se richiesto inserimento ultima retta verticale
if ( fabs( dLenVertLast) > EPS_SMALL) {
Point3d ptP1 ;
if ( ! ccOffs.GetEndPoint( ptP1))
return false ;
Point3d ptP2 = ptP1 ;
ptP2.z += dLenVertLast ;
PtrOwner<CurveLine> pCrv( CreateBasicCurveLine()) ;
if ( IsNull( pCrv) || ! pCrv->Set( ptP1, ptP2))
return false ;
if ( ! ccOffs.AddCurve( Release( pCrv)))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
MediaInternalAngleDeltaZ( CurveComposite& ccOffs)
{
// definisco una composita temporanea
CurveComposite ccTemp ;
// ciclo sulle curve
bool bModifyNext = false ;
Point3d ptMid ;
ICurve* pCrv = ccOffs.RemoveFirstOrLastCurve( false) ;
while ( pCrv != nullptr) {
// verifico se curva di raccordo in Z di angolo interno
if ( pCrv->GetTempProp() == TP_IS_VERT_LINE) {
// ne recupero il punto medio e la cancello
pCrv->GetMidPoint( ptMid) ;
delete pCrv ;
// modifico il finale della curva precedente
if ( ! ccTemp.ModifyEnd( ptMid))
return false ;
// imposto flag per modifica iniziale della curva successiva
bModifyNext = true ;
}
// altrimenti
else {
// se da modificare
if ( bModifyNext && ! pCrv->ModifyStart( ptMid)) {
delete pCrv ;
return false ;
}
bModifyNext = false ;
// la sposto nella composita di offset
if ( ! ccTemp.AddCurve( pCrv))
return false ;
}
// passo alla curva successiva
pCrv = ccOffs.RemoveFirstOrLastCurve( false) ;
}
// se modifica in sospeso, allora curva originale chiusa e modifico inizio
if ( bModifyNext && ! ccTemp.ModifyStart( ptMid))
return false ;
// riporto le curve nella composita di offset
return ccOffs.RelocateFrom( ccTemp) ;
}
+12 -9
View File
@@ -29,7 +29,7 @@ GEOOBJ_REGISTER( CRV_LINE, NGE_C_LIN, CurveLine) ;
//----------------------------------------------------------------------------
CurveLine::CurveLine( void)
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick()
: m_nStatus( TO_VERIFY), m_PtStart(), m_PtEnd(), m_VtExtr(), m_dThick(), m_nTempProp()
{
}
@@ -123,6 +123,7 @@ CurveLine::CopyFrom( const CurveLine& clSrc)
return true ;
m_VtExtr = clSrc.m_VtExtr ;
m_dThick = clSrc.m_dThick ;
m_nTempProp = clSrc.m_nTempProp ;
return Set( clSrc.m_PtStart, clSrc.m_PtEnd) ;
}
@@ -515,22 +516,24 @@ CurveLine::Invert( void)
//----------------------------------------------------------------------------
bool
CurveLine::Offset( double dDist, int nSide, int nType)
CurveLine::SimpleOffset( double dDist, int nType)
{
// verifico lo stato
if ( m_nStatus != OK)
return false ;
// calcolo il versore direzione linea nel piano XY
// determinazione versore normale al piano di offset
Vector3d vtNorm = Z_AX ;
if ( ! m_VtExtr.IsSmall())
vtNorm = m_VtExtr ;
// calcolo il versore direzione linea nel piano perpendicolare alla normale
Vector3d vtDir = m_PtEnd - m_PtStart ;
vtDir.z = 0 ;
vtDir -= vtDir * vtNorm * vtNorm ;
if ( ! vtDir.Normalize())
return false ;
// calcolo il versore ortogonale dal lato di offset
if ( nSide != OFF_LEFT)
vtDir.Rotate( Z_AX, 0, -1) ; // rotazione CW di 90 deg
else
vtDir.Rotate( Z_AX, 0, 1) ; // rotazione CCW di 90 deg
// calcolo il versore ortogonale dal lato destro (offset positivo)
vtDir.Rotate( vtNorm, 0, -1) ; // rotazione CW di 90 deg
// sposto i punti
m_PtStart += vtDir * dDist ;
+12 -7
View File
@@ -49,6 +49,10 @@ class CurveLine : public ICurveLine, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // ICurve
virtual bool IsSimple( void) const
@@ -93,7 +97,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW
virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ;
virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ;
virtual bool Invert( void) ;
virtual bool Offset( double dDist, int nSide, int nType = OFF_FILLET) ;
virtual bool SimpleOffset( double dDist, int nType = OFF_FILLET) ;
virtual bool ModifyStart( const Point3d& ptNewStart) ;
virtual bool ModifyEnd( const Point3d& ptNewEnd) ;
virtual bool SetExtrusion( const Vector3d& vtExtr)
@@ -142,12 +146,13 @@ class CurveLine : public ICurveLine, public IGeoObjRW
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Status m_nStatus ; // stato
Point3d m_PtStart ; // punto iniziale
Point3d m_PtEnd ; // punto finale
Vector3d m_VtExtr ; // vettore estrusione
double m_dThick ; // spessore
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Status m_nStatus ; // stato
Point3d m_PtStart ; // punto iniziale
Point3d m_PtEnd ; // punto finale
Vector3d m_VtExtr ; // vettore estrusione
double m_dThick ; // spessore
int m_nTempProp ; // proprietà temporanea
} ;
//-----------------------------------------------------------------------------
+7 -2
View File
@@ -110,15 +110,20 @@ DistPointArc::DistPointFlatArc( const Point3d& ptP, const ICurveArc& arArc)
void
DistPointArc::DistPointHelix( const Point3d& ptP, const ICurveArc& arArc)
{
// determino tolleranza di approssimazione in base a raggio curva
double dRad = arArc.GetRadius() ;
const double FRAZ = 0.2 ;
double dLinTol = ( ( FRAZ * dRad > LIN_TOL_APPROX) ? LIN_TOL_APPROX : FRAZ * dRad) ;
// creo una polilinea di approssimazione
PolyLine PL ;
if ( ! arArc.ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, PL))
if ( ! arArc.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, PL))
return ;
// cerco la minima distanza per la polilinea
MDCVECTOR vApproxMin ;
MDCVECTOR::iterator Iter ;
if ( ! CalcMinDistPointPolyLine( ptP, PL, vApproxMin))
if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))
return ;
// raffino i punti trovati
+3 -2
View File
@@ -21,7 +21,7 @@
//----------------------------------------------------------------------------
bool
CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, MDCVECTOR& vApproxMin)
CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCVECTOR& vApproxMin)
{
double dSqDist ;
double dPar ;
@@ -37,6 +37,7 @@ CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, MDCVECTOR& vApproxMi
bool bFound = false ;
bool bOnEnd = false ;
vApproxMin.reserve( 4) ;
vApproxMin.clear() ;
for ( bool bLine = PL.GetFirstULine( &dUIni, &ptIni, &dUFin, &ptFin) ;
bLine ;
bLine = PL.GetNextULine( &dUIni, &ptIni, &dUFin, &ptFin)) {
@@ -45,7 +46,7 @@ CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, MDCVECTOR& vApproxMi
if ( ! dstPtLn.GetSqDist( dSqDist))
continue ;
// altro punto con la stessa minima distanza già trovata
if ( bFound && fabs( dSqDist - dSqMinDist) < 2 * dMinDist * LIN_TOL_APPROX) {
if ( bFound && fabs( dSqDist - dSqMinDist) < 2 * dMinDist * dLinTol) {
// salvo i dati nella struttura
approxMin.dDist = dMinDist ;
dstPtLn.GetMinDistPoint( approxMin.ptQ) ;
+1 -1
View File
@@ -44,7 +44,7 @@ typedef std::vector<MinDistCalc> MDCVECTOR ; // vettore di MinDistCalc
//-----------------------------------------------------------------------------
bool CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, MDCVECTOR& vApproxMin) ;
bool CalcMinDistPointPolyLine( const Point3d& ptP, PolyLine& PL, double dLinTol, MDCVECTOR& vApproxMin) ;
bool PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
const MinDistCalc& approxMin, double& dPrevPar, Point3d& ptQ) ;
bool FilterMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
+12 -2
View File
@@ -16,7 +16,9 @@
#include "DistPointCrvBezier.h"
#include "DistPointCrvAux.h"
#include "GeoConst.h"
#include <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& CrvBez)
@@ -27,15 +29,23 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier&
if ( ! CrvBez.IsValid())
return ;
// determino tolleranza di approssimazione in base a ingombro curva
BBox3d b3Crv ;
CrvBez.GetLocalBBox( b3Crv, BBF_STANDARD) ;
double dRad = INFINITO ;
b3Crv.GetRadius( dRad) ;
const double FRAZ = 0.2 ;
double dLinTol = ( ( FRAZ * dRad > LIN_TOL_APPROX) ? LIN_TOL_APPROX : FRAZ * dRad) ;
// creo una polilinea di approssimazione
PolyLine PL ;
if ( ! CrvBez.ApproxWithLines( LIN_TOL_APPROX, ANG_TOL_APPROX_DEG, PL))
if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, PL))
return ;
// cerco la minima distanza per la polilinea
MDCVECTOR vApproxMin ;
MDCVECTOR::iterator Iter ;
if ( ! CalcMinDistPointPolyLine( ptP, PL, vApproxMin))
if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))
return ;
// verifico presenza singolarità agli estremi degli intervalli trovati
+75 -19
View File
@@ -48,6 +48,8 @@ DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve, bool bI
CrvCompositeCalculate( ptP, Curve) ;
break ;
}
// salvo il punto
m_ptP = ptP ;
// salvo il puntatore alla curva
m_pCurve = &Curve ;
}
@@ -120,10 +122,7 @@ DistPointCurve::GetDist( double& dDist)
bool
DistPointCurve::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag)
{
if ( m_dDist < 0)
return false ;
if ( nInd < 0 || nInd >= (int) m_Info.size())
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
return false ;
ptMinDist = m_Info[nInd].ptQ ;
@@ -135,10 +134,7 @@ DistPointCurve::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag)
bool
DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFlag)
{
if ( m_dDist < 0)
return false ;
if ( m_Info.empty())
if ( m_dDist < 0 || m_Info.empty())
return false ;
// verifico se cade in una zona continua
@@ -172,10 +168,7 @@ DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFl
bool
DistPointCurve::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag)
{
if ( m_dDist < 0)
return false ;
if ( nInd < 0 || nInd >= (int) m_Info.size())
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
return false ;
dParam = m_Info[nInd].dPar ;
@@ -187,10 +180,7 @@ DistPointCurve::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag)
bool
DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int& nFlag)
{
if ( m_dDist < 0)
return false ;
if ( m_Info.empty())
if ( m_dDist < 0 || m_Info.empty())
return false ;
// verifico se cade in una zona continua
@@ -219,12 +209,78 @@ DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int&
//----------------------------------------------------------------------------
bool
DistPointCurve::GetMinDistInfo( int nInd, MinDistPCInfo& aInfo)
DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide)
{
if ( m_dDist < 0)
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
return false ;
if ( nInd < 0 || nInd >= (int) m_Info.size())
// se distanza nulla, il punto giace sulla curva
if ( m_dDist <= EPS_SMALL) {
nSide = MDS_ON ;
return true ;
}
// determino la tangente nell'intorno del punto
Point3d ptQ ;
Vector3d vtPreTg, vtPostTg ;
if ( m_pCurve == nullptr ||
! m_pCurve->GetPointTang( m_Info[nInd].dPar, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
! m_pCurve->GetPointTang( m_Info[nInd].dPar, ICurve::FROM_PLUS, ptQ, vtPostTg))
return false ;
Vector3d vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
// se tangenti opposte, si deve ricalcolare spostandosi un poco
if ( ! vtTg.Normalize()) {
double dDeltaU = 1000 * EPS_PARAM ;
if ( ! m_pCurve->GetPointTang( m_Info[nInd].dPar - dDeltaU, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
! m_pCurve->GetPointTang( m_Info[nInd].dPar + dDeltaU, ICurve::FROM_PLUS, ptQ, vtPostTg))
return false ;
vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
if ( ! vtTg.Normalize( EPS_ZERO))
return false ;
}
// determino la direzione di riferimento
Vector3d vtRef = vtN ^ vtTg ;
if ( ! vtRef.Normalize())
return false ;
// determino il lato di giacitura del punto
double dSide = vtRef * ( m_ptP - ptQ) ;
if ( fabs( dSide) < EPS_SMALL)
nSide = MDS_ON ;
else if ( dSide > 0)
nSide = MDS_LEFT ;
else
nSide = MDS_RIGHT ;
return true ;
}
//----------------------------------------------------------------------------
bool
DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide)
{
if ( m_dDist < 0 || m_Info.empty())
return false ;
// cerco punto discreto più vicino (anche estremi di zone continue)
int nInd ;
double dParam ;
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
if ( i == 0 ||
fabs( m_Info[i].dPar - dNearParam) < fabs( dParam - dNearParam)) {
nInd = i ;
dParam = m_Info[i].dPar ;
}
}
// mi sono ricondotto al caso precedente
return GetSideAtMinDistPoint( nInd, vtN, nSide) ;
}
//----------------------------------------------------------------------------
bool
DistPointCurve::GetMinDistInfo( int nInd, MinDistPCInfo& aInfo)
{
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
return false ;
aInfo = m_Info[nInd] ;
BIN
View File
Binary file not shown.
+9 -3
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -29,12 +29,14 @@
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -42,6 +44,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@@ -49,6 +52,7 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -171,7 +175,7 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<OmitFramePointers>true</OmitFramePointers>
<OmitFramePointers>false</OmitFramePointers>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -181,6 +185,7 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateMapFile>false</GenerateMapFile>
</Link>
<Midl>
<MkTypLibCompatible>false</MkTypLibCompatible>
@@ -209,7 +214,7 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<OmitFramePointers>false</OmitFramePointers>
</ClCompile>
<Link>
@@ -245,6 +250,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="Color.cpp" />
<ClCompile Include="CreateCurveAux.cpp" />
<ClCompile Include="CurveByInterp.cpp" />
<ClCompile Include="CurveCompositeOffset.cpp" />
<ClCompile Include="DistPointArc.cpp" />
<ClCompile Include="DistPointCrvAux.cpp" />
<ClCompile Include="DistPointCrvBezier.cpp" />
+3
View File
@@ -243,6 +243,9 @@
<ClCompile Include="LinePntMinDistCurve.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="CurveCompositeOffset.cpp">
<Filter>File di origine\Geo</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
+2 -1
View File
@@ -29,7 +29,7 @@ GEOOBJ_REGISTER( EXT_TEXT, NGE_E_TXT, ExtText) ;
//----------------------------------------------------------------------------
ExtText::ExtText( void)
: m_ptP(), m_vtN( 0, 0, 1), m_vtD( 1, 0, 0), m_sFont(),
m_nWeight( 400), m_bItalic( false), m_dHeight( 10), m_dRatio( 1), m_dAddAdvance( 0)
m_nWeight( 400), m_bItalic( false), m_dHeight( 10), m_dRatio( 1), m_dAddAdvance( 0), m_nTempProp()
{
}
@@ -174,6 +174,7 @@ ExtText::CopyFrom( const ExtText& clSrc)
m_dRatio = clSrc.m_dRatio ;
m_dAddAdvance = clSrc.m_dAddAdvance ;
m_nInsPos = clSrc.m_nInsPos ;
m_nTempProp = clSrc.m_nTempProp ;
return true ;
}
+17 -12
View File
@@ -49,6 +49,10 @@ class ExtText : public IExtText, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // IExtText
virtual bool CopyFrom( const IGeoObj* pGObjSrc) ;
@@ -121,16 +125,17 @@ class ExtText : public IExtText, public IGeoObjRW
static const char CHR_SPECIAL = '\a' ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Point3d m_ptP ; // punto di inserimento
Vector3d m_vtN ; // versore normale
Vector3d m_vtD ; // versore di direzione
std::string m_sText ; // testo con codifica UTF-8
std::string m_sFont ; // font utilizzato
int m_nWeight ; // 0 (don't care), 100 (thin) - 900 (black)
bool m_bItalic ; // flag per italico (inclinato)
double m_dHeight ; // altezza del carattere
double m_dRatio ; // rapporto tra larghezza e altezza
double m_dAddAdvance ; // avanzamento addizionale tra caratteri
int m_nInsPos ; // posizione del punto di inserimento rispetto al testo
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Point3d m_ptP ; // punto di inserimento
Vector3d m_vtN ; // versore normale
Vector3d m_vtD ; // versore di direzione
std::string m_sText ; // testo con codifica UTF-8
std::string m_sFont ; // font utilizzato
int m_nWeight ; // 0 (don't care), 100 (thin) - 900 (black)
bool m_bItalic ; // flag per italico (inclinato)
double m_dHeight ; // altezza del carattere
double m_dRatio ; // rapporto tra larghezza e altezza
double m_dAddAdvance ; // avanzamento addizionale tra caratteri
int m_nInsPos ; // posizione del punto di inserimento rispetto al testo
int m_nTempProp ; // proprietà temporanea
} ;
+17 -1
View File
@@ -261,10 +261,19 @@ GdbGeo::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoe
// se arco e scalatura non omogenea
if ( m_pGeoObj->GetType() == CRV_ARC &&
(fabs( dCoeffX - dCoeffY) > EPS_SMALL || fabs( dCoeffX - dCoeffZ) > EPS_SMALL)) {
// curva originale
ICurve* pCrv = GetCurve( m_pGeoObj) ;
// trasformo in curva di Bezier (semplice o composta)
ICurve* pCrvNew = ArcToBezierCurve( GetCurve( m_pGeoObj)) ;
ICurve* pCrvNew = ArcToBezierCurve( pCrv) ;
if ( pCrvNew == nullptr)
return false ;
// assegno alla nuova curva estrusione e spessore di quella originale
Vector3d vtExtr ;
if ( pCrv->GetExtrusion( vtExtr))
pCrvNew->SetExtrusion( vtExtr) ;
double dThick ;
if ( pCrv->GetThickness( dThick))
pCrvNew->SetThickness( dThick) ;
// elimino l'arco e lo sostituisco con la curva di Bezier
delete m_pGeoObj ;
m_pGeoObj = pCrvNew ;
@@ -302,6 +311,13 @@ GdbGeo::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDi
ICurve* pCrvNew = ArcToBezierCurve( GetCurve( m_pGeoObj)) ;
if ( pCrvNew == nullptr)
return false ;
// assegno alla nuova curva estrusione e spessore di quella originale
Vector3d vtExtr ;
if ( pArc->GetExtrusion( vtExtr))
pCrvNew->SetExtrusion( vtExtr) ;
double dThick ;
if ( pArc->GetThickness( dThick))
pCrvNew->SetThickness( dThick) ;
// elimino l'arco e lo sostituisco con la curva di Bezier
delete m_pGeoObj ;
m_pGeoObj = pCrvNew ;
+2 -1
View File
@@ -28,7 +28,7 @@ GEOOBJ_REGISTER( GEO_FRAME3D, NGE_G_FRM, GeoFrame3d) ;
//----------------------------------------------------------------------------
GeoFrame3d::GeoFrame3d( void)
: m_frF()
: m_frF(), m_nTempProp()
{
}
@@ -113,6 +113,7 @@ GeoFrame3d::CopyFrom( const GeoFrame3d& gfSrc)
{
if ( &gfSrc == this)
return true ;
m_nTempProp = gfSrc.m_nTempProp ;
return Set( gfSrc.m_frF) ;
}
+7 -2
View File
@@ -59,6 +59,10 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // IGeoFrame3d
virtual bool CopyFrom( const IGeoObj* pGObjSrc) ;
@@ -91,6 +95,7 @@ class GeoFrame3d : public IGeoFrame3d, public IGeoObjRW
bool CopyFrom( const GeoFrame3d& gfSrc) ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Frame3d m_frF ; // oggetto
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Frame3d m_frF ; // oggetto
int m_nTempProp ; // proprietà temporanea
} ;
+2 -1
View File
@@ -27,7 +27,7 @@ GEOOBJ_REGISTER( GEO_PNT3D, NGE_G_PNT, GeoPoint3d) ;
//----------------------------------------------------------------------------
GeoPoint3d::GeoPoint3d( void)
: m_ptP()
: m_ptP(), m_nTempProp()
{
}
@@ -81,6 +81,7 @@ GeoPoint3d::CopyFrom( const GeoPoint3d& clSrc)
{
if ( &clSrc == this)
return true ;
m_nTempProp = clSrc.m_nTempProp ;
return Set( clSrc.m_ptP) ;
}
+7 -2
View File
@@ -57,6 +57,10 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // IGeoPoint3d
virtual bool CopyFrom( const IGeoObj* pGObjSrc) ;
@@ -83,6 +87,7 @@ class GeoPoint3d : public IGeoPoint3d, public IGeoObjRW
bool CopyFrom( const GeoPoint3d& gpSrc) ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Point3d m_ptP ; // oggetto
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Point3d m_ptP ; // oggetto
int m_nTempProp ; // proprietà temporanea
} ;
+2 -1
View File
@@ -28,7 +28,7 @@ GEOOBJ_REGISTER( GEO_VECT3D, NGE_G_VEC, GeoVector3d) ;
//----------------------------------------------------------------------------
GeoVector3d::GeoVector3d( void)
: m_vtV()
: m_vtV(), m_nTempProp()
{
}
@@ -97,6 +97,7 @@ GeoVector3d::CopyFrom( const GeoVector3d& clSrc)
{
if ( &clSrc == this)
return true ;
m_nTempProp = clSrc.m_nTempProp ;
return Set( clSrc.m_vtV, clSrc.m_ptBase) ;
}
+8 -3
View File
@@ -65,6 +65,10 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // IGeoVector3d
virtual bool CopyFrom( const IGeoObj* pGObjSrc) ;
@@ -97,7 +101,8 @@ class GeoVector3d : public IGeoVector3d, public IGeoObjRW
bool CopyFrom( const GeoVector3d& gvSrc) ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Vector3d m_vtV ; // oggetto
Point3d m_ptBase ; // punto base da cui tracciare il vettore
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Vector3d m_vtV ; // oggetto
Point3d m_ptBase ; // punto base da cui tracciare il vettore
int m_nTempProp ; // proprietà temporanea
} ;
+2
View File
@@ -71,6 +71,8 @@ GeomDB::Init( void)
m_IdManager.Init( 1024) ;
// imposto materiale di default
m_GrpRadix.SetMaterial( Color()) ;
// imposto riferimento griglia standard
m_GridFrame = GLOB_FRM ;
return true ;
}
+15 -6
View File
@@ -1,13 +1,13 @@
//----------------------------------------------------------------------------
// EgalTech 2013-2013
// EgalTech 2013-2014
//----------------------------------------------------------------------------
// File : GeomDB.h Data : 08.04.13 Versione : 1.1c1
// File : GeomDB.h Data : 03.12.14 Versione : 1.5l1
// Contenuto : Dichiarazione della classe GeomDB.
//
//
//
// Modifiche : 22.01.13 DS Creazione modulo.
//
// 03.12.14 DS Aggiunta gestione riferimento di griglia.
//
//----------------------------------------------------------------------------
@@ -96,7 +96,7 @@ class GeomDB : public IGeomDB
virtual bool Shear( int nId, const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) ;
virtual bool ShearGlob( int nId, const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) ;
virtual bool ShearGroup( int nId, const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) ;
// selection
// Selection
virtual bool SelectObj( int nId, bool bOnlyIfVisible = false) ;
virtual bool DeselectObj( int nId) ;
virtual bool SelectGroupObjs( int nId, int nFilter = 0, bool bOnlyIfVisible = false) ;
@@ -108,7 +108,7 @@ class GeomDB : public IGeomDB
virtual int GetLastSelectedObj( void) const ;
virtual int GetPrevSelectedObj( void) const ;
virtual bool ClearSelection( void) ;
// attributes
// Attributes
virtual bool DumpAttributes( int nId, std::string& sOut, const char* szNewLine) const ;
virtual bool CopyAttributes( int nIdSou, int nIdDest) ;
virtual bool SetLevel( int nId, int nLevel) ;
@@ -158,7 +158,7 @@ class GeomDB : public IGeomDB
virtual bool GetInfo( int nId, const std::string& sKey, Frame3d& frInfo) const ;
virtual bool ExistsInfo( int nId, const std::string& sKey) const ;
virtual bool RemoveInfo( int nId, const std::string& sKey) ;
// material library
// Material library
virtual int AddMaterial( const std::string& sName, const Material& matM) ;
virtual int FindMaterial( const std::string& sName) const ;
virtual bool EraseMaterial( int nMat, bool& bInUse) ;
@@ -169,6 +169,14 @@ class GeomDB : public IGeomDB
virtual bool IsCustomMaterial( int nMat, bool& bCustom) const ;
virtual bool ModifyMaterialData( int nMat, const Material& matM) ;
virtual bool ModifyMaterialName( int nMat, const std::string& sName) ;
// Grid
virtual bool SetGridFrame( const Frame3d& frFrame)
{ if ( ! frFrame.IsValid())
return false ;
m_GridFrame = frFrame ;
return true ; }
virtual const Frame3d& GetGridFrame( void)
{ return m_GridFrame ; }
public :
GeomDB( void) ;
@@ -211,4 +219,5 @@ class GeomDB : public IGeomDB
SelManager m_SelManager ; // gestore lista oggetti selezionati
GdbMaterialMgr m_MatManager ; // gestore lista materiali
GdbGroup m_GrpRadix ; // gruppo radice di tutto il DB
Frame3d m_GridFrame ; // riferimento della griglia
} ;
+1 -50
View File
@@ -14,6 +14,7 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "IntersCrvCompoCrvCompo.h"
#include "CurveAux.h"
#include <algorithm>
using namespace std ;
@@ -30,7 +31,6 @@ static bool CalcATypeFromDisk( const ICurve& CurveA, double dUA, ICurve::Side nS
const ICurve& CurveB, double dUB, int& nType) ;
static bool CalcATypeFromDisk2( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
const ICurve& CurveB, double dUB1, double dUB2, int& nType) ;
static bool MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve) ;
//----------------------------------------------------------------------------
IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
@@ -761,52 +761,3 @@ CalcATypeFromDisk2( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
nType = ICCT_OUT ;
return true ;
}
//----------------------------------------------------------------------------
static bool
MoveParamToAvoidTg( double& dU, ICurve::Side nSide, const ICurve& Curve)
{
// verifico che il parametro sia accettabile
if ( ! Curve.IsValidParam( dU, nSide))
return false ;
// determino un incremento piccolo ma valido del parametro U
double dDeltaU = 1000 * EPS_PARAM ;
Point3d ptPos ;
Vector3d vtDer1 ;
if ( Curve.GetPointD1D2( dU, nSide, ptPos, &vtDer1)) {
double dDer1 = vtDer1.LenXY() ;
if ( dDer1 > EPS_ZERO)
dDeltaU = 10 * EPS_SMALL / dDer1 ;
}
// cerco di spostarmi per evitare eventuali problemi di tangenza
if ( nSide == ICurve::FROM_MINUS) {
double dUm = dU - dDeltaU ;
if ( ! Curve.IsValidParam( dUm, nSide)) {
if ( Curve.IsClosed()) {
double dStart, dEnd ;
Curve.GetDomain( dStart, dEnd) ;
dUm = ( dEnd - dStart) - dDeltaU ;
}
else
dUm = dU ;
}
dU = dUm ;
return true ;
}
else { // nSide == ICurve::FROM_PLUS
double dUm = dU + dDeltaU ;
if ( ! Curve.IsValidParam( dUm, nSide)) {
if ( Curve.IsClosed()) {
double dStart, dEnd ;
Curve.GetDomain( dStart, dEnd) ;
dUm = dStart + dDeltaU ;
}
else
dUm = dU ;
}
dU = dUm ;
return true ;
}
}
+3 -1
View File
@@ -49,6 +49,8 @@ IntersLineArc::IntersLineArc( const ICurveLine& Line, const ICurveArc& Arc)
// linea : copia e Direzione
m_Line.CopyFrom( &Line) ;
m_vtDirL = m_Line.GetEnd() - m_Line.GetStart() ;
Vector3d vtDirLXY = m_vtDirL ;
vtDirLXY.z = 0 ;
if ( m_vtDirL.SqLenXY() < EPS_SMALL * EPS_SMALL)
return ;
@@ -56,7 +58,7 @@ IntersLineArc::IntersLineArc( const ICurveLine& Line, const ICurveArc& Arc)
m_Arc.CopyFrom( &Arc) ;
// punto proiezione del centro arco sulla linea
double dU = (( m_Arc.GetCenter() - m_Line.GetStart()) * m_vtDirL) / m_vtDirL.SqLenXY() ;
double dU = (( m_Arc.GetCenter() - m_Line.GetStart()) * vtDirLXY) / vtDirLXY.SqLenXY() ;
Point3d ptPrjCen = m_Line.GetStart() + m_vtDirL * dU ;
// quadrato della distanza tra centro e punto proiezione
double dSqDist = ( ptPrjCen - m_Arc.GetCenter()).SqLenXY() ;
+1
View File
@@ -14,6 +14,7 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "IntersLineLine.h"
#include <algorithm>
using namespace std ;
+1
View File
@@ -14,6 +14,7 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "\EgtDev\Include\EGkPointGrid3d.h"
#include <algorithm>
#include <utility>
using namespace std ;
+31 -1
View File
@@ -13,7 +13,8 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "\EgtDev\Include\EGkPolyArc.h"
#include "/EgtDev/Include/EGkPolyArc.h"
#include "/EgtDev/Include/EGkFrame3d.h"
//----------------------------------------------------------------------------
@@ -137,6 +138,31 @@ PolyArc::AddOffsetToU( double dOffset)
return true ;
}
//----------------------------------------------------------------------------
bool
PolyArc::ParamLinearTransform( double dStartU, double dEndU)
{
// ci devono essere almeno 2 punti
if ( m_lUPointBs.size() < 2)
return false ;
// recupero i vecchi estremi del parametro
double dOriStartU = m_lUPointBs.front().dU ;
double dOriEndU = m_lUPointBs.back().dU ;
// determino i coefficienti di riparametrizzazione
double dCoeff ;
if ( fabs( dEndU - dStartU) < EPS_ZERO)
dCoeff = 0 ;
else if ( fabs( dOriEndU - dOriStartU) > EPS_ZERO)
dCoeff = ( dEndU - dStartU) / ( dOriEndU - dOriStartU) ;
else
return false ;
// eseguo la riparametrizzazione
UPNTBLIST::iterator iter ;
for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter)
iter->dU = dStartU + dCoeff * ( iter->dU - dOriStartU) ;
return true ;
}
//----------------------------------------------------------------------------
bool
PolyArc::SetElevation( double dZ)
@@ -237,6 +263,10 @@ PolyArc::ToLoc( const Frame3d& frRef)
bool
PolyArc::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
{
// se i due riferimenti coincidono, non devo fare alcunché
if ( AreSameFrame( frOri, frDest))
return true ;
// ciclo sui punti
m_vtExtr.LocToLoc( frOri, frDest) ;
UPNTBLIST::iterator iter ;
for ( iter = m_lUPointBs.begin() ; iter != m_lUPointBs.end() ; ++ iter)
+4
View File
@@ -198,6 +198,10 @@ PolyLine::ToLoc( const Frame3d& frRef)
bool
PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
{
// se i due riferimenti coincidono, non devo fare alcunché
if ( AreSameFrame( frOri, frDest))
return true ;
// ciclo sui punti
PNTULIST::iterator iter ;
for ( iter = m_lUPoints.begin() ; iter != m_lUPoints.end() ; ++ iter)
iter->first.LocToLoc( frOri, frDest) ;
+3 -1
View File
@@ -32,7 +32,8 @@ GEOOBJ_REGISTER( SRF_TRIMESH, NGE_S_TRM, SurfTriMesh) ;
//----------------------------------------------------------------------------
SurfTriMesh::SurfTriMesh( void)
: m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bClosed( false)
: m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dSmoothAng( STM_STD_SMOOTH_ANG),
m_bClosed( false), m_nTempProp()
{
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
}
@@ -384,6 +385,7 @@ SurfTriMesh::CopyFrom( const SurfTriMesh& stmSrc)
m_dSmoothAng = stmSrc.m_dSmoothAng ;
m_dCosSmAng = stmSrc.m_dCosSmAng ;
m_nStatus = stmSrc.m_nStatus ;
m_nTempProp = stmSrc.m_nTempProp ;
return true ;
}
+6
View File
@@ -18,6 +18,7 @@
#include "GeoObjRW.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EgtNumCollection.h"
#include <algorithm>
//----------------------------------------------------------------------------
class StmVert
@@ -84,6 +85,10 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
{ return m_OGrMgr.GetObjGraphics() ; }
virtual const IObjGraphics* GetObjGraphics( void) const
{ return m_OGrMgr.GetObjGraphics() ; }
virtual void SetTempProp( int nProp)
{ m_nTempProp = nProp ; }
virtual int GetTempProp( void)
{ return m_nTempProp ; }
public : // ISurf
virtual bool IsSimple( void) const
@@ -185,4 +190,5 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool m_bClosed ; // la superficie racchiude un volume
VERTVECTOR m_vVert ; // vettore dei vertici
TRIAVECTOR m_vTria ; // vettore dei triangoli
int m_nTempProp ; // proprietà temporanea
} ;