diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index 99a9069..bb13488 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/WaterJetting.cpp b/WaterJetting.cpp index 24a1d97..3fba9b9 100644 --- a/WaterJetting.cpp +++ b/WaterJetting.cpp @@ -54,6 +54,8 @@ using namespace std ; // 3217 = "Error in WaterJetting : link outstroke xx" // 3218 = "Error in WaterJetting : post apply not calculable" // 3219 = "Error in WaterJetting : Tool loading failed" +// 3220 = "Error in WaterJetting : Center work not allowed with side angle" +// 3221 = "Error in WaterJetting : Path plane different from XY" // 3251 = "Warning in WaterJetting : Skipped entity (xx)" // 3252 = "Warning in WaterJetting : No machinable path" // 3253 = "Warning in WaterJetting : Tool name changed (xx)" @@ -359,6 +361,13 @@ WaterJetting::SetParam( int nType, double dVal) m_nStatus |= MCH_ST_PARAM_MODIF ; m_Params.m_dOverlap = dVal ; return true ; + case MPA_SIDEANGLE : + if ( ! m_Params.VerifySideAngle( dVal)) + return false ; + if ( ! AreSameAngValue( dVal, m_Params.m_dSideAngle)) + m_nStatus |= MCH_ST_PARAM_MODIF ; + m_Params.m_dSideAngle = dVal ; + return true ; case MPA_STARTADDLEN : if ( abs( dVal - m_Params.m_dStartAddLen) > EPS_MACH_LEN_PAR) m_nStatus |= MCH_ST_PARAM_MODIF ; @@ -541,6 +550,10 @@ WaterJetting::Preview( bool bRecalc) return false ; } + // verifiche per angolo di sbandamento + if ( ! VerifySideAngle()) + return false ; + // recupero gruppo per geometria di Preview int nPvId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_PV) ; // se non c'è, lo aggiungo @@ -630,6 +643,10 @@ WaterJetting::Apply( bool bRecalc, bool bPostApply) return false ; } + // verifiche per angolo di sbandamento + if ( ! VerifySideAngle()) + return false ; + // recupero gruppo per geometria di lavorazione (Cutter Location) int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ; // se non c'è, lo aggiungo @@ -795,6 +812,9 @@ WaterJetting::GetParam( int nType, double& dVal) const case MPA_OVERL : dVal = m_Params.m_dOverlap ; return true ; + case MPA_SIDEANGLE : + dVal = m_Params.m_dSideAngle ; + return true ; case MPA_STARTADDLEN : dVal = m_Params.m_dStartAddLen ; return true ; @@ -1193,6 +1213,21 @@ WaterJetting::Chain( int nGrpDestId) return true ; } +//---------------------------------------------------------------------------- +bool +WaterJetting::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( 3220, "Error in WaterJetting : Center work not allowed with side angle") ; + return false ; + } + } + return true ; +} + //---------------------------------------------------------------------------- bool WaterJetting::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) const @@ -1269,8 +1304,10 @@ WaterJetting::ProcessPath( int nPathId, int nPvId, int nClId) // recupero direzione utensile da estrusione e spessore Vector3d vtTool ; pCompo->GetExtrusion( vtTool) ; - if ( vtTool.IsSmall()) - vtTool = Z_AX ; + if ( ! ( vtTool - Z_AX).IsSmall()) { + m_pMchMgr->SetLastError( 3221, "Error in WaterJetting : Path plane different from XY") ; + return false ; + } double dThick ; pCompo->GetThickness( dThick) ; @@ -1324,7 +1361,8 @@ WaterJetting::ProcessPath( int nPathId, int nPvId, int nClId) } // se utensile non centrato, eseguo correzione raggio utensile ed eventuale offset - double dOffs = 0.5 * m_TParams.m_dDiam + GetOffsR() ; + double dSideCoeff = ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL ? 1. / cos( m_Params.m_dSideAngle * DEGTORAD) : 1) ; + double dOffs = 0.5 * m_TParams.m_dDiam * dSideCoeff + GetOffsR() ; if ( m_Params.m_nWorkSide != WJET_WS_CENTER && abs( dOffs) > EPS_SMALL) { // valore offset double dSignOffs = ( m_Params.m_nWorkSide == WJET_WS_RIGHT) ? dOffs : - dOffs ; @@ -1420,9 +1458,6 @@ WaterJetting::ProcessPath( int nPathId, int nPvId, int nClId) double dMaxElev ; if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) dElev = dMaxElev ; - // eventuale elevazione di fianco (solo per lama) - double dSideElev = 0 ; - FromString( ExtractInfo( m_Params.m_sUserNotes, "SideElev="), dSideElev) ; // verifico che il massimo materiale dell'utensile sia sensato const double MIN_MAXMAT = 1.0 ; @@ -1473,7 +1508,7 @@ WaterJetting::ProcessPath( int nPathId, int nPvId, int nClId) // Imposto dati comuni SetPathId( nPxId) ; - SetToolDir( vtTool) ; + //SetToolDir( vtTool) ; // Inserisco la lavorazione if ( ! AddStandardMilling( pCompo, vtTool, dDepth, dElev, bSplitArcs)) @@ -1559,7 +1594,9 @@ WaterJetting::GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) return false ; // calcolo la regione PtrOwner pSfr ; - pSfr.Set( GetSurfFlatRegionFromFatCurve( Release( pCrv), 0.5 * m_TParams.m_dDiam, false, false)) ; + double dSideCoeff = ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL ? 1. / cos( m_Params.m_dSideAngle * DEGTORAD) : 1) ; + double Rad = 0.5 * m_TParams.m_dDiam * dSideCoeff ; + pSfr.Set( GetSurfFlatRegionFromFatCurve( Release( pCrv), Rad, false, false)) ; if ( IsNull( pSfr)) return false ; // ne recupero il contorno @@ -1607,7 +1644,7 @@ WaterJetting::GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) //---------------------------------------------------------------------------- bool WaterJetting::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& vtTool, - double dDepth, double dElev, bool bSplitArcs) + double dDepth, double dElev, bool bSplitArcs) { // recupero distanze di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; @@ -1647,7 +1684,7 @@ WaterJetting::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& // determino se l'inizio dell'attacco è sopra il grezzo bool bAboveStart = GetPointAboveRaw( ptP1) ; // imposto versore correzione e ausiliario sul punto di partenza - CalcAndSetCorrAuxDir( pCompo, i) ; + CalcAndSetToolCorrAuxDir( pCompo, i) ; // aggiungo approccio // correggo elevazione iniziale per punto inizio attacco (se testa da sopra senza aggregato approccio mai Z-) if ( vtTool.z < - EPS_SMALL) @@ -1667,7 +1704,7 @@ WaterJetting::AddStandardMilling( const ICurveComposite* pCompo, const Vector3d& } } // imposto versore correzione e ausiliario sul punto di arrivo - CalcAndSetCorrAuxDir( pCompo, i+1) ; + CalcAndSetToolCorrAuxDir( pCompo, i+1) ; // elaborazioni sulla curva corrente if ( pCurve->GetType() == CRV_LINE) { ICurveLine* pLine = GetCurveLine( pCurve) ; @@ -2104,7 +2141,7 @@ WaterJetting::GetPointAboveRaw( const Point3d& ptP) const //---------------------------------------------------------------------------- bool -WaterJetting::CalcAndSetCorrAuxDir( const ICurveComposite* pCompo, double dU) +WaterJetting::CalcAndSetToolCorrAuxDir( const ICurveComposite* pCompo, double dU) { // verifico curva if ( pCompo == nullptr) @@ -2112,6 +2149,10 @@ WaterJetting::CalcAndSetCorrAuxDir( const ICurveComposite* pCompo, double dU) // se utensile centrato, direzione di correzione nulla if ( m_Params.m_nWorkSide == WJET_WS_CENTER) return true ; + // calcolo del versore fresa + Vector3d vtTool = CalcToolDir( pCompo, dU) ; + // imposto il versore fresa + SetToolDir( vtTool) ; // calcolo del versore correzione Vector3d vtCorr = CalcCorrDir( pCompo, dU) ; // imposto versore correzione @@ -2128,6 +2169,71 @@ WaterJetting::CalcAndSetCorrAuxDir( const ICurveComposite* pCompo, double dU) return true ; } +//---------------------------------------------------------------------------- +Vector3d +WaterJetting::CalcToolDir( const ICurveComposite* pCompo, double dU) +{ + // verifico curva + if ( pCompo == nullptr) + return V_NULL ; + // valore standard della direzione utensile + Vector3d vtTool = Z_AX ; + // se utensile centrato, direzione utensile sempre Z+ + if ( m_Params.m_nWorkSide == WJET_WS_CENTER) + return vtTool ; + // se angolo di fianco nullo, direzione utensile sempre Z+ + if ( abs( m_Params.m_dSideAngle) < EPS_ANG_SMALL) + return vtTool ; + // angolo di rotazione attorno a tg + bool bCcwRot = ( m_Params.m_nWorkSide == WJET_WS_LEFT) ; + double dCaRot = m_Params.m_dSideAngle * ( bCcwRot ? 1 : -1) ; + // dominio parametrico della curva + double dUs, dUe ; + pCompo->GetDomain( dUs, dUe) ; + // se inizio + if ( dU < dUs + EPS_ZERO) { + // recupero la tangente dopo + Point3d ptP ; + Vector3d vtN ; + pCompo->GetPointTang( dU, ICurve::FROM_PLUS, ptP, vtN) ; + vtTool.Rotate( vtN, dCaRot) ; + return vtTool ; + } + // se fine + else if ( dU > dUe - EPS_ZERO) { + // recupero la tangente prima + Point3d ptP ; + Vector3d vtN ; + pCompo->GetPointTang( dU, ICurve::FROM_MINUS, ptP, vtN) ; + vtTool.Rotate( vtN, dCaRot) ; + return vtTool ; + } + // altrimenti + else { + // recupero la tangente prima e dopo il punto + Point3d ptP1, ptP2 ; + Vector3d vtT1, vtT2 ; + pCompo->GetPointTang( dU, ICurve::FROM_MINUS, ptP1, vtT1) ; + pCompo->GetPointTang( dU, ICurve::FROM_PLUS, ptP2, vtT2) ; + // se coincidono + if ( AreSameVectorApprox( vtT1, vtT2)) { + Vector3d vtN = vtT1 ; + vtTool.Rotate( vtN, dCaRot) ; + return vtTool ; + } + // se sono opposte + else if ( AreOppositeVectorApprox( vtT1, vtT2)) { + return vtTool ; + } + // altrimenti + else { + Vector3d vtN = ( vtT1 + vtT2) / 2 ; + vtTool.Rotate( vtN, dCaRot) ; + return vtTool ; + } + } +} + //---------------------------------------------------------------------------- Vector3d WaterJetting::CalcCorrDir( const ICurveComposite* pCompo, double dU) @@ -2150,7 +2256,7 @@ WaterJetting::CalcCorrDir( const ICurveComposite* pCompo, double dU) Point3d ptP ; Vector3d vtN ; pCompo->GetPointTang( dU, ICurve::FROM_PLUS, ptP, vtN) ; - vtN.Rotate( m_vtTool, dCaRot) ; + vtN.Rotate( Z_AX, dCaRot) ; return vtN ; } // se fine @@ -2159,7 +2265,7 @@ WaterJetting::CalcCorrDir( const ICurveComposite* pCompo, double dU) Point3d ptP ; Vector3d vtN ; pCompo->GetPointTang( dU, ICurve::FROM_MINUS, ptP, vtN) ; - vtN.Rotate( m_vtTool, dCaRot) ; + vtN.Rotate( Z_AX, dCaRot) ; return vtN ; } // altrimenti @@ -2172,7 +2278,7 @@ WaterJetting::CalcCorrDir( const ICurveComposite* pCompo, double dU) // se coincidono if ( AreSameVectorApprox( vtT1, vtT2)) { Vector3d vtN = vtT1 ; - vtN.Rotate( m_vtTool, dCaRot) ; + vtN.Rotate( Z_AX, dCaRot) ; return vtN ; } // se sono opposte @@ -2183,7 +2289,7 @@ WaterJetting::CalcCorrDir( const ICurveComposite* pCompo, double dU) // altrimenti else { Vector3d vtN = ( vtT1 + vtT2) / 2 ; - vtN.Rotate( m_vtTool, dCaRot) ; + vtN.Rotate( Z_AX, dCaRot) ; return vtN ; } } diff --git a/WaterJetting.h b/WaterJetting.h index 253cf75..22d082c 100644 --- a/WaterJetting.h +++ b/WaterJetting.h @@ -71,6 +71,7 @@ class WaterJetting : public Machining bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; bool GetCurves( SelData Id, ICURVEPLIST& lstPC) ; bool Chain( int nGrpDestId) ; + bool VerifySideAngle( void) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) const ; bool GenerateMillingPv( int nPathId, const ICurveComposite* pCompo) ; @@ -90,7 +91,8 @@ class WaterJetting : public Machining double GetRadiusForStartEndElevation( void) const ; bool GetPointOutOfRaw( const Point3d& ptP, const Vector3d& vtTool, double dElev) const ; bool GetPointAboveRaw( const Point3d& ptP) const ; - bool CalcAndSetCorrAuxDir( const ICurveComposite* pCompo, double dU) ; + bool CalcAndSetToolCorrAuxDir( const ICurveComposite* pCompo, double dU) ; + Vector3d CalcToolDir( const ICurveComposite* pCompo, double dU) ; Vector3d CalcCorrDir( const ICurveComposite* pCompo, double dU) ; bool CalcOffset( ICurveComposite* pCompo, double dSignOffs) ; diff --git a/WaterJettingData.cpp b/WaterJettingData.cpp index 6fccf60..0b79840 100644 --- a/WaterJettingData.cpp +++ b/WaterJettingData.cpp @@ -448,7 +448,9 @@ WaterJettingData::VerifyLeadOutType( int nVal) const bool WaterJettingData::VerifySideAngle( double dVal) const { - return ( ( dVal > - EPS_SMALL && dVal < 90 + EPS_SMALL) || abs( dVal - 99) < EPS_SMALL) ; + const double MAX_SIDE_ANG = 75.0 + EPS_ANG_SMALL ; + const double AUTO_SIDE_ANG = 99 ; + return ( ( dVal > - MAX_SIDE_ANG && dVal < MAX_SIDE_ANG) || abs( dVal - AUTO_SIDE_ANG) < EPS_ANG_SMALL) ; } //----------------------------------------------------------------------------