Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 08397ae102 | |||
| b7dbc7422c | |||
| 974d1abb41 | |||
| b79617fbe4 | |||
| e5f1abc47d | |||
| 965c6e8f9e | |||
| d59039eae0 | |||
| a404bf2f9e | |||
| 1cde1c94d9 | |||
| a66054a6c8 | |||
| b77e79d0d0 | |||
| cad57b2fd5 | |||
| 5e503762e5 | |||
| f27000b7bc | |||
| f90dd95880 | |||
| 0497877abb | |||
| b8299df247 | |||
| 4a99f2bdf6 | |||
| 1e86180723 | |||
| f6d6043c0e | |||
| b048e2ebe2 | |||
| fc47bca0f1 | |||
| 0274096f57 | |||
| 983609397e | |||
| 05a8d23f6a | |||
| 40580cdc69 | |||
| f6b2477f2b | |||
| 69db74e30e |
+209
-42
@@ -251,6 +251,27 @@ function BeamExec.GetStrategiesFromJSONinBD( sAISetupConfigName)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
local function GetRotationName( nRotIndex, nInvertIndex)
|
||||||
|
local sRotation = ''
|
||||||
|
|
||||||
|
if nRotIndex == 1 then
|
||||||
|
sRotation = '0'
|
||||||
|
elseif nRotIndex == 2 then
|
||||||
|
sRotation = '90'
|
||||||
|
elseif nRotIndex == 3 then
|
||||||
|
sRotation = '180'
|
||||||
|
elseif nRotIndex == 4 then
|
||||||
|
sRotation = '270'
|
||||||
|
end
|
||||||
|
|
||||||
|
if nInvertIndex > 1 then
|
||||||
|
sRotation = sRotation .. 'INV'
|
||||||
|
end
|
||||||
|
|
||||||
|
return sRotation
|
||||||
|
end
|
||||||
|
|
||||||
-- TODO prevedere parametri per preferire carico del pezzo verticale oppure orizzontale?
|
-- TODO prevedere parametri per preferire carico del pezzo verticale oppure orizzontale?
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
-- funzione che controlla validità delle combinazioni proposte
|
-- funzione che controlla validità delle combinazioni proposte
|
||||||
@@ -409,40 +430,43 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
|
|||||||
|
|
||||||
-- Inserimento dei pezzi con il loro grezzo
|
-- Inserimento dei pezzi con il loro grezzo
|
||||||
local nCnt = 0
|
local nCnt = 0
|
||||||
local dLen = dRawL
|
local dResidualLength = dRawL
|
||||||
local idPrevRaw, dPrevDelta
|
local idPrevRaw, dPrevDelta
|
||||||
local dDeltaS = dOvmHead
|
local dStartOffset = dOvmHead
|
||||||
local dDeltaSMin = 0
|
local dEndOffset = 0 -- TODO cosa fare di BD.OVM_MID? usarlo solo se non è nesting obliquo?
|
||||||
local dDeltaE = BeamData.OVM_MID
|
|
||||||
for i = 1, #PARTS do
|
for i = 1, #PARTS do
|
||||||
-- dati del pezzo
|
-- dati del pezzo
|
||||||
local b3BoxExact = EgtGetBBoxGlob( PARTS[i].id or GDB_ID.NULL, GDB_BB.EXACT)
|
local b3BoxExact = EgtGetBBoxGlob( PARTS[i].id or GDB_ID.NULL, GDB_BB.EXACT)
|
||||||
if b3BoxExact:isEmpty() or PARTS[i].b3PartOriginal:isEmpty() then break end
|
if b3BoxExact:isEmpty() or PARTS[i].b3PartOriginal:isEmpty() then break end
|
||||||
EgtOutLog( 'PartSez=' .. EgtNumToString( b3BoxExact:getDimY(), 1) .. 'x' .. EgtNumToString( b3BoxExact:getDimZ(), 1), 3)
|
EgtOutLog( 'PartSez=' .. EgtNumToString( b3BoxExact:getDimY(), 1) .. 'x' .. EgtNumToString( b3BoxExact:getDimZ(), 1), 3)
|
||||||
-- se sezione compatibile e lunghezza disponibile sufficiente
|
-- se sezione compatibile e lunghezza disponibile sufficiente
|
||||||
local dPartLen = PARTS[i].b3PartOriginal:getDimX()
|
local dPartLength = PARTS[i].b3PartOriginal:getDimX()
|
||||||
local dPartWidth = PARTS[i].b3PartOriginal:getDimY()
|
local dPartWidth = PARTS[i].b3PartOriginal:getDimY()
|
||||||
local dPartHeight = PARTS[i].b3PartOriginal:getDimZ()
|
local dPartHeight = PARTS[i].b3PartOriginal:getDimZ()
|
||||||
local dNextLen = dLen - EgtIf( i == 1, dDeltaS, 0) - dPartLen - dDeltaE
|
local dNextResidualLength = dResidualLength - EgtIf( i == 1, dStartOffset, 0) - dPartLength - dEndOffset
|
||||||
if (( abs( dPartWidth - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH) < 100 * GEO.EPS_SMALL) or
|
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)) and
|
( abs( dPartHeight - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH) < 100 * GEO.EPS_SMALL))
|
||||||
dNextLen + dDeltaE >= 0 then
|
if bIsSectionOk and ( dNextResidualLength + dEndOffset >= 0) then
|
||||||
-- eventuale sovramateriale di testa
|
-- eventuale sovramateriale di testa
|
||||||
if i > 1 then
|
if i > 1 then
|
||||||
if PARTS[i].dPosX then
|
if PARTS[i].dPosX then
|
||||||
dDeltaS = max( PARTS[i].dPosX - ( dRawL - dLen), dDeltaSMin)
|
dStartOffset = PARTS[i].dPosX - ( dRawL - dResidualLength)
|
||||||
|
if dStartOffset < -GEO.EPS_SMALL then
|
||||||
|
dResidualLength = dResidualLength - dStartOffset
|
||||||
|
dStartOffset = 0
|
||||||
|
end
|
||||||
else
|
else
|
||||||
dDeltaS = max( dOvmMid - dDeltaE, 0)
|
dStartOffset = max( dOvmMid - dEndOffset, 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- dimensioni del grezzo
|
-- dimensioni del grezzo
|
||||||
local dCrawLen = min( dPartLen + dDeltaS + dDeltaE, dLen)
|
local dCurrentRawLength = min( dPartLength + dStartOffset + dEndOffset, dResidualLength)
|
||||||
local dDelta = dCrawLen - dPartLen - dDeltaS
|
local dDelta = dCurrentRawLength - dPartLength - dStartOffset
|
||||||
-- creo e posiziono il grezzo
|
-- creo e posiziono il grezzo
|
||||||
PARTS[i].idRaw = EgtAddRawPart( Point3d(0,0,0), dCrawLen, dRawW, dRawH, BeamData.RAWCOL)
|
PARTS[i].idRaw = EgtAddRawPart( Point3d(0,0,0), dCurrentRawLength, dRawW, dRawH, BeamData.RAWCOL)
|
||||||
|
|
||||||
EgtMoveToCornerRawPart( PARTS[i].idRaw, BeamData.ptOriXR, BeamData.dPosXR)
|
EgtMoveToCornerRawPart( PARTS[i].idRaw, BeamData.ptOriXR, BeamData.dPosXR)
|
||||||
EgtMoveRawPart( PARTS[i].idRaw, Vector3d( dLen - dRawL, 0, 0))
|
EgtMoveRawPart( PARTS[i].idRaw, Vector3d( dResidualLength - dRawL, 0, 0))
|
||||||
-- assegno ordine in lavorazione
|
-- assegno ordine in lavorazione
|
||||||
nCnt = nCnt + 1
|
nCnt = nCnt + 1
|
||||||
EgtSetInfo( PARTS[i].idRaw, 'ORD', nCnt)
|
EgtSetInfo( PARTS[i].idRaw, 'ORD', nCnt)
|
||||||
@@ -454,14 +478,14 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
|
|||||||
-- aggiungo faccia per taglio iniziale al pezzo
|
-- aggiungo faccia per taglio iniziale al pezzo
|
||||||
BeamLib.AddPartStartFace( PARTS[i].id, PARTS[i].b3PartOriginal)
|
BeamLib.AddPartStartFace( PARTS[i].id, PARTS[i].b3PartOriginal)
|
||||||
-- se sovramateriale di testa, lo notifico
|
-- se sovramateriale di testa, lo notifico
|
||||||
if dDeltaS > 0.09 then
|
if dStartOffset > 0.09 then
|
||||||
EgtSetInfo( PARTS[i].idRaw, 'HOVM', dDeltaS)
|
EgtSetInfo( PARTS[i].idRaw, 'HOVM', dStartOffset)
|
||||||
if idPrevRaw then
|
if idPrevRaw then
|
||||||
EgtSetInfo( idPrevRaw, 'BDST', dDeltaS + dPrevDelta)
|
EgtSetInfo( idPrevRaw, 'BDST', dStartOffset + dPrevDelta)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if dDeltaE > 0.09 then
|
if dEndOffset > 0.09 then
|
||||||
EgtSetInfo( PARTS[i].idRaw, 'TOVM', dDeltaE)
|
EgtSetInfo( PARTS[i].idRaw, 'TOVM', dEndOffset)
|
||||||
end
|
end
|
||||||
-- aggiungo faccia per taglio finale al pezzo
|
-- aggiungo faccia per taglio finale al pezzo
|
||||||
BeamLib.AddPartEndFace( PARTS[i].id, PARTS[i].b3PartOriginal)
|
BeamLib.AddPartEndFace( PARTS[i].id, PARTS[i].b3PartOriginal)
|
||||||
@@ -479,13 +503,13 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
|
|||||||
EgtMovePartInRawPart( PARTS[i].id, ( vtEccOri - vtEccRot))
|
EgtMovePartInRawPart( PARTS[i].id, ( vtEccOri - vtEccRot))
|
||||||
end
|
end
|
||||||
-- aggiorno la lunghezza residua della barra
|
-- aggiorno la lunghezza residua della barra
|
||||||
dLen = dLen - dCrawLen
|
dResidualLength = dResidualLength - dCurrentRawLength
|
||||||
-- aggiorno grezzo precedente
|
-- aggiorno grezzo precedente
|
||||||
idPrevRaw = PARTS[i].idRaw
|
idPrevRaw = PARTS[i].idRaw
|
||||||
dPrevDelta = dDelta
|
dPrevDelta = dDelta
|
||||||
PARTS[i].bIsLastPart = ( i == #PARTS)
|
PARTS[i].bIsLastPart = ( i == #PARTS)
|
||||||
PARTS[i].dDistanceToNextPiece = dDelta
|
PARTS[i].dDistanceToNextPiece = dDelta
|
||||||
PARTS[i].dRestLength = dLen
|
PARTS[i].dRestLength = dResidualLength
|
||||||
PARTS[i].b3Raw = EgtGetRawPartBBox( PARTS[i].idRaw)
|
PARTS[i].b3Raw = EgtGetRawPartBBox( PARTS[i].idRaw)
|
||||||
PARTS[i].dLength = PARTS[i].b3Raw:getDimX()
|
PARTS[i].dLength = PARTS[i].b3Raw:getDimX()
|
||||||
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
|
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
|
||||||
@@ -496,7 +520,7 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
|
|||||||
PARTS[i].nIndexInParts = i
|
PARTS[i].nIndexInParts = i
|
||||||
PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[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].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}}
|
||||||
PARTS[i].dHeadOverMaterial = dDeltaS
|
PARTS[i].dHeadOverMaterial = dStartOffset
|
||||||
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil
|
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil
|
||||||
|
|
||||||
PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or
|
PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or
|
||||||
@@ -512,7 +536,7 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
|
|||||||
PARTS[i].idTempGroup = idTempGroup
|
PARTS[i].idTempGroup = idTempGroup
|
||||||
|
|
||||||
else
|
else
|
||||||
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( dLen - 0.1, 1) .. ')'
|
local sOut = 'Error: part L(' .. EgtNumToString( dPartLength, 1) .. ') too big for raw part L(' .. EgtNumToString( dResidualLength - 0.1, 1) .. ')'
|
||||||
return false, sOut
|
return false, sOut
|
||||||
end
|
end
|
||||||
-- se rimasto troppo poco grezzo, esco
|
-- se rimasto troppo poco grezzo, esco
|
||||||
@@ -525,10 +549,10 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
|
|||||||
|
|
||||||
-- Se rimasto materiale aggiungo grezzo dell'avanzo
|
-- Se rimasto materiale aggiungo grezzo dell'avanzo
|
||||||
-- TODO valutare se ridurre la dLen minima perchè crea discrepanze tra lunghezza inserita e VMill
|
-- TODO valutare se ridurre la dLen minima perchè crea discrepanze tra lunghezza inserita e VMill
|
||||||
if dLen > 10 then
|
if dResidualLength > 10 then
|
||||||
local idRaw = EgtAddRawPart( Point3d(0,0,0), dLen, dRawW, dRawH, BeamData.RAWCOL)
|
local idRaw = EgtAddRawPart( Point3d(0,0,0), dResidualLength, dRawW, dRawH, BeamData.RAWCOL)
|
||||||
EgtMoveToCornerRawPart( idRaw, BeamData.ptOriXR, BeamData.dPosXR)
|
EgtMoveToCornerRawPart( idRaw, BeamData.ptOriXR, BeamData.dPosXR)
|
||||||
EgtMoveRawPart( idRaw, Vector3d( dLen - dRawL, 0, 0))
|
EgtMoveRawPart( idRaw, Vector3d( dResidualLength - dRawL, 0, 0))
|
||||||
-- assegno ordine in lavorazione
|
-- assegno ordine in lavorazione
|
||||||
nCnt = nCnt + 1
|
nCnt = nCnt + 1
|
||||||
EgtSetInfo( idRaw, 'ORD', nCnt)
|
EgtSetInfo( idRaw, 'ORD', nCnt)
|
||||||
@@ -781,6 +805,12 @@ end
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
|
local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
|
||||||
|
-- gruppo per geometrie temporanee
|
||||||
|
local idTempGroup = BeamLib.GetTempGroup()
|
||||||
|
|
||||||
|
local HeadProc = {}
|
||||||
|
local TailProc = {}
|
||||||
|
|
||||||
-- ciclo tutte le feature
|
-- ciclo tutte le feature
|
||||||
for i = 1, #vProcSingleRot do
|
for i = 1, #vProcSingleRot do
|
||||||
local Proc = vProcSingleRot[i]
|
local Proc = vProcSingleRot[i]
|
||||||
@@ -791,6 +821,86 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
|
|||||||
local ProcB = vProcSingleRot[j]
|
local ProcB = vProcSingleRot[j]
|
||||||
-- non si controlla la feature con se stessa o se feature disabilitata
|
-- non si controlla la feature con se stessa o se feature disabilitata
|
||||||
if i ~= j and ProcB.nFlg ~= 0 then
|
if i ~= j and ProcB.nFlg ~= 0 then
|
||||||
|
|
||||||
|
local bAreBothTruncatingCuts =
|
||||||
|
( ID.IsCut( Proc) or ID.IsHeadCut( Proc) or ID.IsTailCut( Proc)) and ( ID.IsCut( ProcB) or ID.IsHeadCut( ProcB) or ID.IsTailCut( ProcB))
|
||||||
|
and ( FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part) and FeatureLib.IsFeatureCuttingEntireSection( ProcB.b3Box, Part))
|
||||||
|
|
||||||
|
-- si trovano i veri tagli di testa e coda e si disattivano gli altri, se necessario
|
||||||
|
if bAreBothTruncatingCuts then
|
||||||
|
-- testa
|
||||||
|
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL and ProcB.Faces[1].vtN:getX() > GEO.EPS_SMALL then
|
||||||
|
-- il primo taglio è più verso il centro della trave
|
||||||
|
if ( Proc.b3Box:getMin():getX() < ProcB.b3Box:getMin():getX() - 10 * GEO.EPS_SMALL) then
|
||||||
|
HeadProc = Proc
|
||||||
|
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||||
|
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||||
|
EgtMove( idProcCopy, - 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
EgtMove( idProcBCopy, 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||||
|
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||||
|
if not Proc.SlaveProcIndexes then
|
||||||
|
Proc.SlaveProcIndexes = {}
|
||||||
|
end
|
||||||
|
table.insert( Proc.SlaveProcIndexes, j)
|
||||||
|
ProcB.nIndexMasterProc = i
|
||||||
|
ProcB.nFlg = 0
|
||||||
|
end
|
||||||
|
-- il secondo taglio è più verso il centro della trave
|
||||||
|
elseif Proc.b3Box:getMin():getX() >= ProcB.b3Box:getMin():getX() - 10 * GEO.EPS_SMALL then
|
||||||
|
HeadProc = ProcB
|
||||||
|
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||||
|
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||||
|
EgtMove( idProcBCopy, - 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
EgtMove( idProcCopy, 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||||
|
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||||
|
if not ProcB.SlaveProcIndexes then
|
||||||
|
ProcB.SlaveProcIndexes = {}
|
||||||
|
end
|
||||||
|
table.insert( ProcB.SlaveProcIndexes, i)
|
||||||
|
Proc.nIndexMasterProc = j
|
||||||
|
Proc.nFlg = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- coda
|
||||||
|
elseif Proc.Faces[1].vtN:getX() <= GEO.EPS_SMALL and ProcB.Faces[1].vtN:getX() <= GEO.EPS_SMALL then
|
||||||
|
-- il primo taglio è più verso il centro della trave
|
||||||
|
if Proc.b3Box:getMax():getX() > ProcB.b3Box:getMax():getX() + 10 * GEO.EPS_SMALL then
|
||||||
|
TailProc = Proc
|
||||||
|
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||||
|
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||||
|
EgtMove( idProcCopy, - 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
EgtMove( idProcBCopy, 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||||
|
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||||
|
if not Proc.SlaveProcIndexes then
|
||||||
|
Proc.SlaveProcIndexes = {}
|
||||||
|
end
|
||||||
|
table.insert( Proc.SlaveProcIndexes, j)
|
||||||
|
ProcB.nIndexMasterProc = i
|
||||||
|
ProcB.nFlg = 0
|
||||||
|
end
|
||||||
|
-- il secondo taglio è più verso il centro della trave
|
||||||
|
elseif Proc.b3Box:getMax():getX() >= ProcB.b3Box:getMax():getX() - 10 * GEO.EPS_SMALL then
|
||||||
|
TailProc = ProcB
|
||||||
|
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
|
||||||
|
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
|
||||||
|
EgtMove( idProcBCopy, - 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
EgtMove( idProcCopy, 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
|
||||||
|
-- se i tagli non si intersecano, quello più esterno è da disattivare
|
||||||
|
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
|
||||||
|
if not ProcB.SlaveProcIndexes then
|
||||||
|
ProcB.SlaveProcIndexes = {}
|
||||||
|
end
|
||||||
|
table.insert( ProcB.SlaveProcIndexes, i)
|
||||||
|
Proc.nIndexMasterProc = j
|
||||||
|
Proc.nFlg = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- se entrambi tagli di testa, si tiene sempre il primo ( ma non quello aggiunto dall'automatismo)
|
-- se entrambi tagli di testa, si tiene sempre il primo ( ma non quello aggiunto dall'automatismo)
|
||||||
if ( ID.IsHeadCut( Proc) and not EgtGetInfo( Proc.id, 'HEAD_ADD_CUT', 'i')) and ID.IsHeadCut( ProcB) then
|
if ( ID.IsHeadCut( Proc) and not EgtGetInfo( Proc.id, 'HEAD_ADD_CUT', 'i')) and ID.IsHeadCut( ProcB) then
|
||||||
if not Proc.SlaveProcIndexes then
|
if not Proc.SlaveProcIndexes then
|
||||||
@@ -828,7 +938,37 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return vProcSingleRot
|
|
||||||
|
HeadProc.Topology = {}
|
||||||
|
TailProc.Topology = {}
|
||||||
|
HeadProc.Topology.sFamily = 'HeadCut'
|
||||||
|
HeadProc.Topology.sName = 'HeadCut'
|
||||||
|
TailProc.Topology.sFamily = 'TailCut'
|
||||||
|
TailProc.Topology.sName = 'TailCut'
|
||||||
|
HeadProc.AvailableStrategies = GetStrategies( HeadProc, Part.sAISetupConfig)
|
||||||
|
TailProc.AvailableStrategies = GetStrategies( TailProc, Part.sAISetupConfig)
|
||||||
|
-- per nesting, si settano come info gli offset X degli estremi dei tagli
|
||||||
|
local HeadcutInfo = {}
|
||||||
|
local PtSortedHead = BeamLib.GetSortedVertices( HeadProc)
|
||||||
|
if PtSortedHead then
|
||||||
|
HeadcutInfo.OffsetX = {}
|
||||||
|
for i = 1, #PtSortedHead do
|
||||||
|
table.insert( HeadcutInfo.OffsetX, Part.b3Part:getMax():getX() - PtSortedHead[i]:getX())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local TailcutInfo = {}
|
||||||
|
local PtSortedTail = BeamLib.GetSortedVertices( TailProc)
|
||||||
|
if PtSortedTail then
|
||||||
|
TailcutInfo.OffsetX = {}
|
||||||
|
for i = 1, #PtSortedHead do
|
||||||
|
table.insert( TailcutInfo.OffsetX, Part.b3Part:getMin():getX() - PtSortedTail[i]:getX())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- per nesting, si settano come info le normali delle facce di taglio
|
||||||
|
HeadcutInfo.vtN = HeadProc.Faces[1].vtN
|
||||||
|
TailcutInfo.vtN = TailProc.Faces[1].vtN
|
||||||
|
|
||||||
|
return vProcSingleRot, HeadcutInfo, TailcutInfo
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
@@ -983,6 +1123,9 @@ local function CalculateStrategies( vProcSingleRot, Part)
|
|||||||
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99
|
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not Proc.AvailableStrategies.dAllStrategiesTotalTime then
|
||||||
|
Proc.AvailableStrategies.dAllStrategiesTotalTime = 0
|
||||||
|
end
|
||||||
Proc.AvailableStrategies.dAllStrategiesTotalTime = Proc.AvailableStrategies.dAllStrategiesTotalTime + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine
|
Proc.AvailableStrategies.dAllStrategiesTotalTime = Proc.AvailableStrategies.dAllStrategiesTotalTime + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine
|
||||||
-- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa
|
-- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa
|
||||||
if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
|
if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
|
||||||
@@ -1244,12 +1387,16 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
|
|||||||
-- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
|
-- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
|
||||||
local bCalcInverted = bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion
|
local bCalcInverted = bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion
|
||||||
local nCycles = EgtIf( bCalcInverted, 2, 1)
|
local nCycles = EgtIf( bCalcInverted, 2, 1)
|
||||||
|
PARTS[nPart].HeadcutInfo = {}
|
||||||
|
PARTS[nPart].TailcutInfo = {}
|
||||||
-- per ogni inversione
|
-- per ogni inversione
|
||||||
for nInvertIndex = 1, nCycles do
|
for nInvertIndex = 1, nCycles do
|
||||||
-- per ogni rotazione
|
-- per ogni rotazione
|
||||||
for nRotIndex = 1, 4 do
|
for nRotIndex = 1, 4 do
|
||||||
local nOffsetIndex = EgtIf( nInvertIndex == 2, 4, 0)
|
local nOffsetIndex = EgtIf( nInvertIndex == 2, 4, 0)
|
||||||
|
-- le rotazioni sono 1,2,3,4 (0, 90, 180, 270) e 5,6,7,8 (le stesse invertite)
|
||||||
local nIndex = nRotIndex + nOffsetIndex
|
local nIndex = nRotIndex + nOffsetIndex
|
||||||
|
local HeadcutInfo, TailcutInfo
|
||||||
-- si calcolano le feature solo se la rotazione può essere presa in considerazione
|
-- si calcolano le feature solo se la rotazione può essere presa in considerazione
|
||||||
if PARTS[nPart].CombinationList.Rotations[nRotIndex] == 1 then
|
if PARTS[nPart].CombinationList.Rotations[nRotIndex] == 1 then
|
||||||
-- recupero le feature di lavorazione della trave
|
-- recupero le feature di lavorazione della trave
|
||||||
@@ -1257,11 +1404,23 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
|
|||||||
|
|
||||||
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
|
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
|
||||||
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
|
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
|
||||||
vProcRot[nIndex] = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart])
|
vProcRot[nIndex], HeadcutInfo, TailcutInfo = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart])
|
||||||
else
|
else
|
||||||
-- inserisco una tabella vuota
|
-- inserisco una tabella vuota
|
||||||
table.insert( vProcRot, {})
|
table.insert( vProcRot, {})
|
||||||
end
|
end
|
||||||
|
if HeadcutInfo then
|
||||||
|
PARTS[nPart].HeadcutInfo[nIndex] = {
|
||||||
|
OffsetX = HeadcutInfo.OffsetX,
|
||||||
|
vtN = HeadcutInfo.vtN
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if TailcutInfo then
|
||||||
|
PARTS[nPart].TailcutInfo[nIndex] = {
|
||||||
|
OffsetX = TailcutInfo.OffsetX,
|
||||||
|
vtN = TailcutInfo.vtN
|
||||||
|
}
|
||||||
|
end
|
||||||
-- rotazione pezzo di 90° per volta
|
-- rotazione pezzo di 90° per volta
|
||||||
BeamLib.RotateRawPart( PARTS[nPart], 1)
|
BeamLib.RotateRawPart( PARTS[nPart], 1)
|
||||||
-- aggiorno info pezzo
|
-- aggiorno info pezzo
|
||||||
@@ -1962,8 +2121,8 @@ end
|
|||||||
function BeamExec.ProcessAlternatives( PARTS)
|
function BeamExec.ProcessAlternatives( PARTS)
|
||||||
|
|
||||||
-- inizializzazione variabili globali per interfaccia
|
-- inizializzazione variabili globali per interfaccia
|
||||||
BEAM.ALTERNATIVESNEST2D = ''
|
local Alternatives = {}
|
||||||
BEAM.ALTERNATIVES = ''
|
local AlternativesNest2D = {}
|
||||||
|
|
||||||
-- ciclo sui pezzi
|
-- ciclo sui pezzi
|
||||||
local BestCombination = {}
|
local BestCombination = {}
|
||||||
@@ -2292,23 +2451,14 @@ function BeamExec.ProcessAlternatives( PARTS)
|
|||||||
local bApplOk, _, _ = EgtApplyAllMachinings()
|
local bApplOk, _, _ = EgtApplyAllMachinings()
|
||||||
-- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia
|
-- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia
|
||||||
if bApplOk then
|
if bApplOk then
|
||||||
local Alternatives = {}
|
|
||||||
local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '')
|
local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '')
|
||||||
if TotalCombiToTest[z].bIsNesting2D then
|
if TotalCombiToTest[z].bIsNesting2D then
|
||||||
if BEAM.ALTERNATIVESNEST2D and BEAM.ALTERNATIVESNEST2D ~= "" then
|
table.insert( AlternativesNest2D, sBitIndexCombinationWithInvert)
|
||||||
table.insert( Alternatives, BEAM.ALTERNATIVESNEST2D)
|
|
||||||
end
|
|
||||||
table.insert( Alternatives, sBitIndexCombinationWithInvert)
|
|
||||||
BEAM.ALTERNATIVESNEST2D = table.concat( Alternatives, ', ')
|
|
||||||
else
|
else
|
||||||
if BEAM.ALTERNATIVES and BEAM.ALTERNATIVES ~= "" then
|
|
||||||
table.insert( Alternatives, BEAM.ALTERNATIVES)
|
|
||||||
end
|
|
||||||
table.insert( Alternatives, sBitIndexCombinationWithInvert)
|
table.insert( Alternatives, sBitIndexCombinationWithInvert)
|
||||||
BEAM.ALTERNATIVES = table.concat( Alternatives, ', ')
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- se ultima combinazione, si esce e non si riporta in posizione inizale. Verrà infatti cancellata
|
-- se ultima combinazione, si esce e non si riporta in posizione iniziale. Verrà infatti cancellata
|
||||||
if z == #TotalCombiToTest then break end
|
if z == #TotalCombiToTest then break end
|
||||||
|
|
||||||
-- si riporta pezzo in posizione iniziale
|
-- si riporta pezzo in posizione iniziale
|
||||||
@@ -2322,6 +2472,23 @@ function BeamExec.ProcessAlternatives( PARTS)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- passaggio info a interfaccia da scrivere sul pezzo
|
||||||
|
BEAM.INFONGEPART = {}
|
||||||
|
table.insert( BEAM.INFONGEPART, 'INITIALPOSITION=' .. PARTS[nPart].nInitialPosition)
|
||||||
|
for i = 1, #AlternativesNest2D do
|
||||||
|
local sRotation = BeamLib.ConvertBitIndexToRotationIndex( AlternativesNest2D[i])
|
||||||
|
if PARTS[nPart].HeadcutInfo then
|
||||||
|
local sOffsetX = table.concat( PARTS[nPart].HeadcutInfo[sRotation].OffsetX, ',')
|
||||||
|
local sVtN = ( tostring( PARTS[nPart].HeadcutInfo[sRotation].vtN)):gsub("^%(", ""):gsub("%)$", "")
|
||||||
|
table.insert( BEAM.INFONGEPART, 'ALT' .. AlternativesNest2D[i].. '_H' .. '=' .. sOffsetX .. ';' .. sVtN )
|
||||||
|
end
|
||||||
|
if PARTS[nPart].TailcutInfo then
|
||||||
|
local sOffsetX = table.concat( PARTS[nPart].TailcutInfo[sRotation].OffsetX, ',')
|
||||||
|
local sVtN = ( tostring( PARTS[nPart].TailcutInfo[sRotation].vtN)):gsub("^%(", ""):gsub("%)$", "")
|
||||||
|
table.insert( BEAM.INFONGEPART, 'ALT' .. AlternativesNest2D[i] .. '_T' .. '=' .. sOffsetX .. ';' .. sVtN)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- si cancella eventuale mach group creato per le alternative
|
-- si cancella eventuale mach group creato per le alternative
|
||||||
EgtRemoveMachGroup( nTempMachGroupName)
|
EgtRemoveMachGroup( nTempMachGroupName)
|
||||||
|
|
||||||
|
|||||||
@@ -516,6 +516,65 @@ function BeamLib.GetDirectionFromSCC( nSCC)
|
|||||||
return vtSCC
|
return vtSCC
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Restituisce una tabella con i punti ai vertici della faccia, in globale
|
||||||
|
-- ordinati partendo da quello ai valori minimi degli assi e i successivi secondo rotazione destrorsa X+;
|
||||||
|
-- solo per Proc a 1 faccia
|
||||||
|
function BeamLib.GetSortedVertices( Proc)
|
||||||
|
local PtVerticesSorted = {}
|
||||||
|
|
||||||
|
-- se più di una faccia si esce subito
|
||||||
|
if Proc.nFct > 1 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local PtVertices = {}
|
||||||
|
local nFirstIndex
|
||||||
|
local dMinYZ = GEO.INFINITO
|
||||||
|
for i = 1, #Proc.Faces[1].Edges do
|
||||||
|
local Edge = Proc.Faces[1].Edges[i]
|
||||||
|
table.insert( PtVertices, Edge.ptStart)
|
||||||
|
if ( Edge.ptStart:getY() + Edge.ptStart:getZ() < dMinYZ) then
|
||||||
|
nFirstIndex = i
|
||||||
|
dMinYZ = Edge.ptStart:getY() + Edge.ptStart:getZ()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert( PtVerticesSorted, PtVertices[nFirstIndex])
|
||||||
|
local nCurrentIndex = nFirstIndex
|
||||||
|
-- faccia che guarda verso X+, ordine ok
|
||||||
|
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL then
|
||||||
|
for _ = 1, #PtVertices - 1 do
|
||||||
|
_, nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
|
||||||
|
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
|
||||||
|
end
|
||||||
|
-- faccia che guarda verso X-, ordine da invertire
|
||||||
|
else
|
||||||
|
for _ = 1, #PtVertices - 1 do
|
||||||
|
nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
|
||||||
|
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return PtVerticesSorted
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
-- restituisce il precedente e prossimo indice 1-based, tenendo conto del massimo indice
|
||||||
|
function BeamLib.GetAdjacentIndices( nCurrentIndex, nMaxIndex)
|
||||||
|
local nPreviousIndex, nNextIndex
|
||||||
|
|
||||||
|
if ( nCurrentIndex < 1) or ( nCurrentIndex > nMaxIndex) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- circular indexing 1-based
|
||||||
|
nPreviousIndex = ((nCurrentIndex - 2 + nMaxIndex) % nMaxIndex) + 1
|
||||||
|
nNextIndex = (nCurrentIndex % nMaxIndex) + 1
|
||||||
|
|
||||||
|
return nPreviousIndex, nNextIndex
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
|
||||||
function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
|
function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
|
||||||
@@ -830,6 +889,43 @@ function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
|
|||||||
return NumberString
|
return NumberString
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
function BeamLib.ConvertBitIndexToRotationIndex( sBitIndexCombination)
|
||||||
|
local nRotationIndex
|
||||||
|
|
||||||
|
if sBitIndexCombination == '1000' then
|
||||||
|
return 1
|
||||||
|
elseif sBitIndexCombination == '0100' then
|
||||||
|
return 2
|
||||||
|
elseif sBitIndexCombination == '0010' then
|
||||||
|
return 3
|
||||||
|
elseif sBitIndexCombination == '0001' then
|
||||||
|
return 4
|
||||||
|
elseif sBitIndexCombination == '1000_INV' then
|
||||||
|
return 5
|
||||||
|
elseif sBitIndexCombination == '0100_INV' then
|
||||||
|
return 6
|
||||||
|
elseif sBitIndexCombination == '0010_INV' then
|
||||||
|
return 7
|
||||||
|
elseif sBitIndexCombination == '0001_INV' then
|
||||||
|
return 8
|
||||||
|
end
|
||||||
|
|
||||||
|
return nRotationIndex
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
-- reindicizza una tabella passata ripartendo dall'indice nStartIndex e mantenendo l'ordine
|
||||||
|
function BeamLib.RotateTableFromIndex( Table, nStartIndex)
|
||||||
|
local RotatedTable = {}
|
||||||
|
|
||||||
|
for i = 1, #Table do
|
||||||
|
RotatedTable[#RotatedTable + 1] = Table[((RotatedTable + i - 2) % #Table) + 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
return RotatedTable
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
--- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle
|
--- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle
|
||||||
--- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs
|
--- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ end
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra
|
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra
|
||||||
local function IsFeatureCuttingEntireSection( b3Proc, Part)
|
function FeatureLib.IsFeatureCuttingEntireSection( b3Proc, Part)
|
||||||
return ( b3Proc:getDimY() > ( Part.b3Part:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Part:getDimZ() - 500 * GEO.EPS_SMALL))
|
return ( b3Proc:getDimY() > ( Part.b3Part:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Part:getDimZ() - 500 * GEO.EPS_SMALL))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ function FeatureLib.ClassifyTopology( Proc, Part)
|
|||||||
|
|
||||||
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
|
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
|
||||||
|
|
||||||
local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part)
|
local bIsFeatureCuttingEntireSection = FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part)
|
||||||
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
|
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
|
||||||
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part)
|
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part)
|
||||||
local vAdj = Proc.AdjacencyMatrix
|
local vAdj = Proc.AdjacencyMatrix
|
||||||
|
|||||||
+582
-400
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,477 @@
|
|||||||
|
-- BeamNestProcess.lua by Egaltech s.r.l. 2023/01/15
|
||||||
|
-- Gestione nesting automatico travi
|
||||||
|
-- 2022/10/05 Piccole modifiche per far funzionare correttamente i compilati.
|
||||||
|
-- 2022/10/06 Corretto bug che moltiplicava i pezzi se erano presenti più grezzi della stessa sezione.
|
||||||
|
-- 2023/01/15 Piccole correzioni.
|
||||||
|
|
||||||
|
-- Intestazioni
|
||||||
|
require( 'EgtBase')
|
||||||
|
_ENV = EgtProtectGlobal()
|
||||||
|
EgtEnableDebug( false)
|
||||||
|
|
||||||
|
-- Per test
|
||||||
|
--NEST = {}
|
||||||
|
--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl'
|
||||||
|
--NEST.MACHINE = 'Essetre-90480019_MW'
|
||||||
|
--NEST.FLAG = 3
|
||||||
|
|
||||||
|
local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN[1]
|
||||||
|
EgtOutLog( sLog)
|
||||||
|
|
||||||
|
-- flag per abilitare statistiche in log
|
||||||
|
local bLogStat = false
|
||||||
|
|
||||||
|
-- Cancello file di log specifico
|
||||||
|
local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt')
|
||||||
|
EgtEraseFile( sLogFile)
|
||||||
|
|
||||||
|
-- Funzioni per scrittura su file di log specifico
|
||||||
|
local function WriteErrToLogFile( nErr, sMsg, nRot, nCutId, nTaskId)
|
||||||
|
local hFile = io.open( sLogFile, 'a')
|
||||||
|
hFile:write( 'ERR=' .. tostring( nErr) .. '\n')
|
||||||
|
hFile:write( sMsg .. '\n')
|
||||||
|
hFile:write( 'ROT=' .. tostring( nRot or 0) .. '\n')
|
||||||
|
hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n')
|
||||||
|
hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n')
|
||||||
|
hFile:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function WriteTimeToLogFile( dTime)
|
||||||
|
local hFile = io.open( sLogFile, 'a')
|
||||||
|
hFile:write( 'TIME=' .. EgtNumToString( dTime) .. '\n')
|
||||||
|
hFile:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Funzione per gestire visualizzazione dopo errore
|
||||||
|
local function PostErrView( nErr, sMsg)
|
||||||
|
if nErr ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||||
|
EgtSetView( SCE_VD.ISO_SW, false)
|
||||||
|
EgtZoom( SCE_ZM.ALL)
|
||||||
|
EgtOutBox( sMsg, 'BatchProcess (err=' .. tostring( nErr) .. ')', 'ERRORS')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Funzione per gestire visualizzazione dopo warning
|
||||||
|
local function PostWarnView( nWarn, sMsg)
|
||||||
|
if nWarn ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
|
||||||
|
EgtSetView( SCE_VD.ISO_SW, false)
|
||||||
|
EgtZoom( SCE_ZM.ALL)
|
||||||
|
EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Funzione per aggiornare dati ausiliari
|
||||||
|
local function UpdateAuxData( sAuxFile)
|
||||||
|
local bModif = false
|
||||||
|
-- Se definito LOAD90, aggiorno
|
||||||
|
local sLoad90 = EgtGetStringFromIni( 'AuxData', 'LOAD90', '', sAuxFile)
|
||||||
|
if sLoad90 ~= '' then
|
||||||
|
local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL
|
||||||
|
EgtSetInfo( BtlInfoId, 'LOAD90', sLoad90)
|
||||||
|
bModif = true
|
||||||
|
end
|
||||||
|
return bModif
|
||||||
|
end
|
||||||
|
|
||||||
|
local function PartsToFill( Parts)
|
||||||
|
local nToFill = 0
|
||||||
|
for i = 1, #Parts do
|
||||||
|
if Parts[i].Cnt > 0 then
|
||||||
|
nToFill = nToFill + Parts[i].Cnt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nToFill
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ExecMaximumFilling( Raw, Parts)
|
||||||
|
-- Inizializzo maximum filler
|
||||||
|
EgtMaxFillerStart()
|
||||||
|
-- Inserisco i pezzi
|
||||||
|
for i = 1, #Parts do
|
||||||
|
EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1)
|
||||||
|
end
|
||||||
|
-- Eseguo l'ottimizzazione
|
||||||
|
EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType)
|
||||||
|
-- Recupero i risultati
|
||||||
|
local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults()
|
||||||
|
local OneRes = {}
|
||||||
|
for i = 0, nDiffParts - 1 do
|
||||||
|
local nPartId, nCount = EgtMaxFillerGetOneResult( i)
|
||||||
|
table.insert( OneRes, { Id=nPartId, Count=nCount})
|
||||||
|
end
|
||||||
|
--return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes}
|
||||||
|
return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Data=OneRes}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Funzione per trovare nome MachGroup
|
||||||
|
local function NewMachGroupName()
|
||||||
|
local nMachGroupId = EgtGetFirstMachGroup()
|
||||||
|
if not nMachGroupId then return 1 end
|
||||||
|
local nMaxMachGroup = 0
|
||||||
|
while nMachGroupId do
|
||||||
|
sMachGroupName = EgtGetMachGroupName(nMachGroupId)
|
||||||
|
local nMachGroupName = tonumber(sMachGroupName)
|
||||||
|
if nMachGroupName > nMaxMachGroup then
|
||||||
|
nMaxMachGroup = nMachGroupName
|
||||||
|
end
|
||||||
|
nMachGroupId = EgtGetNextMachGroup(nMachGroupId)
|
||||||
|
end
|
||||||
|
return nMaxMachGroup + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function TotRawCount(Raws)
|
||||||
|
local nTotRaws = 0
|
||||||
|
for RawIndex = 1, #Raws do
|
||||||
|
nTotRaws = nTotRaws + Raws[RawIndex].Count
|
||||||
|
end
|
||||||
|
return nTotRaws
|
||||||
|
end
|
||||||
|
|
||||||
|
local function TotPartLen(Parts)
|
||||||
|
local nTotPartLen = 0
|
||||||
|
for PartIndex = 1, #Parts do
|
||||||
|
nTotPartLen = nTotPartLen + ( Parts[PartIndex].Len * Parts[PartIndex].Cnt)
|
||||||
|
end
|
||||||
|
return nTotPartLen
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Imposto direttorio libreria specializzata per Travi
|
||||||
|
EgtAddToPackagePath( NEST.BASEDIR .. '\\LuaLibs\\?.lua')
|
||||||
|
|
||||||
|
-- Imposto la macchina corrente e verifico sia abilitata per la lavorazione delle Travi
|
||||||
|
EgtSetCurrMachine( NEST.MACHINE)
|
||||||
|
local sMachDir = EgtGetCurrMachineDir()
|
||||||
|
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
|
||||||
|
NEST.ERR = 12
|
||||||
|
NEST.MSG = 'Error not configured for beam machine : ' .. sMachine
|
||||||
|
WriteErrToLogFile( NEST.ERR, NEST.MSG)
|
||||||
|
PostErrView( NEST.ERR, NEST.MSG)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
|
||||||
|
EgtRemoveBaseMachineDirFromPackagePath()
|
||||||
|
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
|
||||||
|
|
||||||
|
-- Inizializzo contatori errori e avvisi
|
||||||
|
local nErrCnt = 0
|
||||||
|
local nWarnCnt = 0
|
||||||
|
|
||||||
|
-- Grezzi
|
||||||
|
local Raws = {}
|
||||||
|
-- creo tabella dei grezzi
|
||||||
|
for nIndex, nLen in pairs( LEN) do
|
||||||
|
Raws[tonumber(nIndex)] = {LenToFill = nLen, StartGap = NEST.STARTOFFSET, MidGap = NEST.OFFSET, EndGap = 0, SortType = -1}
|
||||||
|
end
|
||||||
|
for nIndex, nQty in pairs( QTY) do
|
||||||
|
Raws[tonumber(nIndex)].Count = nQty
|
||||||
|
end
|
||||||
|
-- cerco il grezzo con la lunghezza maggiore, epurata dello start gap
|
||||||
|
local maxRawLenToFillNoStartGap = 0
|
||||||
|
for RawIndex = 1, #Raws do
|
||||||
|
if Raws[RawIndex].Count > 0 then
|
||||||
|
maxRawLenToFillNoStartGap = max( maxRawLenToFillNoStartGap, Raws[RawIndex].LenToFill - Raws[RawIndex].StartGap)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pezzi
|
||||||
|
local Parts = {}
|
||||||
|
-- ciclo su pezzi per aggiungerli al nesting
|
||||||
|
local dTotLen = 0
|
||||||
|
for nPartId, nCount in pairs( PART) do
|
||||||
|
-- recupero lunghezza pezzo
|
||||||
|
local Len = EgtGetInfo( nPartId, "L", 'd')
|
||||||
|
local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0)
|
||||||
|
-- aggiungo il pezzo solo se ci sta nel grezzo più lungo a disposizione
|
||||||
|
if Len < maxRawLenToFillNoStartGap then
|
||||||
|
for nCntIndex = 1 , nCount do
|
||||||
|
table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = 1})
|
||||||
|
dTotLen = dTotLen + Len
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- lunghezza totale pezzi
|
||||||
|
local dTotPartLen = TotPartLen( Parts)
|
||||||
|
-- calcolo media delle barre necessarie
|
||||||
|
local NeededRawsForType = {}
|
||||||
|
for RawIndex = 1, #Raws do
|
||||||
|
NeededRawsForType[RawIndex] = min( ceil( dTotPartLen / Raws[RawIndex].LenToFill), Raws[RawIndex].Count)
|
||||||
|
end
|
||||||
|
local RawQtySum = 0
|
||||||
|
for NeededRawIndex = 1, #NeededRawsForType do
|
||||||
|
RawQtySum = RawQtySum + NeededRawsForType[NeededRawIndex]
|
||||||
|
end
|
||||||
|
local MediumRawQty = ceil( RawQtySum / #NeededRawsForType)
|
||||||
|
if MediumRawQty > 1 then
|
||||||
|
MediumRawQty = MediumRawQty - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- lista dei risultati
|
||||||
|
local ResultList = {}
|
||||||
|
local BestResult = nil
|
||||||
|
local BestResultIndex = nil
|
||||||
|
-- riordino lista pezzi per lunghezza
|
||||||
|
table.sort( Parts, function( B1, B2) return B1.Len < B2.Len end)
|
||||||
|
|
||||||
|
local function NestSolutionByIndex( Index)
|
||||||
|
|
||||||
|
-- creo copia lista raw
|
||||||
|
local TempRaws = {}
|
||||||
|
for TempRawIndex = 1, #Raws do
|
||||||
|
table.insert(TempRaws, {LenToFill = Raws[TempRawIndex].LenToFill, StartGap = Raws[TempRawIndex].StartGap, MidGap = Raws[TempRawIndex].MidGap, EndGap = Raws[TempRawIndex].EndGap, SortType = Raws[TempRawIndex].SortType, Count = Raws[TempRawIndex].Count})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- recupero pezzi corti
|
||||||
|
local ShortList = {}
|
||||||
|
local LongList = {}
|
||||||
|
|
||||||
|
for PartIndex = 1, #Parts do
|
||||||
|
if PartIndex <= Index then
|
||||||
|
table.insert( ShortList, Parts[PartIndex])
|
||||||
|
else
|
||||||
|
table.insert( LongList, Parts[PartIndex])
|
||||||
|
end
|
||||||
|
Parts[PartIndex].Cnt = 1
|
||||||
|
end
|
||||||
|
-- numero di pezzi piccoli per barra
|
||||||
|
local ShortCount = Index
|
||||||
|
local ShortForRaw = floor( ShortCount / MediumRawQty)
|
||||||
|
local ExtraShortForRaw = 0
|
||||||
|
if MediumRawQty > 0 then
|
||||||
|
ExtraShortForRaw = fmod( ShortCount, MediumRawQty)
|
||||||
|
end
|
||||||
|
-- creo lista pezzi corti singoli
|
||||||
|
local SingleShortList = {}
|
||||||
|
for ShortIndex = 1, #ShortList do
|
||||||
|
for ShortCount = 1, ShortList[ShortIndex].Cnt do
|
||||||
|
table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- li divido per le barre previste
|
||||||
|
local RawsShortList = {}
|
||||||
|
local RawIndex = 0
|
||||||
|
local ShortRawIndex = 0
|
||||||
|
for ShortIndex = 1, #SingleShortList do
|
||||||
|
if ShortRawIndex > 0 then
|
||||||
|
table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex])
|
||||||
|
ShortRawIndex = ShortRawIndex - 1
|
||||||
|
else
|
||||||
|
table.insert( RawsShortList, {SingleShortList[ShortIndex]})
|
||||||
|
RawIndex = RawIndex + 1
|
||||||
|
ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ciclo fino ad esaurimento pezzi o barre
|
||||||
|
local dTotPartInRawLen = 0
|
||||||
|
local nRawTot = 0
|
||||||
|
local dRawTotLen = 0
|
||||||
|
local dTime = 0
|
||||||
|
local nCycle = 1
|
||||||
|
local CurrResult = {}
|
||||||
|
while TotRawCount( TempRaws) > 0 and PartsToFill( Parts) > 0 do
|
||||||
|
|
||||||
|
-- creo lista con pezzi lunghi e pezzi corti di questo Cycle
|
||||||
|
local PartsToNest = {}
|
||||||
|
for PartIndex = 1, #LongList do
|
||||||
|
table.insert( PartsToNest, LongList[PartIndex])
|
||||||
|
end
|
||||||
|
for CycleIndex = 1, #RawsShortList do
|
||||||
|
if CycleIndex <= nCycle then
|
||||||
|
for PartIndex = 1, #RawsShortList[CycleIndex] do
|
||||||
|
table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- se non ci sono pezzi da nestare, esco
|
||||||
|
if PartsToFill( PartsToNest) <= 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
-- Eseguo ottimizzazione per ogni lunghezza di barra
|
||||||
|
local Results = {}
|
||||||
|
for RawIndex = 1, #TempRaws do
|
||||||
|
if TempRaws[RawIndex].Count > 0 then
|
||||||
|
Results[RawIndex] = ExecMaximumFilling( TempRaws[RawIndex], PartsToNest)
|
||||||
|
else
|
||||||
|
Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000, DiffParts = 0}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- verifico quale e' quella con meno scarto
|
||||||
|
local nMinWasteRawIndex = GDB_ID.NULL
|
||||||
|
local dMinWaste = 100000
|
||||||
|
for ResultIndex = 1, #Results do
|
||||||
|
if Results[ResultIndex] then
|
||||||
|
local dWaste = (1 - Results[ResultIndex].FillRatio) * TempRaws[ResultIndex].LenToFill
|
||||||
|
if Results[ResultIndex].DiffParts > 0 and dWaste < dMinWaste then
|
||||||
|
dMinWaste = dWaste
|
||||||
|
nMinWasteRawIndex = ResultIndex
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- verifico se ci sono pezzi
|
||||||
|
if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then
|
||||||
|
-- riporto barra e pezzi nel risultato corrente
|
||||||
|
local CurrBar = { BarLen = TempRaws[nMinWasteRawIndex].LenToFill, Parts = {}}
|
||||||
|
local CurrX = TempRaws[nMinWasteRawIndex].StartGap
|
||||||
|
local nInfoIndex = 1
|
||||||
|
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||||
|
local PartIndex = Results[nMinWasteRawIndex].Data[i].Id
|
||||||
|
local PartId = PartsToNest[PartIndex].Id
|
||||||
|
local dLen = PartsToNest[PartIndex].Len
|
||||||
|
for j = 1, Results[nMinWasteRawIndex].Data[i].Count do
|
||||||
|
-- creo pezzo copia
|
||||||
|
CurrPart = { Index = nInfoIndex, PartId = PartId, PosX = CurrX}
|
||||||
|
table.insert( CurrBar.Parts, CurrPart)
|
||||||
|
CurrX = CurrX + dLen + TempRaws[nMinWasteRawIndex].MidGap
|
||||||
|
nInfoIndex = nInfoIndex + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert( CurrResult, CurrBar)
|
||||||
|
dTotPartInRawLen = dTotPartInRawLen + ( Results[nMinWasteRawIndex].FillRatio * TempRaws[nMinWasteRawIndex].LenToFill)
|
||||||
|
nRawTot = nRawTot + 1
|
||||||
|
dRawTotLen = dRawTotLen + TempRaws[nMinWasteRawIndex].LenToFill
|
||||||
|
-- Aggiorno per prossima iterazione
|
||||||
|
TempRaws[nMinWasteRawIndex].Count = TempRaws[nMinWasteRawIndex].Count - 1
|
||||||
|
for i = 1, Results[nMinWasteRawIndex].DiffParts do
|
||||||
|
local PartId = Results[nMinWasteRawIndex].Data[i].Id
|
||||||
|
PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- se non sono riuscito ad inserire alcun pezzo esco dal ciclo perche' non ci sono pezzi inseribili
|
||||||
|
break
|
||||||
|
end
|
||||||
|
nCycle = nCycle + 1
|
||||||
|
end
|
||||||
|
-- riporto risultato in lista
|
||||||
|
ResultList[Index] = dTotPartInRawLen
|
||||||
|
if not BestResult or not BestResultIndex or
|
||||||
|
( dTotPartInRawLen > ResultList[BestResultIndex] + 0.02 or ( abs( dTotPartInRawLen - ResultList[BestResultIndex]) < 0.02 and dRawTotLen < BestResult.RawTotLen - 0.02)) then
|
||||||
|
BestResult = CurrResult
|
||||||
|
BestResult.RawTotLen = dRawTotLen
|
||||||
|
BestResultIndex = Index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local CycleCount = 0
|
||||||
|
|
||||||
|
local MinTime = 10 + pow( 3, ceil( log10( #Parts)) - 1)
|
||||||
|
if bLogStat then EgtOutLog('MinTime: ' .. MinTime ) end
|
||||||
|
local MaxTime = 30 + pow( 7, ceil( log10( #Parts)) - 1)
|
||||||
|
if bLogStat then EgtOutLog('MaxTime: ' .. MaxTime ) end
|
||||||
|
local TargetRatio = 0.98
|
||||||
|
local dTargetRatioLen = TargetRatio * dTotLen
|
||||||
|
if bLogStat then EgtOutLog('TargetRatioLen: ' .. dTargetRatioLen ) end
|
||||||
|
local CurrTime = 0
|
||||||
|
|
||||||
|
local function NestSolutionFromSP( StartingPoint, OscillationStep)
|
||||||
|
-- ciclo sulle possibilita' da un punto di origine con uno step fisso
|
||||||
|
local CurrResultIndex = StartingPoint
|
||||||
|
NestSolutionByIndex( StartingPoint)
|
||||||
|
if OscillationStep == 0 then return end
|
||||||
|
local CycleIndex = 1
|
||||||
|
local nOutOfBoundary = 0
|
||||||
|
while nOutOfBoundary ~= 3 do
|
||||||
|
CurrTime = EgtStopCounter() / 1000
|
||||||
|
if bLogStat then EgtOutLog('CurrTime: ' .. CurrTime ) end
|
||||||
|
if bLogStat then EgtOutLog('BestRatio: ' .. dTotLen / BestResult.RawTotLen ) end
|
||||||
|
-- se e' passato il tempo massimo, o e' passato il tempo minimo, ha inserito tutti i pezzi e la percentuale di utilizzo del materiale e' maggiore della soglia
|
||||||
|
if CurrTime > MaxTime or ( CurrTime > MinTime and ResultList[BestResultIndex] > dTotLen - 0.1 and ( dTotLen / BestResult.RawTotLen ) >= TargetRatio) then
|
||||||
|
if bLogStat then EgtOutLog('Brake') end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local bCurrOutOfBoundary = false
|
||||||
|
if CurrResultIndex < 0 then
|
||||||
|
bCurrOutOfBoundary = true
|
||||||
|
if nOutOfBoundary == 2 then
|
||||||
|
nOutOfBoundary = 3
|
||||||
|
else
|
||||||
|
nOutOfBoundary = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if CurrResultIndex > #Parts then
|
||||||
|
bCurrOutOfBoundary = true
|
||||||
|
if nOutOfBoundary == 1 then
|
||||||
|
nOutOfBoundary = 3
|
||||||
|
else
|
||||||
|
nOutOfBoundary = 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not bCurrOutOfBoundary and not ResultList[CurrResultIndex] then
|
||||||
|
NestSolutionByIndex( CurrResultIndex)
|
||||||
|
if bLogStat then EgtOutLog('CurrResultIndex: ' .. CurrResultIndex ) end
|
||||||
|
if bLogStat then EgtOutLog('Result: ' .. ResultList[CurrResultIndex]) end
|
||||||
|
CycleCount = CycleCount + 1
|
||||||
|
end
|
||||||
|
CurrResultIndex = StartingPoint + EgtIf( CycleIndex % 2 == 0, (CycleIndex / 2) * OscillationStep, -( ( CycleIndex + 1) / 2) * OscillationStep )
|
||||||
|
CycleIndex = CycleIndex + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- lancio calcolo
|
||||||
|
EgtStartCounter()
|
||||||
|
local StartingResult = floor( #Parts * 0.3)
|
||||||
|
if bLogStat then EgtOutLog('StartingResult: ' .. StartingResult ) end
|
||||||
|
--local Step = floor( #Parts / 10) * floor( log10( #Parts))
|
||||||
|
local nDividendo = pow( 10, floor( log10( #Parts)) - 1)
|
||||||
|
nDividendo = EgtIf( nDividendo ~= 1, nDividendo, 10)
|
||||||
|
local Step = floor( #Parts / nDividendo) * floor( log10( #Parts))
|
||||||
|
if bLogStat then EgtOutLog('Step: ' .. Step ) end
|
||||||
|
NestSolutionFromSP( StartingResult, Step)
|
||||||
|
if Step > 1 then
|
||||||
|
NestSolutionFromSP( StartingResult, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creo gruppi di lavorazione per risultato
|
||||||
|
for MachGroupIndex = 1, #BestResult do
|
||||||
|
local CurrMachGroup = BestResult[ MachGroupIndex]
|
||||||
|
-- creo gruppo di lavorazione
|
||||||
|
local MachGroupName = NewMachGroupName()
|
||||||
|
nMachGroup = EgtAddMachGroup( MachGroupName)
|
||||||
|
EgtSetInfo( nMachGroup, "BARLEN", CurrMachGroup.BarLen)
|
||||||
|
EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL)
|
||||||
|
EgtSetInfo( nMachGroup, "AUTONEST", 1)
|
||||||
|
-- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
|
||||||
|
EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID)
|
||||||
|
EgtSetInfo( nMachGroup, "PATTID", nMachGroup)
|
||||||
|
-- Disegno i pezzi
|
||||||
|
for i = 1, #CurrMachGroup.Parts do
|
||||||
|
local CurrPart = CurrMachGroup.Parts[ i]
|
||||||
|
-- creo pezzo copia
|
||||||
|
local nPartDuploId = EgtDuploNew( CurrPart.PartId)
|
||||||
|
EgtSetInfo( nMachGroup, "PART" .. CurrPart.Index, nPartDuploId .. "," .. CurrPart.PosX)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creo grezzi per ogni gruppo di lavorazione
|
||||||
|
local nRawCnt = 0
|
||||||
|
local nRawTot = ResultList[BestResultIndex]
|
||||||
|
_G.BEAM = {}
|
||||||
|
BEAM.FILE = NEST.FILE
|
||||||
|
BEAM.MACHINE = NEST.MACHINE
|
||||||
|
BEAM.FLAG = 6 -- CREATE_PANEL
|
||||||
|
BEAM.BASEDIR = NEST.BASEDIR
|
||||||
|
nMachGroup = EgtGetFirstMachGroup()
|
||||||
|
while nMachGroup do
|
||||||
|
local nNextMachGroup = EgtGetNextMachGroup( nMachGroup)
|
||||||
|
EgtSetCurrMachGroup( nMachGroup)
|
||||||
|
if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then
|
||||||
|
EgtRemoveInfo( nMachGroup, "AUTONEST")
|
||||||
|
EgtSetInfo( nMachGroup, "UPDATEUI", 1)
|
||||||
|
local bOk, sErr = pcall( dofile, BEAM.BASEDIR .. "\\BatchProcessNew.lua")
|
||||||
|
if not bOk then
|
||||||
|
EgtOutLog( 'Error in BatchProcessNew.lua call (' .. ( sErr or '') ..')')
|
||||||
|
end
|
||||||
|
nRawCnt = nRawCnt + 1
|
||||||
|
-- aggiorno interfaccia
|
||||||
|
EgtProcessEvents( 200 + ( nRawCnt / nRawTot * 100), 0)
|
||||||
|
end
|
||||||
|
nMachGroup = nNextMachGroup
|
||||||
|
end
|
||||||
|
|
||||||
|
EgtResetCurrMachGroup()
|
||||||
|
|
||||||
|
NEST.ERR = 0
|
||||||
|
|
||||||
|
EgtOutLog( ' +++ BeamNestProcess completed')
|
||||||
Reference in New Issue
Block a user