- 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
This commit is contained in:
+221
-35
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user