-- BeamExec.lua by Egaltech s.r.l. 2019/10/03 -- Libreria esecuzione lavorazioni per Travi -- 2019/07/11 Aggiunta gestione stato rotazione di feature per TS3. -- 2019/09/04 Corretto controllo feature di testa e coda con sovramateriale di testa elevato. -- 2019/09/25 Aggiunta gestione StepJoint e StepJointNotch -- Tabella per definizione modulo local BeamExec = {} -- Include require( 'EgtBase') -- Carico i dati globali e libero tutti gli altri _G.package.loaded.BeamData = nil _G.package.loaded.CutData = nil _G.package.loaded.MillingData = nil _G.package.loaded.PocketingData = nil _G.package.loaded.DrillData = nil _G.package.loaded.SawingData = nil local BD = require( 'BeamData') -- Carico le librerie _G.package.loaded.MachiningLib = nil local BM = require( 'MachiningLib') _G.package.loaded.BeamLib = nil local BL = require( 'BeamLib') _G.package.loaded.DiceCut = nil local DC = require( 'DiceCut') _G.package.loaded.FacesBySaw = nil local Fbs = require( 'FacesBySaw') _G.package.loaded.ProcessHeadCut = nil local Hcut= require( 'ProcessHeadCut') _G.package.loaded.ProcessSplit = nil local Split = require( 'ProcessSplit') _G.package.loaded.ProcessCut = nil local Cut = require( 'ProcessCut') _G.package.loaded.ProcessDoubleCut = nil local DoubleCut = require( 'ProcessDoubleCut') _G.package.loaded.ProcessLongCut = nil local LongCut = require( 'ProcessLongCut') _G.package.loaded.ProcessLongDoubleCut = nil local Long2Cut = require( 'ProcessLongDoubleCut') _G.package.loaded.ProcessRidgeLap = nil local RidgeLap = require( 'ProcessRidgeLap') _G.package.loaded.ProcessLapJoint = nil local LapJoint = require( 'ProcessLapJoint') _G.package.loaded.ProcessChamfer = nil local Chamfer = require( 'ProcessChamfer') _G.package.loaded.ProcessDrill = nil local Drill = require( 'ProcessDrill') _G.package.loaded.ProcessTenon = nil local Tenon = require( 'ProcessTenon') _G.package.loaded.ProcessMortise = nil local Mortise = require( 'ProcessMortise') _G.package.loaded.ProcessDtTenon = nil local DtTenon = require( 'ProcessDtTenon') _G.package.loaded.ProcessDtMortise = nil local DtMortise = require( 'ProcessDtMortise') _G.package.loaded.ProcessMark = nil local Mark = require( 'ProcessMark') _G.package.loaded.ProcessText = nil local Text = require( 'ProcessText') _G.package.loaded.ProcessSimpleScarf = nil local Scarf = require( 'ProcessSimpleScarf') _G.package.loaded.ProcessStepJoint = nil local StepJoint = require( 'ProcessStepJoint') _G.package.loaded.ProcessStepJointNotch = nil local StJoNotch = require( 'ProcessStepJointNotch') _G.package.loaded.ProcessProfFront = nil local ProfFront = require( 'ProcessProfFront') _G.package.loaded.ProcessProfConcave = nil local ProfConcave = require( 'ProcessProfConcave') _G.package.loaded.ProcessProfConvex = nil local ProfConvex = require( 'ProcessProfConvex') _G.package.loaded.ProcessProfCamb = nil local ProfCamb = require( 'ProcessProfCamb') _G.package.loaded.ProcessProfHead = nil local ProfHead = require( 'ProcessProfHead') _G.package.loaded.ProcessRoundArch = nil local RoundArch = require( 'ProcessRoundArch') _G.package.loaded.ProcessFreeContour = nil local FreeContour = require( 'ProcessFreeContour') _G.package.loaded.ProcessDecor = nil local Decor = require( 'ProcessDecor') EgtOutLog( ' BeamExec started', 1) ------------------------------------------------------------------------------------------------------------- -- *** Inserimento delle travi nel grezzo *** ------------------------------------------------------------------------------------------------------------- function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) -- Determinazione minimo grezzo scaricabile BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) -- Creazione nuovo gruppo di lavoro local sMgName = EgtGetMachGroupNewName( 'Mach_1') local NewMgId = EgtAddMachGroup( sMgName) if not NewMgId then local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName return false, sOut end -- Impostazione della tavola EgtSetTable( 'Tab') -- Area tavola local b3Tab = EgtGetTableArea() -- Calcolo posizione estremo TR della tavola rispetto a sua origine in BL BD.OriTR = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) -- Impostazione dell'attrezzaggio di default EgtImportSetup() -- Inserimento dei pezzi con il loro grezzo local Cnt = 0 local Len = dRawL local DeltaS = dOvmHead local DeltaE = BD.OVM_MID for i = 1, #vBeam do -- assegno identificativo pezzo local Pz = vBeam[i].Id -- dati del pezzo local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) local b3Solid = vBeam[i].Box if b3Part:isEmpty() or b3Solid:isEmpty() then break end EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3) -- se sezione compatibile e lunghezza disponibile sufficiente local PartLen = b3Solid:getDimX() local PartWidth = b3Solid:getDimY() local PartHeight = b3Solid:getDimZ() local NextLen = Len - DeltaS - PartLen - DeltaE if (( abs( PartWidth - dRawW) < 10 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 10 * GEO.EPS_SMALL) or ( abs( PartHeight - dRawW) < 10 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 10 * GEO.EPS_SMALL)) and NextLen + DeltaE >= 0 then -- eventuale sovramateriale di testa if vBeam[i].PosX then DeltaS = max( vBeam[i].PosX - ( dRawL - Len), 0) end -- dimensioni del grezzo local CrawLen = min( PartLen + DeltaS + DeltaE, Len) local Delta = CrawLen - PartLen - DeltaS -- creo e posiziono il grezzo local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL) EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) -- assegno ordine in lavorazione Cnt = Cnt + 1 EgtSetInfo( nRaw, 'ORD', Cnt) -- creo o pulisco gruppo geometrie aggiuntive if not BL.CreateOrEmptyAddGroup( Pz) then local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) return false, sOut end -- se sovramateriale di testa, aggiungo faccia per taglio iniziale al pezzo if DeltaS > 1. then BL.AddPartStartFace( Pz, b3Solid) EgtSetInfo( nRaw, 'HOVM', DeltaS) end -- aggiungo faccia per taglio finale al pezzo BL.AddPartEndFace( Pz, b3Solid) -- inserisco il pezzo nel grezzo EgtDeselectPartObjs( Pz) local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2) EgtAddPartToRawPart( Pz, ptPos, nRaw) if abs( PartWidth - dRawW) > 10 * GEO.EPS_SMALL then -- rotazione attorno a centro geometria complessiva del pezzo EgtRotatePartInRawPart( Pz, X_AX(), 90) -- correggo per eccentricità solido rispetto a geometria complessiva del pezzo local vtEccOri = b3Solid:getCenter() - b3Part:getCenter() local vtEccRot = Vector3d( vtEccOri) vtEccRot:rotate( X_AX(), 90) EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot)) end -- aggiorno la lunghezza residua della barra Len = Len - CrawLen end -- se rimasto troppo poco grezzo, esco --if Len < BD.MinRaw then break end DeltaS = 0 end -- Se rimasto materiale aggiungo grezzo dell'avanzo if Len > 10 then local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL) EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) -- assegno ordine in lavorazione Cnt = Cnt + 1 EgtSetInfo( nRaw, 'ORD', Cnt) end return true end ------------------------------------------------------------------------------------------------------------- function BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) -- Determinazione minimo grezzo scaricabile if dRawW * dRawH > 40000 then BD.MinRaw = BD.MINRAW_L elseif dRawW * dRawH > 14500 then BD.MinRaw = BD.MINRAW_M else BD.MinRaw = BD.MINRAW_S end end ------------------------------------------------------------------------------------------------------------- -- *** Inserimento delle lavorazioni nelle travi *** ------------------------------------------------------------------------------------------------------------- local function IsHeadFeature( Proc, b3Raw, dCurrOvmH) -- feature sempre di testa o coda per il gruppo if Proc.Grp == 1 or Proc.Grp == 2 then return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) end -- feature sempre di testa o coda nonostante il gruppo if ( Proc.Grp == 3 or Proc.Grp == 4) and ( Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) end -- gestioni speciali if LapJoint.Identify( Proc) then return LapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) end if Drill.Identify( Proc) then return Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) end if RoundArch.Identify( Proc) then return RoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) end if FreeContour.Identify( Proc) then return FreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) end -- non è di testa return false end ------------------------------------------------------------------------------------------------------------- local function IsTailFeature( Proc, b3Raw, dCurrOvmH) -- feature sempre di testa o coda per il gruppo if Proc.Grp == 1 or Proc.Grp == 2 then return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) end -- feature sempre di testa o coda nonostante il gruppo if ( Proc.Grp == 3 or Proc.Grp == 4) and ( Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX() - 0.5 * dCurrOvmH) end -- gestioni speciali if LapJoint.Identify( Proc) then return LapJoint.IsTailFeature( Proc, b3Raw) end if RoundArch.Identify( Proc) then return RoundArch.IsTailFeature( Proc, b3Raw) end if Drill.Identify( Proc) then return Drill.IsTailFeature( Proc, b3Raw) end if FreeContour.Identify( Proc) then return FreeContour.IsTailFeature( Proc, b3Raw) end -- non è di coda return false end ------------------------------------------------------------------------------------------------------------- local function CollectFeatures( PartId, b3Raw, dCurrOvmH) -- recupero le feature local vProc = {} local LayerId = {} LayerId[1] = BL.GetAddGroup( PartId) LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') for nInd = 1, 2 do local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) while ProcId do local nEntType = EgtGetType( ProcId) if nEntType == GDB_TY.SRF_MESH or nEntType == GDB_TY.EXT_TEXT or nEntType == GDB_TY.CRV_LINE or nEntType == GDB_TY.CRV_ARC or nEntType == GDB_TY.CRV_BEZ or nEntType == GDB_TY.CRV_COMPO then local nGrp = EgtGetInfo( ProcId, 'GRP', 'i') local nPrc = EgtGetInfo( ProcId, 'PRC', 'i') local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1 local nCutId = EgtGetInfo( EgtGetParent( EgtGetParent( ProcId)), 'CUTID', 'i') or 0 local nTaskId = EgtGetInfo( ProcId, 'TASKID', 'i') or 0 if nGrp and nPrc and nDo == 1 then local Proc = {} Proc.Id = ProcId Proc.Grp = nGrp Proc.Prc = nPrc Proc.Flg = 1 Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) Proc.Fct = EgtSurfTmFacetCount( ProcId) or 0 Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) Proc.Tail = IsTailFeature( Proc, b3Raw, dCurrOvmH) Proc.Diam = 0 Proc.Fcs = 0 Proc.Fce = 0 Proc.CutId = nCutId Proc.TaskId = nTaskId table.insert( vProc, Proc) -- se foro if Drill.Identify( Proc) then -- assegno diametro Proc.Diam = EgtGetInfo( Proc.Id, 'P12', 'd') or 0 -- assegno faccia di entrata e uscita (dati tabelle sempre per riferimento) Proc.Fcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 Proc.Fce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta if Drill.Split( Proc, b3Raw) then -- aggiorno flag prima parte foro (dati tabelle sempre per riferimento) Proc.Flg = 2 -- definisco dati seconda parte local Proc2 = {} Proc2.Id = ProcId Proc2.Grp = nGrp Proc2.Prc = nPrc Proc2.Flg = -2 Proc2.Box = BBox3d( Proc.Box) Proc2.Fct = Proc.Fct Proc2.Diam = Proc.Diam Proc2.Head = Proc.Head Proc2.Tail = Drill.IsTailFeature( Proc2, b3Raw, dCurrOvmH) Proc2.Fcs = Proc.Fce Proc2.Fce = Proc.Fcs Proc2.CutId = Proc.CutId Proc2.TaskId = Proc.TaskId table.insert( vProc, Proc2) end end end end ProcId = EgtGetNext( ProcId) end end return vProc end ------------------------------------------------------------------------------------------------------------- local function OrderFeatures( vProc, b3Raw) -- funzione di confronto -- secondo centro box in X (taglio di intestazione prima di altri tagli di testa e taglio di separazione però prima di altri tagli di coda) local function CompareFeatures( B1, B2) -- se primo è intestazione va sempre prima if Hcut.Identify( B1) then return true end -- se l'altro è intestazione va sempre prima if Hcut.Identify( B2) then return false end -- se primo è feature di coda e l'altro è separazione o non è feature di coda if B1.Tail and ( Split.Identify( B2) or not B2.Tail) then return false end -- se secondo è feature di coda e l'altro è separazione o non è feature di coda if B2.Tail and ( Split.Identify( B1) or not B1.Tail) then return true end -- se primo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda if abs( B1.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then -- se anche l'altra è lunga, faccio prima quello a Zmax if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then return B1.Box:getMax():getZ() > B2.Box:getMax():getZ() else return B1.Box:getMin():getX() + 50 > B2.Box:getCenter():getX() end end -- se secondo è taglio longitudinale completo o altra lav. lunga, dopo tutte le altre feature non di coda if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 0.2 * b3Raw:getDimX() then return B1.Box:getCenter():getX() > B2.Box:getMin():getX() + 50 end -- se primo è foro e l'altro no, lo penalizzo if B1.Prc == 40 and B2.Prc ~= 40 then return B1.Box:getCenter():getX() > B2.Box:getMax():getX() + 100 end -- se secondo è foro e l'altro no, lo penalizzo if B2.Prc == 40 and B1.Prc ~= 40 then return B1.Box:getMax():getX() + 100 > B2.Box:getCenter():getX() end -- se sono fori e hanno posizione praticamente uguale ordino secondo diametro e faccia di inizio (Fcs) if B1.Prc == 40 and B2.Prc == 40 and abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < 600 then if abs( B1.Diam - B2.Diam) < 1.0 then if B1.Fcs == B2.Fcs then return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() else return B1.Fcs > B2.Fcs end else return ( B1.Diam > B2.Diam) end end -- se entrambi tenoni e si intersecano, metto prima tenone vero e poi base tenone if Tenon.Identify( B1) and Tenon.Identify( B2) and B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then return ( B1.Prc == 50 and B2.Prc == 52) end -- se uno di testa e non l'altro, privilegio questo if B1.Head ~= B2.Head then return B1.Head end -- confronto standard if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) > 0.4 * ( B1.Box:getDimX() + B2.Box:getDimX()) then return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() elseif abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) > 0.4 * ( B1.Box:getDimY() + B2.Box:getDimY()) then return B1.Box:getCenter():getY() > B2.Box:getCenter():getY() else return B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ() end end -- eseguo ordinamento table.sort( vProc, CompareFeatures) -- riunisco fori con lo stesso diametro e non troppo lontani for i = 1, #vProc do local ProcI = vProc[i] if ProcI.Prc == 40 then for j = i + 1, #vProc do local ProcJ = vProc[j] if ProcJ.Prc == 40 and ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and abs( ProcJ.Diam - ProcI.Diam) < 1.0 and abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < 600.0 then if j > i + 1 then local ProcK = vProc[i+1] if ProcK.Prc ~= 40 or abs( ProcK.Diam - ProcJ.Diam) > 1.0 or ProcJ.Box:getCenter():getX() < ProcK.Box:getCenter():getX() then table.insert( vProc, i + 1, table.remove( vProc, j)) end end break end end end end -- riunisco marcature, testi e decori non troppo lontani for i = 1, #vProc do local ProcI = vProc[i] if ProcI.Prc == 60 or ProcI.Prc == 61 or ProcI.Prc == 959 then for j = i + 1, #vProc do local ProcJ = vProc[j] if ( ProcJ.Prc == 60 or ProcJ.Prc == 61 or ProcJ.Prc == 959) and ProcJ.Head == ProcI.Head and ProcJ.Tail == ProcI.Tail and abs( ProcJ.Box:getCenter():getX() - ProcI.Box:getCenter():getX()) < 300.0 then if j > i + 1 then table.insert( vProc, i + 1, table.remove( vProc, j)) end break end end end end end ------------------------------------------------------------------------------------------------------------- local function ClassifyFeatures( vProc, b3Raw, Stats) local bAllOk = true local bSomeDown = false local bSplitRot = false local nHeading local nSplitting for i = 1, #vProc do local Proc = vProc[i] local bOk = true local bDown = false -- se intestatura if Hcut.Identify( Proc) then nHeading = i -- se separazione elseif Split.Identify( Proc) then nSplitting = i -- se taglio elseif Cut.Identify( Proc) then bOk, bDown = Cut.Classify( Proc) -- se doppio taglio elseif DoubleCut.Identify( Proc) then bOk, bDown = DoubleCut.Classify( Proc) -- se taglio longitudinale elseif LongCut.Identify( Proc) then bOk, bDown = LongCut.Classify( Proc) -- se doppio taglio longitudinale elseif Long2Cut.Identify( Proc) then bOk, bDown = Long2Cut.Classify( Proc) -- se mezzo-legno di testa elseif RidgeLap.Identify( Proc) then bOk, bDown = RidgeLap.Classify( Proc) -- se mezzo-legno, fessura, fessura frontale, notch, tasca, tacca elseif LapJoint.Identify( Proc) then bOk, bDown = LapJoint.Classify( Proc) -- se foratura elseif Drill.Identify( Proc) then bOk, bDown = Drill.Classify( Proc, b3Raw) -- se tenone elseif Tenon.Identify( Proc) then bOk, bDown = Tenon.Classify( Proc, b3Raw) -- se mortasa (anche frontale) elseif Mortise.Identify( Proc) then bOk, bDown = Mortise.Classify( Proc) -- se tenone a coda di rondine elseif DtTenon.Identify( Proc) then bOk, bDown = DtTenon.Classify( Proc, b3Raw) -- se mortasa a coda di rondine (anche frontale) elseif DtMortise.Identify( Proc) then bOk, bDown = DtMortise.Classify( Proc) -- se marcatura elseif Mark.Identify( Proc) then bOk, bDown = Mark.Classify( Proc) -- se testo elseif Text.Identify( Proc) then bOk, bDown = Text.Classify( Proc) -- se giunto Gerber elseif Scarf.Identify( Proc) then bOk, bDown = Scarf.Classify( Proc) -- se giunto a gradino elseif StepJoint.Identify( Proc) then bOk, bDown = StepJoint.Classify( Proc) -- se tacca a gradino elseif StJoNotch.Identify( Proc) then bOk, bDown = StJoNotch.Classify( Proc) -- se arco elseif RoundArch.Identify( Proc) then bOk, bDown = RoundArch.Classify( Proc) -- se contorno libero elseif FreeContour.Identify( Proc) then bOk, bDown = FreeContour.Classify( Proc) -- se decorazione elseif Decor.Identify( Proc) then bOk, bDown = Decor.Classify( Proc) end -- assegno risultato if bOk then -- non ammessa feature di testa da lavorare ribaltata if Proc.Head and bDown then Proc.Flg = 0 Proc.Down = true bAllOk = false table.insert( Stats, {Err = 1, Msg='Error : impossible to machine by orientation', CutId=Proc.CutId, TaskId=Proc.TaskId}) -- gestione feature di coda da lavorare ribaltata elseif Proc.Tail and bDown then Proc.Down = true bSomeDown = true bSplitRot = true -- caso normale else Proc.Down = bDown if bDown then bSomeDown = true end end else Proc.Flg = 0 bAllOk = false table.insert( Stats, {Err = 1, Msg='Error : impossible to machine', CutId=Proc.CutId, TaskId=Proc.TaskId}) end end -- se necessario ribaltamento, assegno intestatura alla fase ribaltata if bSomeDown and nHeading then vProc[nHeading].Down = true end -- se necessaria rotazione del ribaltato, assegno separazione alla fase ribaltata if bSplitRot then vProc[nSplitting].Down = true end return bAllOk, bSomeDown, bSplitRot end ------------------------------------------------------------------------------------------------------------- local function PrintFeatures( vProc, b3Raw) EgtOutLog( ' RawBox=' .. tostring( b3Raw)) for i = 1, #vProc do local Proc = vProc[i] local sOut = string.format( ' Proc=%3d Grp=%1d Prc=%3d TC=%2d/%d Flg=%2d Down=%s Head=%s Tail=%s Fcse=%1d,%1d Diam=%.2f Fct=%2d Box=%s', Proc.Id, Proc.Grp, Proc.Prc, Proc.TaskId, Proc.CutId, Proc.Flg, EgtIf( Proc.Down, 'T', 'F'), EgtIf( Proc.Head, 'T', 'F'), EgtIf( Proc.Tail, 'T', 'F'), Proc.Fcs, Proc.Fce, Proc.Diam, Proc.Fct, tostring( Proc.Box)) EgtOutLog( sOut) end end ------------------------------------------------------------------------------------------------------------- local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) local bOk = true local sErr = '' local bNewPhase = false -- se intestatura ( 1-340-X ) if Hcut.Identify( Proc) then -- esecuzione taglio di testa bOk, sErr = Hcut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se separazione ( 2-350-X ) elseif Split.Identify( Proc) then -- esecuzione separazione o eliminazione grezzo residuo bOk, _, sErr = Split.Make( Proc, nPhase, nRawId, nPartId) -- richiedo il passaggio alla seconda fase di lavorazione di questa trave bNewPhase = true -- se taglio ( 1/2-010-X) elseif Cut.Identify( Proc) then -- esecuzione taglio bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se doppio taglio ( 1/2-011-X) elseif DoubleCut.Identify( Proc) then -- se due facce, eseguo doppio taglio if Proc.Fct == 2 then bOk, sErr = DoubleCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- altrimenti eseguo singolo taglio else bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) end -- se taglio longitudinale ( 0/3/4-010-X) elseif LongCut.Identify( Proc) then -- esecuzione taglio longitudinale bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) -- se doppio taglio longitudinale ( 0-012-X) elseif Long2Cut.Identify( Proc) then -- se due facce, eseguo doppio taglio longitudinale if Proc.Fct == 2 then bOk, sErr = Long2Cut.Make( Proc, nPhase, nRawId, nPartId) -- altrimenti eseguo singolo taglio longitudinale else bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) end -- se mezzo-legno di testa ( 1/2-030-X) elseif RidgeLap.Identify( Proc) then -- esecuzione mezzo-legno di testa bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se mezzo-legno ( 3/4-030-X) o scanalatura ( 3/4-016-X) o tacca ( 3/4-020-X) elseif LapJoint.Identify( Proc) then -- esecuzione mezzo-legno o scanalatura bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se smusso ( 3/4-036-X) elseif Chamfer.Identify( Proc) then -- esecuzione smusso bOk, sErr = Chamfer.Make( Proc, nPhase, nRawId, nPartId) -- se foratura ( 3/4-040-X) elseif Drill.Identify( Proc) then -- esecuzione foratura bOk, sErr = Drill.Make( Proc, nPhase, nRawId, nPartId) -- se tenone ( 1/2-050-X) elseif Tenon.Identify( Proc) then -- esecuzione tenone bOk, sErr = Tenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se mortasa ( 3/4-050-X) anche frontale ( 3/4-051-X) elseif Mortise.Identify( Proc) then -- esecuzione mortasa bOk, sErr = Mortise.Make( Proc, nPhase, nRawId, nPartId) -- se tenone a coda di rondine ( 1/2-055-X) elseif DtTenon.Identify( Proc) then -- esecuzione tenone bOk, sErr = DtTenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se mortasa a coda di rondine ( 3/4-055-X) anche frontale ( 3/4-056-X) elseif DtMortise.Identify( Proc) then -- esecuzione mortasa bOk, sErr = DtMortise.Make( Proc, nPhase, nRawId, nPartId) -- se marcatura ( 3/4-060-X) elseif Mark.Identify( Proc) then -- esecuzione marcatura bOk, sErr = Mark.Make( Proc, nPhase, nRawId, nPartId) -- se testo ( 4-061-X) elseif Text.Identify( Proc) then -- esecuzione testo bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId) -- se giunto Gerber ( 1/2-070-X) elseif Scarf.Identify( Proc) then -- esecuzione giunto Gerber bOk, sErr = Scarf.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se giunto a gradino elseif StepJoint.Identify( Proc) then -- esecuzione giunto a gradino bOk, sErr = StepJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se tacca a gradino elseif StJoNotch.Identify( Proc) then -- esecuzione tacca a gradino bOk, sErr = StJoNotch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se profilo Front ( 3/4-100-X) elseif ProfFront.Identify( Proc) then -- esecuzione profilo bOk, sErr = ProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se profilo concavo ( 3/4-101-X) elseif ProfConcave.Identify( Proc) then -- esecuzione profilo bOk, sErr = ProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se profilo convesso ( 3/4-102-X) elseif ProfConvex.Identify( Proc) then -- esecuzione profilo bOk, sErr = ProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se profilo caudato ( 3/4-103-X) elseif ProfCamb.Identify( Proc) then -- esecuzione profilo bOk, sErr = ProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se arco ( 4-104-X) elseif RoundArch.Identify( Proc) then -- esecuzione arco bOk, sErr = RoundArch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se profilo Head ( 3/4-106-X) elseif ProfHead.Identify( Proc) then -- esecuzione profilo bOk, sErr = ProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se contorno libero ( 0/3/4-250-X) elseif FreeContour.Identify( Proc) then -- esecuzione contorno bOk, sErr = FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) -- se decorazione ( 0/3/4-959-X) elseif Decor.Identify( Proc) then -- esecuzione decorazione bOk, sErr = Decor.Make( Proc, nPhase, nRawId, nPartId) -- altrimenti feature sconosciuta else sErr = 'Error on process ' .. tostring( Proc.Id) .. ' unknown type (' .. tonumber( Proc.Grp) .. '-' .. tonumber( Proc.Prc) .. ')' EgtOutLog( sErr) bOk = false end return bOk, sErr, bNewPhase end ------------------------------------------------------------------------------------------------------------- function BeamExec.ProcessFeatures() local nTotErr = 0 local Stats = {} local nOrd = 1 local nRawId = EgtGetFirstRawPart() while nRawId do -- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli local nPartId = EgtGetFirstPartInRawPart( nRawId) if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end -- aggiungo la fase, se non è la prima if nOrd == 1 then EgtSetCurrPhase( 1) else BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) end local nPhase = EgtGetCurrPhase() local nDispId = EgtGetPhaseDisposition( nPhase) EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST')) EgtSetInfo( nDispId, 'ORD', nOrd) EgtOutLog( 'Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId), 1) -- ingombro del grezzo e sovramateriale di testa local b3Raw = EgtGetRawPartBBox( nRawId) local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 -- recupero le feature di lavorazione della trave vProc = CollectFeatures( nPartId, b3Raw, dCurrOvmH) -- le ordino lungo X OrderFeatures( vProc, b3Raw) -- le classifico local bAllOk, bSomeDown, bSplitRot = ClassifyFeatures( vProc, b3Raw, Stats) if not bAllOk then nTotErr = nTotErr + 1 end -- debug if EgtGetDebugLevel() >= 1 then PrintFeatures( vProc, b3Raw) end -- se richiesto ribaltamento if bSomeDown then -- ribalto le travi della fase corrente local nRId = nRawId while nRId do EgtRotateRawPart( nRId, X_AX(), 180) nRId = EgtGetNextRawPart( nRId) end EgtSetInfo( nDispId, 'ROT', -2) -- inserisco le lavorazioni da lavorare ribaltate for i = 1, #vProc do -- creo la lavorazione local Proc = vProc[i] if Proc.Flg ~= 0 and Proc.Down then local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) if not bOk then nTotErr = nTotErr + 1 table.insert( Stats, {Err=1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) elseif sMsg and #sMsg > 0 then table.insert( Stats, {Err=-1, Msg=sMsg, Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) else table.insert( Stats, {Err=0, Msg='', Rot=-2, CutId=Proc.CutId, TaskId=Proc.TaskId}) end -- se era taglio di separazione, aggiungo nuova fase if bNewPhase then BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) EgtRotateRawPart( nRawId, X_AX(), 180) -- se grezzo successivo senza pezzi e finale, va tolto local nNextRawId = EgtGetNextRawPart( nRawId) if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then EgtRemoveRawPartFromCurrPhase( nNextRawId) end nPhase = EgtGetCurrPhase() nDispId = EgtGetPhaseDisposition( nPhase) EgtSetInfo( nDispId, 'TYPE', 'MID2') EgtSetInfo( nDispId, 'ORD', nOrd) EgtSetInfo( nDispId, 'ROT', -2) end end end -- se separazione non ancora effettuata, aggiungo nuova fase con le travi in posizione standard if not bSplitRot then BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) -- altrimenti else BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) -- se grezzo successivo senza pezzi e finale, va tolto local nNextRawId = EgtGetNextRawPart( nRawId) if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then EgtRemoveRawPartFromCurrPhase( nNextRawId) end end nPhase = EgtGetCurrPhase() nDispId = EgtGetPhaseDisposition( nPhase) EgtSetInfo( nDispId, 'TYPE', EgtIf( not bSplitRot, 'MID', 'END2')) EgtSetInfo( nDispId, 'ORD', nOrd) end -- inserisco le lavorazioni non ribaltate della trave for i = 1, #vProc do -- creo la lavorazione local Proc = vProc[i] if Proc.Flg ~= 0 and not Proc.Down then local bOk, sMsg, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) if not bOk then nTotErr = nTotErr + 1 table.insert( Stats, {Err=1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) elseif sMsg and #sMsg > 0 then table.insert( Stats, {Err=-1, Msg=sMsg, Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) else table.insert( Stats, {Err=0, Msg='', Rot=0, CutId=Proc.CutId, TaskId=Proc.TaskId}) end -- se era taglio di separazione, aggiungo nuova fase if bNewPhase then BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) -- se grezzo successivo senza pezzi e finale, va tolto local nNextRawId = EgtGetNextRawPart( nRawId) if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then EgtRemoveRawPartFromCurrPhase( nNextRawId) end nPhase = EgtGetCurrPhase() nDispId = EgtGetPhaseDisposition( nPhase) EgtSetInfo( nDispId, 'TYPE', 'END') EgtSetInfo( nDispId, 'ORD', nOrd) end end end -- passo al grezzo successivo nOrd = nOrd + 1 nRawId = EgtGetNextRawPart( nRawId) end -- Aggiornamento finale di tutto EgtSetCurrPhase( 1) local bApplOk, sApplErrors = EgtApplyAllMachinings() if not bApplOk then nTotErr = nTotErr + 1 table.insert( Stats, {Err = 1, Msg=sApplErrors, Rot=0, CutId=0, TaskId=0}) end return ( nTotErr == 0), Stats end ------------------------------------------------------------------------------------------------------------- return BeamExec