diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index 34496ec..cd73529 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/WaterJetting.cpp b/WaterJetting.cpp index e6fcb4c..75eb93d 100644 --- a/WaterJetting.cpp +++ b/WaterJetting.cpp @@ -66,6 +66,7 @@ using namespace std ; //---------------------------------------------------------------------------- const double EXTRA_ACC_LEN = 0.5 ; const double INTANG_ROT_LEN = 5.0 ; +const double LEN_TOL = 100 * EPS_SMALL ; // valore limite per gestione degli angoli //---------------------------------------------------------------------------- USEROBJ_REGISTER( GetOperationClass( OPER_WATERJETTING), WaterJetting) ; @@ -1726,6 +1727,8 @@ WaterJetting::ProcessPath( int nPathId, int nPvId, int nClId) return false ; m_pGeomDB->SetName( nPxId, sPathName) ; m_pGeomDB->SetMaterial( nPxId, GREEN) ; + // Sistemazioni per angoli interni + AdjustPathForInternalAngles( pCompo) ; // creo l'anteprima del percorso if ( ! GeneratePreView( nPxId, pCompo, dAddedOverlap)) return false ; @@ -1783,6 +1786,7 @@ WaterJetting::GeneratePreView( int nPathId, const ICurveComposite* pCompo, doubl pCrv->TrimStartAtLen( dAddedOverlap) ; pCrv->Invert() ; } + bool bClosed = pCrv->IsClosed() ; // calcolo la regione ridotta PtrOwner pSfr ; double dSideCoeff = ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL ? 1. / cos( m_Params.m_dSideAngle * DEGTORAD) : 1) ; @@ -1805,19 +1809,35 @@ WaterJetting::GeneratePreView( int nPathId, const ICurveComposite* pCompo, doubl m_pGeomDB->SetMaterial( nRRId, INVISIBLE) ; // regione per attacco - PtrOwner pSfrLI( GenerateLeadInPreview( pCompo)) ; + PtrOwner pSfrLI( GenerateLeadInPreview( pCompo, bClosed)) ; if ( IsNull( pSfrLI)) return false ; - if ( pSfrLI->IsValid()) { - // se regione definita la aggiungo alla regione completa - if ( ! pSfrTot->Add( *pSfrLI)) - return false ; - // aggiungo nel DB - int nRLiId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pSfrLI)) ; - if ( nRLiId == GDB_ID_NULL) - return false ; - m_pGeomDB->SetName( nRLiId, MCH_PV_RLICUT) ; - m_pGeomDB->SetMaterial( nRLiId, INVISIBLE) ; + if ( pSfrLI->IsValid()) { + // se nessun attacco pSrfLI รจ solo un cerchio segnaposto, aggiungo la sua curva di bordo al DB + if ( GetLeadInType() == WJET_LI_NONE) { + PtrOwner pCrvLI( pSfrLI->GetLoop( 0, 0)) ; + if ( IsNull( pCrvLI)) + return false ; + int nCLIId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrvLI)) ; + // int nCLIId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pSfrLI)) ; + if ( nCLIId == GDB_ID_NULL) + return false ; + // assegno nome e colore + m_pGeomDB->SetName( nCLIId, MCH_PV_CUT) ; + m_pGeomDB->SetMaterial( nCLIId, colCut) ; + } + // altrimenti aggiungo la regione + else { + // aggiungo alla regione completa + if ( ! pSfrTot->Add( *pSfrLI)) + return false ; + // aggiungo nel DB + int nRLiId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pSfrLI)) ; + if ( nRLiId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nRLiId, MCH_PV_RLICUT) ; + m_pGeomDB->SetMaterial( nRLiId, INVISIBLE) ; + } } // regione per uscita @@ -1982,22 +2002,33 @@ WaterJetting::GeneratePreView( int nPathId, const ICurveComposite* pCompo, doubl //---------------------------------------------------------------------------- ISurfFlatRegion* -WaterJetting::GenerateLeadInPreview( const ICurveComposite* pCompo) +WaterJetting::GenerateLeadInPreview( const ICurveComposite* pCompo, bool bClosed) { // Creo la superficie PtrOwner pSfr( CreateSurfFlatRegion()) ; if ( IsNull( pSfr)) return nullptr ; - // Assegno il tipo - int nType = GetLeadInType() ; - if ( nType == WJET_LI_NONE) - return Release( pSfr) ; + double dSideCoeff = ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL ? 1. / cos( m_Params.m_dSideAngle * DEGTORAD) : 1) ; + double dRad = 0.49 * m_TParams.m_dDiam * dSideCoeff ; // non 0.5 per evitare problemi di coincidenza + // Recupero punto e direzione iniziali del percorso Point3d ptStart ; pCompo->GetStartPoint( ptStart) ; Vector3d vtStart ; pCompo->GetStartDir( vtStart) ; // Recupero versore estrusione Vector3d vtN ; pCompo->GetExtrusion( vtN) ; + + // Verifico il tipo + int nType = GetLeadInType() ; + if ( nType == WJET_LI_NONE) { + // se nessun attacco e curva chiusa creo segnaposto per indicare punto di inizio + if ( bClosed) { + pSfr.Set( GetSurfFlatRegionDisk( dRad)) ; + if ( ! IsNull( pSfr)) + pSfr->Translate( ptStart - ORIG) ; + } + return Release( pSfr) ; + } // Calcolo punto iniziale dell'attacco Point3d ptP1 ; if ( ! CalcLeadInStart( ptStart, vtStart, vtN, pCompo, ptP1)) @@ -2020,9 +2051,7 @@ WaterJetting::GenerateLeadInPreview( const ICurveComposite* pCompo) default : return nullptr ; } - // calcolo la regione - double dSideCoeff = ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL ? 1. / cos( m_Params.m_dSideAngle * DEGTORAD) : 1) ; - double dRad = 0.49 * m_TParams.m_dDiam * dSideCoeff ; // non 0.5 per evitare problemi di coincidenza + // calcolo la regione pSfr.Set( GetSurfFlatRegionFromFatCurve( Release( pCrv), dRad, false, false)) ; if ( IsNull( pSfr)) return nullptr ; @@ -2113,20 +2142,22 @@ WaterJetting::AddLoopsPreview( const ICurveComposite* pCompo, ISurfFlatRegion* p for ( int i = 1 ; i <= nMaxInd ; ++ i) { // curva corrente const ICurve* pCrvC = pCompo->GetCurve( i) ; - // Recupero versore estrusione - Vector3d vtN ; pCompo->GetExtrusion( vtN) ; - // direzione finale precedente + // curva precedente const ICurve* pCrvP = pCompo->GetCurve( i - 1) ; + // verifico che tratti abbiano lunghezza sufficiente per gestione angolo + double dLenC ; pCrvC->GetLength( dLenC) ; + double dLenP ; pCrvP->GetLength( dLenP) ; + if ( dLenC < LEN_TOL || dLenP < LEN_TOL) + continue ; + // angolo tra direzione finale precedente e direzione iniziale corrente Vector3d vtEnd ; pCrvP->GetEndDir( vtEnd) ; - // direzione iniziale corrente Vector3d vtStart ; pCrvC->GetStartDir( vtStart) ; - // angolo tra le direzioni double dAng ; vtEnd.GetAngleXY( vtStart, dAng) ; // se previsto e angolo esterno, si aggiunge l'anello if ( m_Params.m_nExtCornerType == WJET_EC_LOOP && IsExternalAngle( dAng)) { // curva dell'anello - PtrOwner pCompo( CreateCurveComposite()) ; - if ( IsNull( pCompo)) + PtrOwner pLoop( CreateCurveComposite()) ; + if ( IsNull( pLoop)) return false ; // lunghezza tratti lineari e loro punti estremi double dTgLen = 0.5 * m_TParams.m_dDiam * tan( 0.5 * dAng * DEGTORAD) ; @@ -2139,29 +2170,33 @@ WaterJetting::AddLoopsPreview( const ICurveComposite* pCompo, ISurfFlatRegion* p Point3d ptPe = ptP + vtEnd * dTgLen ; Point3d ptPs = ptP - vtStart * dTgLen ; // tratto prima dell'anello - if ( ! pCompo->AddPoint( ptP) || ! pCompo->AddLine( ptPe)) + if ( ! pLoop->AddPoint( ptP) || ! pLoop->AddLine( ptPe)) return false ; // anello - if ( ! pCompo->AddArcTg( ptPs)) + if ( ! pLoop->AddArcTg( ptPs)) return false ; + // verifico che l'anello non interferisca con la curva di lavoro + IntersCurveCurve intAC( *pLoop->GetLastCurve(), *pCompo) ; + if ( intAC.GetIntersCount() > 0) + continue ; // tratto dopo l'anello - if ( ! pCompo->AddLine( ptP)) + if ( ! pLoop->AddLine( ptP)) return false ; // lo porto in antiorario double dArea ; - if ( ! pCompo->GetAreaXY( dArea)) + if ( ! pLoop->GetAreaXY( dArea)) return false ; if ( dArea < 0) - pCompo->Invert() ; + pLoop->Invert() ; // ne eseguo l'offset double dSideCoeff = ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL ? 1. / cos( m_Params.m_dSideAngle * DEGTORAD) : 1) ; double Rad = 0.49 * m_TParams.m_dDiam * dSideCoeff ; // non 0.5 per evitare problemi di coincidenza - if ( ! pCompo->SimpleOffset( Rad, ICurve::OFF_FILLET)) + if ( ! pLoop->SimpleOffset( Rad, ICurve::OFF_FILLET)) return false ; // calcolo la regione PtrOwner pSfr ; SurfFlatRegionByContours SfrCntr ; - SfrCntr.AddCurve( Release( pCompo)) ; + SfrCntr.AddCurve( Release( pLoop)) ; pSfr.Set( SfrCntr.GetSurf()) ; // Unisco le due regioni if ( IsNull( pSfr) || ! pSPV->Add( *pSfr)) @@ -2268,8 +2303,6 @@ WaterJetting::AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTo const int ACC_PNT_NUM = 7 ; // lunghezza minima per poter suddividere con punti di accelerazione/decelerazione const double MIN_ACC_LEN = 1.0 ; - // valori limite per gestione degli angoli - const double LEN_TOL = 100 * EPS_SMALL ; // recupero distanze di sicurezza double dSafeZ = GetSafeZ() ; diff --git a/WaterJetting.h b/WaterJetting.h index 8399ba9..43b55a4 100644 --- a/WaterJetting.h +++ b/WaterJetting.h @@ -83,7 +83,7 @@ class WaterJetting : public Machining bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool AdjustPathForInternalAngles( ICurveComposite* pCompo) ; bool GeneratePreView( int nPathId, const ICurveComposite* pCompo, double dAddedOverlap) ; - ISurfFlatRegion* GenerateLeadInPreview( const ICurveComposite* pCompo) ; + ISurfFlatRegion* GenerateLeadInPreview( const ICurveComposite* pCompo, bool bClosed) ; ISurfFlatRegion* GenerateLeadOutPreview( const ICurveComposite* pCompo) ; bool AddLoopsPreview( const ICurveComposite* pCompo, ISurfFlatRegion* pSPV) ; bool AddStandardWj( const ICurveComposite* pCompo, const Vector3d& vtTool, bool bSplitArcs, double dAddedOverlap) ;