diff --git a/SurfRoughing.cpp b/SurfRoughing.cpp index efbd220..99ff2df 100644 --- a/SurfRoughing.cpp +++ b/SurfRoughing.cpp @@ -36,6 +36,8 @@ #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EGkDistPointCurve.h" #include "/EgtDev/Include/EGkCurveAux.h" +#include "/EgtDev/Include/EGkDistPointSurfTm.h" +#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h" // per far dimenticare macro di WinUser.h #undef GetClassName @@ -66,6 +68,9 @@ using namespace std ; // 3022 = "Error in SurfRoughing : aggregate from bottom not allowed" // 3023 = "Error in SurfRoughing : missing surfaces" // 3024 = "Error in SurfRoughing : region not computable" +// 3025 = "Error in SurfRoughing : RawPart not computable" +// 3026 = "Error in SurfRoughing : Detecting open edges failed" +// 3027 = "Error in SurfRoughing : Slicing Raw failed" // 3051 = "Warning in SurfRoughing : Skipped entity (xx)" // 3052 = "Warning in SurfRoughing : No machinable path" // 3053 = "Warning in SurfRoughing : Tool name changed (xx)" @@ -1151,6 +1156,11 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) if ( plPlane.GetVersN() * vtExtr < 0) plPlane.Invert() ; + // creo un frame centrato sulla curva + Frame3d fr_pCompo ; + if ( ! fr_pCompo.Set( plPlane.GetPoint(), plPlane.GetVersN())) + return false ; + // unisco le parti allineate if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL, true)) return false ; @@ -1203,12 +1213,25 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) return false ; } + // recupero il grezzo + PtrOwner pStmRaw( CreateSurfTriMesh()) ; + if ( IsNull( pStmRaw) || + ! GetRaw( pStmRaw)) { + m_pMchMgr->SetLastError( 3025, "Error in SurfRoughing : RawPart not computable") ; + return false ; + } + + // inizializzo la classe di intersezione tra il piano e il grezzo ( serve per limitare le + // FlatRegions per il calcolo delle svuotature ) + IntersParPlanesSurfTm IPPStm( fr_pCompo, *pStmRaw) ; + // calcolo le regioni di svuotatura alle varie quote come differenza tra regioni da lavorare e regioni di silhouette INTVECTOR vPocket ; const double SILH_TOL = max( GetOffsR(), 1.) ; int nStep = max( 1, static_cast( ceil( dDepth / dOkStep))) ; double dStep = dDepth / nStep ; for ( int i = 1 ; i <= nStep ; ++ i) { + // regione di lavoro allo step corrente PtrOwner pSfr( CreateSurfFlatRegion()) ; if ( IsNull( pSfr) || ! pSfr->AddExtLoop( *pCompo)) { @@ -1216,14 +1239,28 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) return false ; } pSfr->Translate( -i * dStep * vtTool) ; + // piano di taglio per silhouette (compreso di offset longitudinale) Plane3d plCut = plPlane ; plCut.Translate( - ( i * dStep + GetOffsL()) * vtTool) ; + + // questa regione bisogna ridurla basandosi sulla geometria del grezzo, in modo da non lavorare + // parti in eccesso ; taglio il grezzo sul piano corrente + PtrOwner pSfrInt( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrInt) || + ! GetSfrByRawIntersection( pSfrInt, IPPStm, -i * dStep)) { + m_pMchMgr->SetLastError( 3027, "Error in SurfRoughing : Slicing Raw failed") ; + return false ; + } + pSfr->Intersect( *pSfrInt) ; + // per ogni superficie for ( int nSurfId : vSurfId) { + const ISurfTriMesh* pSurf = GetSurfTriMesh( m_pGeomDB->GetGeoObj( nSurfId)) ; Frame3d frSurf ; m_pGeomDB->GetGlobFrame( nSurfId, frSurf) ; Plane3d plCutL = plCut ; plCutL.ToLoc( frSurf) ; + // determino le regioni da non lavorare e le sottraggo POLYLINEVECTOR vPL ; if ( pSurf == nullptr || ! pSurf->GetSilhouette( plCutL, SILH_TOL, vPL)) { @@ -1244,10 +1281,21 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) return false ; } pSfrSil->ToGlob( frSurf) ; + + // sottraggo le parti da non lavorare pSfr->Subtract( *pSfrSil) ; + } - // se regione risultante non vuota, la salvo nel gruppo temporaneo + // se regione risultante non vuota if ( pSfr->IsValid()) { + + // determino i lati aperti + if ( ! ChooseCloseOrOpenEdge( pSfr, pStmRaw, false)) { + m_pMchMgr->SetLastError( 3026, "Error in SurfRoughing : Detecting open edges failed") ; + return false ; + } + + // la salvo nel gruppo temporaneo int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nTempId, Release( pSfr)) ; if ( nNewId == GDB_ID_NULL) { m_pMchMgr->SetLastError( 3024, "Error in SurfRoughing : region not computable") ; @@ -1276,6 +1324,132 @@ SurfRoughing::ProcessPath( int nPathId, int nTempId, int nPvId, int nClId) return true ; } +//---------------------------------------------------------------------------- +bool +SurfRoughing::GetRaw( ISurfTriMesh* pStmRaw) const +{ + + // controllo parametri, MachManager e database geometrico + if ( pStmRaw == nullptr || m_pMchMgr == nullptr || m_pGeomDB == nullptr) + return false ; + pStmRaw->AdjustTopology() ; + + // Id prima RawPart + int nRawId = m_pMchMgr->GetFirstRawPart() ; + + while ( nRawId != GDB_ID_NULL) { + // verifico che il grezzo compaia nella fase + if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) { + // recupero l'oggetto dal database con tale Id + int nRawSolidId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ; + const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( nRawSolidId) ; + // recupero il frame in cui si trova + Frame3d frRaw ; + m_pGeomDB->GetGlobFrame( nRawSolidId, frRaw) ; + if ( pGObj == nullptr) + return false ; + // controllo che sia una Trimesh + if ( pGObj->GetType() == SRF_TRIMESH) { + // Trimesh della parte p-esima + PtrOwner pStmRawPart( CloneSurfTriMesh( pGObj)) ; + if ( IsNull( pStmRawPart)) + return false ; + // porto la trimesh in globale + pStmRawPart->LocToLoc( frRaw, GLOB_FRM) ; + // lo aggiungo alla Trimesh complessiva + pStmRaw->Add( *pStmRawPart) ; + } + } + // passo al grezzo successivo + nRawId = m_pMchMgr->GetNextRawPart( nRawId) ; + } + + return pStmRaw->IsValid() && pStmRaw->GetTriangleCount() > 0 ; +} + +//---------------------------------------------------------------------------- +bool +SurfRoughing::GetSfrByRawIntersection( ISurfFlatRegion* pSfrInt, IntersParPlanesSurfTm IPPStm, double dDist) const +{ + // controllo dei parametri + if ( pSfrInt == nullptr) + return false ; + pSfrInt->Clear() ; + + // interseco la superficie alla quota corrente + PNTVECTOR vPnt ; + BIPNTVECTOR vBpt ; + TRIA3DVECTOR vTria ; + if ( ! IPPStm.GetInters( dDist, vPnt, vBpt, vTria)) + return false ; + + // definisco la tolleranza per i concatenamenti + double dToler = EPS_SMALL ; + + // costruisco la FlatRegion da ritornare + SurfFlatRegionByContours SfrByC ; + + // Considero l'intersezione solo con Curve ( escludo punti e superfici) + ChainCurves chainC ; + chainC.Init( false, dToler, int( vBpt.size())) ; + for ( int i = 0 ; i < int( vBpt.size()) ; ++ i) { + Vector3d vtDir = vBpt[i].second - vBpt[i].first ; + vtDir.Normalize() ; + if ( ! chainC.AddCurve( i + 1, vBpt[i].first, vtDir, vBpt[i].second, vtDir)) + return false ; + } + // recupero i percorsi concatenati + Point3d ptNear = ( vBpt.empty() ? ORIG : vBpt[0].first) ; + INTVECTOR vId ; + while ( chainC.GetChainFromNear( ptNear, false, vId)) { + // creo una curva composita + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo)) + return false ; + // recupero gli estremi dei segmenti, creo le linee e le inserisco nella composita + bool bAdded = true ; + for ( int i = 0 ; i < int( vId.size()) ; ++ i) { + // creo un segmento di retta + PtrOwner pLine( CreateCurveLine()) ; + if ( IsNull( pLine)) + return false ; + // recupero gli estremi ( non vanno mai invertiti per opzione di concatenamento) + int nInd = abs( vId[i]) - 1 ; + Point3d ptStart = ( bAdded ? vBpt[nInd].first : ptNear) ; + Point3d ptEnd = vBpt[nInd].second ; + // provo ad accodarlo alla composita + bAdded = ( Dist( ptStart, ptEnd) > dToler / 2 && + pLine->Set( ptStart, ptEnd) && + pCrvCompo->AddCurve( Release( pLine), true, dToler)) ; + ptNear = ( bAdded ? ptEnd : ptStart) ; + } + // se lunghezza curva inferiore a 5 volte la tolleranza, la ignoro + double dCrvLen ; + if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 5. * dToler) + continue ; + // se curva chiusa entro 5 volte la tolleranza ma considerata aperta, la chiudo bene + Point3d ptStart, ptEnd ; + if ( pCrvCompo->GetStartPoint( ptStart) && + pCrvCompo->GetEndPoint( ptEnd) && + AreSamePointEpsilon( ptStart, ptEnd, 5. * dToler) && + ! AreSamePointApprox( ptStart, ptEnd)) { + // porto il punto finale a coincidere esattamente con l'inizio + pCrvCompo->ModifyEnd( ptStart) ; + } + // unisco segmenti allineati + pCrvCompo->MergeCurves( 0.5 * dToler, ANG_TOL_STD_DEG) ; + // inserisco la curva nella FlatRegion + SfrByC.AddCurve( Release( pCrvCompo)) ; + } + + // recupero la regione da restituire + PtrOwner pSfrFromCrvs( SfrByC.GetSurf()) ; + if ( IsNull( pSfrFromCrvs) || ! pSfrFromCrvs->IsValid()) + return false ; + + return ( pSfrInt->CopyFrom( pSfrFromCrvs)) ; +} + //---------------------------------------------------------------------------- bool SurfRoughing::GetActiveSurfaces( INTVECTOR& vSurfId) const @@ -1425,6 +1599,8 @@ SurfRoughing::AddPocket( const INTVECTOR& vPocket, const Vector3d& vtTool, const // prendo il punto finale della prima curva, coś sono interno alla regione Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ; + if ( bOutStart) + ptEnd.Translate( ( 0.5 * m_TParams.m_dDiam) * vtStart) ; if ( IsPointInsidePolyLine( ptEnd, vPLExtLoops[nInd], 500 * EPS_SMALL)) break ; } @@ -1832,6 +2008,109 @@ SurfRoughing::GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) cons return min( GetFeed(), GetTipFeed() / abs( dCosMove)) ; } +//---------------------------------------------------------------------------- +bool +SurfRoughing::ResetCurveAllTempProp( ICurve* pCurve) const +{ + // controllo validità della curva + if ( pCurve == nullptr) + return false ; + + // metto a 0 le tmpProps della curva + pCurve->SetTempProp( 0, 0) ; + pCurve->SetTempProp( 0, 1) ; + + // ricavo la composita associata + ICurveComposite* pCC = GetCurveComposite( pCurve) ; + if ( pCC != nullptr) + for ( int i = 0 ; i < pCC->GetCurveCount() ; ++ i) { + // per ogni sottcurva metto a 0 le temProps + pCC->SetCurveTempProp( i, 0, 0) ; + pCC->SetCurveTempProp( i, 0, 1) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfRoughing::ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStm, const bool bOnIsClosed) const +{ + + // controllo parametri : + if ( pSfr == nullptr || ! pSfr->IsValid()) + return true ; // <- se superficie non valida, allora non ho niente da impostare sui suoi lati + if ( pStm == nullptr || ! pStm->IsValid()) + return false ; + + bool bStmClosed = pStm->IsClosed() ; + + // per ogni curva dei Loop della FlatRegion vengono presi 4 punti di controllo equidistanti. + // " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO NON SONO DENTRO AL GREZZO " ( bOnIsClosed = T) + // " IL LATO E' APERTO <=> TUTTI I PUNTI DI CONTROLLO DISTANO MENO DI 50 * EPS_SMALL DALLE FACCE ( bOnIsClosed = F) + + const int NUM_POINTS = 4 ; + PtrOwner pSfrWithTmpProps( CreateSurfFlatRegion()) ; + if ( IsNull( pSfrWithTmpProps)) + return false ; + + // scorro tutti i loop + for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++ c) { + for ( int l = 0 ; l < pSfr->GetLoopCount( c) ; ++ l) { + + // recupero la curva composita del Loop + PtrOwner pCrvCompoLoop( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ; + if ( IsNull( pCrvCompoLoop) || ! pCrvCompoLoop->IsValid()) + return false ; + // miglioro + pCrvCompoLoop->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ; + // resetto tutte le temp Prop + ResetCurveAllTempProp( pCrvCompoLoop) ; // -> tutto chiuso ( 0) + // scorro ogni sua sottocurva + for ( int u = 0 ; u < pCrvCompoLoop->GetCurveCount() ; ++ u) { + // recupero la sottocurva + const ICurve* pCrv = pCrvCompoLoop->GetCurve( u) ; + if ( pCrv == nullptr) + return false ; + // recupero i NUM_POINTS punti + bool bIsOn = true ; + for ( int p = 0 ; p < NUM_POINTS + 1 && bIsOn ; ++ p) { + double dPar = ( 1. / ( 1. * NUM_POINTS)) * p ; + Point3d ptPar ; + if ( ! pCrv->GetPointD1D2( dPar, ICurve::FROM_PLUS, ptPar)) + return false ; + // calcolo la distanza tra tale punto e la TriMesh + DistPointSurfTm distPtStm( ptPar, *pStm) ; + if ( bStmClosed) + bIsOn = ! distPtStm.IsPointInside() ; + else { + double dDist = 0. ; + bIsOn = distPtStm.GetDist( dDist) && dDist < 50 * EPS_SMALL ; + } + } + if (( bIsOn && ! bOnIsClosed) || ( ! bIsOn && bOnIsClosed)) + pCrvCompoLoop->SetCurveTempProp( u, 1, 0) ; + } + // aggiungo il Loop con Flag di lato Aperto/Chiuso alla superficie + if ( l == 0) { + if ( ! pSfrWithTmpProps->AddExtLoop( *pCrvCompoLoop)) + return false ; + } + else + if ( ! pSfrWithTmpProps->AddIntLoop( *pCrvCompoLoop)) + return false ; + } + } + + // sostituisco la superficie da restituire + if ( ! pSfrWithTmpProps->IsValid() || + ! pSfr->Clear() || + ! pSfr->CopyFrom( pSfrWithTmpProps)) + return false ; + + return pSfr->IsValid() && pSfr->GetChunkCount() != 0 ; +} + + //---------------------------------------------------------------------------- double SurfRoughing::GetRadiusForStartEndElevation( void) const diff --git a/SurfRoughing.h b/SurfRoughing.h index d218312..402bde5 100644 --- a/SurfRoughing.h +++ b/SurfRoughing.h @@ -19,6 +19,9 @@ #include "MachiningConst.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EgtNumUtils.h" +#include "/EgtDev/Include/EGkSurfFlatRegion.h" +#include "/EgtDev/Include/EGkSurfTriMesh.h" +#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h" class ICAvToolSurfTm ; @@ -86,9 +89,13 @@ class SurfRoughing : public Machining bool AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, const ICurveComposite* pRCrv, bool bSplitArcs, bool bNoneForced, Point3d& ptP1, double& dElev) ; + bool GetRaw( ISurfTriMesh* pStmRaw) const ; + bool GetSfrByRawIntersection( ISurfFlatRegion* pSfrInt, IntersParPlanesSurfTm IPPStm, double dDist) const ; bool GetActiveSurfaces( INTVECTOR& vSurfId) const ; double GetRightFeed( const Vector3d& vtMove, const Vector3d& vtTool) const ; double GetRadiusForStartEndElevation( void) const ; + bool ResetCurveAllTempProp( ICurve* pCurve) const ; + bool ChooseCloseOrOpenEdge( ISurfFlatRegion* pSfr, const ISurfTriMesh* pStmRaw, bool bOnIsClosed) const ; bool CalcRetCrv( const ICurveComposite* pCompo, const Point3d& ptRef, bool bOutStart, ICurveComposite* pRCrv) const ; bool VerifyLeadInHelix( const ICurveComposite* pCompo, const Point3d& ptCen, double dRad) const ;