From 3e8e7e2e2a7a0110559d6d7b7773e117b50709a6 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 17 Dec 2014 15:03:29 +0000 Subject: [PATCH] =?UTF-8?q?EgtGeomKernel=201.5l1=20:=20-=20aggiornamento?= =?UTF-8?q?=20a=20VS2013=20-=20migliorato=20SimpleOffset=20e=20implementat?= =?UTF-8?q?o=20anche=20per=20CurveComposite=20-=20il=20lato=20di=20offset?= =?UTF-8?q?=20ora=20viene=20dal=20segno=20dello=20spostamento=20(=20+=20a?= =?UTF-8?q?=20destra,=20-=20a=20sinistra)=20-=20il=20vettore=20estrusione?= =?UTF-8?q?=20ora=20=C3=A8=20la=20normale=20al=20piano=20di=20offset=20(se?= =?UTF-8?q?=20non=20c'=C3=A8=20uso=20Z+)=20-=20aggiunto=20a=20tutte=20le?= =?UTF-8?q?=20entit=C3=A0=20geometriche=20membro=20m=5FnTempProp=20intero?= =?UTF-8?q?=20temporaneo=20-=20migliorata=20DistPointCrvBezier=20e=20DistP?= =?UTF-8?q?ointArc=20-=20corretta=20IntersLineArc=20con=20linee=20che=20no?= =?UTF-8?q?n=20giacciono=20nel=20piano=20XY=20-=20corretta=20ModifyStart?= =?UTF-8?q?=20di=20CurveArc=20-=20a=20PolyArc=20aggiunto=20metodo=20ParamL?= =?UTF-8?q?inearTransform=20-=20aggiunta=20gestione=20riferimento=20di=20g?= =?UTF-8?q?riglia=20(CPlane).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Angle.cpp | 19 +- ArcXxTgArc.cpp | 8 +- CreateCurveAux.cpp | 6 +- CurveArc.cpp | 104 +++---- CurveArc.h | 11 +- CurveAux.cpp | 126 ++++++++- CurveAux.h | 3 + CurveBezier.cpp | 44 ++- CurveBezier.h | 12 +- CurveComposite.cpp | 244 +++++++++++++--- CurveComposite.h | 20 +- CurveCompositeOffset.cpp | 508 ++++++++++++++++++++++++++++++++++ CurveLine.cpp | 21 +- CurveLine.h | 19 +- DistPointArc.cpp | 9 +- DistPointCrvAux.cpp | 5 +- DistPointCrvAux.h | 2 +- DistPointCrvBezier.cpp | 14 +- DistPointCurve.cpp | 94 +++++-- EgtGeomKernel.rc | Bin 11718 -> 11718 bytes EgtGeomKernel.vcxproj | 12 +- EgtGeomKernel.vcxproj.filters | 3 + ExtText.cpp | 3 +- ExtText.h | 29 +- GdbGeo.cpp | 18 +- GeoFrame3d.cpp | 3 +- GeoFrame3d.h | 9 +- GeoPoint3d.cpp | 3 +- GeoPoint3d.h | 9 +- GeoVector3d.cpp | 3 +- GeoVector3d.h | 11 +- GeomDB.cpp | 2 + GeomDB.h | 21 +- IntersCrvCompoCrvCompo.cpp | 51 +--- IntersLineArc.cpp | 4 +- IntersLineLine.cpp | 1 + PointGrid3d.cpp | 1 + PolyArc.cpp | 32 ++- PolyLine.cpp | 4 + SurfTriMesh.cpp | 4 +- SurfTriMesh.h | 6 + 41 files changed, 1227 insertions(+), 271 deletions(-) create mode 100644 CurveCompositeOffset.cpp diff --git a/Angle.cpp b/Angle.cpp index bc2c80a..180a4a6 100644 --- a/Angle.cpp +++ b/Angle.cpp @@ -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) ; + } } diff --git a/ArcXxTgArc.cpp b/ArcXxTgArc.cpp index f63fbbe..0c9b527 100644 --- a/ArcXxTgArc.cpp +++ b/ArcXxTgArc.cpp @@ -210,8 +210,8 @@ GetArcPntDirTgArc( const Point3d& ptP, double dDirStartDeg, const ICurveArc& crv Point3d ptP1 = ptP + vtOrtho * crvArc.GetRadius() ; PtrOwner 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 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) ; diff --git a/CreateCurveAux.cpp b/CreateCurveAux.cpp index e296061..42ddc36 100644 --- a/CreateCurveAux.cpp +++ b/CreateCurveAux.cpp @@ -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 ; diff --git a/CurveArc.cpp b/CurveArc.cpp index 1e51aca..54ef8d1 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -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 diff --git a/CurveArc.h b/CurveArc.h index 6ff18bf..8c13ff1 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -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 } ; //----------------------------------------------------------------------------- diff --git a/CurveAux.cpp b/CurveAux.cpp index fdab918..280a924 100644 --- a/CurveAux.cpp +++ b/CurveAux.cpp @@ -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 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 pCopyCC( GetCurveComposite( pCrv->Clone())) ; + PtrOwner 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 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() ; + } } //---------------------------------------------------------------------------- diff --git a/CurveAux.h b/CurveAux.h index 71f4649..974df6c 100644 --- a/CurveAux.h +++ b/CurveAux.h @@ -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) ; diff --git a/CurveBezier.cpp b/CurveBezier.cpp index 7db932a..9ae69bb 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -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 ; } } diff --git a/CurveBezier.h b/CurveBezier.h index 3b7a095..e8d7314 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -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 } ; //----------------------------------------------------------------------------- diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 7e01726..625909e 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -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( 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 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 ; +} \ No newline at end of file diff --git a/CurveComposite.h b/CurveComposite.h index d955367..4bc4927 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -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 PCRVSMPL_DEQUE ; + typedef std::deque 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 } ; //----------------------------------------------------------------------------- diff --git a/CurveCompositeOffset.cpp b/CurveCompositeOffset.cpp new file mode 100644 index 0000000..ffefa38 --- /dev/null +++ b/CurveCompositeOffset.cpp @@ -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 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 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 pCrvOri1( pCrv1->Clone()) ; + PtrOwner 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 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 pCrv( CreateBasicCurveLine()) ; + if ( IsNull( pCrv) || ! pCrv->Set( ptP1, ptP1a)) + return false ; + if ( ! ccAux.AddCurve( Release( pCrv))) + return false ; + } + // tratto intermedio + { + PtrOwner 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 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 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 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 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 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) ; +} diff --git a/CurveLine.cpp b/CurveLine.cpp index 055077e..523739f 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -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 ; diff --git a/CurveLine.h b/CurveLine.h index eb58611..c3cacea 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -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 } ; //----------------------------------------------------------------------------- diff --git a/DistPointArc.cpp b/DistPointArc.cpp index 00c786d..f4f9443 100644 --- a/DistPointArc.cpp +++ b/DistPointArc.cpp @@ -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 diff --git a/DistPointCrvAux.cpp b/DistPointCrvAux.cpp index adfa3de..45e09c6 100644 --- a/DistPointCrvAux.cpp +++ b/DistPointCrvAux.cpp @@ -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) ; diff --git a/DistPointCrvAux.h b/DistPointCrvAux.h index 33ec500..5abcd4d 100644 --- a/DistPointCrvAux.h +++ b/DistPointCrvAux.h @@ -44,7 +44,7 @@ typedef std::vector 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, diff --git a/DistPointCrvBezier.cpp b/DistPointCrvBezier.cpp index 9970e14..4c47052 100644 --- a/DistPointCrvBezier.cpp +++ b/DistPointCrvBezier.cpp @@ -16,7 +16,9 @@ #include "DistPointCrvBezier.h" #include "DistPointCrvAux.h" #include "GeoConst.h" +#include +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 diff --git a/DistPointCurve.cpp b/DistPointCurve.cpp index 5bd1b2b..618df4a 100644 --- a/DistPointCurve.cpp +++ b/DistPointCurve.cpp @@ -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] ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index debfe979974c4b90bf460e7d23bdc1361d925bde..df59174a14f9835f7ea312d7b85dfa28228877ca 100644 GIT binary patch delta 129 zcmX>WeJpyz7dBQS1|0^&&A0i^Gfl4H(wY20QiVB(!Eo|M0rAZON^y*vCvdwl!xdRG X!zB%bmat$K2Wsk(M$&}UWeJpyz7dBQy1|0^|&A0i^Gfl4H(wY20QiVC2!F2LQ0rAZON^y*vCvdwl!xdRG X!zB%bmat$K2Wsk(M$&}U - + Debug @@ -29,12 +29,14 @@ true Unicode false + v120_xp DynamicLibrary true Unicode false + v120_xp DynamicLibrary @@ -42,6 +44,7 @@ true Unicode false + v120_xp DynamicLibrary @@ -49,6 +52,7 @@ true Unicode false + v120_xp @@ -171,7 +175,7 @@ copy $(TargetPath) \EgtProg\DllD64 AnySuitable true StreamingSIMDExtensions2 - true + false Windows @@ -181,6 +185,7 @@ copy $(TargetPath) \EgtProg\DllD64 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) + false false @@ -209,7 +214,7 @@ copy $(TargetPath) \EgtProg\Dll32 Speed AnySuitable true - StreamingSIMDExtensions2 + NotSet false @@ -245,6 +250,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index 4d31519..69294ec 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -243,6 +243,9 @@ File di origine\GeoCreate + + File di origine\Geo + diff --git a/ExtText.cpp b/ExtText.cpp index 3784336..c4eff93 100644 --- a/ExtText.cpp +++ b/ExtText.cpp @@ -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 ; } diff --git a/ExtText.h b/ExtText.h index 5f8af4f..f719d23 100644 --- a/ExtText.h +++ b/ExtText.h @@ -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 } ; diff --git a/GdbGeo.cpp b/GdbGeo.cpp index 17d1c01..341f0d8 100644 --- a/GdbGeo.cpp +++ b/GdbGeo.cpp @@ -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 ; diff --git a/GeoFrame3d.cpp b/GeoFrame3d.cpp index 21eaec0..66c1f6d 100644 --- a/GeoFrame3d.cpp +++ b/GeoFrame3d.cpp @@ -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) ; } diff --git a/GeoFrame3d.h b/GeoFrame3d.h index 7d54cc8..9f4fb82 100644 --- a/GeoFrame3d.h +++ b/GeoFrame3d.h @@ -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 } ; diff --git a/GeoPoint3d.cpp b/GeoPoint3d.cpp index cf77c64..0aa5381 100644 --- a/GeoPoint3d.cpp +++ b/GeoPoint3d.cpp @@ -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) ; } diff --git a/GeoPoint3d.h b/GeoPoint3d.h index acaa748..a858841 100644 --- a/GeoPoint3d.h +++ b/GeoPoint3d.h @@ -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 } ; diff --git a/GeoVector3d.cpp b/GeoVector3d.cpp index 9eea141..051e699 100644 --- a/GeoVector3d.cpp +++ b/GeoVector3d.cpp @@ -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) ; } diff --git a/GeoVector3d.h b/GeoVector3d.h index d20555d..8337875 100644 --- a/GeoVector3d.h +++ b/GeoVector3d.h @@ -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 } ; diff --git a/GeomDB.cpp b/GeomDB.cpp index 250bd0e..72176be 100644 --- a/GeomDB.cpp +++ b/GeomDB.cpp @@ -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 ; } diff --git a/GeomDB.h b/GeomDB.h index 840396d..de5473a 100644 --- a/GeomDB.h +++ b/GeomDB.h @@ -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 } ; diff --git a/IntersCrvCompoCrvCompo.cpp b/IntersCrvCompoCrvCompo.cpp index 6c0d787..db8d5cc 100644 --- a/IntersCrvCompoCrvCompo.cpp +++ b/IntersCrvCompoCrvCompo.cpp @@ -14,6 +14,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "IntersCrvCompoCrvCompo.h" +#include "CurveAux.h" #include 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 ; - } -} diff --git a/IntersLineArc.cpp b/IntersLineArc.cpp index 527fdd1..649ee9c 100644 --- a/IntersLineArc.cpp +++ b/IntersLineArc.cpp @@ -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() ; diff --git a/IntersLineLine.cpp b/IntersLineLine.cpp index 01890a6..041c7bd 100644 --- a/IntersLineLine.cpp +++ b/IntersLineLine.cpp @@ -14,6 +14,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "IntersLineLine.h" +#include using namespace std ; diff --git a/PointGrid3d.cpp b/PointGrid3d.cpp index c34488f..6b2fd65 100644 --- a/PointGrid3d.cpp +++ b/PointGrid3d.cpp @@ -14,6 +14,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "\EgtDev\Include\EGkPointGrid3d.h" +#include #include using namespace std ; diff --git a/PolyArc.cpp b/PolyArc.cpp index 5c3b8fc..5ac6766 100644 --- a/PolyArc.cpp +++ b/PolyArc.cpp @@ -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) diff --git a/PolyLine.cpp b/PolyLine.cpp index d9d9af0..2974f15 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -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) ; diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index 4a702ba..f5dd02f 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -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 ; } diff --git a/SurfTriMesh.h b/SurfTriMesh.h index f81a6b9..55f755a 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -18,6 +18,7 @@ #include "GeoObjRW.h" #include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EgtNumCollection.h" +#include //---------------------------------------------------------------------------- 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 } ;