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 04a364a..9a3a14b 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
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) ;
+}