diff --git a/BatchProcessNew.lua b/BatchProcessNew.lua index 06de795..7a34d53 100644 --- a/BatchProcessNew.lua +++ b/BatchProcessNew.lua @@ -3,7 +3,7 @@ -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() -EgtEnableDebug( false) +EgtEnableDebug( true) -- Imposto direttorio libreria specializzata per Travi EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua') @@ -566,7 +566,11 @@ if bToProcess then for i = 1, #RESULT do local sMsg = '' if RESULT[i].sType == 'Feature' then - sMsg = RESULT[i].ChosenStrategy.sInfo + if RESULT[i].ChosenStrategy.bIsApplyOk then + sMsg = RESULT[i].ChosenStrategy.sInfo + else + sMsg = RESULT[i].ChosenStrategy.sApplyInfo + end elseif RESULT[i].sType == 'Part' then sMsg = RESULT[i].sMsg end diff --git a/LuaLibs/BasicCustomerStrategies.lua b/LuaLibs/BasicCustomerStrategies.lua index 5b4775a..1c91db6 100644 --- a/LuaLibs/BasicCustomerStrategies.lua +++ b/LuaLibs/BasicCustomerStrategies.lua @@ -61,6 +61,7 @@ local function GetStrategies_Egalware( Proc) --------------------------------------------------------------------- -- Feature : Double Cut (1-11) elseif ID.IsDoubleCut( Proc) then + Strategies = { { sStrategyId = 'STR0005'}} --------------------------------------------------------------------- -- Feature : Ridge or Valley Cut (0-12) elseif ID.IsDoubleLongitudinalCut( Proc) then @@ -361,6 +362,7 @@ local function GetStrategies_Essetre( Proc) --------------------------------------------------------------------- -- Feature : Double Cut (1-11) elseif ID.IsDoubleCut( Proc) then + Strategies = { { sStrategyId = 'STR0005'}} --------------------------------------------------------------------- -- Feature : Ridge or Valley Cut (0-12) elseif ID.IsDoubleLongitudinalCut( Proc) then diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 1a53cef..2acb6e7 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -1036,7 +1036,6 @@ local function OrderFeatures( vProc) end ------------------------------------------------------------------------------------------------------------- --- TODO gestire Proc che non hanno una ChosenStrategy, perchè sono specchiate, multi (si legge il risultato da un'altra feature?) o non è stata trovata una strategia local function AddFeatureResultToGlobalList( Proc, OptionalParameters) local sStrategyId local sStatus @@ -1085,6 +1084,9 @@ local function AddFeatureResultToGlobalList( Proc, OptionalParameters) RESULT[#RESULT].AvailableStrategies = BeamLib.TableCopyDeep( Proc.AvailableStrategies) end + -- si segna nella Proc la sua posizione nel RESULT + Proc.nIndexInResult = #RESULT + return RESULT end @@ -1587,6 +1589,17 @@ function BeamExec.ProcessMachinings( PARTS) bIsCombinationMachinable = bIsCombinationMachinable and bAllStrategiesApplied end + -- cancellazione entità create ma non usate + -- TODO funzione? + local idAddGroup = BeamLib.GetAddGroup( PARTS[nPart].id) + local idCreatedEntity = EgtGetFirstInGroup( idAddGroup or GDB_ID.NULL) + while idCreatedEntity do + if EgtGetLevel( idCreatedEntity) == GDB_LV.TEMP then + EgtErase( idCreatedEntity) + end + idCreatedEntity = EgtGetNext( idCreatedEntity) + end + -- ordinamento lavorazioni -- TODO completare ordinamento. Mancano le dipendenze. -- TODO la FinalizeSorting andrebbe rimossa e usato un sorting che non viola le dipendenze diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index ce9a446..9531b97 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -870,7 +870,13 @@ function MachiningLib.AddOperations( vProc, Part, sRotation) bAreAllMachiningApplyOk = false nErr, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nOperationId, false) + -- update risultati + -- TODO è corretto mettere non applicabile????? + RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.sStatus = 'Not-Applicable' + RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.sApplyInfo = sErr + RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.nApplyError = nErr end + RESULT[MACHININGS[i].Proc.nIndexInResult].ChosenStrategy.bIsApplyOk = bIsApplyOk -- TODO è giusto inserire queste info alla fine della lavorazione? oppure conviene creare un record in MACHININGS apposito per la disposizione? -- se era taglio di separazione, aggiungo nuova fase diff --git a/Strategies/AvailableStrategyList.json b/Strategies/AvailableStrategyList.json index 2cee64b..36b2ba8 100644 --- a/Strategies/AvailableStrategyList.json +++ b/Strategies/AvailableStrategyList.json @@ -26,7 +26,7 @@ "nGrp": "1", "TopologyList" : [ { "sName": "Feature", - "StrategyList" : [ ] + "StrategyList" : [ { "sStrategyID": "STR0005" } ] } ] }, diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index 0487a58..2aaf0ec 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -18,7 +18,6 @@ local DiceCut = require( 'DiceCut') local FaceByBlade = require('FACEBYBLADE') -- tabella per definizione modulo -local Machinings = {} local FeatureInfo = {} ------------------------------------------------------------------------------------------------------------- @@ -238,21 +237,28 @@ end local function CutWholeWaste( Proc, Part, OptionalParameters) + local Machinings = {} local Cutting = {} local Result = {} local EdgeToMachine = {} - local nToolIndex local sChosenBladeType = '' local dDepthToMachine = 0 local dCompletionPercentage = 0 + -- parametri opzionali e default + if not OptionalParameters then + OptionalParameters = {} + end + local nToolIndex = OptionalParameters.nToolIndex + local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 + -- lato da lavorare in base al tipo di lama local EdgeToMachineTopBlade = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'Top') local EdgeToMachineBottomBlade = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'Bottom') local EdgeToMachineTopBladeDownUp = GetEdgeToMachine( Proc.Faces[1].Edges, Proc.Faces[1].vtN, 'TopDownUp') -- scelta lama da sopra o da sotto - if OptionalParameters.nToolIndex then + if nToolIndex then nToolIndex = OptionalParameters.nToolIndex else local OptionalParametersGetBestBlade = { dElevationTop = EdgeToMachineTopBlade.dElevation + BeamData.CUT_EXTRA, @@ -265,7 +271,6 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) -- utensile non trovato if not nToolIndex then Result = FeatureLib.GetStrategyResultNotApplicable( 'Blade not found') - return Machinings, Result end @@ -283,7 +288,8 @@ local function CutWholeWaste( Proc, Part, OptionalParameters) -- TODO qui gestire il caso in cui si può tagliare da due lati (inizialmente solo se vtN:Y è ~= 0?). Andranno ricercati gli utensili di nuovo con l'elevazione a metà?? if dResidualDepth < 10 * GEO.EPS_SMALL then - local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, dExtendAfterTail = OptionalParameters.dExtendAfterTail} + local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex, dExtendAfterTail = dExtendAfterTail} + Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade) end if Cutting.bIsApplicable then @@ -313,6 +319,7 @@ end local function CutWithDicing( Proc, Part, OptionalParameters) + local Machinings = {} local Result = {} -- parametri opzionali e default @@ -321,6 +328,11 @@ local function CutWithDicing( Proc, Part, OptionalParameters) end local nToolIndex = OptionalParameters.nToolIndex local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 + local b3BoxDicing = OptionalParameters.b3BoxDicing + local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries + if bSaveAddedGeometries == nil then + bSaveAddedGeometries = true + end -- scelta faccia da lavorare -- se due facce, la faccia principale Face1 è la più grande @@ -362,6 +374,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) OptionalParametersDiceCut.dOffsetOrthogonal = dDiceDimension OptionalParametersDiceCut.dOffsetOrthogonalReduced = dDiceDimensionReduced OptionalParametersDiceCut.dMinNzDownUp = dMinNzDownUp + OptionalParametersDiceCut.b3BoxDicing = b3BoxDicing local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut) -- se nessun cubetto trovato, si richiama il taglio singolo @@ -377,7 +390,7 @@ local function CutWithDicing( Proc, Part, OptionalParameters) local bAreOrthogonalCutsInverted = false for i = 1, #vCuts do for j = 1, #vCuts[i] do - SetDiceFaceInfo( Proc, vCuts[i][j]) + SetDiceFaceInfo( Proc, vCuts[i][j], bSaveAddedGeometries) if ( i % 2) == 1 then local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) if ( Face1.vtN:getY() > 0.766 and vtO:getY() < -0.05) or @@ -523,8 +536,43 @@ local function CutWithDicing( Proc, Part, OptionalParameters) end +local function MakeOneFace( ProcOrId, Part, OptionalParameters) + local Machinings = {} + local Result = {} + + -- disambiguazione feature vs id trimesh + local Proc = {} + if type( ProcOrId) == "table" then + Proc = ProcOrId + elseif type( ProcOrId) == "number" then + Proc = FeatureLib.GetProcFromTrimesh( ProcOrId, Part) + else + error( 'BLADETOWASTE : Only feature or trimesh supported') + end + + -- parametri opzionali e default + if not OptionalParameters then + OptionalParameters = {} + end + local bForceDicing = OptionalParameters.bForceDicing or false + + -- si taglia tutto lo scarto in una sola lavorazione + -- TODO qui si deve entrare anche se lo spessore lama è maggiore dell'elevazione delle faccia + if FeatureInfo.bIsFeatureSmall and not bForceDicing then + Machinings, Result = CutWholeWaste( Proc, Part, OptionalParameters) + end + + -- se non completata con taglio singolo, lavorazione con cubetti + if not Result.sStatus or Result.sStatus ~= 'Completed' then + Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters) + end + + return Machinings, Result +end + + function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) - Machinings = {} + local Machinings = {} local Result = {} -- disambiguazione feature vs id trimesh @@ -540,20 +588,15 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) -- controlli preventivi if Proc.nFct > 2 then error( 'BladeToWaste : max 2 faces supported') - elseif Proc.nFct == 2 then - if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then - error( 'BladeToWaste : angle between faces must be concave and >= 90deg') - end end -- parametri opzionali e default + -- quelli non censiti sono gestiti direttamente nelle funzioni sotto e devono quindi solo transitare if not OptionalParameters then OptionalParameters = {} end - local nToolIndex = OptionalParameters.nToolIndex local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0 local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0 - local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 local bSaveAddedGeometries = OptionalParameters.bSaveAddedGeometries if bSaveAddedGeometries == nil then bSaveAddedGeometries = true @@ -563,19 +606,70 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) FeatureInfo.dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part) FeatureInfo.dFeatureMaxDimension = max( Proc.b3Box:getDimX(), Proc.b3Box:getDimY()) FeatureInfo.bIsFeatureSmall = FeatureInfo.dFeatureVolume < dMaxWasteVolume + 10 * GEO.EPS_SMALL - and FeatureInfo.dFeatureMaxDimension < dMaxWasteLength + 10 * GEO.EPS_SMALL + and FeatureInfo.dFeatureMaxDimension < dMaxWasteLength + 10 * GEO.EPS_SMALL - -- si taglia tutto lo scarto in una sola lavorazione - -- TODO qui si deve entrare anche se lo spessore lama è maggiore dell'elevazione delle faccia - if Proc.nFct == 1 and FeatureInfo.bIsFeatureSmall then - Machinings, Result = CutWholeWaste( Proc, Part, OptionalParameters) - if Result.sStatus == 'Completed' then - return Machinings, Result + -- calcolo lavorazioni + if Proc.nFct == 1 then + Machinings, Result = MakeOneFace( Proc, Part, OptionalParameters) + + elseif Proc.nFct == 2 then + local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] + + -- feature convessa: lavorata come 2 facce singole con prolungamento + if dAngleBetweenFaces > 10 * GEO.EPS_SMALL then + -- si creano superfici singole per le facce, estese fino al box della parte + local nAddGrpId = BeamLib.GetAddGroup( Part.id) + local idFace1 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[1].ptCenter, Proc.Faces[1].vtN, Part.b3Part, GDB_ID.ROOT) + local idFace2 = EgtSurfTmPlaneInBBox( nAddGrpId, Proc.Faces[2].ptCenter, Proc.Faces[2].vtN, Part.b3Part, GDB_ID.ROOT) + if not bSaveAddedGeometries then + EgtSetLevel( idFace1, GDB_LV.TEMP) + EgtSetLevel( idFace2, GDB_LV.TEMP) + end + + -- lavorazione facce + local Machinings1, Result1 = MakeOneFace( idFace1, Part, OptionalParameters) + local Machinings2, Result2 = MakeOneFace( idFace2, Part, OptionalParameters) + + -- tutte le lavorazioni raggruppatee e calcolo area lavorata + local dAreaToMachineTotal = 0 + for i = 1, #Machinings1 do + if Machinings1[i].bIsApplicable then + table.insert( Machinings, Machinings1[i]) + dAreaToMachineTotal = dAreaToMachineTotal + Machinings1[i].dAreaToMachine + end + end + for i = 1, #Machinings2 do + if Machinings2[i].bIsApplicable then + table.insert( Machinings, Machinings2[i]) + dAreaToMachineTotal = dAreaToMachineTotal + Machinings2[i].dAreaToMachine + end + end + + -- calcolo risultati + Result.nQuality = FeatureLib.GetStrategyQuality( Machinings) + Result.dCompletionPercentage = dAreaToMachineTotal / ( Proc.Faces[1].dArea + Proc.Faces[2].dArea) * 100 + Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Result.dCompletionPercentage) + Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings) + Result.dMRR = ( FeatureInfo.dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) + if Result1.sStatus == 'Completed' and Result2.sStatus == 'Completed' then + Result.sStatus = 'Completed' + elseif Result1.sStatus == 'Completed' or Result2.sStatus == 'Completed' then + Result.sStatus = 'Not-Completed' + else + Result.sStatus = 'Not-Applicable' + Result = FeatureLib.GetStrategyResultNotApplicable() + end + + -- feature concava >= 90deg: lavorata con cubetti + elseif dAngleBetweenFaces >= -91 then + Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters) + + -- feature concava < 90deg: lavorata come 2 facce singole con accorciamento + else + -- TODO da fare end + end - - -- lavorazione con cubetti - Machinings, Result = CutWithDicing( Proc, Part, OptionalParameters) return Machinings, Result end