From 52b9b411cd857591db3f272c072d27ad8cbc0e2a Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Fri, 20 Mar 2015 08:31:41 +0000 Subject: [PATCH] EgtGeomKernel 1.6c4 : - aggiunti raccordi e smussi di curve - aggiunte a curve funzioni che danno parametro e distanza da inizio di punto di curva. --- CurveArc.cpp | 23 ++++ CurveArc.h | 2 + CurveBezier.cpp | 23 ++++ CurveBezier.h | 2 + CurveComposite.cpp | 27 ++++ CurveComposite.h | 2 + CurveLine.cpp | 22 ++++ CurveLine.h | 2 + EgtGeomKernel.rc | Bin 11710 -> 11710 bytes EgtGeomKernel.vcxproj | 2 + EgtGeomKernel.vcxproj.filters | 6 + FilletChamfer.cpp | 233 ++++++++++++++++++++++++++++++++++ 12 files changed, 344 insertions(+) create mode 100644 FilletChamfer.cpp diff --git a/CurveArc.cpp b/CurveArc.cpp index 0d03474..9a58309 100644 --- a/CurveArc.cpp +++ b/CurveArc.cpp @@ -968,6 +968,29 @@ CurveArc::IsPointOn( const Point3d& ptP, double dTol) const return ( DistPointArc( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; } +//---------------------------------------------------------------------------- +bool +CurveArc::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const +{ + double dSqDist ; + dTol = max( dTol, EPS_ZERO) ; + DistPointArc DPA( ptP, *this) ; + if ( ! DPA.GetSqDist( dSqDist) || dSqDist > dTol * dTol) + return false ; + int nFlag ; + return DPA.GetParamAtMinDistPoint( 0, dPar, nFlag) ; +} + +//---------------------------------------------------------------------------- +bool +CurveArc::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) const +{ + double dU ; + if ( ! GetParamAtPoint( ptP, dU, dTol)) + return false ; + return GetLengthAtParam( dU, dLen) ; +} + //---------------------------------------------------------------------------- bool CurveArc::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const diff --git a/CurveArc.h b/CurveArc.h index 31f8da7..e8ff0eb 100644 --- a/CurveArc.h +++ b/CurveArc.h @@ -94,6 +94,8 @@ class CurveArc : public ICurveArc, public IGeoObjRW { oDiffG.nFlag = CrvPointDiffGeom::STD ; return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; } virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ; + virtual bool GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol = EPS_SMALL) const ; + virtual bool GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol = EPS_SMALL) const ; virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; diff --git a/CurveBezier.cpp b/CurveBezier.cpp index fa1ac2d..763b497 100644 --- a/CurveBezier.cpp +++ b/CurveBezier.cpp @@ -1278,6 +1278,29 @@ CurveBezier::IsPointOn( const Point3d& ptP, double dTol) const return ( DistPointCrvBezier( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; } +//---------------------------------------------------------------------------- +bool +CurveBezier::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const +{ + double dSqDist ; + dTol = max( dTol, EPS_ZERO) ; + DistPointCrvBezier DPB( ptP, *this) ; + if ( ! DPB.GetSqDist( dSqDist) || dSqDist > dTol * dTol) + return false ; + int nFlag ; + return DPB.GetParamAtMinDistPoint( 0, dPar, nFlag) ; +} + +//---------------------------------------------------------------------------- +bool +CurveBezier::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) const +{ + double dU ; + if ( ! GetParamAtPoint( ptP, dU, dTol)) + return false ; + return GetLengthAtParam( dU, dLen) ; +} + //---------------------------------------------------------------------------- bool CurveBezier::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const diff --git a/CurveBezier.h b/CurveBezier.h index 1dd9445..4296114 100644 --- a/CurveBezier.h +++ b/CurveBezier.h @@ -95,6 +95,8 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW { oDiffG.nFlag = CrvPointDiffGeom::STD ; return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; } virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ; + virtual bool GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol = EPS_SMALL) const ; + virtual bool GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol = EPS_SMALL) const ; virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; diff --git a/CurveComposite.cpp b/CurveComposite.cpp index 7268b77..770ad2c 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -1183,6 +1183,29 @@ CurveComposite::IsPointOn( const Point3d& ptP, double dTol) const return ( DistPointCrvComposite( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; } +//---------------------------------------------------------------------------- +bool +CurveComposite::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const +{ + double dSqDist ; + dTol = max( dTol, EPS_ZERO) ; + DistPointCrvComposite DPC( ptP, *this) ; + if ( ! DPC.GetSqDist( dSqDist) || dSqDist > dTol * dTol) + return false ; + int nFlag ; + return DPC.GetParamAtMinDistPoint( 0, dPar, nFlag) ; +} + +//---------------------------------------------------------------------------- +bool +CurveComposite::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) const +{ + double dU ; + if ( ! GetParamAtPoint( ptP, dU, dTol)) + return false ; + return GetLengthAtParam( dU, dLen) ; +} + //---------------------------------------------------------------------------- bool CurveComposite::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const @@ -1322,6 +1345,10 @@ CurveComposite::Invert( void) bool CurveComposite::SimpleOffset( double dDist, int nType) { + // se distanza di offset nulla, non devo fare alcunché + if ( fabs( dDist) < EPS_SMALL) + return true ; + // --- l'offset va effettuato in un piano perpendicolare al vettore estrusione --- // verifico il vettore estrusione diff --git a/CurveComposite.h b/CurveComposite.h index b66bcf5..89f84d6 100644 --- a/CurveComposite.h +++ b/CurveComposite.h @@ -94,6 +94,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW { oDiffG.nFlag = ( IsParamAtJoint( dU) ? CrvPointDiffGeom::TO_VERIFY : CrvPointDiffGeom::STD) ; return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; } virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ; + virtual bool GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol = EPS_SMALL) const ; + virtual bool GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol = EPS_SMALL) const ; virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; diff --git a/CurveLine.cpp b/CurveLine.cpp index 523739f..d32e398 100644 --- a/CurveLine.cpp +++ b/CurveLine.cpp @@ -444,6 +444,28 @@ CurveLine::IsPointOn( const Point3d& ptP, double dTol) const return ( DistPointLine( ptP, *this).GetSqDist( dSqDist) && dSqDist < dTol * dTol) ; } +//---------------------------------------------------------------------------- +bool +CurveLine::GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol) const +{ + double dSqDist ; + dTol = max( dTol, EPS_ZERO) ; + DistPointLine DPL( ptP, *this) ; + if ( ! DPL.GetSqDist( dSqDist) || dSqDist > dTol * dTol) + return false ; + return DPL.GetParamAtMinDistPoint( dPar) ; +} + +//---------------------------------------------------------------------------- +bool +CurveLine::GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol) const +{ + double dU ; + if ( ! GetParamAtPoint( ptP, dU, dTol)) + return false ; + return GetLengthAtParam( dU, dLen) ; +} + //---------------------------------------------------------------------------- bool CurveLine::ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const diff --git a/CurveLine.h b/CurveLine.h index cda0ebc..5083a72 100644 --- a/CurveLine.h +++ b/CurveLine.h @@ -95,6 +95,8 @@ class CurveLine : public ICurveLine, public IGeoObjRW { oDiffG.nFlag = CrvPointDiffGeom::STD ; return ::GetPointDiffGeom( *this, dU, nS, oDiffG) ; } virtual bool IsPointOn( const Point3d& ptP, double dTol = EPS_SMALL) const ; + virtual bool GetParamAtPoint( const Point3d& ptP, double& dPar, double dTol = EPS_SMALL) const ; + virtual bool GetLengthAtPoint( const Point3d& ptP, double& dLen, double dTol = EPS_SMALL) const ; virtual bool ApproxWithLines( double dLinTol, double dAngTolDeg, PolyLine& PL) const ; virtual bool ApproxWithArcs( double dLinTol, double dAngTolDeg, PolyArc& PA) const ; virtual ICurve* CopyParamRange( double dUStart, double dUEnd) const ; diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 04a364a3b58f2d5416ee0f40bc4383de4135ed50..9a3a14b31e70bd0e9fc4943f9476e6e79cd9e395 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&P#&A-_cnHfzcD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-WjGrO delta 94 zcmdlNy)SyhFE&Qw&A-_cnHh~ID{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-W11TR diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj index cf7f12c..89b8e5b 100644 --- a/EgtGeomKernel.vcxproj +++ b/EgtGeomKernel.vcxproj @@ -267,6 +267,7 @@ copy $(TargetPath) \EgtProg\Dll64 + @@ -355,6 +356,7 @@ copy $(TargetPath) \EgtProg\Dll64 + diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters index a03a628..58c4456 100644 --- a/EgtGeomKernel.vcxproj.filters +++ b/EgtGeomKernel.vcxproj.filters @@ -273,6 +273,9 @@ File di origine\GeoCreate + + File di origine\GeoCreate + @@ -629,6 +632,9 @@ File di intestazione\Include + + File di intestazione\Include + diff --git a/FilletChamfer.cpp b/FilletChamfer.cpp new file mode 100644 index 0000000..334b79d --- /dev/null +++ b/FilletChamfer.cpp @@ -0,0 +1,233 @@ +//---------------------------------------------------------------------------- +// EgalTech 2015-2015 +//---------------------------------------------------------------------------- +// File : FilletChamfer.cpp Data : 19.03.15 Versione : 1.6c4 +// Contenuto : Implementazione funzioni per fillet e chamfer. +// +// +// +// Modifiche : 19.03.15 DS Creazione modulo. +// +// +//---------------------------------------------------------------------------- + +//--------------------------- Include ---------------------------------------- +#include "stdafx.h" +#include "CurveArc.h" +#include "CurveLine.h" +#include "/EgtDev/Include/EgkFilletChamfer.h" +#include "/EgtDev/Include/EgkDistPointCurve.h" +#include "/EgtDev/Include/EgkIntersCurveCurve.h" +#include "/EgtDev/Include/EgtPointerOwner.h" + +using namespace std ; + +//---------------------------------------------------------------------------- +ICurveArc* +CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1, + const ICurve& cCrv2, const Point3d& ptNear2, + const Vector3d& vtNorm, double dRadius, double& dPar1, double& dPar2) +{ + // verifico validità parametri ricevuti + if ( &cCrv1 == nullptr || &ptNear1 == nullptr || + &cCrv2 == nullptr || &ptNear2 == nullptr || + &vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr) + return nullptr ; + + // calcolo un riferimento sul piano perpendicolare alla normale + Frame3d frIntr ; + if ( ! frIntr.Set( ORIG, vtNorm)) + return nullptr ; + + // determino il lato di offset della curva 1 + DistPointCurve dPC1( ptNear2, cCrv1) ; + int nSide1 ; + if ( ! dPC1.GetSideAtMinDistPoint( 0, vtNorm, nSide1)) + return nullptr ; + double dOffs1 = ( nSide1 == MDS_RIGHT ? dRadius : - dRadius) ; + // calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 1 + PtrOwner pCopy1( cCrv1.Clone()) ; + if ( IsNull( pCopy1)) + return nullptr ; + pCopy1->ToLoc( frIntr) ; + pCopy1->SetExtrusion( Z_AX) ; + if ( ! pCopy1->SimpleOffset( dOffs1, ICurve::OFF_FILLET)) + return nullptr ; + + // determino il lato di offset della curva 2 + DistPointCurve dPC2( ptNear1, cCrv2) ; + int nSide2 ; + if ( ! dPC2.GetSideAtMinDistPoint( 0, vtNorm, nSide2)) + return nullptr ; + double dOffs2 = ( nSide2 == MDS_RIGHT ? dRadius : - dRadius) ; + // calcolo l'offset nel piano locale e dal lato opportuno di una copia della curva 2 + PtrOwner pCopy2( cCrv2.Clone()) ; + if ( IsNull( pCopy2)) + return nullptr ; + pCopy2->ToLoc( frIntr) ; + pCopy2->SetExtrusion( Z_AX) ; + if ( ! pCopy2->SimpleOffset( dOffs2, ICurve::OFF_FILLET)) + return nullptr ; + + // calcolo l'intersezione tra le due curve + Point3d ptInt1, ptInt2 ; + Point3d ptNear1I = ptNear1 ; + ptNear1I.ToLoc( frIntr) ; + IntersCurveCurve intCC( *Get( pCopy1), *Get( pCopy2)) ; + if ( ! intCC.GetIntersPointNearTo( 0, ptNear1I, ptInt1) || + ! intCC.GetIntersPointNearTo( 1, ptNear1I, ptInt2)) + return nullptr ; + ptInt1.ToGlob( frIntr) ; + ptInt2.ToGlob( frIntr) ; + + // proiezione del punto di intersezione sulla prima curva + DistPointCurve dPCI1( ptInt1, cCrv1) ; + double dTgPar1 ; + int nFlag1 ; + if ( ! dPCI1.GetParamAtMinDistPoint( 0, dTgPar1, nFlag1) || nFlag1 != MDPCI_NORMAL) + return nullptr ; + Point3d ptTg1 ; + Vector3d vtTg1 ; + if ( ! cCrv1.GetPointTang( dTgPar1, ICurve::FROM_MINUS, ptTg1, vtTg1)) + return nullptr ; + + // proiezione del punto di intersezione sulla seconda curva + DistPointCurve dPCI2( ptInt2, cCrv2) ; + double dTgPar2 ; + int nFlag2 ; + if ( ! dPCI2.GetParamAtMinDistPoint( 0, dTgPar2, nFlag2) || nFlag2 != MDPCI_NORMAL) + return nullptr ; + Point3d ptTg2 ; + Vector3d vtTg2 ; + if ( ! cCrv2.GetPointTang( dTgPar2, ICurve::FROM_MINUS, ptTg2, vtTg2)) + return nullptr ; + + // determino rotazione tra le curve + bool bCCW = (( vtTg1 ^ vtTg2) * vtNorm) > 0 ; + + // assegno i valori dei parametri di trim (+ da inizio, - da fine) + if ( bCCW) { + dPar1 = ( nSide2 == MDS_RIGHT ? dTgPar1 : - dTgPar1) ; + dPar2 = ( nSide1 == MDS_RIGHT ? - dTgPar2 : + dTgPar2) ; + } + else { + dPar1 = ( nSide2 == MDS_RIGHT ? - dTgPar1 : dTgPar1) ; + dPar2 = ( nSide1 == MDS_RIGHT ? dTgPar2 : - dTgPar2) ; + } + + // creo l'arco di fillet + PtrOwner crvFillet( CreateBasicCurveArc()) ; + if ( IsNull( crvFillet) || + ! crvFillet->SetC2PN( ptInt1, ptTg1, ptTg2, vtNorm)) + return nullptr ; + return Release(crvFillet) ; +} + +//---------------------------------------------------------------------------- +ICurveLine* +CreateChamfer( const ICurve& cCrv1, const Point3d& ptNear1, + const ICurve& cCrv2, const Point3d& ptNear2, + const Vector3d& vtNorm, double dDist, double& dPar1, double& dPar2) +{ + // verifico validità parametri ricevuti + if ( &cCrv1 == nullptr || &ptNear1 == nullptr || + &cCrv2 == nullptr || &ptNear2 == nullptr || + &vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr) + return nullptr ; + + // calcolo un riferimento sul piano perpendicolare alla normale + Frame3d frIntr ; + if ( ! frIntr.Set( ORIG, vtNorm)) + return nullptr ; + + // determino il lato di offset della curva 1 + DistPointCurve dPC1( ptNear2, cCrv1) ; + int nSide1 ; + if ( ! dPC1.GetSideAtMinDistPoint( 0, vtNorm, nSide1)) + return nullptr ; + // porto la curva1 nel piano locale + PtrOwner pCopy1( cCrv1.Clone()) ; + if ( IsNull( pCopy1)) + return nullptr ; + pCopy1->ToLoc( frIntr) ; + pCopy1->SetExtrusion( Z_AX) ; + + // determino il lato di offset della curva 2 + DistPointCurve dPC2( ptNear1, cCrv2) ; + int nSide2 ; + if ( ! dPC2.GetSideAtMinDistPoint( 0, vtNorm, nSide2)) + return nullptr ; + // porto la curva2 nel piano locale + PtrOwner pCopy2( cCrv2.Clone()) ; + if ( IsNull( pCopy2)) + return nullptr ; + pCopy2->ToLoc( frIntr) ; + pCopy2->SetExtrusion( Z_AX) ; + + // calcolo l'intersezione tra le due curve + Point3d ptInt1, ptInt2 ; + Point3d ptNear1I = ptNear1 ; + ptNear1I.ToLoc( frIntr) ; + IntersCurveCurve intCC( *Get( pCopy1), *Get( pCopy2)) ; + if ( ! intCC.GetIntersPointNearTo( 0, ptNear1I, ptInt1) || + ! intCC.GetIntersPointNearTo( 1, ptNear1I, ptInt2)) + return nullptr ; + ptInt1.ToGlob( frIntr) ; + ptInt2.ToGlob( frIntr) ; + + // determino le posizioni parametriche e le distanze dell'intersezione sulle due curve + double dU1, dDist1 ; + if ( ! cCrv1.GetParamAtPoint( ptInt1, dU1) || ! cCrv1.GetLengthAtParam( dU1, dDist1)) + return nullptr ; + double dU2, dDist2 ; + if ( ! cCrv2.GetParamAtPoint( ptInt2, dU2) || ! cCrv2.GetLengthAtParam( dU2, dDist2)) + return nullptr ; + + // tangenti alle curve nel punto di intersezione + Point3d ptTg1 ; + Vector3d vtTg1 ; + if ( ! cCrv1.GetPointTang( dU1, ICurve::FROM_MINUS, ptTg1, vtTg1)) + return nullptr ; + Point3d ptTg2 ; + Vector3d vtTg2 ; + if ( ! cCrv2.GetPointTang( dU2, ICurve::FROM_MINUS, ptTg2, vtTg2)) + return nullptr ; + + // determino rotazione tra le curve + bool bCCW = (( vtTg1 ^ vtTg2) * vtNorm) > 0 ; + + // assegno i valori delle distanze degli estremi dello smusso + if ( bCCW) { + dDist1 += ( nSide2 == MDS_RIGHT ? dDist : - dDist) ; + dDist2 += ( nSide1 == MDS_RIGHT ? - dDist : + dDist) ; + } + else { + dDist1 += ( nSide2 == MDS_RIGHT ? - dDist : dDist) ; + dDist2 += ( nSide1 == MDS_RIGHT ? dDist : - dDist) ; + } + // li converto in posizioni parametriche + if ( ! cCrv1.GetParamAtLength( dDist1, dU1) || + ! cCrv2.GetParamAtLength( dDist2, dU2)) + return nullptr ; + + // assegno i valori dei parametri di trim (+ da inizio, - da fine) + if ( bCCW) { + dPar1 = ( nSide2 == MDS_RIGHT ? dU1 : - dU1) ; + dPar2 = ( nSide1 == MDS_RIGHT ? - dU2 : + dU2) ; + } + else { + dPar1 = ( nSide2 == MDS_RIGHT ? - dU1 : dU1) ; + dPar2 = ( nSide1 == MDS_RIGHT ? dU2 : - dU2) ; + } + + // calcolo la linea di smusso + Point3d ptP1, ptP2 ; + if ( ! cCrv1.GetPointD1D2( dU1, ICurve::FROM_MINUS, ptP1) || + ! cCrv2.GetPointD1D2( dU2, ICurve::FROM_MINUS, ptP2)) + return nullptr ; + PtrOwner crvChamfer( CreateBasicCurveLine()) ; + if ( IsNull( crvChamfer) || + ! crvChamfer->Set( ptP1, ptP2)) + return nullptr ; + return Release(crvChamfer) ; +}