From 47036161c8ef2de0bb35db8f64e8934d43b77b6b Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Wed, 14 Mar 2018 11:00:18 +0000 Subject: [PATCH] EgtMachKernel 1.9c3 : - tagli di lama ora possono operare su facce di trimesh - migliorato recupero contorni da facce. --- Chiseling.cpp | 25 +---- Chiseling.h | 1 - EgtMachKernel.rc | Bin 11774 -> 11774 bytes Milling.cpp | 181 ++----------------------------- Milling.h | 1 - Mortising.cpp | 181 ++----------------------------- Mortising.h | 1 - Operation.cpp | 156 +++++++++++++++++++++++++++ Operation.h | 7 ++ Pocketing.cpp | 28 +---- Pocketing.h | 1 - Sawing.cpp | 269 +++++++++++++++++++++++++++++------------------ Sawing.h | 4 +- 13 files changed, 359 insertions(+), 496 deletions(-) diff --git a/Chiseling.cpp b/Chiseling.cpp index 03ad9da..51f7205 100644 --- a/Chiseling.cpp +++ b/Chiseling.cpp @@ -831,10 +831,12 @@ Chiseling::GetCurve( SelData Id) return nullptr ; // assegno l'estrusione dalla normale alla faccia pCrvCompo->SetExtrusion( vtN) ; + // unisco le eventuali parti allineate + pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; // la porto in globale pCrvCompo->ToGlob( frGlob) ; // sistemazioni varie - AdjustCurveFromSurf( pCrvCompo) ; + AdjustCurveFromSurf( pCrvCompo, TOOL_ORTHO, FACE_CONT, 0) ; // la restituisco return Release( pCrvCompo) ; } @@ -843,27 +845,6 @@ Chiseling::GetCurve( SelData Id) return nullptr ; } -//---------------------------------------------------------------------------- -bool -Chiseling::AdjustCurveFromSurf( ICurveComposite* pCrvCompo) -{ - // cerco l'estremo più alto del contorno e lo imposto come inizio - double dU = 0 ; - double dUmax = 0 ; - double dZmax = - INFINITO ; - Point3d ptP ; - while ( pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) { - if ( ptP.z > dZmax + EPS_SMALL) { - dZmax = ptP.z ; - dUmax = dU ; - } - dU += 1 ; - } - if ( dU != 0) - pCrvCompo->ChangeStartPoint( dUmax) ; - return true ; -} - //---------------------------------------------------------------------------- bool Chiseling::Chain( int nGrpDestId) diff --git a/Chiseling.h b/Chiseling.h index b91aee9..0e71de9 100644 --- a/Chiseling.h +++ b/Chiseling.h @@ -68,7 +68,6 @@ class Chiseling : public Machining bool UpdateToolData( void) ; bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; ICurve* GetCurve( SelData Id) ; - bool AdjustCurveFromSurf( ICurveComposite* pCrvCompo) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) ; diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index b16ce8d5c9fe6a4384ed6bdc847aebfa2cc25cf4..ec5f87f7a6ba9ef609269960690164e217c64c90 100644 GIT binary patch delta 97 zcmewt{V#gMFE&Qw&A-`fnHh~IKa|wnoW?bQ1uSxrY4Qod0+^@}R1`^_2jk{d(jGv4 NK<#LXK~l;gTmUD-Bai?9 delta 97 zcmewt{V#gMFE&P_&A-`fnHh~HKa|wnoW?bQ1uSxrY4Qod0+^@}R1`^_2jk{d(jGv4 NK<#LXK~l;gTmU8!BZvS1 diff --git a/Milling.cpp b/Milling.cpp index 98f53f7..ffefb6e 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -953,10 +953,20 @@ Milling::GetCurve( SelData Id) return nullptr ; // assegno l'estrusione dalla normale alla faccia pCrvCompo->SetExtrusion( vtN) ; + // unisco le eventuali parti allineate + pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; // la porto in globale pCrvCompo->ToGlob( frGlob) ; // sistemazioni varie - AdjustCurveFromSurf( pCrvCompo) ; + int nToolDir ; + if ( ( m_Params.m_nFaceUse & 64) != 0) + nToolDir = TOOL_ORTUP ; + else if ( ( m_Params.m_nFaceUse & 32) != 0) + nToolDir = TOOL_ORTHO ; + else + nToolDir = TOOL_PARAL ; + int nFaceUse = ( m_Params.m_nFaceUse & 31) ; + AdjustCurveFromSurf( pCrvCompo, nToolDir, nFaceUse, m_TParams.m_dThick) ; // la restituisco return Release( pCrvCompo) ; } @@ -965,175 +975,6 @@ Milling::GetCurve( SelData Id) return nullptr ; } -//---------------------------------------------------------------------------- -bool -Milling::AdjustCurveFromSurf( ICurveComposite* pCrvCompo) -{ - // tipo posizione utensile - enum { TOOL_PARAL = 1, TOOL_ORTHO = 2, TOOL_ORTUP = 3} ; - int nToolDir ; - if ( ( m_Params.m_nFaceUse & 64) != 0) - nToolDir = TOOL_ORTUP ; - else if ( ( m_Params.m_nFaceUse & 32) != 0) - nToolDir = TOOL_ORTHO ; - else - nToolDir = TOOL_PARAL ; - // tipo di utilizzo contorno faccia - enum { FACE_DOWN = 1, FACE_TOP = 2, FACE_FRONT = 3, FACE_BACK = 4, FACE_LEFT = 5, FACE_RIGHT = 6, FACE_CONT = 7} ; - int nFace = ( m_Params.m_nFaceUse & 31) ; - - // copia della curva originale - PtrOwner pCopy( pCrvCompo->Clone()) ; - - // se richiesto contorno - if ( nFace == FACE_CONT) { - // cerco l'estremo più alto e lo imposto come inizio - double dU = 0 ; - double dUmax = 0 ; - double dZmax = - INFINITO ; - Point3d ptP ; - while ( pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) { - if ( ptP.z > dZmax + EPS_SMALL) { - dZmax = ptP.z ; - dUmax = dU ; - } - dU += 1 ; - } - if ( dU != 0) - pCrvCompo->ChangeStartPoint( dUmax) ; - } - // altrimenti - else { - // ingombro - BBox3d b3Box ; - pCrvCompo->GetLocalBBox( b3Box) ; - double dMin = b3Box.GetMin().z ; - double dMax = b3Box.GetMax().z ; - if ( nFace == FACE_FRONT || nFace == FACE_BACK) { - dMin = b3Box.GetMin().y ; - dMax = b3Box.GetMax().y ; - } - else if ( nFace == FACE_RIGHT || nFace == FACE_LEFT) { - dMin = b3Box.GetMin().x ; - dMax = b3Box.GetMax().x ; - } - double dTol = min( ( dMax - dMin) / 4., 20.) ; - // cerco il punto medio delle curve più vicino all'estremo desiderato - double dRef = dMin ; - if ( nFace == FACE_DOWN || nFace == FACE_FRONT || nFace == FACE_LEFT) - dRef = dMax ; - const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; - while ( pCrv != nullptr) { - Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; - switch ( nFace) { - case FACE_DOWN : dRef = min( dRef, ptMid.z) ; break ; - case FACE_TOP : dRef = max( dRef, ptMid.z) ; break ; - case FACE_FRONT : dRef = min( dRef, ptMid.y) ; break ; - case FACE_BACK : dRef = max( dRef, ptMid.y) ; break ; - case FACE_LEFT : dRef = min( dRef, ptMid.x) ; break ; - case FACE_RIGHT : dRef = max( dRef, ptMid.x) ; break ; - } - pCrv = pCrvCompo->GetNextCurve() ; - } - // elimino le linee troppo discoste dal riferimento dall'inizio e poi dalla fine - pCrv = pCrvCompo->GetFirstCurve() ; - while ( pCrv != nullptr) { - Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; - if ( ( nFace == FACE_DOWN && ptMid.z > dRef + dTol) || - ( nFace == FACE_TOP && ptMid.z < dRef - dTol) || - ( nFace == FACE_FRONT && ptMid.y > dRef + dTol) || - ( nFace == FACE_BACK && ptMid.y < dRef - dTol) || - ( nFace == FACE_LEFT && ptMid.x > dRef + dTol) || - ( nFace == FACE_RIGHT && ptMid.x < dRef - dTol)) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ; - delete( pErase) ; - pCrv = pCrvCompo->GetFirstCurve() ; - } - else - break ; - } - pCrv = pCrvCompo->GetLastCurve() ; - while ( pCrv != nullptr) { - Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; - if ( ( nFace == FACE_DOWN && ptMid.z > dRef + dTol) || - ( nFace == FACE_TOP && ptMid.z < dRef - dTol) || - ( nFace == FACE_FRONT && ptMid.y > dRef + dTol) || - ( nFace == FACE_BACK && ptMid.y < dRef - dTol) || - ( nFace == FACE_LEFT && ptMid.x > dRef + dTol) || - ( nFace == FACE_RIGHT && ptMid.x < dRef - dTol)) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ; - delete( pErase) ; - pCrv = pCrvCompo->GetLastCurve() ; - } - else - break ; - } - } - // determino il versore estrusione (utensile) - if ( nToolDir == TOOL_ORTHO) - pCrvCompo->SetThickness( 0) ; - else if ( nToolDir == TOOL_ORTUP) { - Vector3d vtN ; - pCrvCompo->GetExtrusion( vtN) ; - if ( vtN.z < - sin( 2 * DEGTORAD)) { - // pCrvCompo->Invert() ; - pCrvCompo->Translate( vtN * m_TParams.m_dThick) ; - pCrvCompo->SetExtrusion( - vtN) ; - } - pCrvCompo->SetThickness( 0) ; - } - else { // nToolDir == TOOL_PARAL - // sistemo versore - Vector3d vtN ; - pCrvCompo->GetExtrusion( vtN) ; - Point3d ptStart, ptEnd ; - pCrvCompo->GetStartPoint( ptStart) ; - pCrvCompo->GetEndPoint( ptEnd) ; - Vector3d vtT = ptEnd - ptStart ; - Vector3d vtExtr = vtN ^ vtT ; - if ( ! vtExtr.Normalize()) - return false ; - pCrvCompo->SetExtrusion( vtExtr) ; - // elimino eventuali parti iniziali e/o finali dirette circa come il versore - const double MAX_ALL_COS = cos( 25 * DEGTORAD) ; - const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; - while ( pCrv != nullptr) { - Vector3d vtDir ; pCrv->GetStartDir( vtDir) ; - if ( abs( vtDir * vtExtr) > MAX_ALL_COS) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ; - delete( pErase) ; - pCrv = pCrvCompo->GetFirstCurve() ; - } - else if ( pCrvCompo->IsClosed()) { - pCrvCompo->ChangeStartPoint( 1) ; - pCrv = pCrvCompo->GetFirstCurve() ; - } - else - break ; - } - pCrv = pCrvCompo->GetLastCurve() ; - while ( pCrv != nullptr) { - Vector3d vtDir ; pCrv->GetStartDir( vtDir) ; - if ( abs( vtDir * vtExtr) > MAX_ALL_COS) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ; - delete( pErase) ; - pCrv = pCrvCompo->GetLastCurve() ; - } - else - break ; - } - // determino lo spessore misurato lungo la direzione - if ( ! IsNull( pCopy)) { - Frame3d frOcs ; frOcs.Set( ORIG, vtExtr) ; - Frame3d frExtr ; frExtr.ToLoc( frOcs) ; - BBox3d b3Extr ; pCopy->GetBBox( frExtr, b3Extr) ; - if ( ! b3Extr.IsEmpty()) - pCrvCompo->SetThickness( b3Extr.GetMax().z - b3Extr.GetMin().z) ; - } - } - return true ; -} - //---------------------------------------------------------------------------- bool Milling::Chain( int nGrpDestId) diff --git a/Milling.h b/Milling.h index 1a26e2d..7491c2f 100644 --- a/Milling.h +++ b/Milling.h @@ -67,7 +67,6 @@ class Milling : public Machining bool UpdateToolData( bool* pbChanged = nullptr) ; bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; ICurve* GetCurve( SelData Id) ; - bool AdjustCurveFromSurf( ICurveComposite* pCrvCompo) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) ; diff --git a/Mortising.cpp b/Mortising.cpp index d9755ce..7b03585 100644 --- a/Mortising.cpp +++ b/Mortising.cpp @@ -844,10 +844,20 @@ Mortising::GetCurve( SelData Id) return nullptr ; // assegno l'estrusione dalla normale alla faccia pCrvCompo->SetExtrusion( vtN) ; + // unisco le eventuali parti allineate + pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; // la porto in globale pCrvCompo->ToGlob( frGlob) ; // sistemazioni varie - AdjustCurveFromSurf( pCrvCompo) ; + int nToolDir ; + if ( ( m_Params.m_nFaceUse & 64) != 0) + nToolDir = TOOL_ORTUP ; + else if ( ( m_Params.m_nFaceUse & 32) != 0) + nToolDir = TOOL_ORTHO ; + else + nToolDir = TOOL_PARAL ; + int nFaceUse = ( m_Params.m_nFaceUse & 31) ; + AdjustCurveFromSurf( pCrvCompo, nToolDir, nFaceUse, m_TParams.m_dThick) ; // la restituisco return Release( pCrvCompo) ; } @@ -856,175 +866,6 @@ Mortising::GetCurve( SelData Id) return nullptr ; } -//---------------------------------------------------------------------------- -bool -Mortising::AdjustCurveFromSurf( ICurveComposite* pCrvCompo) -{ - // tipo posizione utensile - enum { TOOL_PARAL = 1, TOOL_ORTHO = 2, TOOL_ORTUP = 3} ; - int nToolDir ; - if ( ( m_Params.m_nFaceUse & 64) != 0) - nToolDir = TOOL_ORTUP ; - else if ( ( m_Params.m_nFaceUse & 32) != 0) - nToolDir = TOOL_ORTHO ; - else - nToolDir = TOOL_PARAL ; - // tipo di utilizzo contorno faccia - enum { FACE_DOWN = 1, FACE_TOP = 2, FACE_FRONT = 3, FACE_BACK = 4, FACE_LEFT = 5, FACE_RIGHT = 6, FACE_CONT = 7} ; - int nFace = ( m_Params.m_nFaceUse & 31) ; - - // copia della curva originale - PtrOwner pCopy( pCrvCompo->Clone()) ; - - // se richiesto contorno - if ( nFace == FACE_CONT) { - // cerco l'estremo più alto e lo imposto come inizio - double dU = 0 ; - double dUmax = 0 ; - double dZmax = - INFINITO ; - Point3d ptP ; - while ( pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) { - if ( ptP.z > dZmax + EPS_SMALL) { - dZmax = ptP.z ; - dUmax = dU ; - } - dU += 1 ; - } - if ( dU != 0) - pCrvCompo->ChangeStartPoint( dUmax) ; - } - // altrimenti - else { - // ingombro - BBox3d b3Box ; - pCrvCompo->GetLocalBBox( b3Box) ; - double dMin = b3Box.GetMin().z ; - double dMax = b3Box.GetMax().z ; - if ( nFace == FACE_FRONT || nFace == FACE_BACK) { - dMin = b3Box.GetMin().y ; - dMax = b3Box.GetMax().y ; - } - else if ( nFace == FACE_RIGHT || nFace == FACE_LEFT) { - dMin = b3Box.GetMin().x ; - dMax = b3Box.GetMax().x ; - } - double dTol = min( ( dMax - dMin) / 4., 20.) ; - // cerco il punto medio delle curve più vicino all'estremo desiderato - double dRef = dMin ; - if ( nFace == FACE_DOWN || nFace == FACE_FRONT || nFace == FACE_LEFT) - dRef = dMax ; - const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; - while ( pCrv != nullptr) { - Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; - switch ( nFace) { - case FACE_DOWN : dRef = min( dRef, ptMid.z) ; break ; - case FACE_TOP : dRef = max( dRef, ptMid.z) ; break ; - case FACE_FRONT : dRef = min( dRef, ptMid.y) ; break ; - case FACE_BACK : dRef = max( dRef, ptMid.y) ; break ; - case FACE_LEFT : dRef = min( dRef, ptMid.x) ; break ; - case FACE_RIGHT : dRef = max( dRef, ptMid.x) ; break ; - } - pCrv = pCrvCompo->GetNextCurve() ; - } - // elimino le linee troppo discoste dal riferimento dall'inizio e poi dalla fine - pCrv = pCrvCompo->GetFirstCurve() ; - while ( pCrv != nullptr) { - Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; - if ( ( nFace == FACE_DOWN && ptMid.z > dRef + dTol) || - ( nFace == FACE_TOP && ptMid.z < dRef - dTol) || - ( nFace == FACE_FRONT && ptMid.y > dRef + dTol) || - ( nFace == FACE_BACK && ptMid.y < dRef - dTol) || - ( nFace == FACE_LEFT && ptMid.x > dRef + dTol) || - ( nFace == FACE_RIGHT && ptMid.x < dRef - dTol)) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ; - delete( pErase) ; - pCrv = pCrvCompo->GetFirstCurve() ; - } - else - break ; - } - pCrv = pCrvCompo->GetLastCurve() ; - while ( pCrv != nullptr) { - Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; - if ( ( nFace == FACE_DOWN && ptMid.z > dRef + dTol) || - ( nFace == FACE_TOP && ptMid.z < dRef - dTol) || - ( nFace == FACE_FRONT && ptMid.y > dRef + dTol) || - ( nFace == FACE_BACK && ptMid.y < dRef - dTol) || - ( nFace == FACE_LEFT && ptMid.x > dRef + dTol) || - ( nFace == FACE_RIGHT && ptMid.x < dRef - dTol)) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ; - delete( pErase) ; - pCrv = pCrvCompo->GetLastCurve() ; - } - else - break ; - } - } - // determino il versore estrusione (utensile) - if ( nToolDir == TOOL_ORTHO) - pCrvCompo->SetThickness( 0) ; - else if ( nToolDir == TOOL_ORTUP) { - Vector3d vtN ; - pCrvCompo->GetExtrusion( vtN) ; - if ( vtN.z < - sin( 2 * DEGTORAD)) { - // pCrvCompo->Invert() ; - pCrvCompo->Translate( vtN * m_TParams.m_dThick) ; - pCrvCompo->SetExtrusion( - vtN) ; - } - pCrvCompo->SetThickness( 0) ; - } - else { // nToolDir == TOOL_PARAL - // sistemo versore - Vector3d vtN ; - pCrvCompo->GetExtrusion( vtN) ; - Point3d ptStart, ptEnd ; - pCrvCompo->GetStartPoint( ptStart) ; - pCrvCompo->GetEndPoint( ptEnd) ; - Vector3d vtT = ptEnd - ptStart ; - Vector3d vtExtr = vtN ^ vtT ; - if ( ! vtExtr.Normalize()) - return false ; - pCrvCompo->SetExtrusion( vtExtr) ; - // elimino eventuali parti iniziali e/o finali dirette circa come il versore - const double MAX_ALL_COS = cos( 25 * DEGTORAD) ; - const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; - while ( pCrv != nullptr) { - Vector3d vtDir ; pCrv->GetStartDir( vtDir) ; - if ( abs( vtDir * vtExtr) > MAX_ALL_COS) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ; - delete( pErase) ; - pCrv = pCrvCompo->GetFirstCurve() ; - } - else if ( pCrvCompo->IsClosed()) { - pCrvCompo->ChangeStartPoint( 1) ; - pCrv = pCrvCompo->GetFirstCurve() ; - } - else - break ; - } - pCrv = pCrvCompo->GetLastCurve() ; - while ( pCrv != nullptr) { - Vector3d vtDir ; pCrv->GetStartDir( vtDir) ; - if ( abs( vtDir * vtExtr) > MAX_ALL_COS) { - ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ; - delete( pErase) ; - pCrv = pCrvCompo->GetLastCurve() ; - } - else - break ; - } - // determino lo spessore misurato lungo la direzione - if ( ! IsNull( pCopy)) { - Frame3d frOcs ; frOcs.Set( ORIG, vtExtr) ; - Frame3d frExtr ; frExtr.ToLoc( frOcs) ; - BBox3d b3Extr ; pCopy->GetBBox( frExtr, b3Extr) ; - if ( ! b3Extr.IsEmpty()) - pCrvCompo->SetThickness( b3Extr.GetMax().z - b3Extr.GetMin().z) ; - } - } - return true ; -} - //---------------------------------------------------------------------------- bool Mortising::Chain( int nGrpDestId) diff --git a/Mortising.h b/Mortising.h index 512d25e..dd217f1 100644 --- a/Mortising.h +++ b/Mortising.h @@ -68,7 +68,6 @@ class Mortising : public Machining bool UpdateToolData( void) ; bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; ICurve* GetCurve( SelData Id) ; - bool AdjustCurveFromSurf( ICurveComposite* pCrvCompo) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) ; diff --git a/Operation.cpp b/Operation.cpp index 94d6462..62e8617 100644 --- a/Operation.cpp +++ b/Operation.cpp @@ -469,6 +469,162 @@ Operation::GetRawGlobBox( int nPhase, const BBox3d& b3Test, double dToler, BBox3 } //---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +bool +Operation::AdjustCurveFromSurf( ICurveComposite* pCrvCompo, int nToolDir, int nFaceUse, double dToolThick) +{ + // copia della curva originale + PtrOwner pCopy( pCrvCompo->Clone()) ; + + // se richiesto contorno + if ( nFaceUse == FACE_CONT) { + // cerco l'estremo più alto e lo imposto come inizio + double dU = 0 ; + double dUmax = 0 ; + double dZmax = - INFINITO ; + Point3d ptP ; + while ( pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) { + if ( ptP.z > dZmax + EPS_SMALL) { + dZmax = ptP.z ; + dUmax = dU ; + } + dU += 1 ; + } + if ( dU != 0) + pCrvCompo->ChangeStartPoint( dUmax) ; + } + // altrimenti + else { + // ingombro + BBox3d b3Box ; + pCrvCompo->GetLocalBBox( b3Box) ; + double dMin = b3Box.GetMin().z ; + double dMax = b3Box.GetMax().z ; + if ( nFaceUse == FACE_FRONT || nFaceUse == FACE_BACK) { + dMin = b3Box.GetMin().y ; + dMax = b3Box.GetMax().y ; + } + else if ( nFaceUse == FACE_RIGHT || nFaceUse == FACE_LEFT) { + dMin = b3Box.GetMin().x ; + dMax = b3Box.GetMax().x ; + } + double dTol = min( ( dMax - dMin) / 4., 20.) ; + // cerco il punto medio delle curve più vicino all'estremo desiderato + double dRef = dMin ; + if ( nFaceUse == FACE_DOWN || nFaceUse == FACE_FRONT || nFaceUse == FACE_LEFT) + dRef = dMax ; + const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; + switch ( nFaceUse) { + case FACE_DOWN : dRef = min( dRef, ptMid.z) ; break ; + case FACE_TOP : dRef = max( dRef, ptMid.z) ; break ; + case FACE_FRONT : dRef = min( dRef, ptMid.y) ; break ; + case FACE_BACK : dRef = max( dRef, ptMid.y) ; break ; + case FACE_LEFT : dRef = min( dRef, ptMid.x) ; break ; + case FACE_RIGHT : dRef = max( dRef, ptMid.x) ; break ; + } + pCrv = pCrvCompo->GetNextCurve() ; + } + // elimino le linee troppo discoste dal riferimento dall'inizio e poi dalla fine + pCrv = pCrvCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; + if ( ( nFaceUse == FACE_DOWN && ptMid.z > dRef + dTol) || + ( nFaceUse == FACE_TOP && ptMid.z < dRef - dTol) || + ( nFaceUse == FACE_FRONT && ptMid.y > dRef + dTol) || + ( nFaceUse == FACE_BACK && ptMid.y < dRef - dTol) || + ( nFaceUse == FACE_LEFT && ptMid.x > dRef + dTol) || + ( nFaceUse == FACE_RIGHT && ptMid.x < dRef - dTol)) { + ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ; + delete( pErase) ; + pCrv = pCrvCompo->GetFirstCurve() ; + } + else + break ; + } + pCrv = pCrvCompo->GetLastCurve() ; + while ( pCrv != nullptr) { + Point3d ptMid ; pCrv->GetMidPoint( ptMid) ; + if ( ( nFaceUse == FACE_DOWN && ptMid.z > dRef + dTol) || + ( nFaceUse == FACE_TOP && ptMid.z < dRef - dTol) || + ( nFaceUse == FACE_FRONT && ptMid.y > dRef + dTol) || + ( nFaceUse == FACE_BACK && ptMid.y < dRef - dTol) || + ( nFaceUse == FACE_LEFT && ptMid.x > dRef + dTol) || + ( nFaceUse == FACE_RIGHT && ptMid.x < dRef - dTol)) { + ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ; + delete( pErase) ; + pCrv = pCrvCompo->GetLastCurve() ; + } + else + break ; + } + } + // determino il versore estrusione (utensile) + if ( nToolDir == TOOL_ORTHO) + pCrvCompo->SetThickness( 0) ; + else if ( nToolDir == TOOL_ORTUP) { + Vector3d vtN ; + pCrvCompo->GetExtrusion( vtN) ; + if ( vtN.z < - sin( 2 * DEGTORAD)) { + // pCrvCompo->Invert() ; + pCrvCompo->Translate( vtN * dToolThick) ; + pCrvCompo->SetExtrusion( - vtN) ; + } + pCrvCompo->SetThickness( 0) ; + } + else { // nToolDir == TOOL_PARAL + // sistemo versore + Vector3d vtN ; + pCrvCompo->GetExtrusion( vtN) ; + Point3d ptStart, ptEnd ; + pCrvCompo->GetStartPoint( ptStart) ; + pCrvCompo->GetEndPoint( ptEnd) ; + Vector3d vtT = ptEnd - ptStart ; + Vector3d vtExtr = vtN ^ vtT ; + if ( ! vtExtr.Normalize()) + return false ; + pCrvCompo->SetExtrusion( vtExtr) ; + // elimino eventuali parti iniziali e/o finali dirette circa come il versore + const double MAX_ALL_COS = cos( 25 * DEGTORAD) ; + const ICurve* pCrv = pCrvCompo->GetFirstCurve() ; + while ( pCrv != nullptr) { + Vector3d vtDir ; pCrv->GetStartDir( vtDir) ; + if ( abs( vtDir * vtExtr) > MAX_ALL_COS) { + ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ; + delete( pErase) ; + pCrv = pCrvCompo->GetFirstCurve() ; + } + else if ( pCrvCompo->IsClosed()) { + pCrvCompo->ChangeStartPoint( 1) ; + pCrv = pCrvCompo->GetFirstCurve() ; + } + else + break ; + } + pCrv = pCrvCompo->GetLastCurve() ; + while ( pCrv != nullptr) { + Vector3d vtDir ; pCrv->GetStartDir( vtDir) ; + if ( abs( vtDir * vtExtr) > MAX_ALL_COS) { + ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ; + delete( pErase) ; + pCrv = pCrvCompo->GetLastCurve() ; + } + else + break ; + } + // determino lo spessore misurato lungo la direzione + if ( ! IsNull( pCopy)) { + Frame3d frOcs ; frOcs.Set( ORIG, vtExtr) ; + Frame3d frExtr ; frExtr.ToLoc( frOcs) ; + BBox3d b3Extr ; pCopy->GetBBox( frExtr, b3Extr) ; + if ( ! b3Extr.IsEmpty()) + pCrvCompo->SetThickness( b3Extr.GetMax().z - b3Extr.GetMin().z) ; + } + } + return true ; +} + //---------------------------------------------------------------------------- bool Operation::ApproxWithArcsIfUseful( ICurveComposite* pCompo) diff --git a/Operation.h b/Operation.h index 80fc20c..643bd36 100644 --- a/Operation.h +++ b/Operation.h @@ -73,6 +73,7 @@ class Operation : public IUserObj bool GetRawGlobBox( int nPhase, int nPathId, double dToler, BBox3d& b3Raw) ; bool GetRawGlobBox( int nPhase, const BBox3d& b3Test, double dToler, BBox3d& b3Raw) ; + bool AdjustCurveFromSurf( ICurveComposite* pCrvCompo, int nToolDir, int nFaceUse, double dToolThick) ; bool ApproxWithArcsIfUseful( ICurveComposite* pCompo) ; bool ApproxWithLines( ICurveComposite* pCompo) ; bool VerifyArcs( ICurveComposite* pCompo, double dMaxAngCen = MAX_ANG_CEN) ; @@ -143,3 +144,9 @@ inline const Operation* GetOperation( const IUserObj* pUserObj) { return dynamic_cast( pUserObj) ; } inline Operation* GetOperation( IUserObj* pUserObj) { return dynamic_cast< Operation*>( pUserObj) ; } + +//---------------------------------------------------------------------------- +// tipo posizione utensile +enum { TOOL_PARAL = 1, TOOL_ORTHO = 2, TOOL_ORTUP = 3} ; +// tipo di utilizzo contorno faccia +enum { FACE_DOWN = 1, FACE_TOP = 2, FACE_FRONT = 3, FACE_BACK = 4, FACE_LEFT = 5, FACE_RIGHT = 6, FACE_CONT = 7} ; diff --git a/Pocketing.cpp b/Pocketing.cpp index 7cdf812..d314e57 100644 --- a/Pocketing.cpp +++ b/Pocketing.cpp @@ -891,10 +891,12 @@ Pocketing::GetCurve( SelData Id) return nullptr ; // assegno l'estrusione dalla normale alla faccia pCrvCompo->SetExtrusion( vtN) ; + // unisco le eventuali parti allineate + pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; // la porto in globale pCrvCompo->ToGlob( frGlob) ; // sistemazioni varie - AdjustCurveFromSurf( pCrvCompo) ; + AdjustCurveFromSurf( pCrvCompo, TOOL_ORTHO, FACE_CONT, 0) ; // la restituisco return Release( pCrvCompo) ; } @@ -903,30 +905,6 @@ Pocketing::GetCurve( SelData Id) return nullptr ; } -//---------------------------------------------------------------------------- -bool -Pocketing::AdjustCurveFromSurf( ICurveComposite* pCrvCompo) -{ - // con utensile fresa fa il contorno - if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) { - // cerco l'estremo più alto e lo imposto come inizio - double dU = 0 ; - double dUmax = 0 ; - double dZmax = - INFINITO ; - Point3d ptP ; - while ( pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) { - if ( ptP.z > dZmax + EPS_SMALL) { - dZmax = ptP.z ; - dUmax = dU ; - } - dU += 1 ; - } - if ( dU != 0) - pCrvCompo->ChangeStartPoint( dUmax) ; - } - return true ; -} - //---------------------------------------------------------------------------- bool Pocketing::Chain( int nGrpDestId) diff --git a/Pocketing.h b/Pocketing.h index 4cc0cb9..dc2bc21 100644 --- a/Pocketing.h +++ b/Pocketing.h @@ -68,7 +68,6 @@ class Pocketing : public Machining bool UpdateToolData( void) ; bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; ICurve* GetCurve( SelData Id) ; - bool AdjustCurveFromSurf( ICurveComposite* pCrvCompo) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) ; diff --git a/Sawing.cpp b/Sawing.cpp index 0d369d3..2098e8f 100644 --- a/Sawing.cpp +++ b/Sawing.cpp @@ -25,6 +25,7 @@ #include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkSfrCreate.h" +#include "/EgtDev/Include/EGkSurfTriMesh.h" #include "/EgtDev/Include/EGkUserObjFactory.h" #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -402,23 +403,19 @@ Sawing::SetGeometry( const SELVECTOR& vIds) // reset della geometria corrente m_vId.clear() ; // verifico che gli identificativi rappresentino delle entità ammissibili + int nType = GEO_NONE ; for ( const auto& Id : vIds) { // test sull'entità int nSubs ; - if ( ! VerifyGeometry( Id, nSubs)) { + if ( ! VerifyGeometry( Id, nSubs, nType)) { string sOut = "Warning in Sawing : Skipped entity " + ToString( Id) ; LOG_INFO( GetEMkLogger(), sOut.c_str()) ; continue ; } // posso aggiungere alla lista - if ( nSubs == 0) - m_vId.emplace_back( Id) ; - else { - for ( int i = 0 ; i < nSubs ; ++ i) - m_vId.emplace_back( Id.nId, i) ; - } + m_vId.emplace_back( Id) ; } - return ( ! m_vId.empty()) ; + return ( ! m_vId.empty() || vIds.empty()) ; } //---------------------------------------------------------------------------- @@ -811,31 +808,58 @@ Sawing::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) const //---------------------------------------------------------------------------- bool -Sawing::VerifyGeometry( SelData Id, int& nSubs) +Sawing::VerifyGeometry( SelData Id, int& nSubs, int& nType) { - // ammessi : curve o facce di polymesh - - // per ora accetto solo curve - const ICurve* pCurve = nullptr ; + // ammessi : tutte curve o tutte facce di trimesh const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; - // se direttamente la curva - if ( Id.nSub == SEL_SUB_ALL) { - pCurve = ::GetCurve( m_pGeomDB->GetGeoObj( Id.nId)) ; - if ( pCurve != nullptr) { - if ( pCurve->GetType() == CRV_COMPO) - nSubs = ::GetCurveComposite( pCurve)->GetCurveCount() ; - else - nSubs = 0 ; + if ( pGObj == nullptr) + return false ; + // se ammesse curve ed è tale + if ( nType != GEO_SURF && ( pGObj->GetType() & GEO_CURVE) != 0) { + const ICurve* pCurve = nullptr ; + const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; + // se direttamente la curva + if ( Id.nSub == SEL_SUB_ALL) { + pCurve = ::GetCurve( m_pGeomDB->GetGeoObj( Id.nId)) ; + if ( pCurve != nullptr) { + if ( pCurve->GetType() == CRV_COMPO) + nSubs = ::GetCurveComposite( pCurve)->GetCurveCount() ; + else + nSubs = 0 ; + } + } + // altrimenti sottocurva di composita + else { + const ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( Id.nId)) ; + if ( pCompo != nullptr) + pCurve = pCompo->GetCurve( Id.nSub) ; + nSubs = 0 ; + } + return ( pCurve != nullptr) ; + } + // se altrimenti ammesse superfici trimesh ed è tale + else if ( nType != GEO_CURVE && ( pGObj->GetType() & GEO_SURF) != 0) { + const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ; + if ( pSurf == nullptr) + return false ; + // se direttamente la superficie + if ( Id.nSub == SEL_SUB_ALL) { + nSubs = pSurf->GetFacetCount() ; + return true ; + } + // altrimenti faccia di superficie trimesh + else { + // se faccia non esistente + if ( Id.nSub > pSurf->GetFacetCount()) + return false ; + // tutto bene + nSubs = 0 ; + return true ; } } - // altrimenti sottocurva di composita - else { - const ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( Id.nId)) ; - if ( pCompo != nullptr) - pCurve = pCompo->GetCurve( Id.nSub) ; - nSubs = 0 ; - } - return ( pCurve != nullptr) ; + // altrimenti errore + else + return false ; } //---------------------------------------------------------------------------- @@ -843,91 +867,85 @@ ICurve* Sawing::GetCurve( SelData Id) { // ammessi : curve o facce di polymesh - // nel caso di facce si deve recuperare la linea di base - - // per ora accetto solo curve - PtrOwner pCurve ; - // se direttamente curva - if ( Id.nSub == SEL_SUB_ALL) { - // recupero e duplico la curva - const ICurve* pOriCurve = ::GetCurve( m_pGeomDB->GetGeoObj( Id.nId)) ; - if ( pOriCurve != nullptr) - pCurve.Set( pOriCurve->Clone()) ; - } - // altrimenti sottocurva di composita - else { - // recupero la composita - const ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( Id.nId)) ; - if ( pCompo != nullptr) { - // duplico la curva semplice - const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ; - if ( pOriCurve != nullptr) { - pCurve.Set( pOriCurve->Clone()) ; - // recupero estrusione e spessore - Vector3d vtExtr ; - if ( pCompo->GetExtrusion( vtExtr)) - pCurve->SetExtrusion( vtExtr) ; - double dThick ; - if ( pCompo->GetThickness( dThick)) - pCurve->SetThickness( dThick) ; - } - } - } - if ( IsNull( pCurve)) + const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ; + if ( pGObj == nullptr) return nullptr ; // ne recupero il riferimento globale Frame3d frGlob ; if ( ! m_pGeomDB->GetGlobFrame( Id.nId, frGlob)) return nullptr ; - // la porto in globale - pCurve->ToGlob( frGlob) ; - // la restituisco - return Release( pCurve) ; -} - -//---------------------------------------------------------------------------- -bool -Sawing::VerifySideAngle( void) -{ - // verifiche per angolo di sbandamento - if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { - // non ammesso lato di lavoro in centro - if ( m_Params.m_nWorkSide == SAW_WS_CENTER) { - m_pMchMgr->SetLastError( 2202, "Error in Sawing : Center work not allowed with side angle") ; - return false ; + // se curva + if ( ( pGObj->GetType() & GEO_CURVE) != 0) { + PtrOwner pCurve ; + // se direttamente curva + if ( Id.nSub == SEL_SUB_ALL) { + // recupero e duplico la curva + const ICurve* pOriCurve = ::GetCurve( pGObj) ; + if ( pOriCurve != nullptr) + pCurve.Set( pOriCurve->Clone()) ; } - // se angolo esterno lato mandrino deve uguagliare lato di lavoro - if ( m_Params.m_dSideAngle > 0) { - if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) { - if ( m_Params.m_nHeadSide == SAW_HS_LEFT) { - m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ; - m_Params.m_nHeadSide = SAW_HS_RIGHT ; - } - } - if ( m_Params.m_nWorkSide == SAW_WS_LEFT) { - if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) { - m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ; - m_Params.m_nHeadSide = SAW_HS_LEFT ; - } - } - } - // altrimenti angolo interno, lato mandrino deve essere opposto a lato di lavoro + // altrimenti sottocurva di composita else { - if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) { - if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) { - m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ; - m_Params.m_nHeadSide = SAW_HS_LEFT ; - } - } - if ( m_Params.m_nWorkSide == SAW_WS_LEFT) { - if ( m_Params.m_nHeadSide == SAW_HS_LEFT) { - m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ; - m_Params.m_nHeadSide = SAW_HS_RIGHT ; + // recupero la composita + const ICurveComposite* pCompo = GetCurveComposite( pGObj) ; + if ( pCompo != nullptr) { + // duplico la curva semplice + const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ; + if ( pOriCurve != nullptr) { + pCurve.Set( pOriCurve->Clone()) ; + // recupero estrusione e spessore + Vector3d vtExtr ; + if ( pCompo->GetExtrusion( vtExtr)) + pCurve->SetExtrusion( vtExtr) ; + double dThick ; + if ( pCompo->GetThickness( dThick)) + pCurve->SetThickness( dThick) ; } } } + if ( IsNull( pCurve)) + return nullptr ; + // la porto in globale + pCurve->ToGlob( frGlob) ; + // la restituisco + return Release( pCurve) ; } - return true ; + // se altrimenti superficie + else if ( ( pGObj->GetType() & GEO_SURF) != 0) { + // recupero la trimesh + const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ; + if ( pSurf == nullptr) + return nullptr ; + // recupero l'indice della faccia + int nFacet = ( ( Id.nSub == SEL_SUB_ALL) ? 0 : Id.nSub) ; + // recupero i contorni della faccia + POLYLINEVECTOR vPL ; + pSurf->GetFacetLoops( nFacet, vPL) ; + if ( vPL.empty()) + return nullptr ; + // recupero la normale esterna della faccia + Vector3d vtN ; + if ( ! pSurf->GetFacetNormal( nFacet, vtN)) + return nullptr ; + // creo la curva a partire da quello esterno + PtrOwner pCrvCompo( CreateCurveComposite()) ; + pCrvCompo->FromPolyLine( vPL[0]) ; + if ( ! pCrvCompo->IsValid()) + return nullptr ; + // assegno l'estrusione dalla normale alla faccia + pCrvCompo->SetExtrusion( vtN) ; + // unisco le eventuali parti allineate + pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + // la porto in globale + pCrvCompo->ToGlob( frGlob) ; + // sistemazioni varie + AdjustCurveFromSurf( pCrvCompo, TOOL_ORTUP, FACE_DOWN, m_TParams.m_dThick) ; + // la restituisco + return Release( pCrvCompo) ; + } + // altrimenti errore + else + return nullptr ; } //---------------------------------------------------------------------------- @@ -1031,6 +1049,51 @@ Sawing::Chain( int nGrpDestId) return true ; } +//---------------------------------------------------------------------------- +bool +Sawing::VerifySideAngle( void) +{ + // verifiche per angolo di sbandamento + if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) { + // non ammesso lato di lavoro in centro + if ( m_Params.m_nWorkSide == SAW_WS_CENTER) { + m_pMchMgr->SetLastError( 2202, "Error in Sawing : Center work not allowed with side angle") ; + return false ; + } + // se angolo esterno lato mandrino deve uguagliare lato di lavoro + if ( m_Params.m_dSideAngle > 0) { + if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) { + if ( m_Params.m_nHeadSide == SAW_HS_LEFT) { + m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ; + m_Params.m_nHeadSide = SAW_HS_RIGHT ; + } + } + if ( m_Params.m_nWorkSide == SAW_WS_LEFT) { + if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) { + m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ; + m_Params.m_nHeadSide = SAW_HS_LEFT ; + } + } + } + // altrimenti angolo interno, lato mandrino deve essere opposto a lato di lavoro + else { + if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) { + if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) { + m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ; + m_Params.m_nHeadSide = SAW_HS_LEFT ; + } + } + if ( m_Params.m_nWorkSide == SAW_WS_LEFT) { + if ( m_Params.m_nHeadSide == SAW_HS_LEFT) { + m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ; + m_Params.m_nHeadSide = SAW_HS_RIGHT ; + } + } + } + } + return true ; +} + //---------------------------------------------------------------------------- bool Sawing::ProcessPath( int nPathId, int nPvId, int nClId) diff --git a/Sawing.h b/Sawing.h index a6e28f6..13f93dd 100644 --- a/Sawing.h +++ b/Sawing.h @@ -68,10 +68,10 @@ class Sawing : public Machining private : bool UpdateToolData( void) ; - bool VerifyGeometry( SelData Id, int& nSubs) ; + bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; ICurve* GetCurve( SelData Id) ; - bool VerifySideAngle( void) ; bool Chain( int nGrpDestId) ; + bool VerifySideAngle( void) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool ProcessEntity( const ICurve* pCrvP, const ICurve* pCrvC, const ICurve* pCrvN, double dDepth, double dExtraCut, double dRbHeight, bool bIsFirst, bool bIsLast,