-- ProcessSplit.lua by Egaltech s.r.l. 2023/05/09 -- Gestione calcolo tagli di separazione per Travi -- 2022/05/31 Aggiunta gestione sezioni alte e larghe con taglio con sega a catena seguito da rifinitura con lama (aggiunta funzione MakeSplitByChainSaw); gestione eventuale creazione nuova fase dall'interno della Make. -- 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. -- 2022/09/08 Migliorato verso di lavorazione in caso di DoubleCut -- 2022/11/02 Corretti accorciamenti per DoubleCut -- 2022/11/10 Corrette finiture lama per BigSection con trave alta -- 2022/11/16 Correzioni per travi larghe -- 2022/11/30 Correzione per tagli su grandi sezioni (dopo taglio con sega a catena senza finitura aggiungeva uno split con lama). -- 2023/04/04 Modifiche per travi con sezioni molto grandi e materiale inferiore allo spessore lama. -- 2023/04/20 Per travi alte aggiunti tagli orizzontali per ridurre le dimensioni degli scarti. -- 2023/05/09 Aggiunta richiesta risalita preliminare a Zmax per tagli da sopra su macchine PF e ONE. -- 2023/06/13 Corrette note Precut e Cut per tagli aggiuntivi orizzontali. -- 2023/08/02 Corretto calcolo allungamenti/accorciamenti pezzi alti per contemplare anche taglio singolo. -- 2023/10/17 Corretto calcolo allungamenti/accorciamenti per evitare lunghezze del percorso negative. -- 2024/01/18 Gestita lama con aggregato con asse bloccato per massimizzare capacità di taglio verticale, se da sotto -- Implementato split per pezzi molto alti con mix sega a catena + lama -- Implementata GetBlockedAxis che gestisce gli assi bloccati per tutti i tipi di utensile. -- 2024/01/22 Nei tagli verticali aggiuntivi si usa ora BD.MAX_LEN_DICE come dimensione (era BD.MAX_DIM_DICE). -- 2024/01/23 Nello split con sega a catena ora si cerca di preferenza una lavorazione di tipo 'SawingForSplitting'. Se non trovata si cerca il tipo 'Sawing' come in precedenza. -- In split con sega a catena aggiunta estensione start/end del percorso se utensile lungo, per evitare collisioni con il pezzo durante rotazione. -- Tabella per definizione modulo local ProcessSplit = {} -- Include require( 'EgtBase') local BL = require( 'BeamLib') local Fbs = require( 'FacesBySaw') local Cut = require( 'ProcessCut') local Pocket = require( 'FaceByPocket') local Topology = require( 'FeatureTopology') EgtOutLog( ' ProcessSplit started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') --------------------------------------------------------------------- -- Riconoscimento della feature function ProcessSplit.Identify( Proc) return ( Proc.Grp == 2 and Proc.Prc == 350) 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( nMch1Id, 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( nMch1Id, false) return false, sErr end return true, nil end --------------------------------------------------------------------- -- lavorazione con sega a catena per sezioni alte e larghe local function MakeSplitByChainSaw( nSurfId, sSawing, nFaceUse, dDepth, sNotes, dOffs, bExtendStartEnd) -- Recupero i dati dell'utensile local dMaxMat = 0 local dSawCornerRad = 0 local dSawThick = 0 -- se non trova una lavorazione di sawing esco if not sSawing then local sErr = 'Error : Sawing not found in library' EgtOutLog( sErr) return false, sErr, 'MNF' else -- recupero i dati dell'utensile if EgtMdbSetCurrMachining( sSawing) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad end end end -- inserisco la lavorazione di sawing local sName = 'Csaw_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_1' local nMchFId = EgtAddMachining( sName, sSawing) if not nMchFId then local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing EgtOutLog( sErr) return false, sErr end sName = EgtGetOperationName( nMchFId) -- aggiungo geometria EgtSetMachiningGeometry( {{ nSurfId, 0}}) -- imposto uso del lato faccia EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) -- imposto angolo 3° asse rot EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetBlockedAxis( sSawing, 'perpendicular')) local vtN = EgtSurfTmFacetNormVersor( nSurfId, 0, GDB_ID.ROOT) local vtOrtho = BL.GetVersRef( nFaceUse) EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 1)) -- imposto offset radiale per mantenere il materiale in coda per la finitura EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) -- imposto eventuale allungamento percorso iniziale local dStartAddLen = 0 local dEndAddLen = 0 if bExtendStartEnd then dStartAddLen = 100 dEndAddLen = 100 end EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) -- faccio in modo che l'attacco della lama sia dal lato opposto rispetto al corpo macchina EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) if dMaxMat >= dDepth then EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) -- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning else EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat) sWarn = 'Warning : elevation bigger than max tool depth' EgtOutLog( sWarn) end -- eventuali note if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end -- eseguo if not ML.ApplyMachining( true, false) then if EgtGetOutstrokeInfo() then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end -- impostazione alternativa angolo 3° asse rot EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetBlockedAxis( sSawing, 'parallel')) EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 2)) if not ML.ApplyMachining( true, false) then local _, sErr = EgtGetLastMachMgrError() EgtSetOperationMode( nMchFId, false) return false, sErr end end if EgtIsMachiningEmpty() then _, sWarn = EgtGetMachMgrWarning( 0) EgtSetOperationMode( nMchFId, false) return false, sWarn end --end return true, sName, nMchFId end --------------------------------------------------------------------- -- tagli verticali aggiuntivi local function AddVerticalPreCuts( Proc, sCutting, dCutXOffset, b3Raw, sNotes) local _, dimH = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw) local nVerticalCuts = ceil( dimH / ( BD.MAX_LEN_DICE)) - 1 local dVerticalSliceHeight = dimH / ( nVerticalCuts + 1) -- recupero il diametro dell'utensile local dSawDiam = 400 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam end end local bOk, sErr -- tagli verticali for j = nVerticalCuts, 1, -1 do local nFaceUse = MCH_MILL_FU.PARAL_FRONT local dVerticalCutOffset = dVerticalSliceHeight * -j bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, nFaceUse, nil, -0.1 -dCutXOffset, BD.CUT_SIC, dVerticalCutOffset, 0, 0, sNotes, b3Raw) if not bOk then return bOk, sErr end end return bOk, sErr end --------------------------------------------------------------------- -- Applicazione della lavorazione function ProcessSplit.Make( Proc, nPhase, nRawId, nPartId, nOrd, sDownOrSideOrStd, bPreMove, vtMove, dOvmTail) -- impostazione default a variabili aggiunte if not BD.OVM_CHAIN_HBEAM then BD.OVM_CHAIN_HBEAM = 8 end if not BD.C_SIMM_ENC then BD.C_SIMM_ENC = EgtIf( BD.C_SIMM, 180, 90) end -- 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( 'TailSide') if not sCutting then local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' EgtOutLog( sErr) return false, sErr end -- recupero i dati dell'utensile local dSawDiam = 400 local dSawMaxDepth = 50 local dSawThick = 2 if EgtMdbSetCurrMachining( sCutting) then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam dSawMaxDepth = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick end end local dMaxVertDepth = dSawMaxDepth - ( BD.DECR_VERT_CUT or 0) -- recupero la eventuale lavorazione con lama da sotto local sCutting2 = ML.FindCutting( 'TailSide_H2', false, true) -- recupero i dati della eventuale seconda lama local dSawDiam2 = 0 local dSawMaxDepth2 = 0 local dSawThick2 = 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 dSawMaxDepth2 = EgtTdbGetCurrToolMaxDepth() or dSawMaxDepth2 dSawThick2 = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick2 end end -- caratteristiche taglio local dDimYRef = EgtIf( b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL, dSawMaxDepth, 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 + dSawMaxDepth2) - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) local bHorizCut = ( ( 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 bHorizCut and b3Raw:getDimY() > 2 * dDimYRef - BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) local bDoubleCut = ( 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) -- flag di lavorazione faccia local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_BACK) -- separazione solo se esiste grezzo successivo con pezzi o scaricabile local nNextRawId = EgtGetNextRawPart( nRawId) local bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BD.MinRaw)) -- determino se più tagli con offset local dLenEndRaw = dOvmTail local nCuts = 1 local dOffsL = 0 local _, dimH, dimV = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw) local dMinTailScrapForAdditionalCuts = 10.123 if not bSplit then -- cerco grezzo successivo che sia nella fase if nNextRawId and EgtVerifyRawPartPhase( nNextRawId, nPhase) then local b3NextRaw = EgtGetRawPartBBox( nNextRawId) dLenEndRaw = ptC:getX() - b3NextRaw:getMin():getX() nCuts = ceil( dLenEndRaw / ( EgtIf( bBigSectionCut, BD.MAX_DIM_DICE - 0.1, BD.MAX_LEN_SCRAP + 0.5))) dOffsL = dLenEndRaw / nCuts -- aggiorno ingombro del grezzo corrente con quello del successivo b3Raw:Add( b3NextRaw) end end -- se taglio per pezzi alti e larghi local nNewPhase = 0 if bBigSectionCut then local bFinishingNeeded = false if bSplit then -- recupero dati utensile della sega a catena più lunga a disposizione local sSawing = ML.FindSawing( 'SawingForSplitting', nil, nil, 'Longest') if not sSawing then sSawing = ML.FindSawing( 'Sawing', nil, nil, 'Longest') end local dChainSawMaxMat = 0 local dChainSawLen = 0 if EgtMdbSetCurrMachining( sSawing or '') then local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then dChainSawMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dChainSawMaxMat dChainSawLen = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dChainSawLen end end local bigSectionSplitType -- se pezzo non troppo alto, taglio singolo da sopra if b3Raw:getDimZ() + BD.CUT_EXTRA_MIN < dChainSawMaxMat + 10 * GEO.EPS_SMALL then bigSectionSplitType = "single horizontal" -- se pezzo non troppo largo, taglio singolo da davanti elseif b3Raw:getDimY() + BD.CUT_EXTRA_MIN < min( dChainSawMaxMat, dChainSawLen - BD.C_SIMM_ENC) + 10 * GEO.EPS_SMALL then bigSectionSplitType = "single vertical" -- se pezzo non troppo largo, tagli dai due fianchi (dietro e davanti) elseif 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN < min( dChainSawMaxMat, dChainSawLen - BD.C_SIMM_ENC) + 10 * GEO.EPS_SMALL then bigSectionSplitType = "double vertical" -- altrimenti taglio con sega a catena da sopra e con lama da sotto elseif BD.DOWN_HEAD and ( b3Raw:getDimZ() + BD.CUT_EXTRA_MIN < dSawMaxDepth2 + dChainSawMaxMat + 10 * GEO.EPS_SMALL) then bigSectionSplitType = "double horizontal" end -- assegno offset in lunghezza local dOffs = 0 if dOvmTail > BD.OVM_CHAIN_HBEAM then dOffs = dOvmTail - BD.OVM_CHAIN_HBEAM bFinishingNeeded = true end -- in base alle scelte precedenti, applico le lavorazioni if bigSectionSplitType == "single horizontal" then local dCutDepth = b3Raw:getDimZ() + BD.CUT_EXTRA_MIN local sNotesSplit = 'Split;' -- verifico se sega a catena lunga e devo quindi estendere ingresso e uscita perchè è probabile che non riesca a ruotare sopra al pezzo local bExtendStartEnd local dMinLengthLongChainSaw = 630 if dChainSawLen > dMinLengthLongChainSaw - 10 * GEO.EPS_SMALL then bExtendStartEnd = true end local bOk, sErr = MakeSplitByChainSaw( Proc.Id, sSawing, MCH_MILL_FU.PARAL_TOP, dCutDepth, sNotesSplit, dOffs, bExtendStartEnd) if not bOk then return bOk, sErr, nNewPhase end elseif bigSectionSplitType == "single vertical" then local dCutDepth = b3Raw:getDimY() + BD.CUT_EXTRA_MIN local sNotesSplit = 'Split;' local bOk, sErr = MakeSplitByChainSaw( Proc.Id, sSawing, MCH_MILL_FU.PARAL_FRONT, dCutDepth, sNotesSplit, dOffs) if not bOk then return bOk, sErr, nNewPhase end elseif bigSectionSplitType == "double vertical" then local dCutDepth = 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN local sNotesSplit = 'Presplit;' local bOk, sErr = MakeSplitByChainSaw( Proc.Id, sSawing, MCH_MILL_FU.PARAL_BACK, dCutDepth, sNotesSplit, dOffs) if not bOk then return bOk, sErr, nNewPhase end sNotesSplit = 'Split;' bOk, sErr = MakeSplitByChainSaw( Proc.Id, sSawing, MCH_MILL_FU.PARAL_FRONT, dCutDepth, sNotesSplit, dOffs) if not bOk then return bOk, sErr, nNewPhase end elseif bigSectionSplitType == "double horizontal" then -- sega a catena da sopra local dChainSawCutDepth = b3Raw:getDimZ() + BD.CUT_EXTRA_MIN - dSawMaxDepth2 local sNotesSplit = 'Presplit;' local bOk, sErr = MakeSplitByChainSaw( Proc.Id, sSawing, MCH_MILL_FU.PARAL_TOP, dChainSawCutDepth, sNotesSplit, dOffs) if not bOk then return bOk, sErr, nNewPhase end -- lama da sotto local dCutExtra = -dChainSawCutDepth + BD.CUT_EXTRA_MIN local dVzLimDwnUp if BD.TURN then dVzLimDwnUp = -2 end local sNotes = 'Split;' local bMaximizeVerticalDepth = true bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting2, dSawDiam2, MCH_MILL_FU.ORTHO_TOP, dVzLimDwnUp, dCutExtra, BD.CUT_SIC, dOffs, 0, 0, sNotes, b3Raw, nil, bMaximizeVerticalDepth) if not bOk then return false, sErr end -- se è comunque troppo grande per essere separato, esco else local sErr = 'Error : section too big for splitting' EgtOutLog( sErr) return false, sErr, -1 end -- se necessaria finitura, creo nuova fase if bFinishingNeeded then BL.AddPhaseWithRawParts( nRawId, BD.OriXR, BD.PosXR, BD.RAW_OFFSET) nNewPhase = EgtGetCurrPhase() local nDispId = EgtGetPhaseDisposition( nNewPhase) if sDownOrSideOrStd == 'down' then EgtRotateRawPart( nRawId, X_AX(), 180) EgtSetInfo( nDispId, 'TYPE', 'MID2') EgtSetInfo( nDispId, 'ROT', -2) elseif sDownOrSideOrStd == 'side' then if bPreMove then EgtMoveRawPart( nRawId, vtMove) end EgtRotateRawPart( nRawId, X_AX(), EgtIf( BD.RIGHT_LOAD, -90, 90)) if not bPreMove then EgtMoveRawPart( nRawId, vtMove) end EgtSetInfo( nDispId, 'TYPE', 'MID2') EgtSetInfo( nDispId, 'ROT', -1) else EgtSetInfo( nDispId, 'TYPE', 'END') end EgtSetInfo( nDispId, 'ORD', nOrd) -- 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 end -- se è necessaria la finitura if bFinishingNeeded or not bSplit then local sNotes, sNotesFinal -- se non c'è separazione va aggiunta la nota Cut per l'ultimo taglio e Precut per i tagli precedenti if not bSplit then sNotes = 'Precut;' sNotesFinal = 'Cut;' end local nQ05 = EgtGetInfo( nOriId or GDB_ID.NULL, 'Q05', 'i') or 0 -- determinazione materiale da asportare local dSawThickCheck = dSawThick if dSawThick2 > 0 and bDoubleHorizCut then dSawThickCheck = min( dSawThick, dSawThick2) end local dMaxElev = 0 if vtN:getX() > 0 then dMaxElev = b3Raw:getMax():getX() - Proc.Box:getMin():getX() else dMaxElev = Proc.Box:getMax():getX() - b3Raw:getMin():getX() end -- se finitura con lama if nQ05 < 2 or ( not bSplit and dMaxElev > dSawThickCheck) then -- controllo se è necessario un taglio con dicing o si deve proseguire ai casi standard if bSplit or dMaxElev > dSawThickCheck then local bOk, sErr if not bSplit and ( dimH > BD.MAX_LEN_DICE) and ( dLenEndRaw > dMinTailScrapForAdditionalCuts - 10 * GEO.EPS_SMALL) then -- ad ogni offset di taglio dovrò fare prima i tagli verticali e poi i cubetti for i = nCuts, 1, -1 do local nAddGrpId = BL.GetAddGroup( Proc.PartId) -- faccia di taglio all'offset corrente local AddId = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL local AddProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, PartId = Proc.PartId} Topology.Classify( AddProc, b3Raw) local dCutOffset = ( i - 1) * dOffsL local vtMoveSurf = Vector3d( -dCutOffset, 0, 0) EgtMove( AddId, vtMoveSurf, GDB_RT.GLOB) -- eventuale faccia di taglio all'offset precedente, per limitare il dicing e evitare di tagliare i cubetti nel vuoto local nLimitingSurf if nCuts > 1 then nLimitingSurf = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL local dLastCutOffset = i * dOffsL local vtMoveLimitingSurf = Vector3d( -dLastCutOffset + 10 * GEO.EPS_SMALL, 0, 0) EgtMove( nLimitingSurf, vtMoveLimitingSurf, GDB_RT.GLOB) local vtNLimitingSurf = EgtSurfTmFacetNormVersor( nLimitingSurf, 0) if AreOppositeVectorApprox( X_AX(), vtNLimitingSurf) then EgtInvertSurf( nLimitingSurf) end end -- tagli verticali bOk, sErr = AddVerticalPreCuts( AddProc, sCutting, 0, b3Raw, sNotes) if not bOk then return bOk, sErr end -- tagli a cubetti con eventuale superficie limitante bOk, sErr = Cut.Make( AddProc, nNewPhase, nRawId, nPartId, dMaxElev, nil, false, true, b3Raw, sNotes, dCurrOvmT, nil, nLimitingSurf) end -- tagli aggiuntivi non necessari else bOk, sErr = Cut.Make( Proc, nNewPhase, nRawId, nPartId, dMaxElev, nil, false, true, b3Raw, sNotes, dCurrOvmT) end if sNotesFinal then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotesFinal) end return bOk, sErr, nNewPhase end -- se finitura con truciolatore elseif nQ05 == 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, dTDiam = ML.FindPocketing( 'OpenPocket', nil, 0) if not sPocketing then local sErr = 'Error : pocketing not found in library' EgtOutLog( sErr) return false, sErr end local dOpenMinSafe if BD.C_SIMM and b3Raw:getDimZ() > 600 then dOpenMinSafe = 230 - dTDiam / 2 end local bOk, sErr = Pocket.Make( Proc, Proc.Id, 0, sPocketing, nPartId, b3Solid, dOpenMinSafe) if sNotesFinal then local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) .. sNotesFinal EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end return bOk, sErr, nNewPhase end else return true, nil, nNewPhase end end -- se tagli standard if not bDoubleHorizCut then -- calcolo extra taglio ed accorciamento local dCutExtra = 0 local dAccStart = 0 local dAccEnd = 0 if bBigSectionCut and BD.C_SIMM then -- qui arrivano sezioni molto grandi su macchine tipo PF con materiale da asportare inferiore allo spessore lama local dSawRad = dSawDiam / 2 dCutExtra = - ( b3Raw:getDimY() - dSawRad) dAccEnd = dSawRad elseif 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() - dSawMaxDepth) local dSawRad = dSawDiam / 2 -- distanza in Y tra il centro della lama e l'intersezione tra la lama stessa e la massima Z della trave, + extra -- se taglio doppio l'intersezione sarà in mezzeria, se taglio singolo sarà all'estremo opposto della trave local dKL = dSawRad - dSawMaxDepth + EgtIf( bDoubleCut, b3Raw:getDimY() / 2 + BD.CUT_EXTRA_MIN, b3Raw:getDimY() + BD.CUT_EXTRA) -- lunghezza minima del percorso di lavorazione, in caso accorciamento porti a lunghezza negativa local dMinSawingLength = 5 if BD.C_SIMM then dAccEnd = sqrt( max( dSawRad * dSawRad - dKL * dKL, 0)) -- non posso comunque accorciare più della dimensione della geometria, quindi in caso allungo entrata if dAccEnd > b3Raw:getDimZ() - 100 * GEO.EPS_SMALL then dAccStart = b3Raw:getDimZ() - dAccEnd - dMinSawingLength end else dAccStart = sqrt( max( dSawRad * dSawRad - dKL * dKL, 0)) -- non posso comunque accorciare più della dimensione della geometria, quindi in caso allungo uscita if dAccStart > b3Raw:getDimZ() - 100 * GEO.EPS_SMALL then dAccEnd = b3Raw:getDimZ() - dAccStart - dMinSawingLength end end end -- per travi alte faccio faccio dei tagli orizzontali aggiuntivi local bAreHorizontalCutsNeeded = not bSplit and ( dimV > BD.MAX_LEN_DICE) and not bBigSectionCut and ( dLenEndRaw > dMinTailScrapForAdditionalCuts - 10 * GEO.EPS_SMALL) if bAreHorizontalCutsNeeded then local nHorizontalCuts = ceil ( dimV / BD.MAX_DIM_DICE) - 1 local dHorizontalSliceHeight = dimV / ( nHorizontalCuts + 1) for i = nCuts, 1, -1 do local dCutXOffset = ( i - 1) * dOffsL -- tagli orizzontali for j = nHorizontalCuts, 1, -1 do local nFaceUse = MCH_MILL_FU.PARAL_DOWN local dHorizontalCutOffset = dHorizontalSliceHeight * -j local bOk, sErr = Fbs.MakeOne( Proc.Id, 0 , sCutting, dSawDiam, nFaceUse, nil, -0.1 - dCutXOffset, BD.CUT_SIC, dHorizontalCutOffset, 0, 0, 'Precut;', b3Raw) if not bOk then return false, sErr end end -- se necessario taglio verticale doppio, eseguo l'opposto if bDoubleCut then -- gli accorciamenti vanno invertiti per il taglio opposto local dAccStartDoubleCut, dAccEndDoubleCut = dAccEnd, dAccStart local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_FRONT, nil, dCutExtra, BD.CUT_SIC, dCutXOffset, dAccStartDoubleCut, dAccEndDoubleCut, 'Precut;', b3Raw, true) if not bOk then return false, sErr end end -- taglio verticale local sInfo = 'PreCut;' if i == 1 then sInfo = 'Cut;' end local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutXOffset, dAccStart, dAccEnd, sInfo, b3Raw) if not bOk then return false, sErr end end return true, sWarn, nNewPhase end -- se necessari tagli in doppio, eseguo gli opposti if bDoubleCut then -- gli accorciamenti vanno invertiti per il taglio opposto local dAccStartDoubleCut, dAccEndDoubleCut = dAccEnd, dAccStart for i = nCuts, 1, -1 do local dCutOffset = ( i - 1) * dOffsL local sNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_FRONT, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStartDoubleCut, dAccEndDoubleCut, sNotes, b3Raw, true) 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 -- se trave larga effettuo tagli verticali aggiuntivi if not bSplit and ( dimH > BD.MAX_LEN_DICE) and ( dLenEndRaw > dMinTailScrapForAdditionalCuts - 10 * GEO.EPS_SMALL) then local sSpecNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') local bOk, sErr = AddVerticalPreCuts( Proc, sCutting, dCutOffset, b3Raw, sSpecNotes) if not bOk then return bOk, sErr end end local sNotes if bSplit then sNotes = EgtIf( i == 1, 'Split;', 'Presplit;') else sNotes = EgtIf( i == 1, 'Cut;', 'Precut;') end -- se primo taglio da sopra e PF o ONE richiedo risalita preliminare a Zmax if i == nCuts and bHorizCut and BD.C_SIMM and not BD.DOWN_HEAD then sNotes = EgtSetValInNotes( sNotes, 'StartZmax', 2) end local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, sNotes, 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 + dSawMaxDepth2 - dDimZ if ( dExtra - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL < 0) and not bBigSectionCut then local sErr = 'Error : section too big for tail cut' EgtOutLog( sErr) return false, sErr end -- calcolo extra taglio ed accorciamento local dCutExtra = -dSawMaxDepth2 + dExtra / 2 + BD.CUT_EXTRA_MIN local dCutExtra2 = -dMaxVertDepth + dExtra / 2 + BD.CUT_EXTRA_MIN local dAccStart = 0 -- limiti da sotto 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 sNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting2, dSawDiam2, MCH_MILL_FU.ORTHO_TOP, dVzLimDwnUp, dCutExtra2, BD.CUT_SIC, dCutOffset, dAccStart, 0, sNotes, b3Raw, nil, true) 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 -- se trave larga effettuo tagli verticali aggiuntivi if not bSplit and ( dimH > BD.MAX_LEN_DICE) and ( dLenEndRaw > dMinTailScrapForAdditionalCuts - 10 * GEO.EPS_SMALL) then local sSpecNotes = EgtIf( bSplit, 'Presplit;', 'Precut;') local bOk, sErr = AddVerticalPreCuts( Proc, sCutting, dCutOffset, b3Raw, sSpecNotes) if not bOk then return bOk, sErr end end local sNotes if bSplit then sNotes = EgtIf( i == 1, 'Split;', 'Presplit;') else sNotes = EgtIf( i == 1, 'Cut;', 'Precut;') end local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_DOWN, dVzLimDwnUp, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, 0, sNotes, b3Raw) if not bOk then return false, sErr end end end return true, nil, nNewPhase end --------------------------------------------------------------------- return ProcessSplit