diff --git a/Disposition.cpp b/Disposition.cpp index b51f742..3443d37 100644 --- a/Disposition.cpp +++ b/Disposition.cpp @@ -275,8 +275,14 @@ Disposition::SetTable( const string& sTable) Table* pTab = pMch->GetTable( sTable) ; if ( pTab == nullptr) return false ; + Point3d ptPrevRef1 = m_ptRef1 ; m_ptRef1 = pTab->GetRef1() ; m_b3Area1 = pTab->GetArea1() ; + if ( ! m_sTabName.empty() && EqualNoCase( m_sTabName, sTable) && + ! AreSamePointApprox( ptPrevRef1, m_ptRef1)) { + string sOut = "Table Ref1 changed : (" + ToString( ptPrevRef1) + ") -> (" + ToString( m_ptRef1) +")" ; + LOG_INFO( GetEMkLogger(), sOut.c_str()) ; + } // salvo il nome e dichiaro tavola verificata m_sTabName = sTable ; m_bTabOk = true ; diff --git a/Drilling.cpp b/Drilling.cpp index be2a017..6cec4c5 100644 --- a/Drilling.cpp +++ b/Drilling.cpp @@ -393,6 +393,13 @@ Drilling::Preview( bool bRecalc) // altrimenti lo svuoto else m_pGeomDB->EmptyGroup( nPvId) ; + + // aggiorno dati geometrici dell'utensile + if ( ! UpdateToolData()) { + LOG_INFO( GetEMkLogger(), "Error in Drilling : UpdateToolData failed") ; + return false ; + } + // se lavorazione standard if ( m_Params.m_nSubType == DRI_SUB_STD) return StdandardProcess( bRecalc, nPvId, GDB_ID_NULL) ; @@ -428,6 +435,12 @@ Drilling::Apply( bool bRecalc) else m_pGeomDB->EmptyGroup( nClId) ; + // aggiorno dati geometrici dell'utensile + if ( ! UpdateToolData()) { + LOG_INFO( GetEMkLogger(), "Error in Drilling : UpdateToolData failed") ; + return false ; + } + // se lavorazione standard if ( m_Params.m_nSubType == DRI_SUB_STD) { if ( ! StdandardProcess( bRecalc, GDB_ID_NULL, nClId)) @@ -548,7 +561,7 @@ Drilling::Chain( int nGrpDestId) chainC.Init( true, dToler, int( vpCrvs.size())) ; for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) { // recupero la curva e il suo riferimento - ICurve* pCrv = Get( vpCrvs[i]) ; + ICurve* pCrv = vpCrvs[i] ; if ( pCrv == nullptr) continue ; // recupero i dati della curva necessari al concatenamento e li assegno @@ -581,7 +594,7 @@ Drilling::Chain( int nGrpDestId) bool bInvert = ( vnId2[i] < 0) ; vId2.emplace_back( m_vId[nId]) ; // recupero la curva - ICurve* pCrv = Get( vpCrvs[nId]) ; + ICurve* pCrv = vpCrvs[nId] ; // se necessario, la inverto if ( bInvert) pCrv->Invert() ; @@ -1028,6 +1041,28 @@ Drilling::GetToolData( void) const return m_TParams ; } +//---------------------------------------------------------------------------- +bool +Drilling::UpdateToolData( void) +{ + // recupero il gestore DB utensili della macchina corrente + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + // recupero l'utensile nel DB utensili + const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; + if ( pTdata == nullptr) + return false ; + // aggiorno i parametri + m_TParams = *pTdata ; + if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { + string sLog = "Warning in Drilling : tool name changed (" + + m_Params.m_sToolName + "->" + m_TParams.m_sName +")" ; + LOG_INFO( GetEMkLogger(), sLog.c_str()) ; + } + return true ; +} + //---------------------------------------------------------------------------- bool Drilling::GetGeometry( SELVECTOR& vIds) const diff --git a/Drilling.h b/Drilling.h index 91e1ac9..d16ee61 100644 --- a/Drilling.h +++ b/Drilling.h @@ -56,6 +56,7 @@ class Drilling : public Machining Drilling( void) ; private : + bool UpdateToolData( void) ; bool GetHoleData( SelData Id, Hole& hole) ; bool StdandardProcess( bool bRecalc, int nPvId, int nClId) ; bool AlongCurveProcess( bool bRecalc, int nPvId, int nClId) ; diff --git a/EgtMachKernel.rc b/EgtMachKernel.rc index c9c26cc..f1b8031 100644 Binary files a/EgtMachKernel.rc and b/EgtMachKernel.rc differ diff --git a/MachMgrMachines.cpp b/MachMgrMachines.cpp index 7fc1f53..872b7d7 100644 --- a/MachMgrMachines.cpp +++ b/MachMgrMachines.cpp @@ -50,7 +50,7 @@ MachMgr::LoadMachine( const string& sMachineName) // creo e carico il DB lavorazioni PtrOwner pMsMgr( new( nothrow) MachiningsMgr) ; string sMachsFile = m_sMachinesDir + "\\" + sMachineName + "\\" + MACHININGS_DIR + "\\" + MACHININGS_FILE ; - if ( IsNull( pMsMgr) || ! pMsMgr->Load( sMachsFile, Get( pTsMgr))) + if ( IsNull( pMsMgr) || ! pMsMgr->Load( sMachsFile, pTsMgr)) return false ; // salvo nel vettore m_vMachines.emplace_back( Release( pMch), Release( pTsMgr), Release( pMsMgr)) ; diff --git a/MachMgrRawParts.cpp b/MachMgrRawParts.cpp index 8d6380d..2b5060c 100644 --- a/MachMgrRawParts.cpp +++ b/MachMgrRawParts.cpp @@ -314,12 +314,12 @@ MachMgr::ModifyRawPart( int nRawId, int nCrvId, double dOverMat, double dZmin, d pMyCrv->Invert() ; // ne eseguo l'offset OffsetCurve OffsCrv ; - OffsCrv.Make( Get( pMyCrv), dOverMat, ICurve::OFF_EXTEND) ; + OffsCrv.Make( pMyCrv, dOverMat, ICurve::OFF_EXTEND) ; PtrOwner pOffsCrv( OffsCrv.GetLongerCurve()) ; if ( IsNull( pOffsCrv)) return false ; // creo il solido - PtrOwner pStm( GetSurfTriMeshByExtrusion( Get( pOffsCrv), Vector3d(0,0,dHeight), true)) ; + PtrOwner pStm( GetSurfTriMeshByExtrusion( pOffsCrv, Vector3d(0,0,dHeight), true)) ; if ( IsNull( pStm)) return false ; // cancello eventuali vecchi solidi e curve di outline diff --git a/Machining.cpp b/Machining.cpp index 7e5c40d..8accd5a 100644 --- a/Machining.cpp +++ b/Machining.cpp @@ -286,7 +286,7 @@ Machining::GetDistanceFromRawSide( int nPhase, const Point3d& ptP, const Vector3 if ( IsNull( pRay) || ! pRay->SetPVL( ptP, vtDir, RAY_LEN)) return false ; pRay->ToLoc( frStm) ; - IntersCurveCurve intCC( *Get( pRay), *pOut) ; + IntersCurveCurve intCC( *pRay, *pOut) ; IntCrvCrvInfo aInfo ; if ( intCC.GetIntCrvCrvInfo( 0, aInfo)) dDist = aInfo.IciA[0].dU * RAY_LEN ; diff --git a/MachiningsMgr.cpp b/MachiningsMgr.cpp index 7ae322e..cf51c88 100644 --- a/MachiningsMgr.cpp +++ b/MachiningsMgr.cpp @@ -833,6 +833,7 @@ MachiningsMgr::GetCurrMachiningParam( int nType, double& dVal) const if ( abs( dVal - UNKNOWN_PAR) > EPS_ANG_SMALL) return true ; // devo recuperare valore da utensile + dVal = 0 ; const ToolData* pTdata ; if ( ! m_pCurrMach->GetTool( m_pTsMgr, pTdata)) return false ; diff --git a/Milling.cpp b/Milling.cpp index b1a4fd4..0285f0a 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -392,6 +392,28 @@ Milling::GetToolData( void) const return m_TParams ; } +//---------------------------------------------------------------------------- +bool +Milling::UpdateToolData( void) +{ + // recupero il gestore DB utensili della macchina corrente + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + // recupero l'utensile nel DB utensili + const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; + if ( pTdata == nullptr) + return false ; + // aggiorno i parametri + m_TParams = *pTdata ; + if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { + string sLog = "Warning in Milling : tool name changed (" + + m_Params.m_sToolName + "->" + m_TParams.m_sName +")" ; + LOG_INFO( GetEMkLogger(), sLog.c_str()) ; + } + return true ; +} + //---------------------------------------------------------------------------- bool Milling::GetGeometry( SELVECTOR& vIds) const @@ -499,7 +521,7 @@ Milling::Chain( int nGrpDestId) chainC.Init( true, dToler, int( vpCrvs.size())) ; for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) { // recupero la curva e il suo riferimento - ICurve* pCrv = Get( vpCrvs[i]) ; + ICurve* pCrv = vpCrvs[i] ; if ( pCrv == nullptr) continue ; // recupero i dati della curva necessari al concatenamento e li assegno @@ -532,7 +554,7 @@ Milling::Chain( int nGrpDestId) bool bInvert = ( vnId2[i] < 0) ; vId2.emplace_back( m_vId[nId]) ; // recupero la curva - ICurve* pCrv = Get( vpCrvs[nId]) ; + ICurve* pCrv = vpCrvs[nId] ; // se necessario, la inverto if ( bInvert) pCrv->Invert() ; diff --git a/Milling.h b/Milling.h index 843e331..3f512be 100644 --- a/Milling.h +++ b/Milling.h @@ -54,6 +54,7 @@ class Milling : public Machining Milling( void) ; private : + bool UpdateToolData( void) ; bool VerifyGeometry( SelData Id, int& nSubs) ; ICurve* GetCurve( SelData Id) ; bool Chain( int nGrpDestId) ; diff --git a/SawFinishing.cpp b/SawFinishing.cpp index 045cb93..f6e74d7 100644 --- a/SawFinishing.cpp +++ b/SawFinishing.cpp @@ -26,6 +26,7 @@ #include "/EgtDev/Include/EgkOffsetCurve.h" #include "/EgtDev/Include/EgkOffsetCurveOnX.h" #include "/EgtDev/Include/EGkSfrCreate.h" +#include "/EgtDev/Include/EGkIntervals.h" #include "/EgtDev/Include/EGkUserObjFactory.h" #include "/EgtDev/Include/EGnStringKeyVal.h" #include "/EgtDev/Include/EgtPointerOwner.h" @@ -41,6 +42,13 @@ typedef std::vector POCRVVECTOR ; //---------------------------------------------------------------------------- const std::string MCH_SECTION = "Sect" ; const std::string MCH_GUIDE = "Guide" ; +enum nCrvClass { + CCL_SMALL = 0, + CCL_VERT = 1, + CCL_FLAT = 2, + CCL_FALL = 3, + CCL_RISE = 4 +}; //---------------------------------------------------------------------------- USEROBJ_REGISTER( "EMkSawFinishing", SawFinishing) ; @@ -221,6 +229,11 @@ SawFinishing::SetParam( int nType, int nVal) return false ; m_Params.m_nStepType = nVal ; return true ; + case MPA_SUBTYPE : + if ( ! m_Params.VerifySubType( nVal)) + return false ; + m_Params.m_nSubType = nVal ; + return true ; case MPA_LEADLINKTYPE : if ( ! m_Params.VerifyLeadLinkType( nVal)) return false ; @@ -267,6 +280,12 @@ SawFinishing::SetParam( int nType, double dVal) else m_Params.m_dTipFeed = dVal ; return true ; + case MPA_VERTFEED : + if ( abs( m_TParams.m_dFeed - dVal) < EPS_MACH_LEN_PAR) + m_Params.m_dVertFeed = 0 ; + else + m_Params.m_dVertFeed = dVal ; + return true ; case MPA_OFFSR : if ( abs( m_TParams.m_dOffsR - dVal) < EPS_MACH_LEN_PAR) m_Params.m_dOffsR = UNKNOWN_PAR ; @@ -282,6 +301,9 @@ SawFinishing::SetParam( int nType, double dVal) case MPA_SIDESTEP : m_Params.m_dSideStep = dVal ; return true ; + case MPA_STEP : + m_Params.m_dStep = dVal ; + return true ; case MPA_APPROX : m_Params.m_dApprox = dVal ; return true ; @@ -374,6 +396,12 @@ SawFinishing::Apply( bool bRecalc) m_pGeomDB->EmptyGroup( nAuxId) ; } + // aggiorno dati geometrici dell'utensile + if ( ! UpdateToolData()) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishing : UpdateToolData failed") ; + return false ; + } + // se necessario, preparo geometria e la inserisco sotto la geometria ausiliaria if ( bRecalc && ! AdjustGeometry( nAuxId)) return false ; @@ -392,9 +420,14 @@ SawFinishing::Apply( bool bRecalc) m_pGeomDB->EmptyGroup( nClId) ; // calcolo le passate - if ( ! CalculateToolPath( nAuxId, nClId)) - return false ; - m_nCuts = 1 ; + if ( m_Params.m_nSubType == SAWFIN_SUB_ALONG) { + if ( ! CalculateAlongToolPath( nAuxId, nClId)) + return false ; + } + else if ( m_Params.m_nSubType == SAWFIN_SUB_ACROSS) { + if ( ! CalculateAcrossToolPath( nAuxId, nClId)) + return false ; + } // se lavorazione vuota, esco if ( m_nCuts == 0) @@ -434,6 +467,9 @@ SawFinishing::GetParam( int nType, int& nVal) const case MPA_STEPTYPE : nVal = m_Params.m_nStepType ; return true ; + case MPA_SUBTYPE : + nVal = m_Params.m_nSubType ; + return true ; case MPA_LEADLINKTYPE : nVal = m_Params.m_nLeadLinkType ; return true ; @@ -461,6 +497,9 @@ SawFinishing::GetParam( int nType, double& dVal) const case MPA_TIPFEED : dVal = GetTipFeed() ; return true ; + case MPA_VERTFEED : + dVal = GetVertFeed() ; + return true ; case MPA_OFFSR : dVal =GetOffsR() ; return true ; @@ -470,6 +509,9 @@ SawFinishing::GetParam( int nType, double& dVal) const case MPA_SIDESTEP : dVal = m_Params.m_dSideStep ; return true ; + case MPA_STEP : + dVal = m_Params.m_dStep ; + return true ; case MPA_APPROX : dVal = m_Params.m_dApprox ; return true ; @@ -515,6 +557,28 @@ SawFinishing::GetToolData( void) const return m_TParams ; } +//---------------------------------------------------------------------------- +bool +SawFinishing::UpdateToolData( void) +{ + // recupero il gestore DB utensili della macchina corrente + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + // recupero l'utensile nel DB utensili + const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; + if ( pTdata == nullptr) + return false ; + // aggiorno i parametri + m_TParams = *pTdata ; + if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { + string sLog = "Warning in SawFinishing : tool name changed (" + + m_Params.m_sToolName + "->" + m_TParams.m_sName +")" ; + LOG_INFO( GetEMkLogger(), sLog.c_str()) ; + } + return true ; +} + //---------------------------------------------------------------------------- bool SawFinishing::GetGeometry( SELVECTOR& vIds) const @@ -658,8 +722,13 @@ SawFinishing::AdjustGeometry( int nAuxId) if ( nGrpSectId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nGrpSectId, MCH_SECTION) ; + // inserisco le sezioni e ne sistemo il senso di rotazione come CCW for ( auto& pSect : vpSects) { pSect->ToLoc( frSect) ; + double dArea ; + pSect->GetAreaXY( dArea) ; + if ( dArea < 0) + pSect->Invert() ; if ( m_pGeomDB->AddGeoObj( GDB_ID_NULL, nGrpSectId, ::Release( pSect)) == GDB_ID_NULL) return false ; } @@ -679,103 +748,33 @@ SawFinishing::AdjustGeometry( int nAuxId) //---------------------------------------------------------------------------- bool -SawFinishing::CalculateToolPath( int nAuxId, int nClId) +SawFinishing::CalculateAlongToolPath( int nAuxId, int nClId) { - // recupero il riferimento globale delle sezioni + // Recupero ed elaboro le sezioni per portarle ad essere la curva del centro in basso della lama + ICurve* pSect ; int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ; + if ( ! CalculateSection( nSectGrpId, pSect)) + return false ; + PtrOwner pCrv( pSect) ; + + // recupero il riferimento globale delle sezioni Frame3d frSect ; m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ; - // recupero le sezioni e il loro ingombro in globale - ICURVEPVECTOR vpSects ; - BBox3d b3Sect ; - int nSectId = m_pGeomDB->GetFirstInGroup( nSectGrpId) ; - while ( nSectId != GDB_ID_NULL) { - // recupero il puntatore alla curva - vpSects.emplace_back( ::GetCurve( m_pGeomDB->GetGeoObj( nSectId))) ; - if ( vpSects.back() == nullptr) - return false ; - // recupero l'ingombro della sezione corrente in globale - BBox3d b3Temp ; - vpSects.back()->GetBBox( frSect, b3Temp) ; - b3Sect.Add( b3Temp) ; - // passo alla successiva - nSectId = m_pGeomDB->GetNext( nSectId) ; - } - // recupero la linea guida - int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; - ICurve* pGuide = ::GetCurve( m_pGeomDB->GetGeoObj( nGuideId)) ; - if ( pGuide == nullptr) - return false ; - // recupero gli estremi della linea guida + // Recupero ed elaboro la linea guida Point3d ptGdStart, ptGdEnd ; - pGuide->GetStartPoint( ptGdStart) ; - pGuide->GetEndPoint( ptGdEnd) ; - // recupero la direzione della linea guida Vector3d vtGdDir ; - pGuide->GetStartDir( vtGdDir) ; - // per ora ammesse solo linee guida rettilinee dirette lungo X o Y - if ( ! AreSameOrOppositeVectorApprox( vtGdDir, X_AX) && - ! AreSameOrOppositeVectorApprox( vtGdDir, Y_AX)) { - LOG_INFO( GetEMkLogger(), "Error in SawFinishing : Guide Line not along X or Y") ; + int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; + if ( ! CalculateGuideLine( nGuideId, ptGdStart, ptGdEnd, vtGdDir)) return false ; - } - // recupero il box del grezzo + // recupero il box del grezzo in globale BBox3d b3Raw ; if ( ! GetRawGlobBox( m_nPhase, nGuideId, b3Raw) || b3Raw.IsEmpty()) { LOG_INFO( GetEMkLogger(), "Error in SawFinishing : Empty RawBox") ; return false ; } - // aggiusto la linea guida al bordo del box - if ( AreSameVectorApprox( vtGdDir, X_AX)) { - ptGdStart.x = b3Raw.GetMin().x ; - ptGdEnd.x = b3Raw.GetMax().x ; - } - else if ( AreOppositeVectorApprox( vtGdDir, X_AX)) { - ptGdStart.x = b3Raw.GetMax().x ; - ptGdEnd.x = b3Raw.GetMin().x ; - } - else if ( AreSameVectorApprox( vtGdDir, Y_AX)) { - ptGdStart.y = b3Raw.GetMin().y ; - ptGdEnd.y = b3Raw.GetMax().y ; - } - else { - ptGdStart.y = b3Raw.GetMax().y ; - ptGdEnd.y = b3Raw.GetMin().y ; - } - - // offset radiale delle sezioni per il sovramateriale - double dOffsR = GetOffsR() ; - POCRVVECTOR vpOvrCrvs ; - vpOvrCrvs.reserve( vpSects.size()) ; - for ( const auto& pSect : vpSects) { - OffsetCurve OffsCrv ; - OffsCrv.Make( pSect, dOffsR, ICurve::OFF_FILLET) ; - vpOvrCrvs.emplace_back( OffsCrv.GetLongerCurve()) ; - } - - // ricavo dalla sezione la curva per centro in basso della lama - double dOffsX = 0.5 * m_TParams.m_dThick ; - POCRVVECTOR vpCrvs ; - vpCrvs.reserve( vpOvrCrvs.size()) ; - for ( auto& pOvrCrv : vpOvrCrvs) { - OffsetCurveOnX OffsCrvX ; - OffsCrvX.Make( Get( pOvrCrv), dOffsX) ; - vpCrvs.emplace_back( OffsCrvX.GetLongerCurve()) ; - } - //int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_pGeomDB->GetParentId( nSectId), ::Release( pCrv)) ; - //m_pGeomDB->Save( nCrvId, "C:\\EgtData\\Varie\\Test\\aaa.nge", GDB_SV_TXT) ; - //pCrv.Set( ::GetCurve( m_pGeomDB->RemoveGeoObjAndErase( nCrvId))) ; - // determino l'ingombro delle sezioni in locale - BBox3d b3Crv ; - for ( auto& pCrv : vpCrvs) { - BBox3d b3Temp ; - pCrv->GetLocalBBox( b3Temp) ; - b3Crv.Add( b3Temp) ; - } - // valuto l'espressione dell'affondamento ExeLuaSetGlobNumVar( "TH", 0) ; ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ; @@ -804,28 +803,439 @@ SawFinishing::CalculateToolPath( int nAuxId, int nClId) SetToolDir( vtTool) ; SetCorrDir( vtCorr) ; - // Ciclo sulle passate - double dLargh = b3Crv.GetMax().x - b3Crv.GetMin().x ; - double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; - int nStep = static_cast( ceil( dLargh / dStep)) ; - dStep = dLargh / nStep ; - double dSectYMin = b3Crv.GetMin().y ; - double dSectYMax = b3Crv.GetMax().y ; - int nCount = 0 ; - for ( int i = 0 ; i <= nStep ; ++ i) { - // flag per primo e ultimo taglio - bool bFirst = ( i == 0) ; - bool bLast = ( i == nStep) ; - // determino l'ascissa della prima intersezione - double dX = b3Crv.GetMax().x - i * dStep ; - // determino l'ordinata della prima intersezione - double dY ; - double dYmin = dSectYMin ; - for ( auto& pCrv : vpCrvs) { - if ( ! GetHeightOnSection( Get( pCrv), dX, dYmin, dSectYMax, dY)) - return false ; - dYmin = dY ; + // Classifico i tratti a seconda della pendenza (salita, discesa, verticale, orizzontale) + INTVECTOR vnClass ; + ClassifySection( pCrv, vnClass) ; + + // Inizializzo contatore tagli + m_nCuts = 0 ; + + // Passate sui lati verticali + int nUmin = -1, nUmax = -1 ; + for ( size_t i = 0 ; i < vnClass.size() ; ++ i) { + // se lato verticale + if ( vnClass[i] == CCL_VERT) { + if ( nUmin < 0) + nUmin = int( i) ; + nUmax = int( i + 1) ; } + // se lato non verticale o ultimo + if ( vnClass[i] != CCL_VERT || i == vnClass.size() - 1) { + if ( nUmin >= 0) { + // eseguo la passata + if ( ! CalcAlongVerticalCuts( pCrv, nUmin, nUmax, frSect, + ptGdStart, ptGdEnd, vtGdDir, + dDepth, vtTool, vtCorr)) + return false ; + nUmin = - 1 ; + } + } + } + // Altre passate + int nStatus = CCL_VERT ; + nUmin = -1 ; + nUmax = -1 ; + bool bSkipMin = false, bSkipMax = false ; + for ( size_t i = 0 ; i < vnClass.size() ; ++ i) { + // se stato nullo (verticale) + if ( nStatus == CCL_VERT) { + if ( vnClass[i] == CCL_VERT || vnClass[i] == CCL_SMALL) + continue ; + else { + nStatus = vnClass[i] ; + nUmin = int( i) ; + nUmax = int( i + 1) ; + bSkipMin = true ; + } + } + // altrimenti + else { + // se classe piatto e trovo salita o discesa, converto a questo + if ( nStatus == CCL_FLAT && ( vnClass[i] == CCL_RISE || vnClass[i] == CCL_FALL)) + nStatus = vnClass[i] ; + // se si conserva la classe, aggiorno fine + if ( vnClass[i] == nStatus || vnClass[i] == CCL_FLAT || vnClass[i] == CCL_SMALL) + nUmax = int( i + 1) ; + // altrimenti calcolo il tratto precedente + else { + // calcolo il tratto + bSkipMax = ( vnClass[i] == CCL_VERT) ; + bool bInvert = ( nStatus == CCL_RISE) ; + if ( ! CalcAlongStdCuts( pCrv, nUmin, nUmax, + bSkipMin, bSkipMax, bInvert, frSect, + ptGdStart, ptGdEnd, vtGdDir, + dDepth, vtTool, vtCorr)) + return false ; + // aggiorno stato + if ( vnClass[i] == CCL_VERT) + nStatus = CCL_VERT ; + else { + nStatus = vnClass[i] ; + nUmin = int( i) ; + nUmax = int( i + 1) ; + } + bSkipMin = true ; + } + } + } + // se c'è qualcosa in sospeso + if ( nStatus != CCL_VERT) { + bSkipMax = false ; + bool bInvert = ( nStatus == CCL_RISE) ; + if ( ! CalcAlongStdCuts( pCrv, nUmin, nUmax, + bSkipMin, bSkipMax, bInvert, frSect, + ptGdStart, ptGdEnd, vtGdDir, + dDepth, vtTool, vtCorr)) + return false ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalculateAcrossToolPath( int nAuxId, int nClId) +{ + // Recupero ed elaboro le sezioni per portarle ad essere la curva del centro in basso della lama + ICurve* pSect ; + int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ; + if ( ! CalculateSection( nSectGrpId, pSect)) + return false ; + PtrOwner pCrv( pSect) ; + + // recupero il riferimento globale delle sezioni + Frame3d frSect ; + m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ; + + // Recupero ed elaboro la linea guida + Point3d ptGdStart, ptGdEnd ; + Vector3d vtGdDir ; + int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; + if ( ! CalculateGuideLine( nGuideId, ptGdStart, ptGdEnd, vtGdDir)) + return false ; + + // recupero il box del grezzo in globale + BBox3d b3Raw ; + if ( ! GetRawGlobBox( m_nPhase, nGuideId, b3Raw) || b3Raw.IsEmpty()) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishing : Empty RawBox") ; + return false ; + } + + // valuto l'espressione dell'affondamento + ExeLuaSetGlobNumVar( "TH", 0) ; + ExeLuaSetGlobNumVar( "RB", b3Raw.GetMax().z - b3Raw.GetMin().z) ; + double dDepth ; + if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishing : Depth not computable") ; + return false ; + } + + // creo gruppo per geometria di lavorazione + int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ; + if ( nPxId == GDB_ID_NULL) + return false ; + m_pGeomDB->SetName( nPxId, MCH_PATH + "1_1") ; + m_pGeomDB->SetMaterial( nPxId, GREEN) ; + + // Determino versori fresa e correzione + Vector3d vtTool, vtCorr ; + if ( ! CalculateToolAndCorrVersors( vtGdDir, m_Params.m_nHeadSide, vtTool, vtCorr)) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishing : CalculateToolAndCorrVersors") ; + return false ; + } + + // Approssimo la curva con una spezzata + const double LIN_TOL_STD = 0.05 ; + const double ANG_TOL_STD_DEG = 15 ; + PolyLine PL ; + if ( ! pCrv->ApproxWithLines( LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL)) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishing : ApproxWithLines") ; + return false ; + } + // Se non centrato, allungo inizio e fine dello spessore lama + if ( m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) { + // inizio + PL.Invert() ; + double dU ; + Point3d ptP ; + PL.GetLastUPoint( &dU, &ptP) ; + PL.AddUPoint( dU, ptP + Vector3d( m_TParams.m_dThick, 0, 0)) ; + PL.Invert() ; + // fine + PL.GetLastUPoint( &dU, &ptP) ; + PL.AddUPoint( dU, ptP - Vector3d( m_TParams.m_dThick, 0, 0)) ; + } + // La porto in globale + PL.ToGlob( frSect) ; + + // Calcolo eventuale anticipo dell'inizio + double dAddStart = 0 ; + if ( m_Params.m_nLeadLinkType == SAWFIN_LL_OUT) { + BBox3d b3PL ; + PL.GetLocalBBox( b3PL) ; + double dMaxElev = min( dDepth, b3Raw.GetMax().z - b3PL.GetMin().z) ; + dAddStart = (( dMaxElev < 0.5 * m_TParams.m_dDiam) ? sqrt( dMaxElev * m_TParams.m_dDiam - dMaxElev * dMaxElev) : 0.5 * m_TParams.m_dDiam) ; + } + + // Imposto dati comuni + SetPathId( nPxId) ; + SetToolDir( vtTool) ; + SetCorrDir( vtCorr) ; + + // Inizializzo contatore tagli + m_nCuts = 0 ; + + // Calcolo le passate + double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; + double dL = Dist( ptGdStart, ptGdEnd) + dAddStart ; + int nStep = static_cast( ceil( dL / dStep)) ; + dStep = dL / nStep ; + Point3d ptP ; + bool bFirst = true ; + for ( int i = 0 ; i <= nStep ; ++ i) { + // vettore di spostamento + Vector3d vtMove = vtGdDir * ( - dAddStart + i * dStep) ; + // lavoro la sezione + if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) { + if ( ! CalcAcrossOneWayCut( PL, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth)) + return false ; + } + else { + bool bFirst = ( i == 0) ; + if ( ! CalcAcrossZigZagCut( PL, vtMove, vtTool, vtCorr, b3Raw.GetMax().z, dDepth, bFirst)) + return false ; + } + } + // se ZigZag aggiungo risalita + if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG) { + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // aggiungo retrazione + Point3d ptEnd ; + if ( ! GetCurrPos( ptEnd)) + return false ; + double dElev = b3Raw.GetMax().z - ptEnd.z ; + if ( ! AddRetract( ptEnd, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + + return true ; +} + + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalculateSection( int nSectGrpId, ICurve*& pSect) +{ + // recupero le sezioni + ICURVEPVECTOR vpSects ; + int nSectId = m_pGeomDB->GetFirstInGroup( nSectGrpId) ; + while ( nSectId != GDB_ID_NULL) { + // recupero il puntatore alla curva + vpSects.emplace_back( ::GetCurve( m_pGeomDB->GetGeoObj( nSectId))) ; + if ( vpSects.back() == nullptr) + return false ; + // passo alla successiva + nSectId = m_pGeomDB->GetNext( nSectId) ; + } + + // elimino eventuali sottosquadra + const double LIN_TOL_STD = 0.1 ; + const double ANG_TOL_STD_DEG = 15 ; + POCRVVECTOR vpNucCrvs ; + vpNucCrvs.reserve( vpSects.size()) ; + for ( const auto& pSect : vpSects) { + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo) || + ! pCrvCompo->AddCurve( *pSect) || + ! pCrvCompo->RemoveUndercutOnY( LIN_TOL_STD, ANG_TOL_STD_DEG)) + return false ; + vpNucCrvs.emplace_back( Release( pCrvCompo)) ; + } + + // calcolo ordinamento delle curve secondo la X decrescente + typedef pair INDASC ; // coppia indice, ascissa + typedef vector INDASCVECTOR ; // vettore di coppie indice, ascissa + INDASCVECTOR vIAsc ; + vIAsc.reserve( vpNucCrvs.size()) ; + for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { + Point3d ptStart ; + if ( ! vpNucCrvs[i]->GetStartPoint( ptStart)) + return false ; + vIAsc.emplace_back( i, ptStart.x) ; + } + std::sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) + { return a.second > b.second ; }) ; + + // unisco le diverse curve (ora aperte) in un unico profilo + PtrOwner pCurve( CreateCurveComposite()) ; + if ( IsNull( pCurve)) + return false ; + bool bFirst = true ; + for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { + if ( ! bFirst) { + Point3d ptStart ; + if ( ! vpNucCrvs[vIAsc[i].first]->GetStartPoint( ptStart) || + ! pCurve->AddLine( ptStart)) + return false ; + } + if ( ! pCurve->AddCurve( Release( vpNucCrvs[vIAsc[i].first]))) + return false ; + bFirst = false ; + } + + // offset radiale delle sezioni per il sovramateriale + double dOffsR = GetOffsR() ; + PtrOwner pOvrCrv ; + OffsetCurve OffsCrv ; + OffsCrv.Make( pCurve, dOffsR, ICurve::OFF_FILLET) ; + pOvrCrv.Set( OffsCrv.GetLongerCurve()) ; + + // ricavo dalla sezione la curva per centro in basso della lama + double dOffsX = 0.5 * m_TParams.m_dThick ; + PtrOwner pCrv ; + OffsetCurveOnX OffsCrvX ; + OffsCrvX.Make( pOvrCrv, dOffsX) ; + pCrv.Set( OffsCrvX.GetLongerCurve()) ; + + //int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ::Release( pCrv)) ; + //m_pGeomDB->Save( nCrvId, "C:\\EgtData\\Varie\\Test\\aaa.nge", GDB_SV_TXT) ; + //pCrv.Set( ::GetCurveComposite( m_pGeomDB->RemoveGeoObjAndErase( nCrvId))) ; + + pSect = Release( pCrv) ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalculateGuideLine( int nGuideId, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir) +{ + // recupero la linea guida + ICurve* pGuide = ::GetCurve( m_pGeomDB->GetGeoObj( nGuideId)) ; + if ( pGuide == nullptr) + return false ; + // recupero il suo riferimento + Frame3d frGdL ; + m_pGeomDB->GetGlobFrame( nGuideId, frGdL) ; + // porto la curva in globale (dovrebbe già avere riferimento globale) + pGuide->ToGlob( frGdL) ; + // recupero gli estremi della linea guida + pGuide->GetStartPoint( ptGdStart) ; + pGuide->GetEndPoint( ptGdEnd) ; + // recupero la direzione della linea guida + pGuide->GetStartDir( vtGdDir) ; + // per ora ammesse solo linee guida rettilinee dirette lungo X o Y + if ( ! AreSameOrOppositeVectorApprox( vtGdDir, X_AX) && + ! AreSameOrOppositeVectorApprox( vtGdDir, Y_AX)) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishing : Guide Line not along X or Y") ; + return false ; + } + + // recupero il box del grezzo in globale + BBox3d b3Raw ; + if ( ! GetRawGlobBox( m_nPhase, nGuideId, b3Raw) || b3Raw.IsEmpty()) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishing : Empty RawBox") ; + return false ; + } + + // aggiusto la linea guida al bordo del box + if ( AreSameVectorApprox( vtGdDir, X_AX)) { + ptGdStart.x = b3Raw.GetMin().x ; + ptGdEnd.x = b3Raw.GetMax().x ; + } + else if ( AreOppositeVectorApprox( vtGdDir, X_AX)) { + ptGdStart.x = b3Raw.GetMax().x ; + ptGdEnd.x = b3Raw.GetMin().x ; + } + else if ( AreSameVectorApprox( vtGdDir, Y_AX)) { + ptGdStart.y = b3Raw.GetMin().y ; + ptGdEnd.y = b3Raw.GetMax().y ; + } + else { + ptGdStart.y = b3Raw.GetMax().y ; + ptGdEnd.y = b3Raw.GetMin().y ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::ClassifySection( ICurve* pCrv, INTVECTOR& vnClass) +{ + const ICurveComposite* pCompo = GetCurveComposite( pCrv) ; + if ( pCompo != nullptr) { + int Ind = 0 ; + const ICurve* pSimpCrv = pCompo->GetFirstCurve() ; + while ( pSimpCrv != nullptr) { + // analizzo la curva + Point3d ptStart, ptEnd ; + pSimpCrv->GetStartPoint( ptStart) ; + pSimpCrv->GetEndPoint( ptEnd) ; + if ( AreSamePointXYEpsilon( ptEnd, ptStart, 10 * EPS_SMALL)) + vnClass.push_back( CCL_SMALL) ; + else if ( abs( ptEnd.x - ptStart.x) < EPS_SMALL) + vnClass.push_back( CCL_VERT) ; + else if ( abs( ptEnd.y - ptStart.y) < EPS_SMALL) + vnClass.push_back( CCL_FLAT) ; + else if ( ptEnd.y > ptStart.y) + vnClass.push_back( CCL_RISE) ; + else + vnClass.push_back( CCL_FALL) ; + // passo alla curva successiva + ++ Ind ; + pSimpCrv = pCompo->GetNextCurve() ; + } + } + else { + Point3d ptStart, ptEnd ; + pCrv->GetStartPoint( ptStart) ; + pCrv->GetEndPoint( ptEnd) ; + if ( AreSamePointXYEpsilon( ptEnd, ptStart, 10 * EPS_SMALL)) + vnClass.push_back( CCL_SMALL) ; + else if ( abs( ptEnd.x - ptStart.x) < EPS_SMALL) + vnClass.push_back( CCL_VERT) ; + else if ( abs( ptEnd.y - ptStart.y) < EPS_SMALL) + vnClass.push_back( CCL_FLAT) ; + else if ( ptEnd.y > ptStart.y) + vnClass.push_back( CCL_RISE) ; + else + vnClass.push_back( CCL_FALL) ; + } + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalcAlongVerticalCuts( ICurve* pSect, int nUmin, int nUmax, const Frame3d& frSect, + const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, + double dDepth, const Vector3d& vtTool, const Vector3d& vtCorr) +{ + // Ingombro del taglio + BBox3d b3Cut ; + for ( int i = nUmin ; i <= nUmax ; ++ i) { + Point3d ptP ; + if ( pSect->GetPointD1D2( i, ICurve::FROM_MINUS, ptP)) + b3Cut.Add( ptP) ; + } + if ( b3Cut.IsEmpty()) + return false ; + // ascissa + double dX = ( b3Cut.GetMin().x + b3Cut.GetMax().x) / 2 ; + // Calcolo dello step tra le passate + double dL = b3Cut.GetMax().y - b3Cut.GetMin().y ; + if ( dL < 10 * EPS_SMALL) + return true ; + double dStep = max( m_Params.m_dStep, 10 * EPS_SMALL) ; + int nStep = static_cast( ceil( dL / dStep)) ; + dStep = dL / nStep ; + // Ciclo sulle passate + double dLastElev ; + Point3d ptStartPrev ; + for ( int i = 0 ; i <= nStep ; ++ i) { + // ordinata + double dY = b3Cut.GetMax().y - i * dStep ; // estremi del taglio Vector3d vtMove = dX * frSect.VersX() + dY * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ; Point3d ptStart = ptGdStart + vtMove ; @@ -846,24 +1256,124 @@ SawFinishing::CalculateToolPath( int nAuxId, int nClId) ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ; dElev = dMaxDepth ; } - // esecuzione del taglio - if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) { - if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast)) - return false ; - } - else { - if ( ! CalculateZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, nCount)) - return false ; + // se diverso da precedente, eseguo il taglio + bool bFirst = ( i == 0) ; + if ( bFirst || ! AreSamePointEpsilon( ptStart, ptStartPrev, 10 * EPS_SMALL)) { + if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) { + if ( ! CalcAlongOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, true)) + return false ; + } + else { + if ( ! CalcAlongZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, true, bFirst)) + return false ; + } + // salvo dati correnti + dLastElev = dElev ; + ptStartPrev = ptStart ; } } + // se ZigZag e non centrato aggiungo risalita + if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG && m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) { + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // aggiungo retrazione + Point3d ptNewEnd ; + if ( ! GetCurrPos( ptNewEnd) || ! AddRetract( ptNewEnd, vtCorr, dSafeZ, dLastElev, dAppr)) + return false ; + } return true ; } //---------------------------------------------------------------------------- bool -SawFinishing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, - const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast) +SawFinishing::CalcAlongStdCuts( ICurve* pSect, double dUmin, double dUmax, + bool bSkipMin, bool bSkipMax, bool bInvert, const Frame3d& frSect, + const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, + double dDepth, const Vector3d& vtTool, const Vector3d& vtCorr) +{ + // Calcolo dello step tra le passate + double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; + double dLmin, dLmax ; + if ( ! pSect->GetLengthAtParam( dUmin, dLmin) || ! pSect->GetLengthAtParam( dUmax, dLmax)) + return false ; + double dL = dLmax - dLmin ; + if ( dL < 10 * EPS_SMALL) + return true ; + int nStep = static_cast( ceil( dL / dStep)) ; + dStep = dL / nStep ; + // Ciclo sulle passate + double dLastElev ; + Point3d ptStartPrev ; + bool bSkipIni = ( bInvert ? bSkipMax : bSkipMin) ; + bool bSkipFin = ( bInvert ? bSkipMin : bSkipMax) ; + int nIni = ( bSkipIni ? 1 : 0) ; + int nFin = ( bSkipFin ? nStep - 1 : nStep) ; + for ( int i = nIni ; i <= nFin ; ++ i) { + // calcolo del parametro + double dLcurr = ( bInvert ? dLmax - i * dStep : dLmin + i * dStep) ; + double dU ; + pSect->GetParamAtLength( dLcurr, dU) ; + // coordinate nel punto + Point3d ptP ; + pSect->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP) ; + // estremi del taglio + Vector3d vtMove = ptP.x * frSect.VersX() + ptP.y * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ; + Point3d ptStart = ptGdStart + vtMove ; + Point3d ptEnd = ptGdEnd + vtMove ; + // determino l'elevazione del taglio + Vector3d vtThick = vtTool * m_TParams.m_dThick ; + double dElev, dElev2 ; + if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || + ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { + LOG_INFO( GetEMkLogger(), "Error in SawFinishinging : GetElevation") ; + return false ; + } + dElev = max( dElev, dElev2) ; + // la confronto con il massimo affondamento e con la massima lavorazione della lama + double dMaxDepth = min( dDepth, m_TParams.m_dMaxMat) ; + if ( dElev > dMaxDepth) { + ptStart += Vector3d( 0, 0, dElev - dMaxDepth) ; + ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ; + dElev = dMaxDepth ; + } + // se diverso da precedente, eseguo il taglio + bool bFirst = ( i == nIni) ; + if ( bFirst || ! AreSamePointEpsilon( ptStart, ptStartPrev, 10 * EPS_SMALL)) { + if ( m_Params.m_nStepType != SAWFIN_ST_ZIGZAG) { + if ( ! CalcAlongOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, false)) + return false ; + } + else { + if ( ! CalcAlongZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, false, bFirst)) + return false ; + } + // salvo dati correnti + dLastElev = dElev ; + ptStartPrev = ptStart ; + } + } + // se ZigZag e non centrato aggiungo risalita + if ( m_Params.m_nStepType == SAWFIN_ST_ZIGZAG && m_Params.m_nLeadLinkType != SAWFIN_LL_CENT) { + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + // aggiungo retrazione + Point3d ptNewEnd ; + if ( ! GetCurrPos( ptNewEnd) || ! AddRetract( ptNewEnd, vtCorr, dSafeZ, dLastElev, dAppr)) + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalcAlongOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, + const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bVert) { // recupero distanza di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; @@ -883,35 +1393,34 @@ SawFinishing::CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, } // Sempre una sola passata - { - // 1 -> approccio - if ( ! AddApproach( ptNewStart, vtCorr, bFirst, dSafeZ, dElev, dAppr)) - return false ; - // 2 -> movimento in affondo al punto iniziale - SetFlag( 0) ; - if ( m_Params.m_nLeadLinkType != SAWFIN_LL_OUT) - SetFeed( GetTipFeed()) ; - else - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) - return false ; - // 3 -> movimento di lato al punto finale - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptEnd) == GDB_ID_NULL) - return false ; - // 4 -> retrazione - if ( ! AddRetract( ptEnd, vtCorr, dSafeZ, dElev, dAppr)) - return false ; - } + // 1 -> approccio + if ( ! AddApproach( ptNewStart, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + // 2 -> movimento in affondo al punto iniziale + SetFlag( 0) ; + if ( m_Params.m_nLeadLinkType != SAWFIN_LL_OUT) + SetFeed( GetTipFeed()) ; + else + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + // 3 -> movimento di lato al punto finale + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptEnd) == GDB_ID_NULL) + return false ; + // 4 -> retrazione + if ( ! AddRetract( ptEnd, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + // incremento contatore passate + ++ m_nCuts ; return true ; } //---------------------------------------------------------------------------- bool -SawFinishing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, - const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, - int& nCount) +SawFinishing::CalcAlongZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, + const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bVert, bool bFirst) { // recupero distanza di sicurezza double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; @@ -941,100 +1450,211 @@ SawFinishing::CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, ptNewEnd = ptEnd + vtDir * ( dDeltaT + dAppr) ; } // le passate dispari sono al contrario - if ( ( nCount % 2) != 0) { + if ( ( m_nCuts % 2) != 0) { swap( ptOriStart, ptOriEnd) ; swap( ptNewStart, ptNewEnd) ; vtNewDir.Invert() ; } // Sempre una sola passata - { - // 1 -> approccio - if ( bFirst || m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { - if ( ! AddApproach( ptNewStart, vtCorr, bFirst, dSafeZ, dElev, dAppr)) - return false ; - } - // 2 -> movimento in affondo al punto iniziale - SetFlag( 0) ; - // con attacco centrato sono sul materiale e devo usare feed di testa - if ( m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { - SetFeed( GetTipFeed()) ; + // 1 -> approccio + if ( bFirst || m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { + if ( ! AddApproach( ptNewStart, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + // 2 -> movimento in affondo al punto iniziale + SetFlag( 0) ; + // con attacco centrato sono sul materiale e devo usare feed di testa + if ( m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { + SetFeed( GetTipFeed()) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; + } + // con attacco fuori sono in aria + else { + if ( bFirst) { + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) return false ; } - // con attacco fuori sono in aria else { - if ( bFirst) { - SetFeed( GetFeed()) ; + Point3d ptLast ; + GetCurrPos( ptLast) ; + double dDiff = ( ptNewStart - ptLast) * vtNewDir ; + // se precedente e corrente sono fuori allo stesso modo + if ( abs( dDiff) < 10 * EPS_SMALL) { + // inizio nuova passata + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) return false ; } + // se il precedente è più fuori + else if ( dDiff > 0) { + // allungo nuova passata + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewStart - dDiff * vtNewDir) == GDB_ID_NULL) + return false ; + } + // se il corrente è più fuori else { - Point3d ptLast ; - GetCurrPos( ptLast) ; - double dDiff = ( ptNewStart - ptLast) * vtNewDir ; - // se precedente e corrente sono fuori allo stesso modo - if ( abs( dDiff) < 10 * EPS_SMALL) { - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) - return false ; - } - // se il precedente è più fuori - else if ( dDiff > 0) { - // allungo nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart - dDiff * vtNewDir) == GDB_ID_NULL) - return false ; - } - // se il corrente è più fuori - else { - // allungo passata precedente - if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL) - return false ; - // inizio nuova passata - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) - return false ; - } + // allungo passata precedente + if ( AddLinearMove( ptLast + dDiff * vtNewDir) == GDB_ID_NULL) + return false ; + // inizio nuova passata + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewStart) == GDB_ID_NULL) + return false ; } } - // 3 -> movimento di lato al punto finale - if ( m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL) - return false ; - } - else { - SetFeed( GetFeed()) ; - if ( AddLinearMove( ptOriEnd) == GDB_ID_NULL) - return false ; - SetFeed( GetEndFeed()) ; - if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL) - return false ; - } - // 4 -> retrazione - if ( bLast || m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { - if ( ! AddRetract( ptNewEnd, vtCorr, dSafeZ, dElev, dAppr)) - return false ; - } - // incremento contatore passate - ++ nCount ; } + // 3 -> movimento di lato al punto finale + if ( m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL) + return false ; + } + else { + SetFeed( ( bVert ? GetVertFeed() : GetFeed())) ; + if ( AddLinearMove( ptOriEnd) == GDB_ID_NULL) + return false ; + SetFeed( GetEndFeed()) ; + if ( AddLinearMove( ptNewEnd) == GDB_ID_NULL) + return false ; + } + // 4 -> retrazione + if ( m_Params.m_nLeadLinkType == SAWFIN_LL_CENT) { + if ( ! AddRetract( ptNewEnd, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + // incremento contatore passate + ++ m_nCuts ; return true ; } //---------------------------------------------------------------------------- bool -SawFinishing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFirst, - double dSafeZ, double dElev, double dAppr) +SawFinishing::CalcAcrossOneWayCut( const PolyLine& PL, const Vector3d& vtMove, + const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth) +{ + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + + Point3d ptP ; + // 1 -> approccio + bool bFound = PL.GetFirstPoint( ptP) ; + if ( bFound) { + ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ; + ptP.z = max( ptP.z, dRawZ - dDepth) ; + double dElev = dRawZ - ptP.z ; + if ( ! AddApproach( ptP, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + // 2 -> movimento lungo la sezione + Point3d ptPrev ; + GetCurrPos( ptPrev) ; + while ( bFound) { + // se diverso da precedente, movimento al punto + if ( ! AreSamePointEpsilon( ptP, ptPrev, 10 * EPS_SMALL)) { + Vector3d vtDelta = ptP - ptPrev ; + if ( vtDelta.z > - EPS_SMALL) + SetFeed( GetFeed()) ; + else { + double dC = sqrt( 1 + ( vtDelta.x * vtDelta.x + vtDelta.y * vtDelta.y) / ( vtDelta.z * vtDelta.z)) ; + double dF = min( GetFeed(), dC * GetTipFeed()) ; + SetFeed( dF) ; + } + if ( AddLinearMove( ptP) == GDB_ID_NULL) + return false ; + ptPrev = ptP ; + } + // recupero punto successivo + bFound = PL.GetNextPoint( ptP) ; + if ( bFound) { + ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ; + ptP.z = max( ptP.z, dRawZ - dDepth) ; + } + } + // 3-> retrazione + { + double dElev = dRawZ - ptP.z ; + if ( ! AddRetract( ptP, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + // incremento contatore passate + ++ m_nCuts ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::CalcAcrossZigZagCut( const PolyLine& PL, const Vector3d& vtMove, + const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth, bool bFirst) +{ + // recupero distanza di sicurezza + double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ; + // lunghezza di approccio/retrazione + double dAppr = m_Params.m_dStartPos ; + + // sezione da invertire + bool bInvert = (( m_nCuts % 2) != 0) ; + + Point3d ptP ; + bool bFound = ( bInvert ? PL.GetLastPoint( ptP) : PL.GetFirstPoint( ptP)) ; + // 1 -> approccio + if ( bFound) { + ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ; + ptP.z = max( ptP.z, dRawZ - dDepth) ; + if ( bFirst) { + double dElev = dRawZ - ptP.z ; + if ( ! AddApproach( ptP, vtCorr, dSafeZ, dElev, dAppr)) + return false ; + } + } + // 2 -> movimento lungo la sezione + Point3d ptPrev ; + GetCurrPos( ptPrev) ; + while ( bFound) { + // se diverso da precedente, movimento al punto + if ( ! AreSamePointEpsilon( ptP, ptPrev, 10 * EPS_SMALL)) { + Vector3d vtDelta = ptP - ptPrev ; + if ( vtDelta.z > - EPS_SMALL) + SetFeed( GetFeed()) ; + else { + double dC = sqrt( 1 + ( vtDelta.x * vtDelta.x + vtDelta.y * vtDelta.y) / ( vtDelta.z * vtDelta.z)) ; + double dF = min( GetFeed(), dC * GetTipFeed()) ; + SetFeed( dF) ; + } + if ( AddLinearMove( ptP) == GDB_ID_NULL) + return false ; + ptPrev = ptP ; + } + // recupero punto successivo + bFound = ( bInvert ? PL.GetPrevPoint( ptP) : PL.GetNextPoint( ptP)) ; + if ( bFound) { + ptP += vtMove - 0.5 * m_TParams.m_dThick * vtTool ; + ptP.z = max( ptP.z, dRawZ - dDepth) ; + } + } + // incremento contatore passate + ++ m_nCuts ; + + return true ; +} + +//---------------------------------------------------------------------------- +bool +SawFinishing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, + double dSafeZ, double dElev, double dAppr) { // se distanza di sicurezza minore di distanza di inizio if ( dSafeZ < m_Params.m_dStartPos + 10 * EPS_SMALL) { // 1 -> punto sopra inizio Point3d ptP1 = ptP + vtCorr * ( dElev + dAppr) ; - if ( bFirst) { + if ( m_nCuts == 0) { SetFlag( 1) ; if ( AddRapidStart( ptP1) == GDB_ID_NULL) return false ; @@ -1049,7 +1669,7 @@ SawFinishing::AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFir // 1a -> punto sopra inizio Point3d ptP1b = ptP + vtCorr * ( dElev + dAppr) ; Point3d ptP1a = ptP1b + Z_AX * ( dSafeZ - m_Params.m_dStartPos) ; - if ( bFirst) { + if ( m_nCuts == 0) { SetFlag( 1) ; if ( AddRapidStart( ptP1a) == GDB_ID_NULL) return false ; @@ -1124,7 +1744,7 @@ SawFinishing::GetHeightOnSection( const ICurve* pSect, double dX, double dYmin, ! pRay->Set( Point3d( dX, dYmin - EPS_SMALL, 0), Point3d( dX, dYmax + EPS_SMALL, 0))) return false ; // eseguo intersezione (considero l'ultima, ovvero quella con Y maggiore) - IntersCurveCurve intCC( *Get( pRay), *pSect) ; + IntersCurveCurve intCC( *pRay, *pSect) ; IntCrvCrvInfo aInfo ; if ( intCC.GetIntCrvCrvInfo( intCC.GetIntersCount() - 1, aInfo)) { // nel caso di sovrapposizione devo prendere la Y in basso del tratto diff --git a/SawFinishing.h b/SawFinishing.h index 1cad8e5..88f0a12 100644 --- a/SawFinishing.h +++ b/SawFinishing.h @@ -58,16 +58,31 @@ class SawFinishing : public Machining SawFinishing( void) ; private : + bool UpdateToolData( void) ; bool VerifyGeometry( SelData Id, int& nSubs) ; ICurve* GetCurve( SelData Id) ; bool AdjustGeometry( int nAuxId) ; - bool CalculateToolPath( int nAuxId, int nClId) ; - bool CalculateOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, - const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast) ; - bool CalculateZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, - const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bFirst, bool bLast, - int& nCount) ; - bool AddApproach( const Point3d& ptP, const Vector3d& vtCorr, bool bFirst, + bool CalculateAlongToolPath( int nAuxId, int nClId) ; + bool CalculateAcrossToolPath( int nAuxId, int nClId) ; + bool CalculateSection( int nSectGrpId, ICurve*& pSect) ; + bool CalculateGuideLine( int nGuideId, Point3d& ptGdStart, Point3d& ptGdEnd, Vector3d& vtGdDir) ; + bool ClassifySection( ICurve* pCrv, INTVECTOR& vnClass) ; + bool CalcAlongVerticalCuts( ICurve* pSect, int nUmin, int nUmax, const Frame3d& frSect, + const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, + double dDepth, const Vector3d& vtTool, const Vector3d& vtCorr) ; + bool CalcAlongStdCuts( ICurve* pSect, double dUmin, double dUmax, + bool bSkipMin, bool bSkipMax, bool bInvert, const Frame3d& frSect, + const Point3d& ptGdStart, const Point3d& ptGdEnd, const Vector3d& vtGdDir, + double dDepth, const Vector3d& vtTool, const Vector3d& vtCorr) ; + bool CalcAlongOneWayCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, + const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bVert) ; + bool CalcAlongZigZagCut( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDir, + const Vector3d& vtTool, const Vector3d& vtCorr, double dElev, bool bVert, bool bFirst) ; + bool CalcAcrossOneWayCut( const PolyLine& PL, const Vector3d& vtMove, + const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth) ; + bool CalcAcrossZigZagCut( const PolyLine& PL, const Vector3d& vtMove, + const Vector3d& vtTool, const Vector3d& vtCorr, double dRawZ, double dDepth, bool bFirst) ; + bool AddApproach( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ; bool AddRetract( const Point3d& ptP, const Vector3d& vtCorr, double dSafeZ, double dElev, double dAppr) ; bool CalculateToolAndCorrVersors( const Vector3d& vtTang, int nHeadSide, @@ -85,6 +100,8 @@ class SawFinishing : public Machining { return ( abs( m_Params.m_dEndFeed) < EPS_MACH_LEN_PAR ? m_TParams.m_dEndFeed : m_Params.m_dEndFeed) ; } double GetTipFeed() const { return ( abs( m_Params.m_dTipFeed) < EPS_MACH_LEN_PAR ? m_TParams.m_dTipFeed : m_Params.m_dTipFeed) ; } + double GetVertFeed() const + { return ( abs( m_Params.m_dVertFeed) < EPS_MACH_LEN_PAR ? m_TParams.m_dFeed : m_Params.m_dVertFeed) ; } double GetOffsR() const { return ( abs( m_Params.m_dOffsR - UNKNOWN_PAR) < EPS_MACH_LEN_PAR ? m_TParams.m_dOffsR : m_Params.m_dOffsR) ; } @@ -92,5 +109,5 @@ class SawFinishing : public Machining SELVECTOR m_vId ; // identificativi entità geometriche da lavorare SawFinishingData m_Params ; // parametri lavorazione ToolData m_TParams ; // parametri utensile - int m_nCuts ; // numero di tagli generati + int m_nCuts ; // numero di passate generate } ; diff --git a/SawFinishingData.cpp b/SawFinishingData.cpp index b3f5359..3d4dbb3 100644 --- a/SawFinishingData.cpp +++ b/SawFinishingData.cpp @@ -31,6 +31,7 @@ enum nSawFinishingKey { KEY_FE, KEY_FS, KEY_FT, + KEY_FV, KEY_HS, KEY_LLTY, KEY_NAME, @@ -40,7 +41,9 @@ enum nSawFinishingKey { KEY_PS, KEY_S, KEY_SS, + KEY_ST, KEY_STY, + KEY_SUBTYPE, KEY_TNAME, KEY_TUUID, KEY_UUID, @@ -53,6 +56,7 @@ static const std::array sSawFinishingKey = { "FE", "FS", "FT", + "FV", "HS", "LLTY", "NAME", @@ -62,7 +66,9 @@ static const std::array sSawFinishingKey = { "PS", "S", "SS", + "ST", "STY", + "SUB", "TN", "TU", "UUID"} ; @@ -107,11 +113,14 @@ SawFinishingData::CopyFrom( const MachiningData* pMdata) m_dEndFeed = pSdata->m_dEndFeed ; m_dStartFeed = pSdata->m_dStartFeed ; m_dTipFeed = pSdata->m_dTipFeed ; + m_dVertFeed = pSdata->m_dVertFeed ; m_dOffsR = pSdata->m_dOffsR ; m_nHeadSide = pSdata->m_nHeadSide ; m_sDepth = pSdata->m_sDepth ; m_dStartPos = pSdata->m_dStartPos ; m_dSideStep = pSdata->m_dSideStep ; + m_dStep = pSdata->m_dStep ; + m_nSubType = pSdata->m_nSubType ; m_nStepType = pSdata->m_nStepType ; m_nLeadLinkType = pSdata->m_nLeadLinkType ; m_dApprox = pSdata->m_dApprox ; @@ -141,11 +150,14 @@ SawFinishingData::SameAs(const MachiningData* pMdata) const abs( m_dEndFeed - pSdata->m_dEndFeed) < EPS_MACH_LEN_PAR && abs( m_dStartFeed - pSdata->m_dStartFeed) < EPS_MACH_LEN_PAR && abs( m_dTipFeed - pSdata->m_dTipFeed) < EPS_MACH_LEN_PAR && + abs( m_dVertFeed - pSdata->m_dVertFeed) < EPS_MACH_LEN_PAR && abs( m_dOffsR - pSdata->m_dOffsR) < EPS_MACH_LEN_PAR && m_nHeadSide == pSdata->m_nHeadSide && m_sDepth == pSdata->m_sDepth && abs( m_dStartPos - pSdata->m_dStartPos) < EPS_MACH_LEN_PAR && abs( m_dSideStep - pSdata->m_dSideStep) < EPS_MACH_LEN_PAR && + abs( m_dStep - pSdata->m_dStep) < EPS_MACH_LEN_PAR && + m_nSubType == pSdata->m_nSubType && m_nStepType == pSdata->m_nStepType && m_nLeadLinkType == pSdata->m_nLeadLinkType && abs( m_dApprox - pSdata->m_dApprox) < EPS_MACH_LEN_PAR && @@ -209,6 +221,9 @@ SawFinishingData::FromString( const string& sString, int& nKey) case KEY_FT : bOk = ::FromString( sVal, m_dTipFeed) ; break ; + case KEY_FV : + bOk = ::FromString( sVal, m_dVertFeed) ; + break ; case KEY_HS : bOk = ::FromString( sVal, m_nHeadSide) ; break ; @@ -237,9 +252,15 @@ SawFinishingData::FromString( const string& sString, int& nKey) case KEY_SS : bOk = ::FromString( sVal, m_dSideStep) ; break ; + case KEY_ST : + bOk = ::FromString( sVal, m_dStep) ; + break ; case KEY_STY : bOk = ::FromString( sVal, m_nStepType) ; break ; + case KEY_SUBTYPE : + bOk = ::FromString( sVal, m_nSubType) ; + break ; case KEY_TNAME : m_sToolName = sVal ; break ; @@ -267,6 +288,7 @@ SawFinishingData::ToString( int nInd) const case KEY_FE : return ( sSawFinishingKey[KEY_FE] + "=" + ::ToString( m_dEndFeed)) ; case KEY_FS : return ( sSawFinishingKey[KEY_FS] + "=" + ::ToString( m_dStartFeed)) ; case KEY_FT : return ( sSawFinishingKey[KEY_FT] + "=" + ::ToString( m_dTipFeed)) ; + case KEY_FV : return ( sSawFinishingKey[KEY_FV] + "=" + ::ToString( m_dVertFeed)) ; case KEY_HS : return ( sSawFinishingKey[KEY_HS] + "=" + ::ToString( m_nHeadSide)) ; case KEY_LLTY : return ( sSawFinishingKey[KEY_LLTY] + "=" + ::ToString( m_nLeadLinkType)) ; case KEY_NAME : return ( sSawFinishingKey[KEY_NAME] + "=" + m_sName) ; @@ -276,7 +298,9 @@ SawFinishingData::ToString( int nInd) const case KEY_PS : return ( sSawFinishingKey[KEY_PS] + "=" + ::ToString( m_dStartPos)) ; case KEY_S : return ( sSawFinishingKey[KEY_S] + "=" + ::ToString( m_dSpeed)) ; case KEY_SS : return ( sSawFinishingKey[KEY_SS] + "=" + ::ToString( m_dSideStep)) ; + case KEY_ST : return ( sSawFinishingKey[KEY_ST] + "=" + ::ToString( m_dStep)) ; case KEY_STY : return ( sSawFinishingKey[KEY_STY] + "=" + ::ToString( m_nStepType)) ; + case KEY_SUBTYPE : return ( sSawFinishingKey[KEY_SUBTYPE] + "=" + ::ToString( m_nSubType)) ; case KEY_TNAME : return ( sSawFinishingKey[KEY_TNAME] + "=" + m_sToolName) ; case KEY_TUUID : return ( sSawFinishingKey[KEY_TUUID] + "=" + ::ToString( m_ToolUuid)) ; case KEY_UUID : return ( sSawFinishingKey[KEY_UUID] + "=" + ::ToString( m_Uuid)) ; @@ -288,7 +312,7 @@ SawFinishingData::ToString( int nInd) const bool SawFinishingData::IsOptional( int nKey) const { - return false ; + return ( nKey == KEY_FV || nKey == KEY_ST || nKey == KEY_SUBTYPE) ; } //---------------------------------------------------------------------------- @@ -305,6 +329,13 @@ SawFinishingData::VerifyStepType( int nVal) const return ( nVal == SAWFIN_ST_ZIGZAG || nVal == SAWFIN_ST_ONEWAY) ; } +//---------------------------------------------------------------------------- +bool +SawFinishingData::VerifySubType( int nVal) const +{ + return ( nVal == SAWFIN_SUB_ALONG || nVal == SAWFIN_SUB_ACROSS) ; +} + //---------------------------------------------------------------------------- bool SawFinishingData::VerifyLeadLinkType( int nVal) const @@ -360,6 +391,11 @@ SawFinishingData::SetParam( int nType, int nVal) return false ; m_nStepType = nVal ; return true ; + case MPA_SUBTYPE : + if ( ! VerifySubType( nVal)) + return false ; + m_nSubType = nVal ; + return true ; case MPA_LEADLINKTYPE : if ( ! VerifyLeadLinkType( nVal)) return false ; @@ -389,6 +425,9 @@ SawFinishingData::SetParam( int nType, double dVal) case MPA_TIPFEED : m_dTipFeed = dVal ; return true ; + case MPA_VERTFEED : + m_dVertFeed = dVal ; + return true ; case MPA_OFFSR : m_dOffsR = dVal ; return true ; @@ -401,6 +440,9 @@ SawFinishingData::SetParam( int nType, double dVal) case MPA_SIDESTEP : m_dSideStep = dVal ; return true ; + case MPA_STEP : + m_dStep = dVal ; + return true ; case MPA_APPROX : m_dApprox = dVal ; return true ; @@ -468,6 +510,9 @@ SawFinishingData::GetParam( int nType, int& nVal) const case MPA_STEPTYPE : nVal = m_nStepType ; return true ; + case MPA_SUBTYPE : + nVal = m_nSubType ; + return true ; case MPA_LEADLINKTYPE : nVal = m_nLeadLinkType ; return true ; @@ -495,6 +540,9 @@ SawFinishingData::GetParam( int nType, double& dVal) const case MPA_TIPFEED : dVal = m_dTipFeed ; return true ; + case MPA_VERTFEED : + dVal = m_dVertFeed ; + return true ; case MPA_OFFSR : dVal = m_dOffsR ; return true ; @@ -504,6 +552,9 @@ SawFinishingData::GetParam( int nType, double& dVal) const case MPA_SIDESTEP : dVal = m_dSideStep ; return true ; + case MPA_STEP : + dVal = m_dStep ; + return true ; case MPA_APPROX : dVal = m_dApprox ; return true ; diff --git a/SawFinishingData.h b/SawFinishingData.h index ada8db1..170936b 100644 --- a/SawFinishingData.h +++ b/SawFinishingData.h @@ -25,11 +25,14 @@ struct SawFinishingData : public MachiningData double m_dStartFeed ; // velocità di lavorazione iniziale ( se 0 da utensile) double m_dEndFeed ; // velocità di lavorazione finale ( se 0 da utensile) double m_dTipFeed ; // velocità di lavorazione di testa ( se 0 da utensile) + double m_dVertFeed ; // velocità di lavorazione per tagli in verticale double m_dOffsR ; // offset radiale ( se UNKNOWN_PAR da utensile) int m_nHeadSide ; // lato di posizionamento del mandrino ( destra o sinistra) std::string m_sDepth ; // affondamento massimo (espressione numerica) double m_dStartPos ; // quota di inizio lavorazione (sempre >= 0) double m_dSideStep ; // distanza tra le passate (0=spessore lama) + double m_dStep ; // passo di affondamento (0=nessun passo) + int m_nSubType ; // 0=movimento longitudinale, 1=movimento trasversale (spatolatura) int m_nStepType ; // tipo di lavorazione a step (una via, va e vieni) int m_nLeadLinkType ; // tipo di attacco/uscita/collegamento ( centro, fuori) double m_dApprox ; // valore di approssimazione per superfici @@ -37,10 +40,10 @@ struct SawFinishingData : public MachiningData std::string m_sUserNotes ; // note dell'utente SawFinishingData( void) - : m_ToolUuid(), m_dSpeed( 0), m_dFeed( 0), m_dStartFeed( 0), m_dEndFeed( 0), m_dTipFeed( 0), + : m_ToolUuid(), m_dSpeed( 0), m_dFeed( 0), m_dStartFeed( 0), m_dEndFeed( 0), m_dTipFeed( 0), m_dVertFeed(0), m_dOffsR( UNKNOWN_PAR), - m_nHeadSide(0), m_dStartPos( 0), m_dSideStep( 0), - m_nStepType( 0), m_nLeadLinkType( 0), m_dApprox( 0) {} + m_nHeadSide( 0), m_dStartPos( 0), m_dSideStep( 0), m_dStep( 0), + m_nSubType( 0), m_nStepType( 0), m_nLeadLinkType( 0), m_dApprox( 0) {} SawFinishingData* Clone( void) const override ; bool CopyFrom( const MachiningData* pMdata) override ; bool SameAs(const MachiningData* pMdata) const override ; @@ -64,6 +67,7 @@ struct SawFinishingData : public MachiningData bool VerifyTool( const ToolsMgr* pToolsMgr, const std::string& sVal, const ToolData*& pTdata) const override ; bool VerifyHeadSide( int nVal) const ; bool VerifyStepType( int nVal) const ; + bool VerifySubType( int nVal) const ; bool VerifyLeadLinkType( int nVal) const ; } ; diff --git a/SawRoughing.cpp b/SawRoughing.cpp index c4dc0c8..e60d99f 100644 --- a/SawRoughing.cpp +++ b/SawRoughing.cpp @@ -383,6 +383,12 @@ SawRoughing::Apply( bool bRecalc) m_pGeomDB->EmptyGroup( nAuxId) ; } + // aggiorno dati geometrici dell'utensile + if ( ! UpdateToolData()) { + LOG_INFO( GetEMkLogger(), "Error in SawRoughing : UpdateToolData failed") ; + return false ; + } + // se necessario, preparo geometria e la inserisco sotto la geometria ausiliaria if ( bRecalc && ! AdjustGeometry( nAuxId)) return false ; @@ -530,6 +536,28 @@ SawRoughing::GetToolData( void) const return m_TParams ; } +//---------------------------------------------------------------------------- +bool +SawRoughing::UpdateToolData( void) +{ + // recupero il gestore DB utensili della macchina corrente + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + // recupero l'utensile nel DB utensili + const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; + if ( pTdata == nullptr) + return false ; + // aggiorno i parametri + m_TParams = *pTdata ; + if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { + string sLog = "Warning in SawRoughing : tool name changed (" + + m_Params.m_sToolName + "->" + m_TParams.m_sName +")" ; + LOG_INFO( GetEMkLogger(), sLog.c_str()) ; + } + return true ; +} + //---------------------------------------------------------------------------- bool SawRoughing::GetGeometry( SELVECTOR& vIds) const @@ -664,7 +692,7 @@ SawRoughing::AdjustGeometry( int nAuxId) Vector3d vtGdDir ; if ( ! pGuide->GetStartDir( vtGdDir) || ! AreSameOrOppositeVectorApprox( vtN, vtGdDir)) return false ; - // creo sottogruppo di ausiliario per le sezioni con riferimento avente + // creo sottogruppo per le sezioni con riferimento avente // l'origine nel punto di inizio della prima sezione e la Z opposta alla direzione della guida Frame3d frSect ; if ( ! frSect.Set( ptStStart, - vtGdDir)) @@ -673,8 +701,13 @@ SawRoughing::AdjustGeometry( int nAuxId) if ( nGrpSectId == GDB_ID_NULL) return false ; m_pGeomDB->SetName( nGrpSectId, MCH_SECTION) ; + // inserisco le sezioni e ne sistemo il senso di rotazione come CCW for ( auto& pSect : vpSects) { pSect->ToLoc( frSect) ; + double dArea ; + pSect->GetAreaXY( dArea) ; + if ( dArea < 0) + pSect->Invert() ; if ( m_pGeomDB->AddGeoObj( GDB_ID_NULL, nGrpSectId, ::Release( pSect)) == GDB_ID_NULL) return false ; } @@ -696,26 +729,21 @@ SawRoughing::AdjustGeometry( int nAuxId) bool SawRoughing::CalculateToolPath( int nAuxId, int nClId) { - // recupero il riferimento globale delle sezioni - int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ; - Frame3d frSect ; - m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ; - // recupero le sezioni e il loro ingombro in globale + // recupero le sezioni ICURVEPVECTOR vpSects ; - BBox3d b3Sect ; + int nSectGrpId = m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_SECTION) ; int nSectId = m_pGeomDB->GetFirstInGroup( nSectGrpId) ; while ( nSectId != GDB_ID_NULL) { // recupero il puntatore alla curva vpSects.emplace_back( ::GetCurve( m_pGeomDB->GetGeoObj( nSectId))) ; if ( vpSects.back() == nullptr) return false ; - // recupero l'ingombro della sezione corrente in globale - BBox3d b3Temp ; - vpSects.back()->GetBBox( frSect, b3Temp) ; - b3Sect.Add( b3Temp) ; // passo alla successiva nSectId = m_pGeomDB->GetNext( nSectId) ; } + // recupero il riferimento globale delle sezioni + Frame3d frSect ; + m_pGeomDB->GetGroupGlobFrame( nSectGrpId, frSect) ; // recupero la linea guida int nGuideId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetFirstNameInGroup( nAuxId, MCH_GUIDE)) ; @@ -736,12 +764,14 @@ SawRoughing::CalculateToolPath( int nAuxId, int nClId) return false ; } - // recupero il box del grezzo + // recupero il box del grezzo in globale e nel riferimento locale delle sezioni BBox3d b3Raw ; if ( ! GetRawGlobBox( m_nPhase, nGuideId, b3Raw) || b3Raw.IsEmpty()) { LOG_INFO( GetEMkLogger(), "Error in SawRoughing : Empty RawBox") ; return false ; } + BBox3d b3RawLoc = b3Raw ; + b3RawLoc.ToLoc( frSect) ; // aggiusto la linea guida al bordo del box if ( AreSameVectorApprox( vtGdDir, X_AX)) { @@ -761,35 +791,70 @@ SawRoughing::CalculateToolPath( int nAuxId, int nClId) ptGdEnd.y = b3Raw.GetMin().y ; } + // elimino eventuali sottosquadra + const double LIN_TOL_STD = 0.1 ; + const double ANG_TOL_STD_DEG = 15 ; + POCRVVECTOR vpNucCrvs ; + vpNucCrvs.reserve( vpSects.size()) ; + for ( const auto& pSect : vpSects) { + PtrOwner pCrvCompo( CreateCurveComposite()) ; + if ( IsNull( pCrvCompo) || + ! pCrvCompo->AddCurve( *pSect) || + ! pCrvCompo->RemoveUndercutOnY( LIN_TOL_STD, ANG_TOL_STD_DEG)) + return false ; + vpNucCrvs.emplace_back( Release( pCrvCompo)) ; + } + + // calcolo ordinamento delle curve secondo la X decrescente + typedef pair INDASC ; // coppia indice, ascissa + typedef vector INDASCVECTOR ; // vettore di coppie indice, ascissa + INDASCVECTOR vIAsc ; + vIAsc.reserve( vpNucCrvs.size()) ; + for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { + Point3d ptStart ; + if ( ! vpNucCrvs[i]->GetStartPoint( ptStart)) + return false ; + vIAsc.emplace_back( i, ptStart.x) ; + } + std::sort( vIAsc.begin(), vIAsc.end(), []( const INDASC& a, const INDASC& b) + { return a.second > b.second ; }) ; + + // unisco le diverse curve (ora aperte) in un unico profilo + PtrOwner pCurve( CreateCurveComposite()) ; + if ( IsNull( pCurve)) + return false ; + bool bFirst = true ; + for ( int i = 0 ; i < int( vpNucCrvs.size()) ; ++ i) { + if ( ! bFirst) { + Point3d ptStart ; + if ( ! vpNucCrvs[vIAsc[i].first]->GetStartPoint( ptStart) || + ! pCurve->AddLine( ptStart)) + return false ; + } + if ( ! pCurve->AddCurve( Release( vpNucCrvs[vIAsc[i].first]))) + return false ; + bFirst = false ; + } + // offset radiale delle sezioni per il sovramateriale double dOffsR = GetOffsR() ; - POCRVVECTOR vpOvrCrvs ; - vpOvrCrvs.reserve( vpSects.size()) ; - for ( const auto& pSect : vpSects) { - OffsetCurve OffsCrv ; - OffsCrv.Make( pSect, dOffsR, ICurve::OFF_FILLET) ; - vpOvrCrvs.emplace_back( OffsCrv.GetLongerCurve()) ; - } + PtrOwner pOvrCrv ; + OffsetCurve OffsCrv ; + OffsCrv.Make( pCurve, dOffsR, ICurve::OFF_FILLET) ; + pOvrCrv.Set( OffsCrv.GetLongerCurve()) ; // ricavo dalla sezione la curva per centro in basso della lama double dOffsX = 0.5 * m_TParams.m_dThick + GetOffsL() - GetOffsR() ; - POCRVVECTOR vpCrvs ; - vpCrvs.reserve( vpOvrCrvs.size()) ; - for ( auto& pOvrCrv : vpOvrCrvs) { - OffsetCurveOnX OffsCrvX ; - OffsCrvX.Make( Get( pOvrCrv), dOffsX) ; - vpCrvs.emplace_back( OffsCrvX.GetLongerCurve()) ; - } - //int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, m_pGeomDB->GetParentId( nSectId), ::Release( pCrv)) ; + PtrOwner pCrv ; + OffsetCurveOnX OffsCrvX ; + OffsCrvX.Make( pOvrCrv, dOffsX) ; + pCrv.Set( OffsCrvX.GetLongerCurve()) ; + // determino l'ingombro della curva risultante in locale + BBox3d b3Crv ; + pCrv->GetLocalBBox( b3Crv) ; + //int nCrvId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, GDB_ID_ROOT, ::Release( pCrv)) ; //m_pGeomDB->Save( nCrvId, "C:\\EgtData\\Varie\\Test\\aaa.nge", GDB_SV_TXT) ; //pCrv.Set( ::GetCurve( m_pGeomDB->RemoveGeoObjAndErase( nCrvId))) ; - // determino l'ingombro delle sezioni in locale - BBox3d b3Crv ; - for ( auto& pCrv : vpCrvs) { - BBox3d b3Temp ; - pCrv->GetLocalBBox( b3Temp) ; - b3Crv.Add( b3Temp) ; - } // valuto l'espressione dell'affondamento ExeLuaSetGlobNumVar( "TH", 0) ; @@ -819,56 +884,108 @@ SawRoughing::CalculateToolPath( int nAuxId, int nClId) SetToolDir( vtTool) ; SetCorrDir( vtCorr) ; - // Ciclo sulle passate - double dLargh = b3Crv.GetMax().x - b3Crv.GetMin().x ; - double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; - int nStep = static_cast( ceil( dLargh / dStep)) ; - dStep = dLargh / nStep ; - double dSectYMin = b3Crv.GetMin().y ; - double dSectYMax = b3Crv.GetMax().y ; + // Determino eventuali pareti verticali (sono in senso decrescente di X) + DBLVECTOR vdVr ; + const ICurveComposite* pCompo = GetCurveComposite( pCrv) ; + if ( pCompo != nullptr) { + const ICurve* pSimpCrv = pCompo->GetFirstCurve() ; + while ( pSimpCrv != nullptr) { + Point3d ptStart, ptEnd ; + pSimpCrv->GetStartPoint( ptStart) ; + pSimpCrv->GetEndPoint( ptEnd) ; + if ( abs( ptEnd.x - ptStart.x) < EPS_SMALL) + vdVr.push_back( ( ptEnd.x + ptStart.x) / 2) ; + pSimpCrv = pCompo->GetNextCurve() ; + } + } + else { + Point3d ptStart, ptEnd ; + pCrv->GetStartPoint( ptStart) ; + pCrv->GetEndPoint( ptEnd) ; + if ( abs( ptEnd.x - ptStart.x) < EPS_SMALL) + vdVr.push_back( ( ptEnd.x + ptStart.x) / 2) ; + } + + // Determino le posizioni particolari + DBLVECTOR vdPp ; + size_t nVr = vdVr.size() ; + double dSawOffs = 0.5 * m_TParams.m_dThick ; + double dFinOffs = m_Params.m_dSideStep - dSawOffs ; + // calcolo dell'inizio (Xmin) + double dRawMin = b3RawLoc.GetMin().x ; // inizio grezzo + double dStart = max( dRawMin + dFinOffs, b3Crv.GetMin().x) ; // inizio con aletta prima + if ( nVr > 0 && + vdVr[nVr-1] < dStart - EPS_SMALL && + vdVr[nVr-1] + dSawOffs > dRawMin + EPS_SMALL) + dStart = vdVr[nVr-1] ; // correzione per parete verticale + // calcolo della fine (Xmax) + double dRawMax = b3RawLoc.GetMax().x ; // fine grezzo + double dEnd = min( dRawMax - dFinOffs, b3Crv.GetMax().x) ; // fine con aletta dopo + if ( nVr > 0 && + vdVr[0] > dEnd + EPS_SMALL && + vdVr[0] - dSawOffs < dRawMax - EPS_SMALL) + dEnd = vdVr[0] ; // correzione per parete verticale + // assegno le posizioni particolari (ordinate in senso decrescente) + vdPp.push_back( dEnd) ; + for ( size_t i = 0 ; i < nVr ; ++ i) { + if ( vdVr[i] > dStart + EPS_SMALL && vdVr[i] < dEnd - EPS_SMALL) + vdPp.push_back( vdVr[i]) ; + } + vdPp.push_back( dStart) ; + + // Ciclo sugli intervalli tra le posizioni particolari per generare le passate int nCount = 0 ; - for ( int i = 0 ; i <= nStep ; ++ i) { - // flag per primo e ultimo taglio - bool bFirst = ( i == 0) ; - bool bLast = ( i == nStep) ; - // determino l'ascissa della prima intersezione - double dX = b3Crv.GetMax().x - i * dStep ; - // determino l'ordinata della prima intersezione - double dY ; - double dYmin = dSectYMin ; - for ( auto& pCrv : vpCrvs) { - if ( ! GetHeightOnSection( Get( pCrv), dX, dYmin, dSectYMax, dY)) + for ( size_t j = 0 ; j < vdPp.size() ; ++ j) { + double dXmax = ( j > 0 ? vdPp[j-1] : vdPp[0]) ; + double dXmin = vdPp[j] ; + double dLargh = dXmax - dXmin ; + double dStep = max( m_Params.m_dSideStep, 10 * EPS_SMALL) ; + int nStep = max( 1, static_cast( ceil( dLargh / dStep))) ; + dStep = dLargh / nStep ; + double dSectYMin = b3Crv.GetMin().y ; + double dSectYMax = b3Crv.GetMax().y ; + for ( int i = 1 ; i <= nStep ; ++ i) { + // flag per primo e ultimo taglio + bool bFirst = ( j == 0 && i == 1) ; + bool bLast = ( j == vdPp.size() -1 && i == nStep) ; + // determino l'ascissa della prima intersezione + double dX = dXmax - i * dStep ; + // determino l'ordinata della prima intersezione + double dY ; + if ( ! GetHeightOnSection( pCrv, dX, dSectYMin, dSectYMax, dY)) return false ; - dYmin = dY ; - } - // estremi del taglio - Vector3d vtMove = dX * frSect.VersX() + dY * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ; - Point3d ptStart = ptGdStart + vtMove ; - Point3d ptEnd = ptGdEnd + vtMove ; - // determino l'elevazione del taglio - Vector3d vtThick = vtTool * m_TParams.m_dThick ; - double dElev, dElev2 ; - if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || - ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { - LOG_INFO( GetEMkLogger(), "Error in SawRoughinging : GetElevation") ; - return false ; - } - dElev = max( dElev, dElev2) ; - // la confronto con il massimo affondamento e con la massima lavorazione della lama - double dMaxDepth = min( dDepth, m_TParams.m_dMaxMat) ; - if ( dElev > dMaxDepth) { - ptStart += Vector3d( 0, 0, dElev - dMaxDepth) ; - ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ; - dElev = dMaxDepth ; - } - // esecuzione del taglio - if ( m_Params.m_nStepType != SAWROU_ST_ZIGZAG) { - if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast)) - return false ; - } - else { - if ( ! CalculateZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, nCount)) + // estremi del taglio + Vector3d vtMove = dX * frSect.VersX() + dY * frSect.VersY() - 0.5 * m_TParams.m_dThick * vtTool ; + Point3d ptStart = ptGdStart + vtMove ; + Point3d ptEnd = ptGdEnd + vtMove ; + // determino l'elevazione del taglio + Vector3d vtThick = vtTool * m_TParams.m_dThick ; + double dElev, dElev2 ; + if ( ! GetElevation( m_nPhase, ptStart, ptEnd, vtCorr, dElev) || + ! GetElevation( m_nPhase, ptStart + vtThick, ptEnd + vtThick, vtCorr, dElev2) ) { + LOG_INFO( GetEMkLogger(), "Error in SawRoughinging : GetElevation") ; return false ; + } + dElev = max( dElev, dElev2) ; + // se elevazione nulla, verifico col massimo del grezzo + if ( dElev < EPS_SMALL) + dElev = max( 0., b3Raw.GetMax().z - ptStart.z) ; + // la confronto con il massimo affondamento e con la massima lavorazione della lama + double dMaxDepth = min( dDepth, m_TParams.m_dMaxMat) ; + if ( dElev > dMaxDepth) { + ptStart += Vector3d( 0, 0, dElev - dMaxDepth) ; + ptEnd += Vector3d( 0, 0, dElev - dMaxDepth) ; + dElev = dMaxDepth ; + } + // esecuzione del taglio + if ( m_Params.m_nStepType != SAWROU_ST_ZIGZAG) { + if ( ! CalculateOneWayCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast)) + return false ; + } + else { + if ( ! CalculateZigZagCut( ptStart, ptEnd, vtGdDir, vtTool, vtCorr, dElev, bFirst, bLast, nCount)) + return false ; + } } } @@ -1271,10 +1388,10 @@ SawRoughing::GetHeightOnSection( const ICurve* pSect, double dX, double dYmin, d if ( IsNull( pRay) || ! pRay->Set( Point3d( dX, dYmin - EPS_SMALL, 0), Point3d( dX, dYmax + EPS_SMALL, 0))) return false ; - // eseguo intersezione (considero l'ultima, ovvero quella con Y maggiore) - IntersCurveCurve intCC( *Get( pRay), *pSect) ; + // eseguo intersezione (considero la prima perchè non ci sono sottosquadra) + IntersCurveCurve intCC( *pRay, *pSect) ; IntCrvCrvInfo aInfo ; - if ( intCC.GetIntCrvCrvInfo( intCC.GetIntersCount() - 1, aInfo)) { + if ( intCC.GetIntCrvCrvInfo( 0, aInfo)) { // nel caso di sovrapposizione devo prendere la Y in basso del tratto dY = aInfo.IciA[0].ptI.y ; return true ; diff --git a/SawRoughing.h b/SawRoughing.h index b18d072..3779489 100644 --- a/SawRoughing.h +++ b/SawRoughing.h @@ -58,6 +58,7 @@ class SawRoughing : public Machining SawRoughing( void) ; private : + bool UpdateToolData( void) ; bool VerifyGeometry( SelData Id, int& nSubs) ; ICurve* GetCurve( SelData Id) ; bool AdjustGeometry( int nAuxId) ; diff --git a/SawRoughingData.h b/SawRoughingData.h index d06ae45..5832a5d 100644 --- a/SawRoughingData.h +++ b/SawRoughingData.h @@ -30,7 +30,7 @@ struct SawRoughingData : public MachiningData int m_nHeadSide ; // lato di posizionamento del mandrino ( destra o sinistra) std::string m_sDepth ; // affondamento massimo (espressione numerica) double m_dStartPos ; // quota di inizio lavorazione (sempre >= 0) - double m_dSideStep ; // distanza tra le passate (0=spessore lama) + double m_dSideStep ; // distanza tra le passate double m_dStep ; // passo di affondamento (0=nessun passo) int m_nStepType ; // tipo di lavorazione a step (una via, va e vieni) int m_nLeadLinkType ; // tipo di attacco/uscita/collegamento ( centro, fuori) diff --git a/Sawing.cpp b/Sawing.cpp index a3240e6..a915e0f 100644 --- a/Sawing.cpp +++ b/Sawing.cpp @@ -409,6 +409,12 @@ Sawing::Preview( bool bRecalc) bChain = true ; } + // aggiorno dati geometrici dell'utensile + if ( ! UpdateToolData()) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : UpdateToolData failed") ; + return false ; + } + // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria if ( bChain && ! Chain( nAuxId)) return false ; @@ -470,6 +476,12 @@ Sawing::Apply( bool bRecalc) bChain = true ; } + // aggiorno dati geometrici dell'utensile + if ( ! UpdateToolData()) { + LOG_INFO( GetEMkLogger(), "Error in Sawing : UpdateToolData failed") ; + return false ; + } + // se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria if ( bChain && ! Chain( nAuxId)) return false ; @@ -651,6 +663,28 @@ Sawing::GetToolData( void) const return m_TParams ; } +//---------------------------------------------------------------------------- +bool +Sawing::UpdateToolData( void) +{ + // recupero il gestore DB utensili della macchina corrente + ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ; + if ( pTMgr == nullptr) + return false ; + // recupero l'utensile nel DB utensili + const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ; + if ( pTdata == nullptr) + return false ; + // aggiorno i parametri + m_TParams = *pTdata ; + if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) { + string sLog = "Warning in Sawing : tool name changed (" + + m_Params.m_sToolName + "->" + m_TParams.m_sName +")" ; + LOG_INFO( GetEMkLogger(), sLog.c_str()) ; + } + return true ; +} + //---------------------------------------------------------------------------- bool Sawing::GetGeometry( SELVECTOR& vIds) const @@ -817,7 +851,7 @@ Sawing::Chain( int nGrpDestId) chainC.Init( true, dToler, int( vpCrvs.size())) ; for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) { // recupero la curva e il suo riferimento - ICurve* pCrv = Get( vpCrvs[i]) ; + ICurve* pCrv = vpCrvs[i] ; if ( pCrv == nullptr) continue ; // recupero i dati della curva necessari al concatenamento e li assegno @@ -850,7 +884,7 @@ Sawing::Chain( int nGrpDestId) bool bInvert = ( vnId2[i] < 0) ; vId2.emplace_back( m_vId[nId]) ; // recupero la curva - ICurve* pCrv = Get( vpCrvs[nId]) ; + ICurve* pCrv = vpCrvs[nId] ; // se necessario, la inverto if ( bInvert) pCrv->Invert() ; @@ -1120,7 +1154,7 @@ Sawing::ProcessLine( const ICurve* pCrvP, const ICurveLine* pLineC, const ICurve return false ; } // correzioni per lato lama, lato mandrino - if ( ! AdjustForSide( Get( pLine))) { + if ( ! AdjustForSide( pLine)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForSide") ; return false ; } @@ -1162,7 +1196,7 @@ Sawing::ProcessLine( const ICurve* pCrvP, const ICurveLine* pLineC, const ICurve } // aggiusto per tipo estremi bool bToSkip = false ; - if ( ! AdjustLineForEdges( Get( pLine), dElev, vtThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { + if ( ! AdjustLineForEdges( pLine, dElev, vtThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForEdges") ; return false ; } @@ -1173,13 +1207,13 @@ Sawing::ProcessLine( const ICurve* pCrvP, const ICurveLine* pLineC, const ICurve // Se richiesto Preview if ( nPvId != GDB_ID_NULL) { - if ( ! GenerateLinePv( Get( pLine), vtTool, vtCorr, dElev, dExtraCut, sName, nPvId)) + if ( ! GenerateLinePv( pLine, vtTool, vtCorr, dElev, dExtraCut, sName, nPvId)) return false ; } // Se richiesta geometria di lavorazione if ( nClId != GDB_ID_NULL) { - if ( ! GenerateLineCl( Get( pLine), vtTool, vtCorr, dElev, dExtraCut, sName, nClId)) + if ( ! GenerateLineCl( pLine, vtTool, vtCorr, dElev, dExtraCut, sName, nClId)) return false ; } @@ -1481,7 +1515,7 @@ Sawing::ProcessExtArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve return false ; } // correzioni per lato lama, lato mandrino - if ( ! AdjustForSide( Get( pArc))) { + if ( ! AdjustForSide( pArc)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForSide") ; return false ; } @@ -1526,7 +1560,7 @@ Sawing::ProcessExtArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve } // aggiusto per tipo estremi bool bToSkip = false ; - if ( ! AdjustArcForEdges( Get( pArc), dElev, vtStaThick, vtEndThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { + if ( ! AdjustArcForEdges( pArc, dElev, vtStaThick, vtEndThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForEdges") ; return false ; } @@ -1537,13 +1571,13 @@ Sawing::ProcessExtArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve // Se richiesto Preview if ( nPvId != GDB_ID_NULL) { - if ( ! GenerateExtArcPv( Get( pArc), vtStaTool, vtMidTool, vtEndTool, vtStaCorr, dElev, dExtraCut, sName, nPvId)) + if ( ! GenerateExtArcPv( pArc, vtStaTool, vtMidTool, vtEndTool, vtStaCorr, dElev, dExtraCut, sName, nPvId)) return false ; } // Se richiesta geometria di lavorazione if ( nClId != GDB_ID_NULL) { - if ( ! GenerateExtArcCl( Get( pArc), vtStaTool, vtMidTool, vtEndTool, vtStaCorr, dElev, dExtraCut, sName, nClId)) + if ( ! GenerateExtArcCl( pArc, vtStaTool, vtMidTool, vtEndTool, vtStaCorr, dElev, dExtraCut, sName, nClId)) return false ; } @@ -2106,7 +2140,7 @@ Sawing::ProcessIntArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve return false ; } // correzioni per lato lama, lato mandrino - if ( ! AdjustIntArcForSide( Get( pArc), dSideAng)) { + if ( ! AdjustIntArcForSide( pArc, dSideAng)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForSide") ; return false ; } @@ -2151,7 +2185,7 @@ Sawing::ProcessIntArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve } // aggiusto per tipo estremi bool bToSkip = false ; - if ( ! AdjustArcForEdges( Get( pArc), dElev, vtStaThick, vtEndThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { + if ( ! AdjustArcForEdges( pArc, dElev, vtStaThick, vtEndThick, bIsFirst, bIsLast, bExtAngPC, bExtAngCN, bToSkip)) { LOG_INFO( GetEMkLogger(), "Error in Sawing : Entity AdjustForEdges") ; return false ; } @@ -2162,14 +2196,14 @@ Sawing::ProcessIntArc( const ICurve* pCrvP, const ICurveArc* pArcC, const ICurve // Se richiesto Preview if ( nPvId != GDB_ID_NULL) { - if ( ! GenerateIntArcPv( Get( pArc), vtStaTool, vtMidTool, vtEndTool, + if ( ! GenerateIntArcPv( pArc, vtStaTool, vtMidTool, vtEndTool, vtStaCorr, vtMidCorr, vtEndCorr, dElev, dExtraCut, sName, nPvId)) return false ; } // Se richiesta geometria di lavorazione if ( nClId != GDB_ID_NULL) { - if ( ! GenerateIntArcCl( Get( pArc), vtStaTool, vtMidTool, vtEndTool, + if ( ! GenerateIntArcCl( pArc, vtStaTool, vtMidTool, vtEndTool, vtStaCorr, vtMidCorr, vtEndCorr, dElev, dExtraCut, sName, nClId)) return false ; } diff --git a/Sawing.h b/Sawing.h index 625ae49..dd80ee4 100644 --- a/Sawing.h +++ b/Sawing.h @@ -58,6 +58,7 @@ class Sawing : public Machining Sawing( void) ; private : + bool UpdateToolData( void) ; bool VerifyGeometry( SelData Id, int& nSubs) ; ICurve* GetCurve( SelData Id) ; bool VerifySideAngle( void) ;