- Calcolo strategie spostato in funzione dedicata
- Migliorato ciclo di calcolo in GetBestResultFromCombinationsMatrix - Rimossi cicli per ricominciare il calcolo in caso di errore (non erano funzionanti e non compatibili con prossime modifiche rifacimento core)
This commit is contained in:
+317
-325
@@ -1339,98 +1339,93 @@ local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart, PartInfo)
|
||||
Logs.WriteMatrixLog( ProcessingsOnPart, PartInfo)
|
||||
end
|
||||
|
||||
-- per ogni posizione di scarico
|
||||
for nUnloadPos = 1, 4 do
|
||||
-- calcolo per tutte le combinazioni disponibili precedentemente verificate
|
||||
for i = 1, #PartInfo.CombinationList do
|
||||
-- controllo che la combinazione abbia ultima fase come quella calcolata in fase di definizione combinazioni
|
||||
if PartInfo.CombinationList[i].nUnloadPos == nUnloadPos then
|
||||
local bRot90, bRot180
|
||||
local SingleCombination = {}
|
||||
SingleCombination.nRotations = 0
|
||||
SingleCombination.dTotalRating = 0
|
||||
SingleCombination.nComplete = 0
|
||||
SingleCombination.nNotComplete = 0
|
||||
SingleCombination.nNotExecute = 0
|
||||
SingleCombination.sBitIndexCombination = PartInfo.CombinationList[i].sBitIndexCombination
|
||||
SingleCombination.nUnloadPos = nUnloadPos
|
||||
-- creo liste dei proc suddivisi per rotazione
|
||||
SingleCombination.Rot0 = {}
|
||||
SingleCombination.Rot90 = {}
|
||||
SingleCombination.Rot180 = {}
|
||||
-- calcolo per tutte le combinazioni disponibili precedentemente verificate
|
||||
for i = 1, #PartInfo.CombinationList do
|
||||
local bRot90, bRot180
|
||||
local SingleCombination = {}
|
||||
local nUnloadPos = PartInfo.CombinationList[i].nUnloadPos
|
||||
SingleCombination.nRotations = 0
|
||||
SingleCombination.dTotalRating = 0
|
||||
SingleCombination.nComplete = 0
|
||||
SingleCombination.nNotComplete = 0
|
||||
SingleCombination.nNotExecute = 0
|
||||
SingleCombination.sBitIndexCombination = PartInfo.CombinationList[i].sBitIndexCombination
|
||||
SingleCombination.nUnloadPos = nUnloadPos
|
||||
-- creo liste dei proc suddivisi per rotazione
|
||||
SingleCombination.Rot0 = {}
|
||||
SingleCombination.Rot90 = {}
|
||||
SingleCombination.Rot180 = {}
|
||||
|
||||
-- ciclo su tutte le feature, ad eccezione dei tagli testa/coda che dipendono dal risultato delle altre
|
||||
-- tagli testa e coda vengono aggiunti sempre alla fine
|
||||
for nProc = 1, #ProcessingsOnPart.Rotation[1] do
|
||||
if ProcessingsOnPart.Rotation[1][nProc].nPrc ~= 340 and ProcessingsOnPart.Rotation[1][nProc].nPrc ~= 350 then
|
||||
-- se feature disattivata perchè eseguita da master a lei associata dichiaro comunque eseguita
|
||||
if ProcessingsOnPart.Rotation[1][nProc].nFlg == 0 and ProcessingsOnPart.Rotation[1][nProc].nIndexMasterProc then
|
||||
ProcessingsOnPart.Rotation[1][nProc].nIndexRotation = nUnloadPos
|
||||
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[1][nProc])
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + 1
|
||||
-- ciclo su tutte le feature, ad eccezione dei tagli testa/coda che dipendono dal risultato delle altre
|
||||
-- tagli testa e coda vengono aggiunti sempre alla fine
|
||||
for nProc = 1, #ProcessingsOnPart.Rotation[1] do
|
||||
if ProcessingsOnPart.Rotation[1][nProc].nPrc ~= 340 and ProcessingsOnPart.Rotation[1][nProc].nPrc ~= 350 then
|
||||
-- se feature disattivata perchè eseguita da master a lei associata dichiaro comunque eseguita
|
||||
if ProcessingsOnPart.Rotation[1][nProc].nFlg == 0 and ProcessingsOnPart.Rotation[1][nProc].nIndexMasterProc then
|
||||
ProcessingsOnPart.Rotation[1][nProc].nIndexRotation = nUnloadPos
|
||||
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[1][nProc])
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + 1
|
||||
else
|
||||
-- ciclo sulle rotazioni
|
||||
local nNextRot = nUnloadPos
|
||||
local ResultsList = {}
|
||||
for nRotation = 1, 3 do
|
||||
-- se rotazione abilitata da combinazione
|
||||
if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
|
||||
-- se è ultima rotazione oppure se feature non impatta su misura laser, allora è valida e può essere effettivamente considerata
|
||||
if nNextRot == nUnloadPos or not( ProcessingsOnPart.Rotation[nNextRot][nProc].bHindersLaserMeasure) then
|
||||
-- controllo se è stata scelta una strategia
|
||||
if ProcessingsOnPart.Rotation[nNextRot][nProc].ChosenStrategy then
|
||||
local Proc = {}
|
||||
Proc.nRotation = nNextRot
|
||||
table.insert( Proc, ProcessingsOnPart.Rotation[nNextRot][nProc])
|
||||
table.insert( ResultsList, Proc)
|
||||
end
|
||||
end
|
||||
end
|
||||
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
|
||||
end
|
||||
|
||||
-- se la feature può essere lavorata in almeno una rotazione
|
||||
if #ResultsList > 0 then
|
||||
local Proc, Data = GetProcBestMachRotationFromList( ResultsList)
|
||||
Proc.nIndexRotation = Data.nIndexRotation
|
||||
-- inserisco la Proc nell'apposita lista
|
||||
if Data.nIndexRotation == nUnloadPos then
|
||||
table.insert( SingleCombination.Rot0, Proc)
|
||||
elseif Data.nIndexRotation == nUnloadPos + 1 then
|
||||
table.insert( SingleCombination.Rot90, Proc)
|
||||
bRot90 = true
|
||||
else
|
||||
-- ciclo sulle rotazioni
|
||||
local nNextRot = nUnloadPos
|
||||
local ResultsList = {}
|
||||
for nRotation = 1, 3 do
|
||||
-- se rotazione abilitata da combinazione
|
||||
if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
|
||||
-- se è ultima rotazione oppure se feature non impatta su misura laser, allora è valida e può essere effettivamente considerata
|
||||
if nNextRot == nUnloadPos or not( ProcessingsOnPart.Rotation[nNextRot][nProc].bHindersLaserMeasure) then
|
||||
-- controllo se è stata scelta una strategia
|
||||
if ProcessingsOnPart.Rotation[nNextRot][nProc].ChosenStrategy then
|
||||
local Proc = {}
|
||||
Proc.nRotation = nNextRot
|
||||
table.insert( Proc, ProcessingsOnPart.Rotation[nNextRot][nProc])
|
||||
table.insert( ResultsList, Proc)
|
||||
end
|
||||
end
|
||||
end
|
||||
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
|
||||
end
|
||||
|
||||
-- se la feature può essere lavorata in almeno una rotazione
|
||||
if #ResultsList > 0 then
|
||||
local Proc, Data = GetProcBestMachRotationFromList( ResultsList)
|
||||
Proc.nIndexRotation = Data.nIndexRotation
|
||||
-- inserisco la Proc nell'apposita lista
|
||||
if Data.nIndexRotation == nUnloadPos then
|
||||
table.insert( SingleCombination.Rot0, Proc)
|
||||
elseif Data.nIndexRotation == nUnloadPos + 1 then
|
||||
table.insert( SingleCombination.Rot90, Proc)
|
||||
bRot90 = true
|
||||
else
|
||||
table.insert( SingleCombination.Rot180, Proc)
|
||||
bRot180 = true
|
||||
end
|
||||
|
||||
SingleCombination.dTotalRating = SingleCombination.dTotalRating + Data.dCompositeRating
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
|
||||
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotApplicable, 1, 0)
|
||||
SingleCombination.nIndexInCombinationList = i
|
||||
SingleCombination.nIndexRotation = nUnloadPos
|
||||
else
|
||||
ProcessingsOnPart.Rotation[nUnloadPos][nProc].nIndexRotation = nUnloadPos
|
||||
ProcessingsOnPart.Rotation[nUnloadPos][nProc].nFlg = 0
|
||||
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos][nProc])
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
|
||||
end
|
||||
table.insert( SingleCombination.Rot180, Proc)
|
||||
bRot180 = true
|
||||
end
|
||||
|
||||
SingleCombination.dTotalRating = SingleCombination.dTotalRating + Data.dCompositeRating
|
||||
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
|
||||
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotApplicable, 1, 0)
|
||||
SingleCombination.nIndexInCombinationList = i
|
||||
SingleCombination.nIndexRotation = nUnloadPos
|
||||
else
|
||||
if ProcessingsOnPart.Rotation[1][nProc].nPrc == 340 then
|
||||
SingleCombination.nIndexHeadCutInVProc = nProc
|
||||
elseif ProcessingsOnPart.Rotation[1][nProc].nPrc == 350 then
|
||||
SingleCombination.nIndexTailCutInVProc = nProc
|
||||
end
|
||||
ProcessingsOnPart.Rotation[nUnloadPos][nProc].nIndexRotation = nUnloadPos
|
||||
ProcessingsOnPart.Rotation[nUnloadPos][nProc].nFlg = 0
|
||||
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos][nProc])
|
||||
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
|
||||
end
|
||||
end
|
||||
-- aggiungo rotazioni
|
||||
SingleCombination.nRotations = EgtIf( bRot90, 1, 0) + EgtIf( bRot180, 1, 0)
|
||||
-- aggiungo la combinazione all'elenco delle combinazioni disponibili
|
||||
table.insert( CombinationsList, SingleCombination)
|
||||
else
|
||||
if ProcessingsOnPart.Rotation[1][nProc].nPrc == 340 then
|
||||
SingleCombination.nIndexHeadCutInVProc = nProc
|
||||
elseif ProcessingsOnPart.Rotation[1][nProc].nPrc == 350 then
|
||||
SingleCombination.nIndexTailCutInVProc = nProc
|
||||
end
|
||||
end
|
||||
end
|
||||
-- aggiungo rotazioni
|
||||
SingleCombination.nRotations = EgtIf( bRot90, 1, 0) + EgtIf( bRot180, 1, 0)
|
||||
-- aggiungo la combinazione all'elenco delle combinazioni disponibili
|
||||
table.insert( CombinationsList, SingleCombination)
|
||||
end
|
||||
|
||||
-- ci deve essere almeno una combinazione, altrimenti errore
|
||||
@@ -1450,6 +1445,25 @@ local function GetBestResultFromCombinationsMatrix( ProcessingsOnPart, PartInfo)
|
||||
return vFinalProc, BestCombinationResult
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.GetCombinationMatrix( PARTS)
|
||||
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
|
||||
for nPart = 1, #PARTS do
|
||||
-- calcolo della migliore strategia per ogni rotazione del pezzo
|
||||
for dRotIndex = 1, 4 do
|
||||
-- calcola le strategie applicabili
|
||||
PROCESSINGS[nPart].Rotation[dRotIndex] = CalculateStrategies( PROCESSINGS[nPart].Rotation[dRotIndex], PARTS[nPart])
|
||||
-- tra le calcolate, sceglie la migliore
|
||||
PROCESSINGS[nPart].Rotation[dRotIndex] = GetBestStrategy( PROCESSINGS[nPart].Rotation[dRotIndex])
|
||||
-- rotazione pezzo di 90° per volta
|
||||
BeamLib.RotateRawPart( PARTS[nPart], 1)
|
||||
-- aggiorno info pezzo
|
||||
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
|
||||
PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
function BeamExec.ProcessMachinings( PARTS)
|
||||
-- ciclo sui pezzi
|
||||
@@ -1477,270 +1491,248 @@ function BeamExec.ProcessMachinings( PARTS)
|
||||
-- EgtOutBox( timeMachining, 'Machining calculation time')
|
||||
--end
|
||||
|
||||
local nCurrLoop = 0
|
||||
-- ciclo fino a che tutte le applicazioni delle lavorazioni sono corrette
|
||||
while not ProcessCompleted do
|
||||
-- aumento numero loop nel quale siamo
|
||||
nCurrLoop = nCurrLoop + 1
|
||||
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
|
||||
for nPart = 1, #PARTS do
|
||||
-- si mette subito il pezzo nella fase
|
||||
if nOrd == 1 then
|
||||
EgtSetCurrPhase( 1)
|
||||
|
||||
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
|
||||
for nPart = 1, #PARTS do
|
||||
-- si mette subito il pezzo nella fase
|
||||
if nOrd == 1 then
|
||||
EgtSetCurrPhase( 1)
|
||||
else
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
end
|
||||
-- si sposta il pezzo nella posizione originale, di quando è stata fatta la collect. In questo modo tutti i dati calcolati nella collect restano validi.
|
||||
-- Altrimenti bisognava ricalcolare tutto, aumentando tempo di calcolo.
|
||||
local vtRawOffsetPos = PARTS[nPart].b3Raw:getMin() - EgtGetRawPartBBox( PARTS[nPart].idRaw):getMin()
|
||||
local nRawId = PARTS[nPart].idRaw
|
||||
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
|
||||
EgtKeepRawPart( nRawId)
|
||||
EgtMoveRawPart( nRawId, vtRawOffsetPos)
|
||||
nRawId = EgtGetNextRawPart( nRawId)
|
||||
end
|
||||
|
||||
-- scrittura nel log del risultato della scelta della strategia migliore tra quelle disponibili
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
Logs.WriteFeaturesLog( PROCESSINGS[nPart], PARTS[nPart])
|
||||
end
|
||||
|
||||
local vProc, MatrixResult
|
||||
local bAllStrategiesApplied = false
|
||||
-- si calcola la combinazione di lavorazione migliore
|
||||
vProc, MatrixResult = GetBestResultFromCombinationsMatrix( PROCESSINGS[nPart], PARTS[nPart])
|
||||
|
||||
|
||||
|
||||
-- TODO NEXT TO MODIFY
|
||||
-- GetBestResultFromCombinationsMatrix ritorna lista combinazioni
|
||||
-- funzione per ricavare combinazioni. Se Process la migliore, se BatchProcess una lista selezionata
|
||||
-- funzione che prepara vproc e MatrixResult da migliore combinazione
|
||||
|
||||
-- Probabilmente la variabile "PartInfo.CombinationList" deve prevedere le pre-rotazioni e inversione in caso di QuickVerify.
|
||||
-- In caso di process e calcolo dopo nesting, calcolare solo con metodo essetre, dove quella è la posizione finale.
|
||||
|
||||
|
||||
-- debug
|
||||
if EgtGetDebugLevel() >= 1 then
|
||||
PrintFeatures( vProc, PARTS[nPart])
|
||||
end
|
||||
EgtOutLog( ' *** AddMachinings ***', 1)
|
||||
|
||||
-- se la posizione iniziale non è calcolata, significa che non ci sono feature da eseguire. Solo taglio testa/coda
|
||||
if not MatrixResult.nInitialPosition then
|
||||
MatrixResult.nInitialPosition = 1
|
||||
MACHININGS.Info.nHeadCutRotation = 1
|
||||
MACHININGS.Info.nSplitCutRotation = 1
|
||||
-- anche se non ci sono feature da eseguire, bisogna comunque scrivrere i risultati
|
||||
for nProc = 1, #vProc do
|
||||
AddFeatureResultToGlobalList( vProc[nProc])
|
||||
end
|
||||
-- altrimenti si fanno tutti i calcoli
|
||||
else
|
||||
-- ordinamento di base delle feature
|
||||
vProc = OrderFeatures( vProc)
|
||||
|
||||
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
|
||||
bAllStrategiesApplied = false
|
||||
MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProc, PARTS[nPart], MatrixResult.nInitialPosition)
|
||||
end
|
||||
-- salvo sul PART la posizione di partenza che è stata scelta
|
||||
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
|
||||
|
||||
-- aggiunge tagli testa e coda in fasi opportune
|
||||
local nRotHeadCut = MatrixResult.nInitialPosition + MACHININGS.Info.nHeadCutRotation - 1
|
||||
if nRotHeadCut > 4 then
|
||||
nRotHeadCut = nRotHeadCut - 4
|
||||
end
|
||||
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
|
||||
if nRotSplitCut > 4 then
|
||||
nRotSplitCut = nRotSplitCut - 4
|
||||
end
|
||||
|
||||
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
|
||||
|
||||
-- si imposta flag rotazione per taglio di testa
|
||||
if MACHININGS.Info.nHeadCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true
|
||||
elseif MACHININGS.Info.nHeadCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true
|
||||
end
|
||||
-- si imposta flag rotazione per taglio di coda
|
||||
if MACHININGS.Info.nSplitCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true
|
||||
elseif MACHININGS.Info.nSplitCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true
|
||||
end
|
||||
|
||||
local vProcHeadTail = {}
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc])
|
||||
|
||||
bAllStrategiesApplied = false
|
||||
MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
|
||||
|
||||
-- cancellazione entità create ma non usate
|
||||
-- TODO funzione?
|
||||
local idAddGroup = BeamLib.GetAddGroup( PARTS[nPart].id)
|
||||
local idCurrentEntity = EgtGetFirstInGroup( idAddGroup or GDB_ID.NULL)
|
||||
while idCurrentEntity do
|
||||
if EgtGetLevel( idCurrentEntity) == GDB_LV.TEMP then
|
||||
local idEntityToDelete = idCurrentEntity
|
||||
idCurrentEntity = EgtGetNext( idCurrentEntity)
|
||||
EgtErase( idEntityToDelete)
|
||||
else
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
end
|
||||
-- si sposta il pezzo nella posizione originale, di quando è stata fatta la collect. In questo modo tutti i dati calcolati nella collect restano validi.
|
||||
-- Altrimenti bisognava ricalcolare tutto, aumentando tempo di calcolo.
|
||||
local vtRawOffsetPos = PARTS[nPart].b3Raw:getMin() - EgtGetRawPartBBox( PARTS[nPart].idRaw):getMin()
|
||||
local nRawId = PARTS[nPart].idRaw
|
||||
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
|
||||
EgtKeepRawPart( nRawId)
|
||||
EgtMoveRawPart( nRawId, vtRawOffsetPos)
|
||||
nRawId = EgtGetNextRawPart( nRawId)
|
||||
idCurrentEntity = EgtGetNext( idCurrentEntity)
|
||||
end
|
||||
end
|
||||
|
||||
-- calcolo della migliore strategia per ogni rotazione del pezzo
|
||||
for dRotIndex = 1, 4 do
|
||||
-- calcola le strategie applicabili
|
||||
PROCESSINGS[nPart].Rotation[dRotIndex] = CalculateStrategies( PROCESSINGS[nPart].Rotation[dRotIndex], PARTS[nPart])
|
||||
-- tra le calcolate, sceglie la migliore
|
||||
PROCESSINGS[nPart].Rotation[dRotIndex] = GetBestStrategy( PROCESSINGS[nPart].Rotation[dRotIndex])
|
||||
-- rotazione pezzo di 90° per volta
|
||||
BeamLib.RotateRawPart( PARTS[nPart], 1)
|
||||
-- aggiorno info pezzo
|
||||
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
|
||||
PARTS[nPart].b3Part = EgtGetBBoxGlob( EgtGetFirstNameInGroup( PARTS[nPart].id, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
||||
end
|
||||
-- ordinamento lavorazioni
|
||||
-- TODO completare ordinamento. Mancano le dipendenze.
|
||||
-- TODO la FinalizeSorting andrebbe rimossa e usato un sorting che non viola le dipendenze
|
||||
MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart])
|
||||
MACHININGS = BeamLib.StableSort( MACHININGS, MachiningLib.CompareMachinings)
|
||||
MACHININGS = MachiningLib.FinalizeSorting()
|
||||
|
||||
-- scrittura nel log del risultato della scelta della strategia migliore tra quelle disponibili
|
||||
if EgtGetDebugLevel() >= 3 then
|
||||
Logs.WriteFeaturesLog( PROCESSINGS[nPart], PARTS[nPart])
|
||||
end
|
||||
-- finiti i calcoli di applicazione delle lavorazioni, si riporta il pezzo nello zero della fase
|
||||
nRawId = PARTS[nPart].idRaw
|
||||
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
|
||||
EgtKeepRawPart( nRawId)
|
||||
EgtMoveRawPart( nRawId, -vtRawOffsetPos)
|
||||
nRawId = EgtGetNextRawPart( nRawId)
|
||||
end
|
||||
|
||||
local bIsCombinationMachinable = false
|
||||
local vProc, MatrixResult
|
||||
while not bIsCombinationMachinable do
|
||||
bIsCombinationMachinable = true
|
||||
local bAllStrategiesApplied = false
|
||||
-- si calcola la combinazione di lavorazione migliore
|
||||
vProc, MatrixResult = GetBestResultFromCombinationsMatrix( PROCESSINGS[nPart], PARTS[nPart])
|
||||
local bAreAllMachiningApplyOk
|
||||
local sErr
|
||||
local bSplitAlreadyExecuted = false
|
||||
local bSplitExecutedOnRot = false
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'START')
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1)
|
||||
|
||||
-- debug
|
||||
if EgtGetDebugLevel() >= 1 then
|
||||
PrintFeatures( vProc, PARTS[nPart])
|
||||
end
|
||||
EgtOutLog( ' *** AddMachinings ***', 1)
|
||||
|
||||
-- se la posizione iniziale non è calcolata, significa che non ci sono feature da eseguire. Solo taglio testa/coda
|
||||
if not MatrixResult.nInitialPosition then
|
||||
MatrixResult.nInitialPosition = 1
|
||||
MACHININGS.Info.nHeadCutRotation = 1
|
||||
MACHININGS.Info.nSplitCutRotation = 1
|
||||
-- anche se non ci sono feature da eseguire, bisogna comunque scrivrere i risultati
|
||||
for nProc = 1, #vProc do
|
||||
AddFeatureResultToGlobalList( vProc[nProc])
|
||||
end
|
||||
-- altrimenti si fanno tutti i calcoli
|
||||
else
|
||||
-- ordinamento di base delle feature
|
||||
vProc = OrderFeatures( vProc)
|
||||
|
||||
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
|
||||
bAllStrategiesApplied = false
|
||||
MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProc, PARTS[nPart], MatrixResult.nInitialPosition)
|
||||
bIsCombinationMachinable = bAllStrategiesApplied
|
||||
end
|
||||
-- salvo sul PART la posizione di partenza che è stata scelta
|
||||
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
|
||||
|
||||
-- aggiunge tagli testa e coda in fasi opportune
|
||||
local nRotHeadCut = MatrixResult.nInitialPosition + MACHININGS.Info.nHeadCutRotation - 1
|
||||
if nRotHeadCut > 4 then
|
||||
nRotHeadCut = nRotHeadCut - 4
|
||||
end
|
||||
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
|
||||
if nRotSplitCut > 4 then
|
||||
nRotSplitCut = nRotSplitCut - 4
|
||||
end
|
||||
|
||||
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
|
||||
|
||||
-- si imposta flag rotazione per taglio di testa
|
||||
if MACHININGS.Info.nHeadCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true
|
||||
elseif MACHININGS.Info.nHeadCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true
|
||||
end
|
||||
-- si imposta flag rotazione per taglio di coda
|
||||
if MACHININGS.Info.nSplitCutRotation == 2 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true
|
||||
elseif MACHININGS.Info.nSplitCutRotation == 3 then
|
||||
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true
|
||||
end
|
||||
|
||||
local vProcHeadTail = {}
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc])
|
||||
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc])
|
||||
|
||||
bAllStrategiesApplied = false
|
||||
MACHININGS, bAllStrategiesApplied = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
|
||||
bIsCombinationMachinable = bIsCombinationMachinable and bAllStrategiesApplied
|
||||
end
|
||||
|
||||
-- cancellazione entità create ma non usate
|
||||
-- TODO funzione?
|
||||
local idAddGroup = BeamLib.GetAddGroup( PARTS[nPart].id)
|
||||
local idCurrentEntity = EgtGetFirstInGroup( idAddGroup or GDB_ID.NULL)
|
||||
while idCurrentEntity do
|
||||
if EgtGetLevel( idCurrentEntity) == GDB_LV.TEMP then
|
||||
local idEntityToDelete = idCurrentEntity
|
||||
idCurrentEntity = EgtGetNext( idCurrentEntity)
|
||||
EgtErase( idEntityToDelete)
|
||||
else
|
||||
idCurrentEntity = EgtGetNext( idCurrentEntity)
|
||||
end
|
||||
end
|
||||
|
||||
-- ordinamento lavorazioni
|
||||
-- TODO completare ordinamento. Mancano le dipendenze.
|
||||
-- TODO la FinalizeSorting andrebbe rimossa e usato un sorting che non viola le dipendenze
|
||||
MACHININGS = MachiningLib.PrepareMachiningsForSorting( PARTS[nPart])
|
||||
MACHININGS = BeamLib.StableSort( MACHININGS, MachiningLib.CompareMachinings)
|
||||
MACHININGS = MachiningLib.FinalizeSorting()
|
||||
|
||||
-- finiti i calcoli di applicazione delle lavorazioni, si riporta il pezzo nello zero della fase
|
||||
nRawId = PARTS[nPart].idRaw
|
||||
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
|
||||
EgtKeepRawPart( nRawId)
|
||||
EgtMoveRawPart( nRawId, -vtRawOffsetPos)
|
||||
nRawId = EgtGetNextRawPart( nRawId)
|
||||
end
|
||||
|
||||
local bAreAllMachiningApplyOk
|
||||
local sErr
|
||||
local bSplitAlreadyExecuted = false
|
||||
local bSplitExecutedOnRot = false
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'START')
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
EgtOutLog( ' *** Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( PARTS[nPart].idRaw) .. ' Part=' .. tostring( PARTS[nPart].id) .. ' ***', 1)
|
||||
|
||||
-- creazione effettiva delle lavorazioni
|
||||
MACHININGS.Info = {}
|
||||
local nCurrPosition = 1
|
||||
local nInitialPosition = MatrixResult.nInitialPosition
|
||||
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
|
||||
if MatrixResult.bSomeFeatureDown then
|
||||
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -2)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
end
|
||||
|
||||
-- se c'è almeno una lavorazione in posizionamento con trave ruotata
|
||||
if MatrixResult.bSomeFeatureSide then
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if MatrixResult.bSomeFeatureDown then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
nPhase = EgtGetCurrPhase()
|
||||
idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
-- se c'è già stata separazione
|
||||
if bSplitAlreadyExecuted then
|
||||
EgtSetInfo( idDisp, 'TYPE', 'MID2')
|
||||
else
|
||||
EgtSetInfo( idDisp, 'TYPE', 'MID')
|
||||
end
|
||||
end
|
||||
local nRotation = EgtIf( nInitialPosition + 1 > 4, nInitialPosition + 1 - 4, nInitialPosition + 1)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -1)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
end
|
||||
-- creazione effettiva delle lavorazioni
|
||||
MACHININGS.Info = {}
|
||||
local nCurrPosition = 1
|
||||
local nInitialPosition = MatrixResult.nInitialPosition
|
||||
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
|
||||
if MatrixResult.bSomeFeatureDown then
|
||||
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -2)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
end
|
||||
|
||||
-- se c'è almeno una lavorazione in posizionamento con trave ruotata
|
||||
if MatrixResult.bSomeFeatureSide then
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
|
||||
if MatrixResult.bSomeFeatureDown then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
nPhase = EgtGetCurrPhase()
|
||||
idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
-- se c'è già stata separazione
|
||||
if bSplitAlreadyExecuted then
|
||||
EgtSetInfo( idDisp, 'TYPE', 'END2')
|
||||
EgtSetInfo( idDisp, 'TYPE', 'MID2')
|
||||
else
|
||||
EgtSetInfo( idDisp, 'TYPE', 'MID')
|
||||
end
|
||||
end
|
||||
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
|
||||
|
||||
-- aggiunta lavorazioni in ultima fase
|
||||
MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
|
||||
|
||||
EgtOutLog( ' *** End AddMachinings ***', 1)
|
||||
-- azzero lavorazioni per pezzo successivo
|
||||
MACHININGS = {}
|
||||
MACHININGS.Info = {}
|
||||
-- indice pezzo successivo
|
||||
nOrd = nOrd + 1
|
||||
local nRotation = EgtIf( nInitialPosition + 1 > 4, nInitialPosition + 1 - 4, nInitialPosition + 1)
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
|
||||
nCurrPosition = nRotation
|
||||
EgtSetInfo( idDisp, 'ROT', -1)
|
||||
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
|
||||
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
|
||||
end
|
||||
|
||||
-- ===== finiti i pezzi, si scarica il restante =====
|
||||
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
|
||||
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
|
||||
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'REST')
|
||||
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
|
||||
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
|
||||
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
|
||||
nPhase = EgtGetCurrPhase()
|
||||
idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
end
|
||||
|
||||
-- Aggiornamento finale di tutto
|
||||
EgtSetCurrPhase( 1)
|
||||
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
|
||||
-- TODO a cosa serve questo ricalcolo? Con nuovo sistema si può eliminare?
|
||||
-- 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
|
||||
-- TODO qui restituire errori in modo migliore, come per feature
|
||||
-- TODO in caso di lavorazioni di coda saltate, l'informazione va restituita anche sulle singole feature
|
||||
if not bApplOk then
|
||||
nTotErr = nTotErr + 1
|
||||
AddApplyResultToGlobalList( 1, 0, sApplErrors)
|
||||
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
|
||||
AddApplyResultToGlobalList( -nWarn, nCutId, vLine[i])
|
||||
end
|
||||
end
|
||||
-- se c'è già stata separazione
|
||||
if bSplitAlreadyExecuted then
|
||||
EgtSetInfo( idDisp, 'TYPE', 'END2')
|
||||
else
|
||||
EgtSetInfo( idDisp, 'TYPE', 'MID')
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO per il momento non si cicla mai una seconda volta. Controllare anche parametro modalità scelta strategia
|
||||
-- Gestione da fare completamente. La strategia che ha generato una lavorazione con errore deve essere annullata
|
||||
-- si può salvare una lista delle strategie da non utilizzare e, nella CalculateStrategy, settare quella specifica strategia come non valida
|
||||
-- si fa un reset del MACH e poi si ritorna a inizio ciclo e si rifà tutto
|
||||
-- se i cicli superano il massimo si esce (nell'ultimo ciclo possibile si potrebbe escludere la feature e basta, anche se avesse altre strategie da provare)
|
||||
if true or nCurrLoop > nMaxLoops then
|
||||
ProcessCompleted = true
|
||||
|
||||
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
|
||||
|
||||
-- aggiunta lavorazioni in ultima fase
|
||||
MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
|
||||
|
||||
EgtOutLog( ' *** End AddMachinings ***', 1)
|
||||
-- azzero lavorazioni per pezzo successivo
|
||||
MACHININGS = {}
|
||||
MACHININGS.Info = {}
|
||||
-- indice pezzo successivo
|
||||
nOrd = nOrd + 1
|
||||
end
|
||||
|
||||
-- ===== finiti i pezzi, si scarica il restante =====
|
||||
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
|
||||
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
|
||||
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
|
||||
local nPhase = EgtGetCurrPhase()
|
||||
local idDisp = EgtGetPhaseDisposition( nPhase)
|
||||
EgtSetInfo( idDisp, 'TYPE', 'REST')
|
||||
EgtSetInfo( idDisp, 'ORD', nOrd)
|
||||
end
|
||||
|
||||
-- Aggiornamento finale di tutto
|
||||
EgtSetCurrPhase( 1)
|
||||
local bApplOk, sApplErrors, sApplWarns = EgtApplyAllMachinings()
|
||||
-- TODO a cosa serve questo ricalcolo? Con nuovo sistema si può eliminare?
|
||||
-- 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
|
||||
-- TODO qui restituire errori in modo migliore, come per feature
|
||||
-- TODO in caso di lavorazioni di coda saltate, l'informazione va restituita anche sulle singole feature
|
||||
if not bApplOk then
|
||||
nTotErr = nTotErr + 1
|
||||
AddApplyResultToGlobalList( 1, 0, sApplErrors)
|
||||
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
|
||||
AddApplyResultToGlobalList( -nWarn, nCutId, vLine[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user