Files
DataWall/NestFlipAndRotate.lua
T
DarioS 3d0336e8e1 DataWall :
- altre modifiche per nesting.
2022-02-01 08:35:03 +01:00

357 lines
13 KiB
Lua

-- NestFlipAndRotate.lua by Egaltech s.r.l. 2021/11/25
-- Flip e rotazione ottimali per il nesting in base all'analisi delle features
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- NFAR.PARTID =
local sLog = 'Flip And Rotate Part ' .. tostring( NFAR.PARTID)
EgtOutLog( sLog)
-- Imposto direttorio libreria specializzata per Travi
local sBaseDir = EgtGetSourceDir()
EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua')
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Pareti
local sMachDir = EgtGetCurrMachineDir()
if not EgtExistsFile( sMachDir .. '\\Wall\\WallData.lua') then
NFAR.ERR = 12
NFAR.MSG = 'Error not configured for walls machine : ' .. sMachine
WriteErrToLogFile( NFAR.ERR, NFAR.MSG)
PostErrView( NFAR.ERR, NFAR.MSG)
return
end
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
EgtRemoveBaseMachineDirFromPackagePath()
EgtAddToPackagePath( sMachDir .. '\\Wall\\?.lua')
-- Carico le librerie
_G.package.loaded.WallExec = nil
local WE = require( 'WallExec')
_G.package.loaded.WProcessLapJoint = nil
local LapJoint = require( 'WProcessLapJoint')
_G.package.loaded.WProcessDrill = nil
local Drill = require( 'WProcessDrill')
_G.package.loaded.WProcessCut = nil
local Cut = require( 'WProcessCut')
_G.package.loaded.WProcessDoubleCut = nil
local DoubleCut = require( 'WProcessDoubleCut')
_G.package.loaded.WProcessSawCut = nil
local SawCut = require( 'WProcessSawCut')
_G.package.loaded.WProcessFreeContour = nil
local FreeContour = require( 'WProcessFreeContour')
_G.package.loaded.WProcessMortise = nil
local Mortise = require( 'WProcessMortise')
_G.package.loaded.WProcessDtMortise = nil
local DtMortise = require( 'WProcessDtMortise')
_G.package.loaded.WProcessMark = nil
local Mark = require( 'WProcessMark')
_G.package.loaded.WProcessText = nil
local Text = require( 'WProcessText')
-- Carico i dati globali
local WD = require( 'WallData')
local function ClassifyFlip( vPartProc, b3Part)
local FlipFeatureStates = {}
local bLapJoints = false
for nInd = 1, #vPartProc do
if LapJoint.Identify( vPartProc[nInd]) then
-- setto parametro Q
if vPartProc[nInd].Prc == 30 then
EgtSetInfo( vPartProc[nInd].Id, "Q08", 1)
EgtSetInfo( vPartProc[nInd].Id, "Q08A", 1)
else
EgtSetInfo( vPartProc[nInd].Id, "Q03", 1)
EgtSetInfo( vPartProc[nInd].Id, "Q03A", 1)
end
bLapJoints = true
local nFlip0, nFlip1 = LapJoint.FlipClassify(vPartProc[nInd])
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif Drill.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = Drill.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif Cut.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = Cut.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif DoubleCut.Identify( vPartProc[nInd]) then
-- setto parametro Q
if vPartProc[nInd].Prc == 12 then
EgtSetInfo( vPartProc[nInd].Id, "Q02", 1)
EgtSetInfo( vPartProc[nInd].Id, "Q02A", 1)
end
local nFlip0, nFlip1 = DoubleCut.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif SawCut.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = SawCut.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif FreeContour.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = FreeContour.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif Mortise.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = Mortise.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif DtMortise.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = DtMortise.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif Mark.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = Mark.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
elseif Text.Identify( vPartProc[nInd]) then
local nFlip0, nFlip1 = Text.FlipClassify(vPartProc[nInd], b3Part)
if nFlip0 and nFlip1 and nFlip0 ~= nFlip1 then
table.insert( FlipFeatureStates, { Flip0 = nFlip0, Flip1 = nFlip1})
end
end
end
return FlipFeatureStates, bLapJoints
end
local function ClassifyRotation( vPartProc)
local RotateFeatureStates = {}
for nInd = 1, #vPartProc do
if Drill.Identify( vPartProc[nInd]) then
local nRot0, nRot90, nRot180, nRot270 = Drill.RotateClassify(vPartProc[nInd], ValidRotations)
if nRot0 and nRot0 >= 0 then
table.insert( RotateFeatureStates, { Rot0 = nRot0, Rot90 = nRot90, Rot180 = nRot180, Rot270 = nRot270})
end
end
end
return RotateFeatureStates
end
---
local vPartProc = WE.CollectFeatures( NFAR.PARTID)
local b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD)
local bManualFlip = EgtGetInfo( NFAR.PARTID, "MANUALFLIP", 'b')
local bManualRot = EgtGetInfo( NFAR.PARTID, "MANUALROT", 'b')
-- FLIP
local FlipFeatureStates, bLapJoints = ClassifyFlip( vPartProc, b3Part)
if not bManualFlip then
local bFlip
-- analizzo stati flip delle feature
local nFlip0Min = 100
local nFlip0Cnt = 0
local nFlip1Min = 100
local nFlip1Cnt = 0
-- calcolo punteggio minimo e sua molteplicita' per entrambi i lati
for nInd = 1, #FlipFeatureStates do
if FlipFeatureStates[nInd].Flip0 < nFlip0Min then
nFlip0Min = FlipFeatureStates[nInd].Flip0
nFlip0Cnt = 1
elseif FlipFeatureStates[nInd].Flip0 == nFlip0Min then
nFlip0Cnt = nFlip0Cnt + 1
end
if FlipFeatureStates[nInd].Flip1 < nFlip1Min then
nFlip1Min = FlipFeatureStates[nInd].Flip1
nFlip1Cnt = 1
elseif FlipFeatureStates[nInd].Flip1 == nFlip1Min then
nFlip1Cnt = nFlip1Cnt + 1
end
end
-- calcolo lato con punteggio minore o molteplicita' piu' alta
if nFlip0Min == nFlip1Min then
if nFlip0Cnt > nFlip1Cnt then
bFlip = true
elseif nFlip0Cnt < nFlip1Cnt then
bFlip = false
elseif bLapJoints then
-- se equivalenti ma ci sono lap joints, fisso il flip per non avere problemi con le aree di lavorazione nel nesting
bFlip = false
end
elseif nFlip0Min < nFlip1Min then
bFlip = true
else
bFlip = false
end
if bFlip ~= nil then
-- se una posizione è più conveniente dell'altra setto info nel pezzo
EgtSetInfo( NFAR.PARTID, "NestAllowFlip", false)
EgtSetInfo( NFAR.PARTID, "NestFlip", bFlip)
else
EgtSetInfo( NFAR.PARTID, "NestAllowFlip", true)
end
if bFlip then
-- flip pezzo
EgtRotate( NFAR.PARTID, b3Part:getCenter(), X_AX(), 180, GDB_RT.GLOB)
-- modifico le info del pezzo
local nPartFlip = EgtGetInfo( NFAR.PARTID, "INVERTED", 'i') or 0
local nTotFlip = EgtIf( nPartFlip == 180, 0, 180)
EgtSetInfo( NFAR.PARTID, "INVERTED", nTotFlip)
EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1)
end
end
-- ROTATION
if not bManualRot then
local RotateFeatureStates = ClassifyRotation( vPartProc)
-- analizzo stati rotazione delle feature
local nRot0Min = 100
local nRot0Cnt = 0
local nRot90Min = 100
local nRot90Cnt = 0
local nRot180Min = 100
local nRot180Cnt = 0
local nRot270Min = 100
local nRot270Cnt = 0
-- calcolo punteggio minimo e sua molteplicita' per tutte le rotazioni
for nInd = 1, #RotateFeatureStates do
if RotateFeatureStates[nInd].Rot0 < nRot0Min then
nRot0Min = RotateFeatureStates[nInd].Rot0
nRot0Cnt = 1
elseif RotateFeatureStates[nInd].Rot0 == nRot0Min then
nRot0Cnt = nRot0Cnt + 1
end
if RotateFeatureStates[nInd].Rot90 < nRot90Min then
nRot90Min = RotateFeatureStates[nInd].Rot90
nRot90Cnt = 1
elseif RotateFeatureStates[nInd].Rot90 == nRot90Min then
nRot90Cnt = nRot90Cnt + 1
end
if RotateFeatureStates[nInd].Rot180 < nRot180Min then
nRot180Min = RotateFeatureStates[nInd].Rot180
nRot180Cnt = 1
elseif RotateFeatureStates[nInd].Rot180 == nRot180Min then
nRot180Cnt = nRot180Cnt + 1
end
if RotateFeatureStates[nInd].Rot270 < nRot270Min then
nRot270Min = RotateFeatureStates[nInd].Rot270
nRot270Cnt = 1
elseif RotateFeatureStates[nInd].Rot270 == nRot270Min then
nRot270Cnt = nRot270Cnt + 1
end
end
-- se c'e' qualche stato di rotazione
local MinList = { { Rot = 0, Score = nRot0Min, ScoreCnt = nRot0Cnt},
{ Rot = 90, Score = nRot90Min, ScoreCnt = nRot90Cnt},
{ Rot = 180, Score = nRot180Min, ScoreCnt = nRot180Cnt},
{ Rot = 270, Score = nRot270Min, ScoreCnt = nRot270Cnt}}
if #RotateFeatureStates > 0 then
-- calcolo lato con punteggio minore o molteplicita' piu' alta
local nRotMax = 0
local nScoreMax = 0
local nScoreCnt = 0
for nInd = 1, #MinList do
if MinList[nInd].Score > nScoreMax then
nRotMax = MinList[nInd].Rot
nScoreMax = MinList[nInd].Score
nScoreCnt = MinList[nInd].ScoreCnt
elseif MinList[nInd].Score == nScoreMax then
if MinList[nInd].ScoreCnt > nScoreCnt then
nRotMax = MinList[nInd].Rot
nScoreMax = MinList[nInd].Score
nScoreCnt = MinList[nInd].ScoreCnt
end
end
end
nRotate = nRotMax
else
nRotate = 0
end
local bRotNest = false
local nStepRotNest = 0
-- se calcolate limitazioni su rotazioni
if MinList and #MinList > 0 then
-- verifico condizioni da permettere al nesting
if MinList[1].Score >= 50 and MinList[2].Score >= 50 and MinList[3].Score >= 50 and MinList[4].Score >= 50 then
bRotNest = true
nStepRotNest = 90
elseif (nRotate == 0 and MinList[3].Score >= 50) or ( nRotate == 90 and MinList[4].Score >= 50) then
bRotNest = true
nStepRotNest = 180
end
else
-- altrimenti permetto tutto
bRotNest = true
nStepRotNest = 90
end
-- eseguo rotazione
EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), nRotate, GDB_RT.GLOB)
-- verifico se ci sono fori lungo Y che bloccano la rotazione
local bDrillOnY = ( nStepRotNest == 180)
-- verifico se rotazione è valida ( pezzo contenuto nel grezzo)
b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD)
local bValidRotationForRaw = b3Part:getDimX() < WD.MAX_LENGTH and b3Part:getDimY() < WD.MAX_WIDTH
local bRotatedIsValid = b3Part:getDimY() < WD.MAX_LENGTH and b3Part:getDimX() < WD.MAX_WIDTH
if not bValidRotationForRaw and bRotatedIsValid then
EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB)
nRotate = nRotate + 90
nStepRotNest = 180
end
-- se non ci sono fori verifico se il pezzo cade
if not bDrillOnY then
b3Part = EgtGetBBoxGlob( NFAR.PARTID, GDB_BB.STANDARD)
local bValidRotation = b3Part:getDimX() > ( WD.INTRULLI or 1200)
-- verifico se ruotata resta valida
local bRotatedIsValid = b3Part:getDimY() > ( WD.INTRULLI or 1200)
-- se non è valida ma ruotato lo sarebbe, ruoto
if not bValidRotation and bRotatedIsValid and nStepRotNest ~= 180 then
EgtRotate( NFAR.PARTID, b3Part:getCenter(), Z_AX(), 90, GDB_RT.GLOB)
nRotate = nRotate + 90
nStepRotNest = 180
elseif bValidRotation and not bRotatedIsValid then
-- se fosse valida ma la sua ruotata no, allora blocco lo step nella rotazione del nesting
nStepRotNest = 180
end
end
-- setto info nel pezzo
if nRotate > 0 then
local nPartRot = EgtGetInfo( NFAR.PARTID, "ROTATED", 'i') or 0
local nTotRot = nPartRot + nRotate
nTotRot = EgtIf( nTotRot < 360, nTotRot, nTotRot - 360)
EgtSetInfo( NFAR.PARTID, "ROTATED", nTotRot)
EgtSetInfo( NFAR.PARTID, "FLIPROTMODIFIED", 1)
end
EgtSetInfo( NFAR.PARTID, "NestStepRot", nStepRotNest)
EgtSetInfo( NFAR.PARTID, "NestRot", nRotate)
EgtSetInfo( NFAR.PARTID, "NestAllowRot", bRotNest)
end
NFAR.ERR = 0