diff --git a/LuaLibs/BasicCustomerStrategies.lua b/LuaLibs/BasicCustomerStrategies.lua index 0ce73e1..2f507cc 100644 --- a/LuaLibs/BasicCustomerStrategies.lua +++ b/LuaLibs/BasicCustomerStrategies.lua @@ -23,17 +23,7 @@ local function GetStrategies_Egalware( Proc) --------------------------------------------------------------------- -- Feature : Cut - if ID.IsHeadCut( Proc) then -- TODO TOGLIERE IL true PER FORZARE IF!!! PROVVISORIO PER PROVARE STRATEGIE - if Proc.Topology.sName == 'FEATURE' then - Strategies = { - { sStrategyId = 'STR0001', - Parameters = { - { sName = 'Step', sValue = '15', sType = 'd'}, - { sName = 'AntiSplint', sValue = 'false', sType = 'b'} - } - } - } - end + if ID.IsHeadCut( Proc) then --------------------------------------------------------------------- -- Feature : Cut elseif ID.IsSplitCut( Proc) then @@ -263,10 +253,10 @@ local function GetStrategies_Essetre( Proc) --------------------------------------------------------------------- -- Feature : Cut - if ID.IsHeadCut( Proc) then -- TODO TOGLIERE IL true PER FORZARE IF!!! PROVVISORIO PER PROVARE STRATEGIE - if Proc.Topology.sName == 'FEATURE' then + if ID.IsHeadCut( Proc) then -- TODO TOGLIERE STRATEGIA. Inserita solo per mostrare come devono essere scritti i dati + if Proc.Topology.sName == 'QQQQQQQQQ' then Strategies = { - { sStrategyId = 'STR0001', + { sStrategyId = 'STR9999', Parameters = { { sName = 'Step', sValue = '15', sType = 'd'}, { sName = 'AntiSplint', sValue = 'false', sType = 'b'} diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 796aa61..7137e6b 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -667,28 +667,28 @@ local function GetIndexBestStrategyFromComparison( AvailableStrategies, nIndex1, dChosenIndex = 0 elseif nIndex1 == 0 then -- basta che sia applicabile - if AvailableStrategies[nIndex2].RatingResult and ( AvailableStrategies[nIndex2].RatingResult.sStatus == 'Completed' or AvailableStrategies[nIndex2].RatingResult.sStatus == 'Not-Completed') then + if AvailableStrategies[nIndex2].Result and ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' or AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed') then dChosenIndex = nIndex2 end elseif nIndex2 == 0 then -- basta che sia applicabile - if AvailableStrategies[nIndex1].RatingResult and ( AvailableStrategies[nIndex1].RatingResult.sStatus == 'Completed' or AvailableStrategies[nIndex1].RatingResult.sStatus == 'Not-Completed') then + if AvailableStrategies[nIndex1].Result and ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' or AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed') then dChosenIndex = nIndex1 end - elseif not AvailableStrategies[nIndex1].RatingResult or not AvailableStrategies[nIndex2].RatingResult then + elseif not AvailableStrategies[nIndex1].Result or not AvailableStrategies[nIndex2].Result then dChosenIndex = 0 - elseif ( AvailableStrategies[nIndex1].RatingResult.sStatus == 'Completed' and AvailableStrategies[nIndex2].RatingResult.sStatus ~= 'Completed') or - ( AvailableStrategies[nIndex1].RatingResult.sStatus == 'Not-Completed' and AvailableStrategies[nIndex2].RatingResult.sStatus == 'Not-Applicable') then + elseif ( AvailableStrategies[nIndex1].Result.sStatus == 'Completed' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Completed') or + ( AvailableStrategies[nIndex1].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex2].Result.sStatus == 'Not-Applicable') then dChosenIndex = nIndex1 - elseif ( AvailableStrategies[nIndex2].RatingResult.sStatus == 'Completed' and AvailableStrategies[nIndex1].RatingResult.sStatus ~= 'Completed') or - ( AvailableStrategies[nIndex2].RatingResult.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].RatingResult.sStatus == 'Not-Applicable') then + elseif ( AvailableStrategies[nIndex2].Result.sStatus == 'Completed' and AvailableStrategies[nIndex1].Result.sStatus ~= 'Completed') or + ( AvailableStrategies[nIndex2].Result.sStatus == 'Not-Completed' and AvailableStrategies[nIndex1].Result.sStatus == 'Not-Applicable') then dChosenIndex = nIndex2 else -- se le due strategie hanno stesso stato e sono entrambe applicabili (quindi entrambe complete o entrambe non-complete) - if AvailableStrategies[nIndex1].RatingResult.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].RatingResult.sStatus ~= 'Not-Applicable' and - AvailableStrategies[nIndex1].RatingResult.sStatus == AvailableStrategies[nIndex2].RatingResult.sStatus then - local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].RatingResult.dRating + AvailableStrategies[nIndex1].RatingResult.dCompletionIndex - local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].RatingResult.dRating + AvailableStrategies[nIndex2].RatingResult.dCompletionIndex + if AvailableStrategies[nIndex1].Result.sStatus ~= 'Not-Applicable' and AvailableStrategies[nIndex2].Result.sStatus ~= 'Not-Applicable' and + AvailableStrategies[nIndex1].Result.sStatus == AvailableStrategies[nIndex2].Result.sStatus then + local dCompositeRatingStrategy1 = AvailableStrategies[nIndex1].Result.dRating + AvailableStrategies[nIndex1].Result.dCompletionIndex + local dCompositeRatingStrategy2 = AvailableStrategies[nIndex2].Result.dRating + AvailableStrategies[nIndex2].Result.dCompletionIndex -- si predilige strategia con rating composito più alto if dCompositeRatingStrategy1 > dCompositeRatingStrategy2 then dChosenIndex = nIndex1 @@ -721,36 +721,112 @@ local function GetBestStrategy( vProcSingleRot, Part) CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId) -- controllo che le librerie siano state effettivamente caricate if CurrentStrategy.Config and CurrentStrategy.Script then + local bStrategyOk -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati - Proc.AvailableStrategies[nIndexCurrentStrategy].RatingResult = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters) + bStrategyOk, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy].Parameters) + -- se la strategia è andata a buon fine + if bStrategyOk then + -- scelgo la migliore strategia tra le due + nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy) - -- scelgo la migliore strategia tra le due - nIndexBestStrategy = GetIndexBestStrategyFromComparison( Proc.AvailableStrategies, nIndexCurrentStrategy, nIndexBestStrategy) - - -- se scelta strategia standard, esco subito alla prima che trovo completa - -- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!! - if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then - if Proc.AvailableStrategies[nIndexBestStrategy].RatingResult.sStatus == 'Complete' then - break + -- se scelta strategia standard, esco subito alla prima che trovo completa + -- TODO serve paraemtro da Beam&Wall ( oppure da confirgurazione) !!!!!!!! + if BEAM.GetFirstCompletedStrategy and nIndexBestStrategy > 0 then + if Proc.AvailableStrategies[nIndexBestStrategy].Result.sStatus == 'Complete' then + break + end end end -- se non trovo i file della strategia, scrivo che non è più disponibile else - Proc.AvailableStrategies[nIndexCurrentStrategy].RatingResult = {} - Proc.AvailableStrategies[nIndexCurrentStrategy].RatingResult.sInfo = 'Strategy not found' + Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {} + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found' end end - -- salvo sulla proc la migliore strategia - if nIndexBestStrategy ~= 0 then - Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy] - end + -- salvo sulla proc la migliore strategia + if nIndexBestStrategy ~= 0 then + Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy] + end end end end return vProcSingleRot end +------------------------------------------------------------------------------------------------------------- +-- Ordina le feature in base a fase di lavorazione +-- 1) Head : ( intestatura) +-- 2) Standard : ( lavorazioni standard che non impattano sulal coda) +-- 3) AdvanceTail : ( lavorazioni che richiedono taglio di separazione, ma che devono essere fatte prima perchè il taglio di separazione farebbe cadere il pezzo) +-- 4) Split : ( taglio di separazione) +-- 5) Tail : ( lavorazionio di coda, fatte dopo il taglio di separazione) +local function OrderFeatures( vProc) + local vProcToSort = vProc + -- funzione di confronto. TRUE = B1 prima di B2. FALSE = B2 prima di B1 + local function CompareFeatures( B1, B2) + -- se secondo disabilitato, va lasciato dopo + if B1.nFlg ~= 0 and B2.nFlg == 0 then + return true + -- se entrambi disabilitati seguo l'Id + elseif B1.nFlg == 0 and B2.nFlg == 0 then + return ( B1.id < B2.id) + -- se in rotazioni diverse, si mette in ordine di rotazioni + elseif B1.nRot ~= B2.nRot then + return ( B1.nRot < B2.nRot) + -- se primo è taglio di testa, va prima degli altri casi + elseif B1.Head and ( B2.Standard or B2.AdvanceTail or B2.Split or B2.Tail) then + return true + -- se primo è taglio standard, va prima degli altri casi + elseif B1.Standard and ( B2.AdvanceTail or B2.Split or B2.Tail) then + return true + -- se primo è taglio di testa anticipata, va prima degli altri casi + elseif B1.AdvanceTail and ( B2.Split or B2.Tail) then + return true + -- se primo è taglio di separazione, va prima delle lavorazioni di coda + elseif B1.Split and B2.Tail then + return true + -- se da lavorare in stessa fase pezzo + elseif B1.Head == B2.Head or B1.Standard == B2.Standard or B1.AdvanceTail == B2.AdvanceTail or B1.Split == B2.Split or B1.Tail == B2.Tail then + -- confronto standard + if abs( B1.b3Box:getCenter():getX() - B2.b3Box:getCenter():getX()) > 0.4 * ( B1.b3Box:getDimX() + B2.b3Box:getDimX()) then + return B1.b3Box:getCenter():getX() > B2.b3Box:getCenter():getX() + elseif abs( B1.b3Box:getCenter():getY() - B2.b3Box:getCenter():getY()) > 0.2 * ( B1.b3Box:getDimY() + B2.b3Box:getDimY()) then + return B1.b3Box:getCenter():getY() > B2.b3Box:getCenter():getY() + elseif abs( B1.b3Box:getCenter():getZ() - B2.b3Box:getCenter():getZ()) > 0.1 * ( B1.b3Box:getDimZ() + B2.b3Box:getDimZ()) then + return B1.b3Box:getCenter():getZ() > B2.b3Box:getCenter():getZ() + end + -- altrimenti si inverte + else + return false + end + end + + -- test della funzione di ordinamento + if EgtGetDebugLevel() >= 3 then + EgtOutLog( ' CompareFeatures Test ') + local bCompTest = true + for i = 1, #vProcToSort do + for j = i + 1, #vProcToSort do + local bComp1 = CompareFeatures( vProcToSort[i], vProcToSort[j]) + local bComp2 = CompareFeatures( vProcToSort[j], vProcToSort[i]) + if bComp1 == bComp2 then + bCompTest = false + EgtOutLog( string.format( ' ProcId : %d vs %d --> ERROR', vProcToSort[i].Id, vProcToSort[j].Id)) + end + end + end + if bCompTest then + EgtOutLog( ' ALL OK') + end + end + + -- eseguo ordinamento + table.sort( vProcToSort, CompareFeatures) + + return vProcToSort +end + ------------------------------------------------------------------------------------------------------------- -- esegue le strategie migliori che ha precedentemente scelto local function ExecPieceFeatures( vProc, Part) @@ -876,13 +952,12 @@ end end EgtOutLog( ' *** AddMachinings ***', 1) - -- TODO ordinare feature e decidere spezzoni - -- ordino le features - -- OrderFeatures( vProc, Part) - -- TODO PROVVISORIO in attesa di scelta lavorazione in fase opportuna vProc = vProcRot[1] + -- ordino le features + vProc = OrderFeatures( vProc) + -- TODO da fare -- esegue le strategie migliori che ha precedentemente scelto ExecPieceFeatures( vProc, Part) @@ -897,6 +972,34 @@ end Part.idRaw = EgtGetNextRawPart( Part.idRaw) end + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings() + -- eventuale ricalcolo per macchine tipo PF (ma tengo warning del primo calcolo) + if EgtExistsInfo( EgtGetCurrMachGroup(), 'RECALC') then + EgtOutLog( ' **** RECALC ****') + bApplOk, sApplErrors, _ = EgtApplyAllMachinings() + EgtRemoveInfo( EgtGetCurrMachGroup(), 'RECALC') + end + if not bApplOk then + nTotErr = nTotErr + 1 + table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) + elseif sApplWarns and #sApplWarns > 0 then + local vLine = EgtSplitString( sApplWarns, '\r\n') + for i = 1, #vLine do + local nPos = vLine[i]:find( '(WRN', 1, true) + if nPos then + local sData = vLine[i]:sub( nPos + 1, -2) + local vVal = EgtSplitString( sData, ',') + local nWarn = EgtGetVal( vVal[1] or '', 'WRN', 'i') + local nCutId = EgtGetVal( vVal[2] or '', 'CUTID', 'i') + if nWarn and nCutId then + table.insert( Stats, { Err=-nWarn, Msg=vLine[i], Rot=0, CutId=nCutId, TaskId=0}) + end + end + end + end + return ( nTotErr == 0), Stats end diff --git a/LuaLibs/FeatureData.lua b/LuaLibs/FeatureData.lua index 7156b62..2d2a789 100644 --- a/LuaLibs/FeatureData.lua +++ b/LuaLibs/FeatureData.lua @@ -228,16 +228,38 @@ function FeatureData.GetDrillingData( Proc) return dDiam, dLen, nFcs, nFce end +------------------------------------------------------------------------------------------------------------- +-- funzione che restituisce indice di completamento in base alla percentuale di volume lavorato +function FeatureData.GetFeatureCompletionIndex( dCompletionPercentage) + -- indice di completamento + local dCompletionIndex = 0 + + -- nullo + if dCompletionPercentage < 5 then + dCompletionIndex = 0 + -- Low + elseif dCompletionPercentage < 50 then + dCompletionIndex = 1 + -- Medium + elseif dCompletionPercentage < 80 then + dCompletionIndex = 2 + -- High / Complete + else + dCompletionIndex = 5 + end + + return dCompletionIndex +end + ------------------------------------------------------------------------------------------------------------- -- funzione che restituisce rating feature in base al numero di lavorazioni, tipo di utensili e indice di completamento -- TODO feature da sistemare -function FeatureData.GetFeatureRating( sTypeTools, dCompletionPercentage) +function FeatureData.GetFeatureRating( sTypeTools, dCompletionIndex) local dRating = 5 - local dCompletionIndex = 0 local TypeTools = EgtSplitString( sTypeTools) -- se non è stato fatto nulla, esco subito - if dCompletionPercentage == 0 then + if dCompletionIndex == 0 then return 0 end @@ -254,15 +276,6 @@ function FeatureData.GetFeatureRating( sTypeTools, dCompletionPercentage) end end - -- indice di completamento - if dCompletionPercentage < 50 then - dCompletionIndex = 1 - elseif dCompletionPercentage < 80 then - dCompletionIndex = 2 - else - dCompletionIndex = 5 - end - dRating = dRating + dCompletionIndex return dRating end diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 88f14a8..3ac4250 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -293,16 +293,16 @@ function MachiningLib.AddNewMachining( Machining) elseif Machining.nType == MCH_MY.MILLING then -- se utensile lama if TOOLS[Machining.nToolIndex].sFamily == 'SAWBLADE' then - Machining.sTypeName = 'Cut' + Machining.sTypeName = 'Cut_' else - Machining.sTypeName = 'Milling' + Machining.sTypeName = 'Milling_' end -- Pocketing elseif Machining.nType == MCH_MY.POCKETING then - Machining.sTypeName = 'Pocketing' + Machining.sTypeName = 'Pocketing_' -- Mortising elseif Machining.nType == MCH_MY.MORTISING then - Machining.sTypeName = 'Mortising' + Machining.sTypeName = 'Mortising_' end -- se nome non definito, assegno alla lavorazioen un nome standard diff --git a/Strategies/STR0002/STR0002.lua b/Strategies/STR0002/STR0002.lua index 7dfb309..712a889 100644 --- a/Strategies/STR0002/STR0002.lua +++ b/Strategies/STR0002/STR0002.lua @@ -39,14 +39,19 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters) Strategy.sName = StrategyLib.Config.sStrategyId CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters) Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters) - Strategy.RatingResult = {} + Strategy.Result = {} if not IsTopologyOk( Proc) then local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.Config.sStrategyId .. ' not implemented' EgtOutLog( sErr) - return false, sErr + Strategy.Result.sStatus = 'Not-Applicable' + Strategy.Result.dCompletionPercentage = 0 + Strategy.Result.dRating = 0 + Strategy.Result.sInfo = sErr + return false, Strategy.Result end + local bApplyMachiningOK = true local ToolInfo = {} local Pocketing = {} Pocketing.Steps = {} @@ -66,13 +71,14 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters) if ToolInfo.nToolIndex and TOOLS[ToolInfo.nToolIndex].sName then if ToolInfo.dResidualDepth > 0 then - Strategy.RatingResult.sStatus = 'Not-Completed' + Strategy.Result.sStatus = 'Not-Completed' else - Strategy.RatingResult.sStatus = 'Completed' + Strategy.Result.sStatus = 'Completed' end - Strategy.RatingResult.dCompletionIndex = min( 100, ( ( Proc.MainFaces.BottomFace.dElevation - ToolInfo.dResidualDepth) / Proc.MainFaces.BottomFace.dElevation) * 100) - Strategy.RatingResult.dRating = FeatureData.GetFeatureRating( 'Mill', Strategy.RatingResult.dCompletionIndex) - Strategy.RatingResult.sInfo = '' + Strategy.Result.dCompletionPercentage = min( 100, ( ( Proc.MainFaces.BottomFace.dElevation - ToolInfo.dResidualDepth) / Proc.MainFaces.BottomFace.dElevation) * 100) + Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage) + Strategy.Result.dRating = FeatureData.GetFeatureRating( 'Mill', Strategy.Result.nCompletionIndex) + Strategy.Result.sInfo = '' -- se richiesto applico lavorazione if bAddMachining then @@ -161,7 +167,7 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters) if vtNSplitFace and AreSameVectorExact( vtNSplitFace, Proc.MainFaces.BottomFace.vtN) then Pocketing.idFaceToMachine = j - 1 Pocketing.idProc = vAddId[i] - MachiningLib.AddNewMachining( Pocketing) + bApplyMachiningOK, Strategy.Result.sInfo = MachiningLib.AddNewMachining( Pocketing) break end end @@ -178,18 +184,19 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters) Pocketing.LeadIn.dElevation = TOOLS[ToolInfo.nToolIndex].dDiameter/2 Pocketing.idFaceToMachine = Proc.MainFaces.BottomFace.id Pocketing.idProc = Proc.id - MachiningLib.AddNewMachining( Pocketing) + bApplyMachiningOK, Strategy.Result.sInfo = MachiningLib.AddNewMachining( Pocketing) end end else - Strategy.RatingResult.sStatus = 'Not-Applicable' - Strategy.RatingResult.dCompletionIndex = 0 - Strategy.RatingResult.dRating = 0 - Strategy.RatingResult.sInfo = 'Mill not found' + Strategy.Result.sStatus = 'Not-Applicable' + Strategy.Result.dCompletionPercentage = 0 + Strategy.Result.dRating = 0 + Strategy.Result.sInfo = 'Mill not found' + bApplyMachiningOK = false end - return Strategy.RatingResult + return bApplyMachiningOK, Strategy.Result end ------------------------------------------------------------------------------------------------------------- diff --git a/Strategies/STR0002/STR0002Config.lua b/Strategies/STR0002/STR0002Config.lua index 345605c..57a5130 100644 --- a/Strategies/STR0002/STR0002Config.lua +++ b/Strategies/STR0002/STR0002Config.lua @@ -3,7 +3,7 @@ local STR0002Data = { sStrategyId = 'STR0002', Parameters = { - { sName = 'dMaxCornerRadius', sValue = '15', sDescription = 'Affondamento lavorazione', sType = 'd'} + { sName = 'dMaxCornerRadius', sValue = '15', sDescriptionShort = 'Max radius left on corners', sDescriptionLong = 'Radius-limit left by the tool at each corner of the feature', sType = 'd', sMinUserLevel = '1', sMessageId = ''} } } diff --git a/Strategies/STR0003/STR0003Config.lua b/Strategies/STR0003/STR0003Config.lua index 879efce..9eac4a6 100644 --- a/Strategies/STR0003/STR0003Config.lua +++ b/Strategies/STR0003/STR0003Config.lua @@ -3,8 +3,8 @@ local STR0003Data = { sStrategyId = 'STR0003', Parameters = { - { sName = 'bApplyOnlyBlade', sValue = 'false', sDescriptionShort = 'Blade only', sDescriptionLong = 'Machining with blade only and avoid chainsaw', sType = 'b', idMessage = ''}, - { sName = 'bForceLongcutBlade', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', idMessage = ''} + { sName = 'bApplyOnlyBlade', sValue = 'false', sDescriptionShort = 'Blade only', sDescriptionLong = 'Machining with blade only and avoid chainsaw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}, + { sName = 'bForceLongcutBlade', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', sMessageId = '', sMinUserLevel = '1'} } }