- in BeamExec.ProcessBeams correzioni. Sembra funzionare correttamente in tutti i casi

This commit is contained in:
luca.mazzoleni
2026-05-21 18:53:02 +02:00
parent 5c7751aebd
commit eacabb5af7
+145 -157
View File
@@ -377,191 +377,179 @@ function BeamExec.GetAvailableCombinations( PartInfo, bIsFlipRot)
end
-------------------------------------------------------------------------------------------------------------
-- *** funzioni posizionamento pezzi all'interno della barra ***
-- *** Funzioni posizionamento pezzi all'interno della barra***
-------------------------------------------------------------------------------------------------------------
function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bIsFlipRot)
-- gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup()
function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bIsFlipRot )
-- 1. Inizializzazione e Default
local idTempGroup = BeamLib.GetTempGroup( )
-- default per nuove costanti qualora non definite
BeamData.OVM_BLADE_HBEAM = ( BeamData.OVM_BLADE_HBEAM or 11)
BeamData.OVM_CHAIN_HBEAM = ( BeamData.OVM_CHAIN_HBEAM or 8)
BeamData.OVM_BLADE_HBEAM = ( BeamData.OVM_BLADE_HBEAM or 11 )
BeamData.OVM_CHAIN_HBEAM = ( BeamData.OVM_CHAIN_HBEAM or 8 )
-- sovramateriale intermedio nullo se non definito
dOvmMid = ( dOvmMid or 0)
dOvmMid = ( dOvmMid or 5.4 )
dOvmHead = ( dOvmHead or 0 )
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH )
-- Determinazione minimo grezzo scaricabile
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
-- Creazione nuovo gruppo di lavoro (di default va creato)
if bCreateMachGroup == nil then
bCreateMachGroup = true
end
if bCreateMachGroup then
local sMgName = EgtGetMachGroupNewName( 'Mach_1')
local idNewMg = EgtAddMachGroup( sMgName)
if not idNewMg then
local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName
return false, sOut
-- 2. Gestione Gruppo di Lavoro
if ( bCreateMachGroup == nil ) then bCreateMachGroup = true end
if ( bCreateMachGroup ) then
local sMgName = EgtGetMachGroupNewName( 'Mach_1' )
local idNewMg = EgtAddMachGroup( sMgName )
if ( not idNewMg ) then
return false, 'Errore creazione gruppo di lavoro'
end
end
-- Impostazione della tavola
EgtSetTable( 'Tab')
-- salvo nota con lunghezza grezzo
-- Recupero l'identificativo del gruppo di lavoro corrente
local nMGrpId = EgtGetCurrMachGroup()
-- Lunghezza della barra
local dBarLen = EgtGetInfo( nMGrpId, 'BARLEN', 'd')
if not dBarLen then
EgtSetInfo( nMGrpId, 'BARLEN', dRawL)
-- 3. Configurazione Tavola Macchina
EgtSetTable( 'Tab' )
local nMGrpId = EgtGetCurrMachGroup( )
if ( not EgtGetInfo( nMGrpId, 'BARLEN', 'd' ) ) then
EgtSetInfo( nMGrpId, 'BARLEN', dRawL )
end
-- Area tavola
local b3Tab = EgtGetTableArea()
-- Calcolo posizione estremo TR/BR della tavola rispetto a sua origine in BL
local dPosY = EgtIf( BeamData.CENTER_BEAM, ( b3Tab:getDimY() + dRawW * EgtIf( BeamData.RIGHT_LOAD, -1, 1)) / 2, EgtIf( BeamData.RIGHT_LOAD, 0, b3Tab:getDimY()))
BeamData.ptOriXR = Point3d( b3Tab:getDimX(), dPosY, 0)
BeamData.dPosXR = EgtIf( BeamData.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR)
local b3Tab = EgtGetTableArea( )
local dPosY = EgtIf( BeamData.CENTER_BEAM, ( b3Tab:getDimY( ) + dRawW * EgtIf( BeamData.RIGHT_LOAD, -1, 1 ) ) / 2, EgtIf( BeamData.RIGHT_LOAD, 0, b3Tab:getDimY( ) ) )
BeamData.ptOriXR = Point3d( b3Tab:getDimX( ), dPosY, 0 )
BeamData.dPosXR = EgtIf( BeamData.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR )
-- Impostazione dell'attrezzaggio di default
EgtImportSetup()
EgtImportSetup( )
-- Inserimento dei pezzi con il loro grezzo
-- 4. Ciclo di Inserimento Pezzi
local nCnt = 0
local dResidualLength = dRawL
local idPrevRaw, dPrevDelta
local dStartOffset = dOvmHead
local dEndOffset = 0 -- TODO cosa fare di BD.OVM_MID? usarlo solo se non è nesting obliquo?
local dMaxX = 0
local idPrevRaw = nil
local dNextStartOffset = dOvmHead -- Il primo pezzo applica il sormonto iniziale a destra (testa)
for i = 1, #PARTS do
-- dati del pezzo
local b3BoxExact = EgtGetBBoxGlob( PARTS[i].id or GDB_ID.NULL, GDB_BB.EXACT)
if b3BoxExact:isEmpty() or PARTS[i].b3PartOriginal:isEmpty() then break end
EgtOutLog( 'PartSez=' .. EgtNumToString( b3BoxExact:getDimY(), 1) .. 'x' .. EgtNumToString( b3BoxExact:getDimZ(), 1), 3)
-- se sezione compatibile e lunghezza disponibile sufficiente
local dPartLength = PARTS[i].b3PartOriginal:getDimX()
local dPartWidth = PARTS[i].b3PartOriginal:getDimY()
local dPartHeight = PARTS[i].b3PartOriginal:getDimZ()
local dNextResidualLength = dResidualLength - EgtIf( i == 1, dStartOffset, 0) - dPartLength - dEndOffset
local bIsSectionOk = (( abs( dPartWidth - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH) < 100 * GEO.EPS_SMALL) or
( abs( dPartHeight - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH) < 100 * GEO.EPS_SMALL))
if bIsSectionOk and ( dNextResidualLength + dEndOffset >= 0) then
-- eventuale sovramateriale di testa
if i > 1 then
if PARTS[i].dPosX then
dStartOffset = PARTS[i].dPosX - ( dRawL - dResidualLength)
if dStartOffset < -GEO.EPS_SMALL then
dResidualLength = dResidualLength - dStartOffset
dStartOffset = 0
end
else
dStartOffset = max( dOvmMid - dEndOffset, 0)
end
end
-- dimensioni del grezzo
local dCurrentRawLength = min( dPartLength + dStartOffset + dEndOffset, dResidualLength)
local dDelta = dCurrentRawLength - dPartLength - dStartOffset
-- creo e posiziono il grezzo
PARTS[i].idRaw = EgtAddRawPart( Point3d(0,0,0), dCurrentRawLength, dRawW, dRawH, BeamData.RAWCOL)
local CurrentPart = PARTS[i]
local b3BoxExact = EgtGetBBoxGlob( CurrentPart.id or GDB_ID.NULL, GDB_BB.EXACT )
if ( b3BoxExact:isEmpty( ) or CurrentPart.b3PartOriginal:isEmpty( ) ) then break end
EgtMoveToCornerRawPart( PARTS[i].idRaw, BeamData.ptOriXR, BeamData.dPosXR)
EgtMoveRawPart( PARTS[i].idRaw, Vector3d( dResidualLength - dRawL, 0, 0))
-- assegno ordine in lavorazione
local dPartLen = CurrentPart.b3PartOriginal:getDimX( )
local dPartWidth = CurrentPart.b3PartOriginal:getDimY( )
local dPartHeight = CurrentPart.b3PartOriginal:getDimZ( )
local dStartOffset = dNextStartOffset
local dEndOffset = dOvmMid
-- LOGICA LOOK-AHEAD: Analisi del gap reale per la ripartizione specchiata
if ( i < #PARTS ) then
local dTotalGap = PARTS[i + 1].dPosX - CurrentPart.dPosX - dPartLen
if ( dTotalGap > dOvmMid ) then
dEndOffset = dOvmMid -- Max 5.4mm sulla coda (lato sinistro del grezzo)
dNextStartOffset = dTotalGap - dOvmMid -- Il residuo sulla testa del prossimo (lato destro)
else
-- Gestione automatica sotto-soglia o compenetrazione geometrica (Nesting Obliquo)
dEndOffset = dTotalGap
dNextStartOffset = 0
end
end
-- MATEMATICA CORRETTA PER X CAD INVERTITA:
-- Il grezzo idRaw si estende verso destra. Spostando il pezzo internamente di dEndOffset (dDelta),
-- lasciamo dEndOffset a sinistra (coda) e matematicamente dStartOffset a destra (testa).
local dCrawLen = dPartLen + dStartOffset + dEndOffset
local dDelta = dEndOffset
local dStartPos = CurrentPart.dPosX - dStartOffset
local bIsSectionOk = ( ( abs( dPartWidth - dRawW ) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH ) < 100 * GEO.EPS_SMALL ) or
( abs( dPartHeight - dRawW ) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH ) < 100 * GEO.EPS_SMALL ) )
if ( bIsSectionOk and ( dStartPos + dCrawLen <= dRawL + GEO.EPS_SMALL ) ) then
-- 5. Creazione e Posizionamento del Contenitore RawPart
CurrentPart.idRaw = EgtAddRawPart( Point3d( 0, 0, 0 ), dCrawLen, dRawW, dRawH, BeamData.RAWCOL )
EgtMoveToCornerRawPart( CurrentPart.idRaw, BeamData.ptOriXR, BeamData.dPosXR )
EgtMoveRawPart( CurrentPart.idRaw, Vector3d( -dStartPos, 0, 0 ) )
-- 6. Configurazione Geometrie Pezzo
nCnt = nCnt + 1
EgtSetInfo( PARTS[i].idRaw, 'ORD', nCnt)
-- creo o pulisco gruppo geometrie aggiuntive
if not BeamLib.CreateOrEmptyAddGroup( PARTS[i].id) then
local sOut = 'Error creating Additional Group in Part ' .. tostring( PARTS[i].id)
return false, sOut
EgtSetInfo( CurrentPart.idRaw, 'ORD', nCnt )
if ( not BeamLib.CreateOrEmptyAddGroup( CurrentPart.id ) ) then
return false, 'Error creating Additional Group in Part ' .. tostring( CurrentPart.id )
end
-- aggiungo faccia per taglio iniziale al pezzo
BeamLib.AddPartStartFace( PARTS[i].id, PARTS[i].b3PartOriginal)
-- se sovramateriale di testa, lo notifico
if dStartOffset > 0.09 then
EgtSetInfo( PARTS[i].idRaw, 'HOVM', dStartOffset)
if idPrevRaw then
EgtSetInfo( idPrevRaw, 'BDST', dStartOffset + dPrevDelta)
end
end
if dEndOffset > 0.09 then
EgtSetInfo( PARTS[i].idRaw, 'TOVM', dEndOffset)
end
-- aggiungo faccia per taglio finale al pezzo
BeamLib.AddPartEndFace( PARTS[i].id, PARTS[i].b3PartOriginal)
-- inserisco il pezzo nel grezzo
EgtDeselectPartObjs( PARTS[i].id)
local ptPos = b3BoxExact:getMin() - PARTS[i].b3PartOriginal:getMin() + Vector3d( dDelta, ( dRawW - dPartWidth) / 2, ( dRawH - dPartHeight) / 2)
EgtAddPartToRawPart( PARTS[i].id, ptPos, PARTS[i].idRaw)
if abs( dPartWidth - dRawW) > 100 * GEO.EPS_SMALL then
-- rotazione attorno a centro geometria complessiva del pezzo
EgtRotatePartInRawPart( PARTS[i].id, X_AX(), 90)
-- correggo per eccentricità solido rispetto a geometria complessiva del pezzo
local vtEccOri = PARTS[i].b3PartOriginal:getCenter() - b3BoxExact:getCenter()
local vtEccRot = Vector3d( vtEccOri)
vtEccRot:rotate( X_AX(), 90)
EgtMovePartInRawPart( PARTS[i].id, ( vtEccOri - vtEccRot))
end
-- aggiorno la lunghezza residua della barra
dResidualLength = dResidualLength - dCurrentRawLength
-- aggiorno grezzo precedente
idPrevRaw = PARTS[i].idRaw
dPrevDelta = dDelta
PARTS[i].bIsLastPart = ( i == #PARTS)
PARTS[i].dDistanceToNextPiece = dDelta
PARTS[i].dRestLength = dResidualLength
PARTS[i].b3Raw = EgtGetRawPartBBox( PARTS[i].idRaw)
PARTS[i].dLength = PARTS[i].b3Raw:getDimX()
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
PARTS[i].dHeight = PARTS[i].b3Raw:getDimZ()
PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL
PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL)
PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD)
PARTS[i].nIndexInParts = i
PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i])
PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}}
PARTS[i].dHeadOverMaterial = dStartOffset
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil
BeamLib.AddPartStartFace( CurrentPart.id, CurrentPart.b3PartOriginal )
BeamLib.AddPartEndFace( CurrentPart.id, CurrentPart.b3PartOriginal )
PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or
( GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo] and GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo].sAISetupConfig) or -- i parametri BTL potrebbero non esistere
GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil
-- Inserimento con dDelta (lascia lo spazio vuoto a sinistra e spinge il pezzo a destra)
EgtDeselectPartObjs( CurrentPart.id )
local ptPos = b3BoxExact:getMin( ) - CurrentPart.b3PartOriginal:getMin( ) + Vector3d( dDelta, ( dRawW - dPartWidth ) / 2, ( dRawH - dPartHeight ) / 2 )
EgtAddPartToRawPart( CurrentPart.id, ptPos, CurrentPart.idRaw )
-- si carica configurazione lavorazioni
TIMER:startElapsed('Json')
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
TIMER:stopElapsed('Json')
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bIsFlipRot)
PARTS[i].idTempGroup = idTempGroup
-- Rotazione sezione se necessaria
if ( abs( dPartWidth - dRawW ) > 100 * GEO.EPS_SMALL ) then
EgtRotatePartInRawPart( CurrentPart.id, X_AX( ), 90 )
local vtEccOri = CurrentPart.b3PartOriginal:getCenter( ) - b3BoxExact:getCenter( )
local vtEccRot = Vector3d( vtEccOri )
vtEccRot:rotate( X_AX( ), 90 )
EgtMovePartInRawPart( CurrentPart.id, ( vtEccOri - vtEccRot ) )
end
-- 7. Popolamento Metadati della Tabella CurrentPart
CurrentPart.bIsLastPart = ( i == #PARTS )
CurrentPart.dDistanceToNextPiece = dEndOffset
CurrentPart.b3Raw = EgtGetRawPartBBox( CurrentPart.idRaw )
CurrentPart.dLength = CurrentPart.b3Raw:getDimX( )
CurrentPart.dWidth = CurrentPart.b3Raw:getDimY( )
CurrentPart.dHeight = CurrentPart.b3Raw:getDimZ( )
CurrentPart.bSquareSection = abs( CurrentPart.dWidth - CurrentPart.dHeight ) < 100 * GEO.EPS_SMALL
CurrentPart.idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( CurrentPart.id, 'Box' ) or GDB_ID.NULL )
CurrentPart.b3Part = EgtGetBBoxGlob( CurrentPart.idBoxTm, GDB_BB.STANDARD )
CurrentPart.nIndexInParts = i
CurrentPart.SplittingPoints = BeamLib.GetPartSplittingPoints( CurrentPart )
CurrentPart.NotClampableLength = { STD = { dHead = 0, dTail = 0 }, SIDE = { dHead = 0, dTail = 0 }, DOWN = { dHead = 0, dTail = 0 } }
CurrentPart.dHeadOverMaterial = dStartOffset
CurrentPart.sBTLInfo = EgtGetInfo( CurrentPart.id, 'PROJ', 's' ) or nil
CurrentPart.idTempGroup = idTempGroup
-- Notifiche al Post-Processor basate sulla nuova scomposizione
if ( dStartOffset > 0.09 ) then EgtSetInfo( CurrentPart.idRaw, 'HOVM', dStartOffset ) end
if ( dEndOffset > 0.09 ) then EgtSetInfo( CurrentPart.idRaw, 'TOVM', dEndOffset ) end
if ( idPrevRaw ) then EgtSetInfo( idPrevRaw, 'BDST', dStartOffset ) end
-- Caricamento Strategie JSON
CurrentPart.sAISetupConfig = EgtGetInfo( CurrentPart.id, 'AISETUP', 's' ) or
( GENERAL_PARAMETERS.BTL[CurrentPart.sBTLInfo] and GENERAL_PARAMETERS.BTL[CurrentPart.sBTLInfo].sAISetupConfig ) or
GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil
TIMER:startElapsed( 'Json' )
BeamExec.GetStrategiesFromJSONinBD( CurrentPart.sAISetupConfig )
CurrentPart.GeneralParameters = BeamLib.GetPieceGeneralParameters( CurrentPart, GENERAL_PARAMETERS_JSON )
TIMER:stopElapsed( 'Json' )
CurrentPart.CombinationList = BeamExec.GetAvailableCombinations( CurrentPart, bIsFlipRot )
-- Avanzamento calcolato sulla coordinata reale di fine RawPart (estremità sinistra sulla barra)
dMaxX = max( dMaxX, dStartPos + dCrawLen )
CurrentPart.dRestLength = dRawL - dMaxX
idPrevRaw = CurrentPart.idRaw
else
local sOut = 'Error: part L(' .. EgtNumToString( dPartLength, 1) .. ') too big for raw part L(' .. EgtNumToString( dResidualLength - 0.1, 1) .. ')'
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1 ) .. ') too big for remaining bar space'
return false, sOut
end
-- se rimasto troppo poco grezzo, esco
--if Len < BeamData.MinRaw then break end
DeltaS = 0
end
if idPrevRaw then
EgtSetInfo( idPrevRaw, 'BDST', 10000)
end
-- Se rimasto materiale aggiungo grezzo dell'avanzo
-- TODO valutare se ridurre la dLen minima perchè crea discrepanze tra lunghezza inserita e VMill
if dResidualLength > 10 then
local idRaw = EgtAddRawPart( Point3d(0,0,0), dResidualLength, dRawW, dRawH, BeamData.RAWCOL)
EgtMoveToCornerRawPart( idRaw, BeamData.ptOriXR, BeamData.dPosXR)
EgtMoveRawPart( idRaw, Vector3d( dResidualLength - dRawL, 0, 0))
-- assegno ordine in lavorazione
-- 8. Chiusura Barra e Gestione Avanzo (Rest Material)
if ( idPrevRaw ) then EgtSetInfo( idPrevRaw, 'BDST', 10000 ) end
local dRemaining = dRawL - dMaxX
if ( dRemaining > 10 ) then
local idRawRest = EgtAddRawPart( Point3d( 0, 0, 0 ), dRemaining, dRawW, dRawH, BeamData.RAWCOL )
EgtMoveToCornerRawPart( idRawRest, BeamData.ptOriXR, BeamData.dPosXR )
EgtMoveRawPart( idRawRest, Vector3d( -dMaxX, 0, 0 ) )
nCnt = nCnt + 1
EgtSetInfo( idRaw, 'ORD', nCnt)
-- aggiorno distanza dell'ultimo pezzo dall'eventuale grezzo scaricabile
if EgtGetRawPartBBox( idRaw):getDimX() < BeamData.dMinRaw then
EgtSetInfo( idRawRest, 'ORD', nCnt )
if ( EgtGetRawPartBBox( idRawRest ):getDimX( ) < BeamData.dMinRaw ) then
PARTS[#PARTS].dDistanceToNextPiece = 10000
end
else
PARTS[#PARTS].dDistanceToNextPiece = 10000
if ( #PARTS > 0 ) then PARTS[#PARTS].dDistanceToNextPiece = 10000 end
end
return true