From f756dc4a7efd55544f2df50aba8315b770b5eecb Mon Sep 17 00:00:00 2001 From: Riccardo Elitropi Date: Tue, 21 Jan 2025 12:50:10 +0100 Subject: [PATCH] EgtMachKernel : - Aggiunta finitura Projection. --- SurfFinishing.cpp | 499 +++++++++++++++++++++++++++++++++++++++++++++- SurfFinishing.h | 12 +- 2 files changed, 498 insertions(+), 13 deletions(-) diff --git a/SurfFinishing.cpp b/SurfFinishing.cpp index 733daa5..1be3c5d 100644 --- a/SurfFinishing.cpp +++ b/SurfFinishing.cpp @@ -591,14 +591,32 @@ SurfFinishing::Apply( bool bRecalc, bool bPostApply) m_pGeomDB->EmptyGroup( nClId) ; // lavoro ogni singola regione piana - bool bOk = true ; - int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; - while ( nPathId != GDB_ID_NULL) { - if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId)) - bOk = false ; - nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + if ( m_Params.m_nSubType == SURFFIN_SUB_ZIGZAG || m_Params.m_nSubType == SURFFIN_SUB_ONEWAY || + m_Params.m_nSubType == SURFFIN_SUB_SPIRALIN || m_Params.m_nSubType == SURFFIN_SUB_SPIRALOUT || + m_Params.m_nSubType == SURFFIN_SUB_Z_CONST || m_Params.m_nSubType == SURFFIN_SUB_OPTIMAL) { + bool bOk = true ; + int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; + while ( nPathId != GDB_ID_NULL) { + if ( ! ProcessSfr( nPathId, GDB_ID_NULL, nClId)) + bOk = false ; + nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + } + if ( ! bOk) + return false ; } - if ( ! bOk) + // lavoro ogni singola curva composita + else if ( m_Params.m_nSubType == SURFFIN_SUB_PROJECT) { + bool bOk = true ; + int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ; + while ( nPathId != GDB_ID_NULL) { + if ( ! ProcessCrvCompo( nPathId, GDB_ID_NULL, nClId)) + bOk = false ; + nPathId = m_pGeomDB->GetNextGroup( nPathId) ; + } + if ( ! bOk) + return false ; + } + else return false ; // assegno ingombri dei vari percorsi di lavorazione e della lavorazione nel suo complesso @@ -1001,6 +1019,7 @@ SurfFinishing::GetCurves( SelData Id, ICURVEPLIST& lstPC) bool SurfFinishing::Chain( int nGrpDestId) { + // vettore puntatori alle curve ICURVEPOVECTOR vpCrvs ; vpCrvs.reserve( m_vId.size()) ; @@ -1019,6 +1038,33 @@ SurfFinishing::Chain( int nGrpDestId) vInds.emplace_back( Id) ; } } + + // se finitura a proiezione di curve + if ( m_Params.m_nSubType == SURFFIN_SUB_PROJECT) { + int nGroupName = -1 ; + for ( int i = 0 ; i < int( vpCrvs.size()) ; ++ i) { + // creo nuovo gruppo + int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDestId, Frame3d()) ; + if ( nPathId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPathId, MCH_PATH + ToString( ++ nGroupName)) ; + m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( nGroupName)) ; + // definisco la curva composita associata + PtrOwner pCrvCompo( ConvertCurveToComposite( Release( vpCrvs[i]))) ; + if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid()) + return false ; + int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, ::CloneCurveComposite( pCrvCompo)) ; + if ( nNewId == GDB_ID_NULL) + return false ; + // memorizzo la Thickness e l'Estrusione nelle Info del gruppo + double dThick ; pCrvCompo->GetThickness( dThick) ; + Vector3d vtExtr ; pCrvCompo->GetExtrusion( vtExtr) ; + m_pGeomDB->SetInfo( nNewId, KEY_THICK, dThick) ; + m_pGeomDB->SetInfo( nNewId, KEY_EXTR, vtExtr) ; + } + return true ; + } + // preparo i dati per il concatenamento Vector3d vtExtr = Z_AX ; bool bFirst = true ; @@ -1174,7 +1220,171 @@ SurfFinishing::Chain( int nGrpDestId) //---------------------------------------------------------------------------- bool -SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) +SurfFinishing::ProcessCrvCompo( int nPathId, int nPvId, int nClId) +{ + // recupero gruppo per geometria temporanea + const string GRP_TEMP = "Temp" ; + int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ; + // se non c'è, lo aggiungo + if ( nTempId == GDB_ID_NULL) { + nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ; + if ( nTempId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nTempId, GRP_TEMP) ; + } + // altrimenti lo svuoto + else + 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) ; + + // recupero la curva composita dal database geometrico + int nCrvCompoId = m_pGeomDB->GetFirstInGroup( nPathId) ; + if ( m_pGeomDB->GetGeoType( nCrvCompoId) != CRV_COMPO) + return false ; + + // copio la curva composits da elaborare + int nCopyId = m_pGeomDB->CopyGlob( nCrvCompoId, GDB_ID_NULL, nTempId) ; + if ( nCopyId == GDB_ID_NULL) + return false ; + const ICurveComposite* pCrvCompoGDB( GetCurveComposite( m_pGeomDB->GetGeoObj( nCopyId))) ; + if ( ! pCrvCompoGDB->IsValid()) + return false ; + + // recupero estrusione e spessore + Vector3d vtExtr = Z_AX ; + if ( m_pGeomDB->ExistsInfo( nCrvCompoId, KEY_EXTR)) + m_pGeomDB->GetInfo( nCrvCompoId, KEY_EXTR, vtExtr) ; + double dThick = 0. ; + if ( m_pGeomDB->ExistsInfo( nCrvCompoId, KEY_THICK)) + m_pGeomDB->GetInfo( nCrvCompoId, KEY_THICK, dThick) ; + + // valuto l'espressione dell'affondamento + ExeLuaSetGlobNumVar( "TH", abs( dThick)) ; + double dDepth ; + string sMyDepth = m_Params.m_sDepth ; + if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) { + m_pMchMgr->SetLastError( 3108, "Error in SurfFinishing : Depth not computable") ; + return false ; + } + + // recupero il box del grezzo in globale + BBox3d b3Raw ; + if ( ! GetRawGlobBox( m_nPhase, nPathId, 0.5 * m_TParams.m_dTDiam, b3Raw) || b3Raw.IsEmpty()) { + m_pMchMgr->SetLastError( 3107, "Error in SurfFinishing : Empty RawBox") ; + return false ; + } + + // verifico che la curva sia piana + Plane3d plPlane ; + if ( ! pCrvCompoGDB->IsFlat( plPlane)) { + m_pMchMgr->SetLastError( 3005, "Error in SurfFinishing : Contour Not Flat") ; + return false ; + } + + // recupero nome del path + 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 + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, sPathName) ; + m_pGeomDB->SetMaterial( nPxId, BLUE) ; + + // 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)) + return false ; + if ( abs( m_TParams.m_dSideAng) < EPS_ANG_SMALL) { + pCAvTlStm->SetStdTool( m_TParams.m_dLen + GetOffsR(), + m_TParams.m_dDiam / 2 + GetOffsR(), + m_TParams.m_dCornRad + GetOffsR()) ; + } + else { + double dDelta ; + double dSideAngRad = m_TParams.m_dSideAng * DEGTORAD ; + if ( m_TParams.m_dSideAng > 0) { + if ( m_TParams.m_dCornRad < EPS_SMALL) + dDelta = 2 * m_TParams.m_dMaxMat * tan( dSideAngRad) ; + else + dDelta = 2 * ( m_TParams.m_dCornRad * cos( dSideAngRad) + + ( m_TParams.m_dMaxMat + m_TParams.m_dCornRad * ( sin( dSideAngRad) - 1)) * tan( dSideAngRad)) ; + } + else { + dDelta = 2 * tan( dSideAngRad) * m_TParams.m_dMaxMat ; + } + double dStemRad = m_TParams.m_dDiam / 2 + dDelta ; + double dTipRad = m_TParams.m_dDiam / 2 ; + pCAvTlStm->SetAdvTool( m_TParams.m_dLen + GetOffsR(), + dStemRad + GetOffsR(), + m_TParams.m_dMaxMat, + dTipRad + GetOffsR(), + m_TParams.m_dCornRad + GetOffsR()) ; + } + pCAvTlStm->SetSurfTm( *GetSurfTriMesh( vSrfLoc[0].Get())) ; + for ( int i = 1 ; i < int( vSrfLoc.size()) ; ++ i) + pCAvTlStm->AddSurfTm( *GetSurfTriMesh( vSrfLoc[i].Get())) ; + + // assegno il vettore estrazione al gruppo del percorso + m_pGeomDB->SetInfo( nPxId, KEY_EXTR, vtTool) ; + + // Imposto dati comuni + SetPathId( nPxId) ; + SetToolDir( vtTool) ; + + // recupero la curva da lavorare + PtrOwner pCrvCompo( pCrvCompoGDB->Clone()) ; + if ( IsNull( pCrvCompo) || ! pCrvCompo->IsValid()) + return false ; + + // Eseguo la lavorazione a seconda del tipo + double dElev = dDepth ; + + switch ( m_Params.m_nSubType) { + case SURFFIN_SUB_PROJECT : + if ( ! AddProjection( pCAvTlStm, vSrfLoc, frSurf, pCrvCompoGDB, vtTool, dDepth, dElev, bSplitArcs)) + return false ; + break ; + } + } + + // incremento numero di percorsi + ++ m_nPaths ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfFinishing::ProcessSfr( int nPathId, int nPvId, int nClId) { // recupero gruppo per geometria temporanea const string GRP_TEMP = "Temp" ; @@ -1222,7 +1432,7 @@ SurfFinishing::ProcessPath( int nPathId, int nPvId, int nClId) m_pMchMgr->SetLastError( 3108, "Error in SurfFinishing : Depth not computable") ; return false ; } - // se spessore positivo, lo sottraggo al risuoltato + // se spessore positivo, lo sottraggo al risultato if ( dThick > 0) dDepth -= dThick ; @@ -2377,7 +2587,7 @@ SurfFinishing::CalcZConstSilCrv( ICAvParSilhouettesSurfTm* pCavParSilh, const SU } // aggiorno la ProgressBar - ExeProcessEvents( 40 + ( 40 / ( dDepth / max( 0.1, m_Params.m_dSideStep)) * ( nPlane - 1)), 0) ; + ExeProcessEvents( 40 + int( 40 / ( dDepth / max( 0.1, m_Params.m_dSideStep)) * ( nPlane - 1)), 0) ; } // controllo la validità di tutte le curve trovate @@ -3777,6 +3987,275 @@ SurfFinishing::AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSr return true ; } +//---------------------------------------------------------------------------- +bool +SurfFinishing::AddProjection( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, + const ICurveComposite* pCrvCompo, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) +{ + // controllo che la curva sia valida + if ( pCrvCompo == nullptr || ! pCrvCompo->IsValid()) + return false ; + + // recupero distanze di sicurezza + double dSafeZ = GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + + // definisco un sistema di riferimento locale alla curva + Point3d ptStart ; pCrvCompo->GetStartPoint( ptStart) ; + Frame3d frLoc ; + if ( ! frLoc.Set( ptStart, vtTool)) + return false ; + // definisco il frame inverso per il calcolo del Box3d + Frame3d frLocInv = frLoc ; + if ( ! frLocInv.Invert()) + return false ; + + // definisco variabili globali + BBox3d BBox3Loc ; // box totale delle superici rispetto a frLoc + CISURFTMPVECTOR vpStm ; // superfici TriMesh selezionate in globale + ICRVCOMPOPVECTOR vCrvToProj ; // vettore delle curve da proiettare sulla superfcie + + // scorro il vettore di superfici selezionate + for ( int i = 0 ; i < int( vSrfLoc.size()) ; ++ i) { + // porto la supercicie nel riferimento globale come TriMesh + PtrOwner pStm( CloneSurfTriMesh( GetSurfTriMesh( vSrfLoc[i].Get()))) ; + if ( IsNull( pStm) || ! pStm->IsValid() || ! pStm->ToGlob( frSurf)) + return false ; + // calcolo il box rispetto a frLoc e sommo i contributi + BBox3d BBox ; + if ( ! pStm->GetBBox( frLocInv, BBox)) + return false ; + BBox3Loc.Add( BBox) ; + // memorizzo la superficie nel vettore + vpStm.emplace_back( Release( pStm)) ; + } + + // recupero flag per saltare parti a massimo affondamento + bool bSkipMaxDown = true ; + GetValInNotes( m_Params.m_sUserNotes, "SkipMaxDown", bSkipMaxDown) ; + if ( bSkipMaxDown) { + // definisco i dati di calcolo della Silhouette + const double SILH_TOL = 1.0 ; + PtrOwner pCavParSilh( CreateCAvParSilhouettesSurfTm()) ; + if ( IsNull( pCavParSilh) || ! pCavParSilh->SetData( vpStm, frLoc, SILH_TOL)) + return false ; + // recupero il vettore di PolyLine della silhouette + POLYLINEVECTOR vPL ; + if ( ! pCavParSilh->GetSilhouette( BBox3Loc.GetMin().z , vPL)) + return false ; + // 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) ; + // approssimo con archi + const double SILH_ARC_TOL = 0.1 * SILH_TOL ; + const double SILH_ARC_FEA_MAX = 100. ; + PolyArc PA ; + if ( pSilCrv->ApproxWithArcsEx( SILH_ARC_TOL, ANG_TOL_STD_DEG, SILH_ARC_FEA_MAX, PA)) { + PtrOwner pTempCrv( CreateCurveComposite()) ; + if ( ! IsNull( pTempCrv) && + pTempCrv->FromPolyArc( PA) && + pTempCrv->RemoveSmallDefects( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG) && + pTempCrv->MergeCurves( SILH_ARC_TOL / 2, ANG_TOL_STD_DEG)) + pSilCrv.Set( pTempCrv) ; + } + // aggiungo per regione + if ( ! SfrMaker.AddCurve( Release( pSilCrv))) { + m_pMchMgr->SetLastError( 3124, "Error in SurfFinishing : region not computable") ; + return false ; + } + } + // definisco la regione piana + PtrOwner pSfrSil( SfrMaker.GetSurf()) ; + if ( ! IsNull( pSfrSil) && pSfrSil->IsValid()) { + // Offset alla Silhouette + double dPockRadOffs = m_TParams.m_dDiam - m_Params.m_dSideStep - m_Params.m_dOverlap ; + pSfrSil->Offset( dPockRadOffs, ICurve::OFF_CHAMFER) ; + // porto la curva e la Silhouette nel frame locale per classificazione ( alla stezza zLoc) + PtrOwner pCrvCompoCL( CloneCurveComposite( pCrvCompo)) ; + if ( IsNull( pCrvCompoCL) || ! pCrvCompoCL->IsValid()) + return false ; + pCrvCompoCL->Translate( BBox3Loc.GetMin().z * vtTool) ; + pCrvCompoCL->ToLoc( frLoc) ; + pSfrSil->ToLoc( frLoc) ; + // classifico + CRVCVECTOR ccClass ; + if ( pSfrSil->GetCurveClassification( *pCrvCompoCL, EPS_SMALL, ccClass)) { + for ( int i = 0 ; i < int( ccClass.size()) ; ++ i) { + // se tratto di curva interno + if ( ccClass[i].nClass != CRVC_OUT) { + // recupero la curva + PtrOwner pCrvInt( pCrvCompo->CopyParamRange( ccClass[i].dParS, ccClass[i].dParE)) ; + if ( ! IsNull( pCrvInt) && pCrvInt->IsValid()) + vCrvToProj.emplace_back( ConvertCurveToComposite( Release( pCrvInt))) ; + } + } + } + } + } + else + vCrvToProj.emplace_back( CloneCurveComposite( pCrvCompo)) ; + + // per ogni tratto di curva ricavato + for ( int i = 0 ; i < int( vCrvToProj.size()) ; ++ i) { + // se curva non valida, passo alla successiva + if ( vCrvToProj[i] == nullptr || ! vCrvToProj[i]->IsValid()) + continue ; + // recupero la PolyLinea associata alla curva + PolyLine PL ; + if ( ! vCrvToProj[i]->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) + return false ; + // recupero la distanza di traslazione della Polyline e la traslo + PL.Translate( BBox3Loc.GetMin().z * vtTool) ; + // calcolo direzione di allontanamento dalle superfici + 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 la polyline nel frame delle superfici + Vector3d vtToolL = GetToLoc( vtTool, frSurf) ; + PL.ToLoc( frSurf) ; + // porto i punti dal tip al naso mandrino + PL.Translate( vtToolL * m_TParams.m_dLen) ; + // eseguo il test del percorso + if ( ! pCAvTlStm->TestPath( PL.GetUPointList(), vtToolL, vtToolL, m_Params.m_dApprox)) + return false ; + // riporto la polyline nel frame globale + PL.ToGlob( frSurf) ; + // traslo della lunghezza utensile + PL.Translate( - vtToolL * m_TParams.m_dLen) ; + // elimino i punti allineati + PL.RemoveAlignedPoints( 0.8 * m_Params.m_dApprox) ; + // recupero la curva composita dalla PolyLine + PtrOwner pCrvPath( CreateCurveComposite()) ; + if ( IsNull( pCrvPath) || ! pCrvPath->FromPolyLine( PL) || ! pCrvPath->IsValid()) + return false ; + + // ciclo sulle curve elementari + bool bStart = true ; + int nMaxInd = pCrvPath->GetCurveCount() - 1 ; + for ( int i = 0 ; i <= nMaxInd ; ++ i) { + // curva corrente + const ICurve* pCrvC = pCrvPath->GetCurve( i) ; + // copio la curva + PtrOwner pCurve( pCrvC->Clone()) ; + if ( IsNull( pCurve)) + return false ; + // 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() ; + } + // determino normale della superficie sul punto iniziale + Vector3d vtNorm ; + if ( ! GetSurfaceNormalAtPoint( pCAvTlStm, frSurf, ptStart, vtTool, vtNorm)) { + Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; + 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 ; + } + 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, 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 ; + // altrimenti aggiungo retrazione finale + if ( ! AddRetract( ptP1, vtTool, dSafeZ, dEndElev, dAppr)) { + m_pMchMgr->SetLastError( 3115, "Error in SurfFinishing : Retract not computable") ; + return false ; + } + } + } + } + + 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 838dd67..e05746d 100644 --- a/SurfFinishing.h +++ b/SurfFinishing.h @@ -86,12 +86,14 @@ class SurfFinishing : public Machining bool VerifyGeometry( SelData Id, int& nSubs) ; bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ; bool Chain( int nGrpDestId) ; - bool ProcessPath( int nPathId, int nPvId, int nClId) ; + bool ProcessSfr( int nPathId, int nPvId, int nClId) ; + bool ProcessCrvCompo( int nPathId, int nPvId, int nClId) ; bool SimplifyCurve( ICurveComposite* pCompo) const ; bool CalcZConstProjectedLink( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frPocket, const Frame3d& frSurf, const Vector3d& vtTool, double dDepth, const Point3d ptStart_forced, const Point3d ptEnd_forced, ICurveComposite* pCrv) ; + // lavorazioni per surperfici bool AddZigZag( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; bool AddOneWay( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, @@ -99,9 +101,13 @@ class SurfFinishing : public Machining bool AddSpiral( ICAvToolSurfTm* pCAvTlStm, const Frame3d& frSurf, const ISurfFlatRegion* pSfrPock, const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs, bool bInVsOut) ; bool AddZConst( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, - const Vector3d& vtTool, double dDepth, double dElev, bool bSliptArcs) ; + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; bool AddOptimal( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ISurfFlatRegion* pSfr, - const Vector3d& vtTool, double dDepth, double dElev, bool bSliptArcs) ; + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; + // lavorazioni per curve + bool AddProjection( ICAvToolSurfTm* pCAvTlStm, const SURFLOCALVECTOR& vSrfLoc, const Frame3d& frSurf, const ICurveComposite* pCompo, + const Vector3d& vtTool, double dDepth, double dElev, bool bSplitArcs) ; + bool ChooseFinishingForOptimal( const ISurfFlatRegion* pSfr, int nChunk, bool& bSpiral, double& dSideAng) ; bool OrderOptimalPathsByZLoc( const ISurfFlatRegion* pSfr, VECTORPATHS& vCrvPaths) ; bool SplitStmTrianglesForSpiralAndZConst( const ISurfTriMesh* pStm, const Frame3d& frSurf,