-- ProcessSplit.lua by Egaltech s.r.l. 2022/08/18 -- Gestione calcolo tagli di testa per Travi -- 2022/05/31 Aggiunta gestione sezioni alte e larghe con taglio di tipo diceCut. -- 2022/06/10 Per sezioni alte e larghe aggiunta gestione finitura in base a sovramateriale e a parametro Q05 dell' eventuale lavorazione sostituita. -- 2022/08/18 Aggiunta gestione macchine con testa da sotto con lama da sotto disabilitata. -- Tabella per definizione modulo local ProcessHeadCut = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local Fbs = require( 'FacesBySaw') local Cut = require( 'ProcessCut') local Pocket = require( 'FaceByPocket') EgtOutLog( ' ProcessHeadCut started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessHeadCut.Identify( Proc) return ( Proc.Grp == 1 and Proc.Prc == 340) end --------------------------------------------------------------------- -- verifica curva per smusso (-1=errore curva, 0=estrusione non va bene, 1=ok) local function VerifyCurveForChamfer( AuxId) if not AuxId then return -2 end if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then return -1 end local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- va bene solo se direzione estrusione orizzontale if abs( vtExtr:getZ()) > 0.1 then return 0 end return 1 end --------------------------------------------------------------------- -- lavorazione smussi local function MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) -- verifico che lo smusso sia richiesto local dDepth = EgtGetInfo( nOriId, 'Q06', 'd') or 0 if dDepth < 0.1 then return true end -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- recupero e verifico le entità curva associate (max 2) local sVal = EgtGetInfo( nOriId, 'AUXID') local vsAuxId = EgtSplitString( sVal) local AuxId, Aux2Id if vsAuxId and #vsAuxId >=1 then AuxId = tonumber( vsAuxId[1]) end if vsAuxId and #vsAuxId >=2 then Aux2Id = tonumber( vsAuxId[2]) end if AuxId then AuxId = AuxId + nOriId end if Aux2Id then Aux2Id = Aux2Id + nOriId end local nRes = VerifyCurveForChamfer( AuxId) if nRes == 0 and Aux2Id then AuxId = Aux2Id nRes = VerifyCurveForChamfer( AuxId) end if nRes == -2 then return true end if nRes == -1 then local sErr = 'Error : missing profile geometry' EgtOutLog( sErr) return false, sErr end if nRes == 0 then local sWarn = 'Warning : skipped not horizontal chamfer' EgtOutLog( sWarn) return true end -- recupero i dati della curva e del profilo local dWidth = abs( EgtCurveThickness( AuxId)) local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) -- eseguo lo smusso solo se feature larga come la trave if dWidth < b3Raw:getDimY() - 1 then local sWarn = 'Warning : skipped chamfer (feature smaller than beam)' EgtOutLog( sWarn) return true, sWarn end local dExtra = 2 -- recupero la lavorazione local sMilling = ML.FindMilling( 'Mark') if not sMilling then local sErr = 'Error : milling not found in library' EgtOutLog( sErr) return false, sErr end -- Inserisco la lavorazione del lato standard local sName1 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMch1Id = EgtAddMachining( sName1, sMilling) if not nMch1Id then local sErr = 'Error adding machining ' .. sName1 .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) -- assegno lato di lavoro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr end -- Inserisco la lavorazione del lato opposto local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) local nMch2Id = EgtAddMachining( sName2, sMilling) if not nMch2Id then local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling EgtOutLog( sErr) return false, sErr end -- aggiungo geometria EgtSetMachiningGeometry( {{ AuxId, -1}}) -- inverto direzione utensile EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra) EgtSetMachiningParam( MCH_MP.OFFSR, dExtra) -- assegno lato di lavoro EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) -- eseguo if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchId, false) return false, sErr end return true, nil end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessHeadCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bNeedHCut) -- ingombro del grezzo local b3Raw = EgtGetRawPartBBox( nRawId) -- inserimento smussi local nOriId = EgtGetInfo( Proc.Id, 'ORI', 'i') if nOriId then local bOkc, sErrC = MakeChamfer( nOriId, Proc, nPhase, nRawId, nPartId, dOvmHead) if not bOkc then return bOkc, sErrC end end -- recupero la lavorazione local sCutting = ML.FindCutting( 'HeadSide') if not sCutting then local sErr = 'Error : cutting not found in library' EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile local dSawDiam = 400 local dMaxDepth = 50 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth end end local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0) -- recupero la eventuale lavorazione con lama da sotto local sCutting2 = ML.FindCutting( 'HeadSide_H2', false, true) -- recupero i dati della eventuale seconda lama local dSawDiam2 = 0 local dMaxDepth2 = 0 if sCutting2 and EgtMdbSetCurrMachining( sCutting2) then local sTuuid2 = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid2) or '') then dSawDiam2 = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam2 dMaxDepth2 = EgtTdbGetCurrToolMaxDepth() or dMaxDepth2 end end -- caratteristiche taglio local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dMaxDepth, abs( BD.MAX_DIM_HTCUT_HBEAM)) local bBigSectionCut = ( b3Raw:getDimY() > 2 * dDimYRef - BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) and ( b3Raw:getDimZ() > EgtIf( BD.TURN, 2 * dMaxVertDepth, dMaxVertDepth + dMaxDepth2) - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) local bHorizCut = ( not bBigSectionCut and ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL or BD.TURN) and b3Raw:getDimZ() < dMaxVertDepth - BD.CUT_EXTRA) local bDoubleHorizCut = ( ( BD.DOWN_HEAD or BD.TURN) and not bBigSectionCut and not bHorizCut and b3Raw:getDimY() > 2 * dDimYRef - BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) local bDoubleCut = ( not bBigSectionCut and not bHorizCut and not bDoubleHorizCut and b3Raw:getDimY() > dDimYRef - BD.CUT_EXTRA + 10 * GEO.EPS_SMALL) -- dati geometrici del taglio local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) -- se non obbligatorio e coincide con inizio grezzo, non va fatto if not bNeedHCut and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then return true end -- determino se più tagli con offset local nCuts = max( ceil( dOvmHead / ( BD.MAX_LEN_SCRAP_START or BD.MAX_LEN_SCRAP)), 1) local dOffsL = dOvmHead / nCuts -- se taglio per sezioni alte e larghe if bBigSectionCut then if dOvmHead > 0 then -- se finitura con lama if not nOriId or EgtGetInfo( nOriId, 'Q05', 'i') == 1 or EgtGetInfo( nOriId, 'Q05', 'i') == 0 then local bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, nil, false, true, nil, nil, dCurrOvmT) if not bOk then return bOk, sErr end -- se finitura con truciolatore elseif EgtGetInfo( nOriId, 'Q05', 'i') == 2 then local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) if not b3Solid then local sErr = 'Error : part box not found' EgtOutLog( sErr) return false, sErr end local sPocketing = ML.FindPocketing( 'OpenPocket', nil, 0) if not sPocketing then local sErr = 'Error : pocketing not found in library' EgtOutLog( sErr) return false, sErr end local bOk, sErr = Pocket.Make( Proc, Proc.Id, 0, sPocketing, nPartId, b3Solid) if not bOk then return bOk, sErr end end end -- se tagli standard elseif not bDoubleHorizCut then -- flag di lavorazione faccia local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) -- calcolo extra taglio ed accorciamento local dCutExtra = 0 local dAccStart = 0 local dAccEnd = 0 if b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL or b3Raw:getDimY() < 2 * BD.MAX_DIM_HTCUT_HBEAM + 10 * GEO.EPS_SMALL then dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) else dCutExtra = - ( b3Raw:getDimY() - dMaxDepth) local dSawRad = dSawDiam / 2 local dKL = dSawRad - dMaxDepth + b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN if BD.C_SIMM then dAccEnd = sqrt( dSawRad * dSawRad - dKL * dKL) else dAccStart = sqrt( dSawRad * dSawRad - dKL * dKL) end end -- se necessari tagli in doppio, eseguo gli opposti if bDoubleCut then for i = nCuts, 1, -1 do local dCutOffset = ( i - 1) * dOffsL local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, '', b3Raw) if not bOk then return false, sErr end end end -- eseguo i tagli necessari for i = nCuts, 1, -1 do local dCutOffset = ( i - 1) * dOffsL local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, '', b3Raw) if not bOk then return false, sErr end end -- altrimenti necessari tagli da sopra e sotto con testa opportuna else -- verifico esistenza della lavorazione con lama da sotto if not sCutting2 then local sErr = 'Error : cutting H2 not found in library' EgtOutLog( sErr) return false, sErr end -- verifico che le due lame riescano a lavorare la sezione local dDimZ = b3Raw:getDimZ() local dExtra = dMaxVertDepth + dMaxDepth2 - dDimZ if dExtra - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL < 0 then local sErr = 'Error : section too big for head cut' EgtOutLog( sErr) return false, sErr end -- calcolo extra taglio ed accorciamento local dCutExtra = -dMaxDepth2 + dExtra / 2 + BD.CUT_EXTRA_MIN local dCutExtra2 = -dMaxVertDepth + dExtra / 2 + BD.CUT_EXTRA_MIN local dAccStart = 0 local dVzLimDwnUp if BD.TURN then dVzLimDwnUp = -2 end -- eseguo i tagli da sotto necessari for i = nCuts, 1, -1 do local dCutOffset = ( i - 1) * dOffsL local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting2, dSawDiam2, MCH_MILL_FU.ORTHO_TOP, dVzLimDwnUp, dCutExtra2, BD.CUT_SIC, dCutOffset, dAccStart, 0, '', b3Raw) if not bOk then return false, sErr end end -- eseguo i tagli da sopra necessari for i = nCuts, 1, -1 do local dCutOffset = ( i - 1) * dOffsL local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_DOWN, dVzLimDwnUp, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, 0, '', b3Raw) if not bOk then return false, sErr end end end return true end --------------------------------------------------------------------- return ProcessHeadCut