From 80dcdb00039ac23d82fe34b5da543e398e239a1b Mon Sep 17 00:00:00 2001 From: "andrea.villa" Date: Tue, 30 Apr 2024 16:30:49 +0200 Subject: [PATCH] - Facce e adiacenze calcolate solo per feature con topologia - Prima versione GetMainFaces funzionante - Prima bozza struttura codice per scelta strategie - Calcolo delle 4 rotazioni per il recupero dei dati - Prima bozza struttura calcolo voto strategie - Modificate strategie di prova STR0001 e STR0002 con nuovo standard --- LuaLibs/BasicCustomerStrategies.lua | 10 +- LuaLibs/BeamExec.lua | 256 +++++++++++++++++++++++---- LuaLibs/FaceData.lua | 102 +++++++---- LuaLibs/FeatureData.lua | 35 ++-- LuaLibs/Identity.lua | 5 + LuaLibs/MachiningLib.lua | 58 ++++++ Process.lua | 10 +- Strategies/STR0001/STR0001.lua | 13 ++ Strategies/STR0001/STR0001Config.lua | 2 +- Strategies/STR0002/STR0002.lua | 13 ++ Strategies/STR0002/STR0002Config.lua | 11 ++ 11 files changed, 411 insertions(+), 104 deletions(-) diff --git a/LuaLibs/BasicCustomerStrategies.lua b/LuaLibs/BasicCustomerStrategies.lua index 8871dff..923116c 100644 --- a/LuaLibs/BasicCustomerStrategies.lua +++ b/LuaLibs/BasicCustomerStrategies.lua @@ -24,10 +24,10 @@ local function GetStrategies_Egalware( Proc) --------------------------------------------------------------------- -- Feature : Cut - if ID.IsHeadCut( Proc) then + if true or ID.IsHeadCut( Proc) then -- TODO TOGLIERE IL true PER FORZARE IF!!! PROVVISORIO PER PROVARE STRATEGIE if Proc.Topology.Name == 'FEATURE' then Strategy_Egalware = { - StrategyID = 'STR0010', + StrategyId = 'STR0010', Parameters = { { Value = '15', Name = 'Step', Type = 'd'}, { Value = 'false', Name = 'AntiSplint', Type = 'b'} @@ -186,6 +186,7 @@ local function GetStrategies_Egalware( Proc) --------------------------------------------------------------------- -- Feature : Variant elseif ID.IsVariant( Proc) then + --------------------------------------------------------------------- end return Strategies_Egalware @@ -202,10 +203,10 @@ local function GetStrategies_Essetre( Proc) --------------------------------------------------------------------- -- Feature : Cut - if ID.IsHeadCut( Proc) then + if true or ID.IsHeadCut( Proc) then -- TODO TOGLIERE IL true PER FORZARE IF!!! PROVVISORIO PER PROVARE STRATEGIE if Proc.Topology.Name == 'FEATURE' then Strategy_Essetre = { - StrategyID = 'STR0010', + StrategyId = 'STR0010', Parameters = { { Value = '15', Name = 'Step', Type = 'd'}, { Value = 'false', Name = 'AntiSplint', Type = 'b'} @@ -364,6 +365,7 @@ local function GetStrategies_Essetre( Proc) --------------------------------------------------------------------- -- Feature : Variant elseif ID.IsVariant( Proc) then + --------------------------------------------------------------------- end return Strategies_Essetre diff --git a/LuaLibs/BeamExec.lua b/LuaLibs/BeamExec.lua index 8346a9a..e43ba65 100644 --- a/LuaLibs/BeamExec.lua +++ b/LuaLibs/BeamExec.lua @@ -17,6 +17,7 @@ local ID = require( 'Identity') local BCS = require( 'BasicCustomerStrategies') local FeatureData = require( 'FeatureData') local FaceData = require( 'FaceData') +local MachiningLib = require( 'MachiningLib') EgtOutLog( ' BeamExec started', 1) @@ -411,33 +412,31 @@ local function GetStrategies( Proc) if not AvailableStrategiesForProc then AvailableStrategiesForProc = BCS.GetStrategiesFromBasicCustomerStrategies( Proc) end - -- TODO se ci sono strategie, le carichiamo qui o quando si lanciano effettivamente? - -- TODO2 Probabilmente meglio lanciarle solo quando serve. Nel caso standard infatti, la prima completa è quella buona, quindi non serve precaricare tutte le altre return AvailableStrategiesForProc end ------------------------------------------------------------------------------------------------------------- local function GetFeatureForcedStrategy( Proc) -- cerco nelle note se è stata forzata una strategia specifica - local sStrategyID = EgtGetInfo( Proc.Id, 'STRATEGY', 's') + local sStrategyId = EgtGetInfo( Proc.Id, 'STRATEGY', 's') -- se è presente la strategia forzata - if sStrategyID then - -- eseguo file config con i parametri di default - local StrategyData = require( sStrategyID .. '\\' .. sStrategyID .. 'Config') + if sStrategyId then + -- eseguo file config con i parametri di default + local StrategyData = require( sStrategyId .. '\\' .. sStrategyId .. 'Config') -- se ID strategia non esiste oppure ID letto in NGE è differente da quello letto nella strategia, esco subito - if not StrategyData or StrategyData.StrategyID ~= sStrategyID then + if not StrategyData or StrategyData.StrategyId ~= sStrategyId then return nil end -- salvo che questa strategia è stata forzata, e che quindi ho già letto il file config con i parametri di default - -- quando si calcolerà la lavorazione non servirà riverificare i dati + -- quando si calcolerà la lavorazione non servirà leggere/riverificare i parametri di default StrategyData.ForcedStrategy = true -- cerco e aggiorno i parametri come sono settati nel processing for i = 1, #StrategyData.Parameters do - local sParameterToRead = StrategyData.StrategyID .. '_' .. StrategyData.Parameters[i].Name + local sParameterToRead = StrategyData.StrategyId .. '_' .. StrategyData.Parameters[i].Name ForcedParameterForProc = EgtGetInfo( Proc.Id, sParameterToRead, 's') -- se ho trovato il valore, lo sovrascrivo al default if ForcedParameterForProc then @@ -469,11 +468,6 @@ local function CollectFeatures( PartId, b3Raw) local nGrp = EgtGetInfo( ProcId, 'GRP', 'i') local nPrc = EgtGetInfo( ProcId, 'PRC', 'i') local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1 - local nCutId = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0 - local nTaskId = EgtGetInfo( ProcId, 'TASKID', 'i') or 0 - -- leggo se ci sono feature collegate - local nAddAdjId = EgtGetInfo( ProcId, 'ADJID', 'i') - local nAddMainId = EgtGetInfo( ProcId, 'MAINID', 'i') if nGrp and nPrc and nDo == 1 then local Proc = {} Proc.PartId = PartId @@ -484,15 +478,8 @@ local function CollectFeatures( PartId, b3Raw) Proc.Prc = nPrc Proc.Flg = 1 Proc.Fct = EgtSurfTmFacetCount( ProcId) or 0 - Proc.CutId = nCutId - Proc.TaskId = nTaskId - -- se ci sono feature collegate ne scrivo il riferimento nella Proc - -- TODO AdjId e MainId servono a qualcosa??? - if nAddAdjId then - Proc.AdjId = Proc.Id + nAddAdjId - elseif nAddMainId then - Proc.MainId = Proc.Id + nAddMainId - end + Proc.CutId = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0 + Proc.TaskId = EgtGetInfo( ProcId, 'TASKID', 'i') or 0 Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) EgtOutLog( '------Feature ' .. Proc.FeatureId .. '------') -- se esiste la geometria @@ -504,23 +491,30 @@ local function CollectFeatures( PartId, b3Raw) Proc.Diam, Proc.Len, Proc.Fcs, Proc.Fce = FeatureData.GetDrillingData( Proc) end -- informazioni facce e topologia - Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc) - Proc.Faces = FaceData.GetFacesInfo( Proc) - Proc.Topology = FeatureData.GetTopology( Proc, b3Raw) + -- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL + Proc.Topology = {} + if FeatureData.NeedTopologyFeature( Proc) then + Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc) + Proc.Faces = FaceData.GetFacesInfo( Proc) + Proc.Topology = FeatureData.ClassifyTopology( Proc, b3Raw) + else + Proc.Topology.Family = 'FEATURE' + Proc.Topology.Name = 'FEATURE' + end -- se topologia feature riconosciuta, oppure da non calcolare perchè il riconoscimento topologico è basato sulla feature stessa if Proc.Topology.Name ~= 'NOT_IMPLEMENTED' then -- TODO Funzione 'GetMainFaces' da scrivere - -- Proc.MainFaces = FaceData.GetMainFaces( Proc) + Proc.MainFaces = FaceData.GetMainFaces( Proc) -- se la processing ha una strategia forzata, riporto tutto nella proc local vForcedStrategy = GetFeatureForcedStrategy( Proc) if vForcedStrategy then - Proc.Strategies = vForcedStrategy + Proc.AvailableStrategies = vForcedStrategy -- altrimenti cerco tra le strategie disponibili else - Proc.Strategies = GetStrategies( Proc) + Proc.AvailableStrategies = GetStrategies( Proc) end -- se ci sono strategie disponibili, aggiungo a lista delle feature da lavorare - if Proc.Strategies and #Proc.Strategies > 0 then + if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then table.insert( vProc, Proc) -- altrimenti errore (non ci sono strategie per lavorare la topologia riconosciuta) else @@ -543,6 +537,70 @@ local function CollectFeatures( PartId, b3Raw) return vProc end +------------------------------------------------------------------------------------------------------------- +local function AreDrillingsMirrored( Proc, ProcMirror, b3Raw) + if Proc.Id == ProcMirror.Id then return false end + + -- geometria ausiliaria foro principale + AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId ) ~= GDB_TY.CRV_ARC then return false end + -- geometria ausiliaria foro specchiato + local AuxIdMirror = EgtGetInfo( ProcMirror.Id, 'AUXID', 'i') + if AuxIdMirror then AuxIdMirror = AuxIdMirror + ProcMirror.Id end + if not AuxIdMirror or EgtGetType( AuxIdMirror ) ~= GDB_TY.CRV_ARC then return false end + -- dati del foro principale + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptBC = EgtGP( AuxId, GDB_RT.GLOB) + -- dati del foro specchiato + local vtExtrMirror = EgtCurveExtrusion( AuxIdMirror, GDB_RT.GLOB) + local ptBCMirror = EgtGP( AuxIdMirror, GDB_RT.GLOB) + + -- direzione fori + local nDouble + if AreOppositeVectorApprox( vtExtr, vtExtrMirror) then + -- fori lungo Y + -- per macchine tipo PF il foro principale è sul lato back, per macchine tipo PF1250 è sul lato front + if ( BD.TWO_EQUAL_HEADS and AreSameVectorApprox( vtExtr, Y_AX())) or + ( BD.DOWN_HEAD and AreOppositeVectorApprox( vtExtr, Y_AX())) then + nDouble = 2 + -- fori lungo Z + elseif BD.DOWN_HEAD and AreSameVectorApprox( vtExtr, Z_AX()) then + nDouble = 3 + else + return false + end + else + return false + end + + -- centri allineati, equidistanti dalla mezzeria trave, non troppo vicini + local vtDisplacement = ptBC - ptBCMirror + local ptCenRaw = b3Raw:getCenter() + if nDouble == 2 then + local dYMinDistance = max( Proc.Box:getMin():getY(), ProcMirror.Box:getMin():getY()) - min( Proc.Box:getMax():getY(), ProcMirror.Box:getMax():getY()) + if not ( abs( vtDisplacement:getX()) < 100 * GEO.EPS_SMALL and abs( vtDisplacement:getZ()) < 100 * GEO.EPS_SMALL and + ( abs( ptBC:getY() - ptCenRaw:getY()) - abs( ptBCMirror:getY() - ptCenRaw:getY())) < 100 * GEO.EPS_SMALL and + dYMinDistance > MIRROR_DRILLINGS_MIN_DISTANCE + 10 * GEO.EPS_SMALL) then + return false + end + else + local dZMinDistance = max( Proc.Box:getMin():getZ(), ProcMirror.Box:getMin():getZ()) - min( Proc.Box:getMax():getZ(), ProcMirror.Box:getMax():getZ()) + if not ( abs( vtDisplacement:getX()) < 100 * GEO.EPS_SMALL and abs( vtDisplacement:getY()) < 100 * GEO.EPS_SMALL and + ( abs( ptBC:getZ() - ptCenRaw:getZ()) - abs( ptBCMirror:getZ() - ptCenRaw:getZ())) < 100 * GEO.EPS_SMALL and + dZMinDistance > MIRROR_DRILLINGS_MIN_DISTANCE + 10 * GEO.EPS_SMALL) then + return false + end + end + + -- fori della stessa profondità + if abs( Proc.Len - ProcMirror.Len) > 10 * GEO.EPS_SMALL then + return false + end + + return true +end + ------------------------------------------------------------------------------------------------------------- local function GetFeatureInfoAndDependency( vProc, b3Raw) -- ciclo tutte le feature @@ -572,6 +630,79 @@ local function GetFeatureInfoAndDependency( vProc, b3Raw) end end +------------------------------------------------------------------------------------------------------------- +-- -- sceglie la strategia migliore tra quelle disponibili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies) +local function ChooseStrategy( Proc, b3Raw) + -- ciclo tutte le strategia + local nIndexBestStrategy = 0 + for i = 1, #Proc.AvailableStrategies do + + end + + -- salvo sulla proc la migliore strategia + if nIndexBestStrategy ~= 0 then + Proc.ChosenStrategy = Proc.AvailableStrategies[nIndexBestStrategy] + end + + return Proc +end + +------------------------------------------------------------------------------------------------------------- +-- funzione che processa tutte le feature sul pezzo e trova la miglior strategia di lavorazione tra quelle disponibili +local function ProcessPieceFeatures( vProcSingleRot, b3Raw) + -- scelgo la strategia migliore + for i = 1, #vProcSingleRot do + -- processo tutte le feature attive + local Proc = vProcSingleRot[i] + if Proc.Flg ~= 0 then + -- processa le strategie disponibili e salva sulla Proc il voto e info varie per ogni startegia + Proc = MachiningLib.CalculateRatingStrategies( Proc, b3Raw) + -- sceglie la strategia migliore tra quelle disponibili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies) + Proc = ChooseStrategy( Proc, b3Raw) + end + end + return vProcSingleRot +end + +------------------------------------------------------------------------------------------------------------- +-- esegue le strategie migliori che ha precedentemente scelto +local function ExecPieceFeatures( vProc, b3Raw) + -- flag per applicare realmente le lavorazioni quando viene lanciata la make delle strategie + local bAddMachining = true + -- applico le strategie scelte + for i = 1, #vProc do + -- processo tutte le feature attive applicando le lavorazioni + local Proc = vProc[i] + if Proc.Flg ~= 0 and Proc.ChosenStrategy then + -- carico file script strategia (non serve verificare presenza del file perchè già fatto durante scelta strategia) + local StrategyScriptName = '\\Strategies\\' .. Proc.ChosenStrategy.StrategyId .. '\\' .. Proc.ChosenStrategy.StrategyId + local StrategyScript = require( StrategyScriptName) + -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati + Proc = StrategyScript.Make( bAddMachining, Proc, Proc.ChosenStrategy.Parameters) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc, b3Raw) + EgtOutLog( ' RawBox=' .. tostring( b3Raw)) + for i = 1, #vProc do + local Proc = vProc[i] + local sOut = string.format( ' Id=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Side=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s TopoName=%s', + Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, + Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Side, 'T', 'F'), + EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', EgtIf( Proc.AdvTail, 'A', 'F')), + Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box), Proc.Topology.Name or '') + -- info speciali per Block Haus Half Lap + if Proc.Prc == 37 then + local sSpec = string.format( ' N=%s Hd=%s', tostring( Proc.vtN or V_NULL()), EgtIf( Proc.HeadDir, 'T', 'F')) + sOut = sOut .. sSpec + end + EgtOutLog( sOut) + end +end + ------------------------------------------------------------------------------------------------------------- function BeamExec.ProcessFeatures() -- ciclo sui pezzi @@ -583,6 +714,49 @@ function BeamExec.ProcessFeatures() -- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli local nPartId = EgtGetFirstPartInRawPart( nRawId) if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BeamData.MinRaw then break end + + local vProc = {} + -- per ogni rotazione, calcolo come lavorare le feature per decidere posizionamento iniziale e in che rotazione verranno lavorate le singole feature + local vProcRot = {} + + -- TODO da rimuovere o lasciare solo per debug + EgtStartCounter() + + -- TODO Il numero di rotazioni da calcolare deve dipendere dalle impostazionei del cliente. Per adesso si calcolano tutte e 4, ma può essere ottimizzato + for dRotIndex = 1, 4 do + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero le feature di lavorazione della trave + table.insert( vProcRot, CollectFeatures( nPartId, b3Raw)) + -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse + -- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no + GetFeatureInfoAndDependency( vProcRot[dRotIndex], b3Raw) + + -- sceglie la strategia migliore tra quelle disponibili ( presenti nella tabella vProcRot[dRotIndex].AvailableStrategies) + ProcessPieceFeatures( vProcRot[dRotIndex], b3Raw) + + -- ruoto il grezzo per calcolare la fattibilità delle lavorazioni nella prossima rotazione + -- vettore movimento grezzi per rotazione di 90deg ogni step + local dDeltaYZ = EgtGetRawPartBBox( nRawId):getDimY() - EgtGetRawPartBBox( nRawId):getDimZ() + local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2) + local bPreMove = ( dDeltaYZ < 0) + -- ruoto le travi della fase corrente + if bPreMove then + EgtMoveRawPart( nRawId, vtMove) + end + EgtRotateRawPart( nRawId, X_AX(), EgtIf( BeamData.RIGHT_LOAD, -90, 90)) + if not bPreMove then + EgtMoveRawPart( nRawId, vtMove) + end + end + + -- TODO da rimuovere o lasciare solo per debug + local time = EgtStopCounter() + + -- TODO decidere come lavorare ogni feature in base alla matrice delle rotazioni + -- la matrice delle rotazioni deve già salvare sulla proc la strategia da utilizzare + -- Conviene salvarsi tutti i dati fino alla lavorazione e il ciclo di applicazione va ad applicare senza calcolare? + -- aggiungo la fase, se non è la prima if nOrd == 1 then EgtSetCurrPhase( 1) @@ -596,14 +770,26 @@ function BeamExec.ProcessFeatures() EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId) .. ' ***', 1) -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) - -- recupero le feature di lavorazione della trave - local vProc = CollectFeatures( nPartId, b3Raw) - -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse - GetFeatureInfoAndDependency( vProc, b3Raw) + + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, b3Raw) + end + EgtOutLog( ' *** AddMachinings ***', 1) -- TODO ordinare feature e decidere spezzoni - -- TODO applicare lavorazioni in base a strategie disponibili (prima applicabile o EgalwareIA in base a parametro) + -- ordino le features + -- OrderFeatures( vProc, b3Raw) + + + -- TODO da fare + -- esegue le strategie migliori che ha precedentemente scelto + ExecPieceFeatures( vProc, b3Raw) + + -- TODO riordinare lavorazioni ottimizzando cambio utensile/spezzone ecc..., mantenendo dipendenze definite prima + -- ordino le lavorazioni + -- OrderMachining( vProc, b3Raw) EgtOutLog( ' *** End AddMachinings ***', 1) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index 53d1d0c..10b687b 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -39,6 +39,11 @@ end --------------------------------------------------------------------- -- restituisce un vettore con gli indici (0 based) delle facce triangolari (o quasi) di Proc function FaceData.GetTriangularFaces( Proc) + -- se la feature ha una sola faccia, esco subito + if Proc.Fct <= 1 then + return + end + local vTriangularFaces = {} for i = 1, Proc.Fct do @@ -74,7 +79,13 @@ end --------------------------------------------------------------------- local function GetFacesContactLength( Proc, idFace1, idFace2) local _, ptP1, ptP2 = EgtSurfTmFacetsContact( Proc.Id, idFace1, idFace2, GDB_ID.ROOT) - local dLength = dist( ptP1, ptP2) + + local dLength = 0 + if ptP1 and ptP2 then + dLength = dist( ptP1, ptP2) + else + -- TODO se non trova lunghezza serve dare messaggio di errore? + end return dLength end @@ -82,6 +93,11 @@ end --------------------------------------------------------------------- -- restituisce una tabella che correla numero di adiacenze e id delle facce con quello stesso numero di adiacenze function FaceData.GetFacesByAdjacencyNumber( Proc) + -- se la feature ha una sola faccia, esco subito + if Proc.Fct <= 1 then + return + end + local FacesByAdjacencyNumber = {} for i = 1, 10 do @@ -190,7 +206,7 @@ local function GetBottomFace( Proc) local BottomFace = {} if Proc.Topology.Family == 'Tunnel' then - return BottomFace + return nil elseif not ( Proc.Topology.Family == 'Rabbet' or Proc.Topology.Family == 'VGroove' or Proc.Topology.Family == 'Groove' or Proc.Topology.Family == 'Pocket') then error( 'GetBottomFace : Topology not implemented') end @@ -222,13 +238,6 @@ local function GetLongFaces( Proc, MainFaces) end local idBottomFace = GDB_ID.NULL - if MainFaces.BottomFace then - idBottomFace = MainFaces.BottomFace.Id - else - local BottomFace = GetBottomFace( Proc) - idBottomFace = BottomFace.Id or idBottomFace - end - local idTunnelMiddleFace = GDB_ID.NULL if Proc.Topology.Family == 'Tunnel' then if MainFaces.TunnelAddedFaces then @@ -237,6 +246,13 @@ local function GetLongFaces( Proc, MainFaces) local TunnelAddedFaces = GetTunnelFaces( Proc) idTunnelMiddleFace = TunnelAddedFaces.MiddleFaceTm.Id or idTunnelMiddleFace end + else + if MainFaces.BottomFace then + idBottomFace = MainFaces.BottomFace.Id + else + local BottomFace = GetBottomFace( Proc) + idBottomFace = BottomFace.Id or idBottomFace + end end local FacesToAnalyze = {} @@ -275,12 +291,15 @@ local function GetSideFaces( Proc, MainFaces) end local idBottomFace = GDB_ID.NULL - if MainFaces.BottomFace then - idBottomFace = MainFaces.BottomFace.Id - else - local BottomFace = GetBottomFace( Proc) - idBottomFace = BottomFace.Id or idBottomFace + if Proc.Topology.Family ~= 'Tunnel' then + if MainFaces.BottomFace then + idBottomFace = MainFaces.BottomFace.Id + else + local BottomFace = GetBottomFace( Proc) + idBottomFace = BottomFace.Id or idBottomFace + end end + local LongFaces = {} if MainFaces.LongFaces then LongFaces = MainFaces.LongFaces @@ -288,8 +307,9 @@ local function GetSideFaces( Proc, MainFaces) LongFaces = GetLongFaces( Proc, MainFaces) end + for i = 1, Proc.Fct do - if i ~= idBottomFace + 1 then + if not idBottomFace or i ~= ( idBottomFace + 1) then local bIsSideFace = true for j = 1, #LongFaces do if Proc.Faces[i].Id == LongFaces[j].Id then @@ -309,38 +329,44 @@ end ------------------------------------------------------------------------------------------------------------- -- recupero facce principali della feature, in base alla topologia function FaceData.GetMainFaces( Proc) + EgtOutLog( '---MainFaces START---') local MainFaces = {} - if Proc.Topology.IsThrough and Proc.Topology.AllRightAngles and Proc.Fct < 5 then - MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc) - end - + -- CASO 1 : Feature tipo LapJoint if Proc.Topology.Family == 'Rabbet' or Proc.Topology.Family == 'VGroove' or Proc.Topology.Family == 'Groove' or Proc.Topology.Family == 'Pocket' or Proc.Topology.Family == 'Tunnel' then + + if Proc.Topology.IsThrough and Proc.Topology.AllRightAngles and Proc.Fct < 5 then + MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc) + end + MainFaces.BottomFace = GetBottomFace( Proc) MainFaces.LongFaces = GetLongFaces( Proc, MainFaces) MainFaces.SideFaces = GetSideFaces( Proc, MainFaces) + -- TODO funzione apposita per informazioni log? + if EgtGetDebugLevel() >= 3 then + if MainFaces.BottomFace then + EgtOutLog( 'Bottom Face : ' .. MainFaces.BottomFace.Id) + end + if MainFaces.LongFaces then + for i = 1, #MainFaces.LongFaces do + EgtOutLog( 'Long Face : ' .. MainFaces.LongFaces[i].Id) + end + end + if MainFaces.SideFaces then + for i = 1, #MainFaces.SideFaces do + EgtOutLog( 'Side Face : ' .. MainFaces.SideFaces[i].Id) + end + end + if MainFaces.TunnelAddedFaces then + EgtOutLog( 'Middle Face (Trimesh): ' .. MainFaces.TunnelAddedFaces.MiddleFaceTm.Id) + end + end + else + EgtOutLog( '---MainFaces NOT NEEDED---') end - -- TODO funzione apposita per informazioni log? - if EgtGetDebugLevel() >= 3 then - if MainFaces.BottomFace then - EgtOutLog( 'Bottom Face : ' .. MainFaces.BottomFace.Id) - end - if MainFaces.LongFaces then - for i = 1, #MainFaces.LongFaces do - EgtOutLog( 'Long Face : ' .. MainFaces.LongFaces[i].Id) - end - end - if MainFaces.SideFaces then - for i = 1, #MainFaces.SideFaces do - EgtOutLog( 'Side Face : ' .. MainFaces.SideFaces[i].Id) - end - end - if MainFaces.TunnelAddedFaces then - EgtOutLog( 'Middle Face (Trimesh): ' .. MainFaces.TunnelAddedFaces.MiddleFaceTm.Id) - end - end + EgtOutLog( '---MainFaces END---') return MainFaces diff --git a/LuaLibs/FeatureData.lua b/LuaLibs/FeatureData.lua index f8cb4bc..73aed07 100644 --- a/LuaLibs/FeatureData.lua +++ b/LuaLibs/FeatureData.lua @@ -16,7 +16,7 @@ local ID = require( 'Identity') ------------------------------------------------------------------------------------------------------------- -- recupero topologia della feature -local function NeedTopologyFeature( Proc) +function FeatureData.NeedTopologyFeature( Proc) -- features tipo taglio if ID.IsCut( Proc) then return true @@ -63,6 +63,11 @@ end --------------------------------------------------------------------- -- restituisce true se Proc ha tutti gli angoli concavi (bAllConcave) e, nei casi in cui ha senso, se questi sono esattamente 90 deg (bAllRight) local function AreAllAnglesConcaveOrRight( vAdj) + -- se la feature ha una sola faccia, esco subito + if #vAdj <= 1 then + return + end + local bAllConcave, bAllRight = true, true local nFct = #( vAdj or {}) @@ -125,19 +130,20 @@ end --------------------------------------------------------------------- -- recupera topologia feature -local function ClassifyTopology( Proc, b3Raw) +function FeatureData.ClassifyTopology( Proc, b3Raw) local FeatureTopology = {} if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetProcessAffectedFaces( Proc) end - local vAdj = FaceData.GetAdjacencyMatrix( Proc) - local bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( vAdj) - local vTriangularFaces = FaceData.GetTriangularFaces( Proc) - local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc) - local vFacesByAdjNumber = FaceData.GetFacesByAdjacencyNumber( Proc) local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.Box, b3Raw) local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.Box, b3Raw) + local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc) + local vAdj = Proc.AdjacencyMatrix + local bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( vAdj) + local vTriangularFaces = FaceData.GetTriangularFaces( Proc) + local vFacesByAdjNumber = FaceData.GetFacesByAdjacencyNumber( Proc) + local sFamily local bIsThrough if Proc.Fct == 1 and ( bIsFeatureCuttingEntireSection or bIsFeatureCuttingEntireLength) then @@ -201,21 +207,6 @@ local function ClassifyTopology( Proc, b3Raw) return FeatureTopology end -------------------------------------------------------------------------------------------------------------- -function FeatureData.GetTopology( Proc, b3Raw) - local FeatureTopology = {} - - -- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL - if NeedTopologyFeature( Proc) then - FeatureTopology = ClassifyTopology( Proc, b3Raw) - else - FeatureTopology.Family = 'FEATURE' - FeatureTopology.Name = FeatureTopology.Family - end - - return FeatureTopology -end - ------------------------------------------------------------------------------------------------------------- -- Recupero dati foro e adattamento se speciale function FeatureData.GetDrillingData( Proc) diff --git a/LuaLibs/Identity.lua b/LuaLibs/Identity.lua index 67fa09a..8b1078d 100644 --- a/LuaLibs/Identity.lua +++ b/LuaLibs/Identity.lua @@ -266,5 +266,10 @@ function Identity.IsVariant( Proc) return ( ( Proc.Grp == 0 or Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 900) end --------------------------------------------------------------------- +-- Feature Decor +function Identity.IsDecor( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 959) +end +--------------------------------------------------------------------- return Identity diff --git a/LuaLibs/MachiningLib.lua b/LuaLibs/MachiningLib.lua index 3f4b08c..83025b4 100644 --- a/LuaLibs/MachiningLib.lua +++ b/LuaLibs/MachiningLib.lua @@ -10,5 +10,63 @@ require( 'EgtBase') EgtOutLog( ' MachiningLib started', 1) +------------------------------------------------------------------------------------------------------------- +-- funzione che trova la strategia migliore per lavorare la feature passata +-- ritorna la lista della strategia scelta (Id + parameters) e una lista con il risultato di tutte le altre (score + messages) +function MachiningLib.CalculateRatingStrategies( Proc, b3Raw) + -- flag per non applicare realmente le lavorazioni, ma limitarsi ai calcoli di fattibilità, quando viene lanciata la make delle strategie + local bAddMachining = false + -- controllo se ci sono strategie disponibili + if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then + -- ciclo tutte le strategie della feature + for nIndexStrategy = 1, #Proc.AvailableStrategies do + -- eseguo file config con i parametri di default + local StrategyDataName = Proc.AvailableStrategies[nIndexStrategy].StrategyId .. '\\' .. Proc.AvailableStrategies[nIndexStrategy].StrategyId .. 'Config' + local StrategyDataPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyDataName .. '.lua' + local StrategyScriptName = '\\Strategies\\' .. Proc.AvailableStrategies[nIndexStrategy].StrategyId .. '\\' .. Proc.AvailableStrategies[nIndexStrategy].StrategyId + local StrategyScriptPath = BEAM.BASEDIR .. '\\Strategies\\' .. StrategyScriptName + if EgtExistsFile( StrategyDataPath) and EgtExistsFile( StrategyScriptPath) then + local StrategyData = require( StrategyDataName) + -- eseguo file script strategia + local StrategyScript = require( StrategyScriptName) + + -- sovrascrivo i parametri personalizzati salvati su Proc a quelli di default dalla strategia + if Proc.AvailableStrategies[nIndexStrategy].Parameters and #Proc.AvailableStrategies[nIndexStrategy].Parameters > 0 then + for j = 1, #StrategyData.Parameters do + for k = 1, #Proc.AvailableStrategies[i].Parameters[k] do + if StrategyData.Parameters[j].Name == Proc.AvailableStrategies[nIndexStrategy].Parameters[k].Name then + StrategyData.Parameters[j].Value = Proc.AvailableStrategies[nIndexStrategy].Parameters[k].Value + end + end + end + end + + -- salvo sul proc i parametri di defalt letti da strategia e personalizzati da interfaccia + -- N.B. : I parametri personalizzati non più presenti tra i default della strategia, verranno ignorati + Proc.AvailableStrategies[nIndexStrategy].Parameters = StrategyData.Parameters + + -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati + Proc = StrategyScript.Make( bAddMachining, Proc, Proc.AvailableStrategies[nIndexStrategy].Parameters) + + -- se lavorazione della feature è completa e si ricerca prima staregia completa, uscire subito + if BEAM.GetFirstCompletedStrategy and Proc.AvailableStrategies[nIndexStrategy].Status == 'Completed' then + return Proc + -- altrimenti continuo e processo le altre strategie e sceglierò la migliore dopo che saranno state tutte analizzate + else + ; -- non si fa alcunché + end + + -- se non trovo i file della strategia, scrivo che non è più disponibile + else + Proc.AvailableStrategies[nIndexStrategy].Rating = 0 + Proc.AvailableStrategies[nIndexStrategy].Info = 'Strategy not found' + Proc.AvailableStrategies[nIndexStrategy].Status = 'Not-Applicable' + end + end + end + -- si ritorna la lista relativa alla singola feature con i nuovi parametri aggiunti + return Proc +end + ------------------------------------------------------------------------------------------------------------- return MachiningLib diff --git a/Process.lua b/Process.lua index 79e0df9..dc59b45 100644 --- a/Process.lua +++ b/Process.lua @@ -12,7 +12,7 @@ EgtEnableDebug( true) -- Imposto direttorio libreria specializzata per Travi EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua') -- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre -EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\?') +EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\?.lua') -- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi local sMachDir = EgtGetCurrMachineDir() @@ -40,10 +40,13 @@ _G.package.loaded.Identity = nil _G.package.loaded.BasicCustomerStrategies = nil _G.package.loaded.FeatureData = nil _G.package.loaded.FaceData = nil +_G.package.loaded.MachiningLib = nil --- TODO controllare se c'è un modo migliore per resettare librerie caricate precedentemente +-- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente +-- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento. +-- Infatti difficile ci siano 9999 strategie. -- reset strategie caricate come librerie -for i = 1, 9999 do +for i = 1, 999 do local IdSTRTemp = EgtReplaceString( tostring( i/10000, 4), '0.', '') local sLibraryToReload = "STR" .. IdSTRTemp .. "\\STR" .. IdSTRTemp .. "Config" local sLibraryConfigToReload = sLibraryToReload .. "Config" @@ -55,7 +58,6 @@ for i = 1, 9999 do end end - local BeamExec = require( 'BeamExec') -- Carico i dati globali diff --git a/Strategies/STR0001/STR0001.lua b/Strategies/STR0001/STR0001.lua index e69de29..bdb081c 100644 --- a/Strategies/STR0001/STR0001.lua +++ b/Strategies/STR0001/STR0001.lua @@ -0,0 +1,13 @@ +-- Strategia: STR0001 + +-- Tabella per definizione modulo +local STR0001 = {} + +------------------------------------------------------------------------------------------------------------- +function STR0001.Make( AddMachining, Proc, Parameters) + +end + +------------------------------------------------------------------------------------------------------------- + + return STR0001 \ No newline at end of file diff --git a/Strategies/STR0001/STR0001Config.lua b/Strategies/STR0001/STR0001Config.lua index dfc5782..5084f82 100644 --- a/Strategies/STR0001/STR0001Config.lua +++ b/Strategies/STR0001/STR0001Config.lua @@ -1,7 +1,7 @@ -- Parametri configurabili da cliente per strategia: STR0001 local STR0001Data = { - StrategyID = 'STR0001', + StrategyId = 'STR0001', Parameters = { { Value = '15', Name = 'Step', Description = 'Questo è lo step di lavorazione', Type = 'd'}, { Value = '2', Name = 'Depth', Description = 'Affondamento lavorazione', Type = 'd'}, diff --git a/Strategies/STR0002/STR0002.lua b/Strategies/STR0002/STR0002.lua index e69de29..ceb8cbc 100644 --- a/Strategies/STR0002/STR0002.lua +++ b/Strategies/STR0002/STR0002.lua @@ -0,0 +1,13 @@ +-- Strategia: STR0002 + +-- Tabella per definizione modulo +local STR0002 = {} + +------------------------------------------------------------------------------------------------------------- +function STR0002.Make( AddMachining, Proc, Parameters) + +end + +------------------------------------------------------------------------------------------------------------- + + return STR0002 \ No newline at end of file diff --git a/Strategies/STR0002/STR0002Config.lua b/Strategies/STR0002/STR0002Config.lua index e69de29..7aa2cf4 100644 --- a/Strategies/STR0002/STR0002Config.lua +++ b/Strategies/STR0002/STR0002Config.lua @@ -0,0 +1,11 @@ +-- Parametri configurabili da cliente per strategia: STR0002 + +local STR0002Data = { + StrategyId = 'STR0002', + Parameters = { + { Value = '10', Name = 'Step', Description = 'Questo è lo step di lavorazione', Type = 'd'}, + { Value = '5', Name = 'Depth', Description = 'Affondamento lavorazione', Type = 'd'}, + } +} + +return STR0002Data \ No newline at end of file