diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index c641822..e791846 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -27,8 +27,11 @@ #include "/EgtDev/Include/EGkChainCurves.h" #include "/EgtDev/Include/EGkOffsetCurve.h" #include "/EgtDev/Include/EGkIntersCurves.h" +#include "/EgtDev/Include/EGkSfrCreate.h" #include "/EgtDev/Include/EGkSurfLocal.h" #include "/EgtDev/Include/EGkCAvToolSurfTm.h" +#include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h" +#include "/EgtDev/Include/EGkCalcPocketing.h" #include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkStringUtils3d.h" #include "/EgtDev/Include/EGkUserObjFactory.h" @@ -62,6 +65,9 @@ using namespace std ; // 3120 = "Error in SurfFinishing : post apply not calculable" // 3121 = "Error in SurfFinishing : Linear Approx not computable" // 3122 = "Error in SurfFinishing : aggregate from bottom not allowed" +// 3123 = "Error in SurfFinishing : missing surfaces" +// 3124 = "Error in SurfFinishing : region not computable" +// 3125 = "Error in SurfFinishing : CalcPocketing failed" // 3151 = "Warning in SurfFinishing : Skipped entity (xx)" // 3152 = "Warning in SurfFinishing : No machinable path" // 3153 = "Warning in SurfFinishing : Tool name changed (xx)" @@ -1096,7 +1102,7 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) m_pGeomDB->EmptyGroup( nTempId) ; // in ogni caso lo dichiaro temporaneo e non visibile m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ; - m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; + //m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ; // verifico sia una curva chiusa (deve delimitare l'area da svuotare) int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ; @@ -1114,9 +1120,9 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) return false ; ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nCopyId)) ; - // recupero estrusione e spessore - Vector3d vtExtr = Z_AX ; - pCompo->GetExtrusion( vtExtr) ; + // recupero estrusione (vettore fresa) e spessore + Vector3d vtTool = Z_AX ; + pCompo->GetExtrusion( vtTool) ; double dThick ; pCompo->GetThickness( dThick) ; @@ -1126,11 +1132,11 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3105, "Error in SurfFinishing : Contour Not Flat") ; return false ; } - if ( abs( plPlane.GetVersN() * vtExtr) < cos( 10 * EPS_ANG_SMALL)) { + if ( abs( plPlane.GetVersN() * vtTool) < cos( 10 * EPS_ANG_SMALL)) { m_pMchMgr->SetLastError( 3106, "Error in SurfFinishing : Tool Dir not perpendicular to Flat Area") ; return false ; } - if ( plPlane.GetVersN() * vtExtr * dArea < 0) + if ( plPlane.GetVersN() * vtTool * dArea < 0) pCompo->Invert() ; // unisco le parti allineate @@ -1161,9 +1167,6 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) string sPathName ; m_pGeomDB->GetName( nPathId, sPathName) ; - // assegno il versore fresa - Vector3d vtTool = vtExtr ; - // se richiesta lavorazione if ( nClId != GDB_ID_NULL) { // creo gruppo per geometria di lavorazione del percorso @@ -1176,6 +1179,23 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) // verifico se archi vanno approssimati con segmenti di retta bool bSplitArcs = GetSplitArcs( vtTool) ; + // porto tutte le superfici nel riferimento della prima + Frame3d frSurf ; + SURFLOCALVECTOR vSrfLoc ; + INTVECTOR vSurfId ; + GetActiveSurfaces( vSurfId) ; + for ( auto nSurfId : vSurfId) { + if ( vSrfLoc.empty()) { + if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf)) + return false ; + } + vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ; + } + if ( ! frSurf.IsValid()) { + m_pMchMgr->SetLastError( 3123, "Error in SurfFinishing : missing surfaces") ; + return false ; + } + // predispongo l'ambiente di correzione dei percorsi utensili con le superfici attive dei pezzi PtrOwner pCAvTlStm( CreateCAvToolSurfTm()) ; if ( IsNull( pCAvTlStm)) @@ -1206,25 +1226,66 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) dTipRad + GetOffsR(), m_TParams.m_dCornRad + GetOffsR()) ; } - Frame3d frSurf ; - const ISurfTriMesh* pStm = nullptr ; - SURFLOCALVECTOR vSrfLoc ; - INTVECTOR vSurfId ; - GetActiveSurfaces( vSurfId) ; - for ( auto nSurfId : vSurfId) { - if ( pStm == nullptr) { - pStm = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nSurfId)) ; - if ( ! m_pGeomDB->GetGlobFrame( nSurfId, frSurf)) - return false ; - pCAvTlStm->SetSurfTm( *pStm) ; + pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSrfLoc[0].Get())) ; + for ( int i = 1 ; i < int( vSrfLoc.size()) ; ++ i) + pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc[i].Get())) ; + + // determino la regione da lavorare + PtrOwner pSfrCnt( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrCnt) || ! pSfrCnt->AddExtLoop( *pCompo)) { + m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; + return false ; + } + // se richiesto, elimino le parti al massimo affondamento + if ( bSkipMaxDown) { + // calcolo silhouette dell'insieme di superfici + CISURFTMPVECTOR vpStm ; vpStm.reserve( vSurfId.size()) ; + for ( int i = 0 ; i < int( vSrfLoc.size()) ; ++ i) + vpStm.emplace_back( GetSurfTriMesh( vSrfLoc[i].Get())) ; + Frame3d frPocket ; + Point3d ptCen ; pCompo->GetCentroid( ptCen) ; + frPocket.Set( ptCen, vtTool) ; + frPocket.ToLoc( frSurf) ; + const double SILH_TOL = 1.0 ; + PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; + if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frPocket, SILH_TOL)) + return false ; + POLYLINEVECTOR vPL ; + if ( ! pCavParSilh->GetSilhouette( -dDepth, vPL)) { + m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; + return false ; } - else { - vSrfLoc.emplace_back( m_pGeomDB, nSurfId, frSurf) ; - pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc.back().Get())) ; + // creo la regione piana dalle PolyLine ricavate dalla Silhouette + SurfFlatRegionByContours SfrMaker ; + for ( auto& PL : vPL) { + // recupero la curva dalla silhouette + PtrOwner pSilCrv( CreateCurveComposite()) ; + if ( IsNull( pSilCrv)) + return false ; + pSilCrv->FromPolyLine( PL) ; + if ( ! SfrMaker.AddCurve( Release( pSilCrv))) { + m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; + return false ; + } + } + PtrOwner pSfrSil( SfrMaker.GetSurf()) ; + if ( ! IsNull( pSfrSil)) { + pSfrSil->ToGlob( frSurf) ; + const double EXTRA_OFFS = 2 ; + double dPockRadOffs = m_TParams.m_dDiam - m_Params.m_dSideStep - m_Params.m_dOverlap ; + pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ; // offset radiale sulla Silhouette + } + // intersezione tra contorno e regione + pSfrCnt->Intersect( *pSfrSil) ; + if ( pSfrCnt->IsValid() && pSfrCnt->GetChunkCount() > 0) { + PtrOwner pCont( ConvertCurveToComposite( pSfrCnt->GetLoop( 0, 0))) ; + if ( ! IsNull( pCont)) { + int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pCont)) ; + if ( nNewId != GDB_ID_NULL) + pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nNewId)) ; + } } } - if ( pStm == nullptr) - pCAvTlStm.Reset() ; // assegno il vettore estrazione al gruppo del percorso m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; @@ -1237,19 +1298,19 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) double dElev = dDepth ; switch ( m_Params.m_nSubType) { case SURFFIN_SUB_ZIGZAG : - if ( ! AddZigZag( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, bSkipMaxDown)) + if ( ! AddZigZag( pCAvTlStm, frSurf, pCompo, vtTool, vtTool, dDepth, dElev, bSplitArcs, false)) return false ; break ; case SURFFIN_SUB_ONEWAY : - if ( ! AddOneWay( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, bSkipMaxDown)) + if ( ! AddOneWay( pCAvTlStm, frSurf, pCompo, vtTool, vtTool, dDepth, dElev, bSplitArcs, false)) return false ; break ; case SURFFIN_SUB_SPIRALIN : - if ( ! AddSpiral( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, true)) + if ( ! AddSpiral( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs, true, false)) return false ; break ; case SURFFIN_SUB_SPIRALOUT : - if ( ! AddSpiral( pCAvTlStm, frSurf, pCompo, vtTool, vtExtr, dDepth, dElev, bSplitArcs, false)) + if ( ! AddSpiral( pCAvTlStm, frSurf, pSfrCnt, vtTool, dDepth, dElev, bSplitArcs, false, false)) return false ; break ; } @@ -2197,199 +2258,196 @@ SurfFinishing::CalcOneWay( const ICurveComposite* pOffs, //---------------------------------------------------------------------------- bool -SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) -{ +SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut, bool bSkipMaxDown) +{ // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; // lunghezza di approccio/retrazione double dAppr = m_Params.m_dStartPos ; - // calcolo la spirale dall'esterno all'interno e la curva che unisce inizio e fine - PtrOwner pMCrv( CreateCurveComposite()) ; - if ( IsNull( pMCrv)) { - m_pMchMgr->SetLastError( 3109, "Error in SurfFinishing : Offset not computable") ; + // calcolo la spirale + double dPockRad = m_Params.m_dSideStep ; + double dPockRadOffs = m_TParams.m_dDiam / 2 - m_Params.m_dSideStep - m_Params.m_dOverlap ; + int nType = ( bInVsOut ? POCKET_SPIRALIN : POCKET_SPIRALOUT) ; + ICRVCOMPOPOVECTOR vpCrvs ; + if ( ! CalcPocketing( pSfrPock, dPockRad, dPockRadOffs, m_Params.m_dSideStep, m_Params.m_dSideAngle, + nType, false, false, nullptr, vpCrvs)) { + m_pMchMgr->SetLastError( 3125, "Error in SurfFinishing : CalcPocketing failed") ; return false ; } - if ( ! CalcSpiral( pCompo, false, pMCrv, nullptr)) - return false ; - if ( ! bInVsOut) - pMCrv->Invert() ; + + // determino il riferimento di base della svuotatura + Frame3d frPocket ; + Point3d ptCen ; pSfrPock->GetCentroid( ptCen) ; + frPocket.Set( ptCen, vtTool) ; // ciclo sulle curve risultanti bool bStart = true ; - if ( true) { - // determino il riferimento di base e il box della svuotatura - Frame3d frPocket ; - Point3d ptCen ; pCompo->GetCentroid( ptCen) ; - frPocket.Set( ptCen, vtExtr) ; - frPocket.Rotate( ptCen, vtExtr, m_Params.m_dSideAngle) ; + for ( int k = 0 ; k < int( vpCrvs.size()) ; ++ k) { + PtrOwner pMCrv( Release( vpCrvs[k])) ; pMCrv->ToLoc( frPocket) ; - // ciclo sui percorsi - if ( true) { - // li correggo per non interferire con le superfici - if ( pCAvTlStm != nullptr) { - // approssimo la curva con una polilinea - PolyLine PL ; - if ( ! pMCrv->ApproxWithLines( m_Params.m_dApprox, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) - return false ; - // eventuale aggiunta di punti per garantire max distanza - const double MIN_DIST = 1. ; - const double MAX_DIST = 50. ; - double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; - if ( ! PL.AdjustForMaxSegmentLen( dDist)) - return false ; - // porto nel riferimento delle superfici - PL.LocToLoc( frPocket, frSurf) ; - // porto i dati geometrici in locale alle superfici - Vector3d vtAxL = vtTool ; - vtAxL.ToLoc( frSurf) ; - Vector3d vtMoveL = vtAxL ; - // traslo della lunghezza utensile diminuita dell'affondamento - PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; - // eseguo CAv - if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox)) - return false ; - // contro-traslo della lunghezza utensile - PL.Translate( - vtAxL * m_TParams.m_dLen) ; - // riporto la polilinea nel riferimento della curva - PL.LocToLoc( frSurf, frPocket) ; - // elimino i punti allineati - PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; - // creo una curva composita a partire dalla polilinea - PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; - if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) - return false ; - // sostituisco la vecchia curva con la nuova - pMCrv.Set( pCompo) ; - } - // ciclo sulle curve elementari - int nMaxInd = pMCrv->GetCurveCount() - 1 ; - for ( int i = 0 ; i <= nMaxInd ; ++ i) { - // curva corrente - const ICurve* pCrvC = pMCrv->GetCurve( i) ; - // copio la curva - PtrOwner pCurve( pCrvC->Clone()) ; - if ( IsNull( pCurve)) - return false ; - pCurve->ToGlob( frPocket) ; - // se prima entità - if ( i == 0 ) { - // dati inizio entità - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - Vector3d vtStart ; - pCurve->GetStartDir( vtStart) ; - // vettore tangente iniziale non deve salire rispetto a estrusione (poi si prende opposto) - double dStartOnExtr = vtStart * vtExtr ; - if ( dStartOnExtr > 0) { - vtStart -= dStartOnExtr * vtExtr ; - vtStart.Normalize() ; - } - // determino normale della superficie sul punto iniziale - Vector3d vtNorm ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtExtr, vtNorm)) { - Point3d ptEnd ; - pCurve->GetEndPoint( ptEnd) ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtExtr, vtNorm)) - vtNorm = V_NULL ; - } - // determino inizio attacco - Point3d ptP1 ; - if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, vtNorm, ptP1)) - return false ; - // eventuale correzione inizio attacco per evitare interferenze - if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptStart, ptP1, vtTool, ptP1)) - return false ; - // determino elevazione su inizio attacco - double dStElev ; - if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) - dStElev = dElev ; - dStElev -= ( ptP1 - ptStart) * vtExtr ; - // se inizio, approccio globale al punto iniziale - if ( bStart) { - if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 3111, "Error in SurfFinishing : Approach not computable") ; - return false ; - } - bStart = false ; - } - // altrimenti, approccio di collegamento - else { - if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { - m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; - return false ; - } - } - // aggiungo attacco - SetFeed( GetStartFeed()) ; - if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr, bSplitArcs)) { - m_pMchMgr->SetLastError( 3113, "Error in SurfFinishing : LeadIn not computable") ; - return false ; - } + // li correggo per non interferire con le superfici + if ( pCAvTlStm != nullptr) { + // approssimo la curva con una polilinea + PolyLine PL ; + if ( ! pMCrv->ApproxWithLines( m_Params.m_dApprox, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL)) + return false ; + // eventuale aggiunta di punti per garantire max distanza + const double MIN_DIST = 1. ; + const double MAX_DIST = 50. ; + double dDist = Clamp( m_TParams.m_dDiam / 2, MIN_DIST, MAX_DIST) ; + if ( ! PL.AdjustForMaxSegmentLen( dDist)) + return false ; + // porto nel riferimento delle superfici + PL.LocToLoc( frPocket, frSurf) ; + // porto i dati geometrici in locale alle superfici + Vector3d vtAxL = vtTool ; + vtAxL.ToLoc( frSurf) ; + Vector3d vtMoveL = vtAxL ; + // traslo della lunghezza utensile diminuita dell'affondamento + PL.Translate( vtAxL * ( m_TParams.m_dLen - dDepth)) ; + // eseguo CAv + if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtAxL, vtMoveL, m_Params.m_dApprox)) + return false ; + // contro-traslo della lunghezza utensile + PL.Translate( - vtAxL * m_TParams.m_dLen) ; + // riporto la polilinea nel riferimento della curva + PL.LocToLoc( frSurf, frPocket) ; + // elimino i punti allineati + PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; + // creo una curva composita a partire dalla polilinea + PtrOwner< ICurveComposite> pCompo( CreateCurveComposite()) ; + if ( IsNull( pCompo) || ! pCompo->FromPolyLine( PL)) + return false ; + // sostituisco la vecchia curva con la nuova + pMCrv.Set( pCompo) ; + } + // ciclo sulle curve elementari + int nMaxInd = pMCrv->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pMCrv->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + pCurve->ToGlob( frPocket) ; + // se prima entità + if ( i == 0 ) { + // dati inizio entità + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + Vector3d vtStart ; + pCurve->GetStartDir( vtStart) ; + // vettore tangente iniziale non deve salire rispetto a estrusione (poi si prende opposto) + double dStartOnExtr = vtStart * vtTool ; + if ( dStartOnExtr > 0) { + vtStart -= dStartOnExtr * vtTool ; + vtStart.Normalize() ; } - // elaborazioni sulla curva corrente (sempre un segmento di retta) - ICurveLine* pLine = GetCurveLine( pCurve) ; - if ( pLine == nullptr) - return false ; - Point3d ptP3 = pLine->GetEnd() ; - Vector3d vtMove ; pLine->GetStartDir( vtMove) ; - SetFeed( GetRightFeed( vtMove, vtTool)) ; - if ( AddLinearMove( ptP3) == GDB_ID_NULL) - return false ; - // se ultima entità - if ( i == nMaxInd) { - // dati fine entità + // determino normale della superficie sul punto iniziale + Vector3d vtNorm ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtTool, vtNorm)) { Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; - Vector3d vtEnd ; - pCurve->GetEndDir( vtEnd) ; - // vettore tangente finale non deve scendere rispetto a estrusione - double dEndOnExtr = vtEnd * vtExtr ; - if ( dEndOnExtr < 0) { - vtEnd -= dEndOnExtr * vtExtr ; - vtEnd.Normalize() ; - } - // determino normale della superficie sul punto finale - Vector3d vtNorm ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtExtr, vtNorm)) { - Point3d ptStart ; - pCurve->GetStartPoint( ptStart) ; - if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtExtr, vtNorm)) - vtNorm = V_NULL ; - } - // determino fine uscita - Point3d ptP1 ; - if ( ! CalcLeadOutEnd( ptEnd, vtEnd, vtExtr, vtNorm, ptP1)) - return false ; - // eventuale correzione fine uscita per evitare interferenze - if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptEnd, ptP1, vtTool, ptP1)) - return false ; - // aggiungo uscita - SetFeed( GetEndFeed()) ; - if ( ! AddLeadOut( ptEnd, vtEnd, ptP1, vtExtr, bSplitArcs)) { - m_pMchMgr->SetLastError( 3114, "Error in SurfFinishing : LeadOut not computable") ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtTool, vtNorm)) + vtNorm = V_NULL ; + } + // determino inizio attacco + Point3d ptP1 ; + if ( ! CalcLeadInStart( ptStart, vtStart, vtTool, vtNorm, ptP1)) + return false ; + // eventuale correzione inizio attacco per evitare interferenze + if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptStart, ptP1, vtTool, ptP1)) + return false ; + // determino elevazione su inizio attacco + double dStElev ; + if ( ! GetElevation( m_nPhase, ptStart - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dStElev)) + dStElev = dElev ; + dStElev -= ( ptP1 - ptStart) * vtTool ; + // se inizio, approccio globale al punto iniziale + if ( bStart) { + if ( ! AddApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 3111, "Error in SurfFinishing : Approach not computable") ; return false ; } - // determino elevazione su fine uscita - double dEndElev ; - if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) - dEndElev = dElev ; - dEndElev -= ( ptP1 - ptEnd) * vtExtr ; - // se non è ultimo tratto, aggiungo retrazione di collegamento - if ( false) { - if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; - return false ; - } + bStart = false ; + } + // altrimenti, approccio di collegamento + else { + if ( ! AddLinkApproach( ptP1, vtTool, dSafeZ, dStElev, dAppr)) { + m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; + return false ; } - // altrimenti aggiungo retrazione finale - else { - if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { - m_pMchMgr->SetLastError( 3115, "Error in SurfFinishing : Retract not computable") ; - return false ; - } + } + // aggiungo attacco + SetFeed( GetStartFeed()) ; + if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtTool, bSplitArcs)) { + m_pMchMgr->SetLastError( 3113, "Error in SurfFinishing : LeadIn not computable") ; + return false ; + } + } + // elaborazioni sulla curva corrente (sempre un segmento di retta) + ICurveLine* pLine = GetCurveLine( pCurve) ; + if ( pLine == nullptr) + return false ; + Point3d ptP3 = pLine->GetEnd() ; + Vector3d vtMove ; pLine->GetStartDir( vtMove) ; + SetFeed( GetRightFeed( vtMove, vtTool)) ; + if ( AddLinearMove( ptP3) == GDB_ID_NULL) + return false ; + // se ultima entità + if ( i == nMaxInd) { + // dati fine entità + Point3d ptEnd ; + pCurve->GetEndPoint( ptEnd) ; + Vector3d vtEnd ; + pCurve->GetEndDir( vtEnd) ; + // vettore tangente finale non deve scendere rispetto a estrusione + double dEndOnExtr = vtEnd * vtTool ; + if ( dEndOnExtr < 0) { + vtEnd -= dEndOnExtr * vtTool ; + vtEnd.Normalize() ; + } + // determino normale della superficie sul punto finale + Vector3d vtNorm ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptEnd, vtTool, vtNorm)) { + Point3d ptStart ; + pCurve->GetStartPoint( ptStart) ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtTool, vtNorm)) + vtNorm = V_NULL ; + } + // determino fine uscita + Point3d ptP1 ; + if ( ! CalcLeadOutEnd( ptEnd, vtEnd, vtTool, vtNorm, ptP1)) + return false ; + // eventuale correzione fine uscita per evitare interferenze + if ( ! GetLastGoodPoint( pCAvTlStm, frSurf, ptEnd, ptP1, vtTool, ptP1)) + return false ; + // aggiungo uscita + SetFeed( GetEndFeed()) ; + if ( ! AddLeadOut( ptEnd, vtEnd, ptP1, vtTool, bSplitArcs)) { + m_pMchMgr->SetLastError( 3114, "Error in SurfFinishing : LeadOut not computable") ; + return false ; + } + // determino elevazione su fine uscita + double dEndElev ; + if ( ! GetElevation( m_nPhase, ptEnd - 10 * EPS_SMALL * vtTool, vtTool, GetRadiusForStartEndElevation(), vtTool, dEndElev)) + dEndElev = dElev ; + dEndElev -= ( ptP1 - ptEnd) * vtTool ; + // se non è ultimo tratto, aggiungo retrazione di collegamento + if ( false) { + if ( ! AddLinkRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 3112, "Error in SurfFinishing : Link not computable") ; + return false ; + } + } + // altrimenti aggiungo retrazione finale + else { + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 3115, "Error in SurfFinishing : Retract not computable") ; + return false ; } } } @@ -2399,108 +2457,6 @@ SurfFinishing::AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, return true ; } -//---------------------------------------------------------------------------- -static double -GetCurveRadius( const ICurve* pCrv) -{ - if ( pCrv == nullptr) - return 0.0 ; - BBox3d b3Loc ; - if ( ! pCrv->GetLocalBBox( b3Loc, BBF_EXACT)) - return 0.0 ; - double dRad ; - if ( ! b3Loc.GetRadius( dRad)) - return 0.0 ; - return dRad ; -} - -//---------------------------------------------------------------------------- -bool -SurfFinishing::CalcSpiral( const ICurveComposite* pCompo, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) -{ - // primo offset pari al raggio utensile - overlap - double dTRad = 0.5 * m_TParams.m_dDiam ; - double dOffs = dTRad - m_Params.m_dOverlap ; - - // ciclo di offset verso l'interno - const int MAX_ITER = 1000 ; - int nIter = 0 ; - PtrOwner pOffs ; - const ICurve* pCurr = pCompo ; - double dCurrRad = GetCurveRadius( pCurr) + m_Params.m_dOverlap ; - while ( nIter < MAX_ITER) { - // calcolo - OffsetCurve OffsCrv ; - if ( ! OffsCrv.Make( pCurr, - dOffs, ICurve::OFF_FILLET)) { - m_pMchMgr->SetLastError( 3109, "Error in SurfFinishing : Offset not computable") ; - return false ; - } - // recupero la prima curva di offset - PtrOwner pNextOffs( OffsCrv.GetLongerCurve()) ; - double dRad = GetCurveRadius( pNextOffs) ; - bool bNextOk = ( dRad > EPS_ZERO && dRad < dCurrRad) ; - bool bSmallRad = ( nIter == 0 ? dOffs < dTRad - m_Params.m_dOverlap + EPS_ZERO : dOffs < dTRad + EPS_ZERO) ; - // se completato step di offset, accodo la curva offsettata al percorso di lavoro - if ( ! IsNull( pOffs) && ( bNextOk || bSmallRad)) { - // verifico se aggiungere linea di congiunzione - if ( pMCrv->GetCurveCount() > 0) { - Point3d ptStart ; - pOffs->GetStartPoint( ptStart) ; - // aggiungo al percorso principale - pMCrv->AddLine( ptStart) ; - // eventuale copia nel percorso di ritorno - if ( pRCrv != nullptr) - pRCrv->AddCurve( *pMCrv->GetLastCurve()) ; - } - // se richiesta percorrenza invertita - if ( m_Params.m_bInvert) - pOffs->Invert() ; - // aggiungo la curva - pMCrv->AddCurve( Release( pOffs)) ; - } - // se offset va bene - if ( bNextOk) { - // sistemo per prossimo step - dCurrRad = dRad ; - pOffs.Set( pNextOffs) ; - pCurr = Get( pOffs) ; - // nuovo valore pari allo step - dOffs = GetSideStep() ; - } - // se altrimenti riducibile, provo con offset ridotto al raggio utensile - else if ( ! bSmallRad) { - // nuovo valore pari al raggio - dOffs = ( nIter == 0 ? dTRad - m_Params.m_dOverlap : dTRad) ; - } - // altrimenti esco - else - break ; - // incremento contatore iterazioni - ++ nIter ; - } - - // verifico il percorso di lavoro - if ( pMCrv->GetCurveCount() == 0) { - m_pMchMgr->SetLastError( 3110, "Error in SurfFinishing : : Toolpath not computable") ; - return false ; - } - // se necessario, approssimo archi con rette - if ( bSplitArcs && ! ApproxWithLines( pMCrv)) { - m_pMchMgr->SetLastError( 3121, "Error in SurfFinishing : Linear Approx not computable") ; - return false ; - } - // eventuale sistemazione archi - VerifyArcs( pMCrv) ; - // eventualmente compatto e inverto il percorso di ritorno - if ( pRCrv != nullptr) { - pRCrv->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, false) ; - pRCrv->Invert() ; - } - - return true ; -} - //---------------------------------------------------------------------------- bool SurfFinishing::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) diff --git a/SurfFinishing.h b/SurfFinishing.h index 7d57c59..1a2bfba 100644 --- a/SurfFinishing.h +++ b/SurfFinishing.h @@ -21,6 +21,7 @@ #include "/EgtDev/Include/EgtNumUtils.h" class ICAvToolSurfTm ; +class ISurfFlatRegion ; //---------------------------------------------------------------------------- class SurfFinishing : public Machining @@ -81,11 +82,8 @@ class SurfFinishing : public Machining const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, double dDepth, double dElev, bool bSplitArcs, bool bSkipMaxDown) ; bool CalcOneWay( const ICurveComposite* pOffs, ICRVCOMPOPOVECTOR& vpCrvs) ; - bool AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, - const ICurveComposite* pCompo, const Vector3d& vtTool, const Vector3d& vtExtr, - double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) ; - bool CalcSpiral( const ICurveComposite* pCompo, bool bSplitArcs, - ICurveComposite* pMCrv, ICurveComposite* pRCrv) ; + bool AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut, bool bSkipMaxDown) ; bool AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; bool AddLinkApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ; bool AddLinkRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr) ;