-- ProcessSplit.lua by Egaltech s.r.l. 2022/09/26 -- 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. -- 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 -- 2023/04/20 Per travi alte aggiunti tagli orizzontali per ridurre le dimensioni degli scarti -- 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 Gestiti tagli verticali aggiuntivi per travi larghe. -- 2024/01/22 Nei tagli verticali aggiuntivi si usa ora BD.MAX_LEN_DICE come dimensione (era BD.MAX_DIM_DICE). -- 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') local Topology = require( 'FeatureTopology') local Split = require( 'ProcessSplit') EgtOutLog( ' ProcessHeadCut started', 1) -- Dati local BD = require( 'BeamData') local ML = require( 'MachiningLib') if BD.PRECUT_HEAD == nil then BD.PRECUT_HEAD = true end --------------------------------------------------------------------- -- 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( 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 --------------------------------------------------------------------- -- smussi in testa local function MakeHeadChamfer( idProc, nPartId) local dDepthHeadChamfer = EgtGetInfo( idProc, 'Q08', 'd') or 0 -- se non attivo esco subito if dDepthHeadChamfer < 100 * GEO.EPS_SMALL then return end -- recupero gruppo per geometria aggiuntiva local AddGrpId = BL.GetAddGroup( nPartId) if not AddGrpId then local sErr = 'Error on process StartFace impossible to find AddGroup' EgtOutLog( sErr) return false, sErr end -- 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 local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( idProc, 0, AddGrpId) if not nLoopId or nLoopCnt > 1 then local sErr = 'Error MakeHeadChamfer : too many loops' EgtOutLog( sErr) return false, sErr end -- setto direzione estrusione corretta EgtModifyCurveExtrusion( nLoopId, X_AX()) EgtSetGridFrame( Frame3d( 0,0,0, GDB_FR.RIGHT)) local dQ09Value = EgtGetInfo( idProc, 'Q09', 'd') if not dQ09Value then dQ09Value = 0.1 end local bChamferedEdge = dQ09Value > 0 dQ09Value = EgtIf( bChamferedEdge, max( dQ09Value, 0.1), min( dQ09Value, -0.1)) local nIdFirstEntity, nEntityCnt = EgtExplodeCurveCompo( nLoopId) local p3MidPoint = EgtMP( nIdFirstEntity, GDB_ID.GRID) for i = 0, nEntityCnt - 1 do if EgtCurveLength( nIdFirstEntity + i) - 10 < abs( dQ09Value) * 2 then local sErr = 'Error MakeHeadChamfer : Q09 too high' EgtOutLog( sErr) return false, sErr end end -- creo raccordo o fillet for i = 0, nEntityCnt - 1 do local idFirst = nIdFirstEntity + i local idSecond = EgtIf( i == nEntityCnt - 1, nIdFirstEntity, idFirst + 1) local ptEndPointFirst = EgtEP( idFirst, GDB_ID.GRID) - ( abs( dQ09Value) * EgtEV( idFirst, GDB_ID.GRID)) local ptStartPointSecond = EgtSP( idSecond, GDB_ID.GRID) + ( abs( dQ09Value) * EgtEV( idSecond, GDB_ID.GRID)) if bChamferedEdge then EgtCurveChamfer( AddGrpId, idFirst, ptEndPointFirst, idSecond, ptStartPointSecond, abs( dQ09Value), true, GDB_RT.GRID) else EgtCurveFillet( AddGrpId, idFirst, ptEndPointFirst, idSecond, ptStartPointSecond, abs( dQ09Value), true, GDB_RT.GRID) end end EgtSelectPathObjs( nIdFirstEntity, true) local idGeom, idGeomCnt = EgtCurveCompoByChain( AddGrpId, GDB_ID.SEL, {0,0,0}, true) if not idGeom or idGeomCnt > 1 then local sErr = 'Error MakeHeadChamfer : too many loops' EgtOutLog( sErr) return false, sErr end EgtChangeClosedCurveStartPoint( idGeom, p3MidPoint, GDB_RT.GRID) -- reimposto la griglia EgtSetGridFrame() -- Inserisco la lavorazione del lato standard local dExtra = 2 local sName1 = 'HeadCham_' .. ( EgtGetName( idProc) or tostring( idProc)) 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( {{ idGeom, -1}}) -- assegno affondamento e offset radiale EgtSetMachiningParam( MCH_MP.DEPTH, dDepthHeadChamfer + 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 return true, nil end --------------------------------------------------------------------- -- tagli verticali aggiuntivi local function AddVerticalPreCuts( Proc, sCutting, dCutXOffset, b3Raw, dOffsetBetweenCuts) local nVerticalCuts = ceil( Proc.Face[1].WidthTrimmed / ( BD.MAX_LEN_DICE)) - 1 local dVerticalSliceHeight = Proc.Face[1].WidthTrimmed / ( 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 orizzontali for j = nVerticalCuts, 1, -1 do local nFaceUse = MCH_MILL_FU.PARAL_FRONT local dVerticalCutOffset = dVerticalSliceHeight * -j local sLeadInOutType = 'PerpendicularOutraw' bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, nFaceUse, nil, -0.1 -dCutXOffset, BD.CUT_SIC, dVerticalCutOffset, 0, 0, '', b3Raw, nil, nil, nil, sLeadInOutType, nil, dOffsetBetweenCuts) if not bOk then return bOk, sErr end end return bOk, sErr end --------------------------------------------------------------------- -- tagli standard local function MakeStandardCuts( Proc, b3Raw, nCuts, dOffsetBetweenCuts, HeadCutType, Cutting1Data, Cutting2Data, dStartOffset, dOvmHead) local PrecutType = { bBigSectionCut = HeadCutType.bBigSectionCut, bHorizCut = HeadCutType.bHorizCut, bDoubleHorizCut = HeadCutType.bDoubleHorizCut, bDoubleCut = HeadCutType.bDoubleCut, sType = 'Precut', bNeedVerticalAddedCuts = false, bNeedHorizontalAddedCuts = false} if not HeadCutType.bDoubleHorizCut then -- flag di lavorazione faccia local nOrthoOpposite = EgtIf( HeadCutType.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( HeadCutType.bDoubleCut, - 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN, BD.CUT_EXTRA) else dCutExtra = - ( b3Raw:getDimY() - Cutting1Data.dMaxDepth) local dSawRad = Cutting1Data.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 - Cutting1Data.dMaxDepth + EgtIf( HeadCutType.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 dei tagli orizzontali aggiuntivi if HeadCutType.bNeedHorizontalAddedCuts then -- taglio a zero (con lama) per evitare problemi con grezzo più lungo del previsto. Se BigSection il pretaglio è già stato fatto. if not ( HeadCutType.bBigSectionCut) and BD.PRECUT_HEAD then dStartOffset = dOvmHead local bOkPrecut, sErrPrecut = MakeStandardCuts( Proc, b3Raw, 1, 0, PrecutType, Cutting1Data, Cutting2Data, dStartOffset) if not bOkPrecut then return false, sErrPrecut end end local nHorizontalCuts = ceil( Proc.Face[1].HeightTrimmed / BD.MAX_DIM_DICE) - 1 local dHorizontalSliceHeight = Proc.Face[1].HeightTrimmed / ( nHorizontalCuts + 1) for i = nCuts, 1, -1 do local dCutXOffset = ( i - 1) * dOffsetBetweenCuts -- tagli orizzontali for j = nHorizontalCuts, 1, -1 do local nFaceUse = MCH_MILL_FU.PARAL_DOWN local dHorizontalCutOffset = dHorizontalSliceHeight * -j local sLeadInOutType = 'PerpendicularOutraw' local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.dSawDiam, nFaceUse, nil, -0.1 -dCutXOffset, BD.CUT_SIC, dHorizontalCutOffset, 0, 0, '', b3Raw, nil, nil, nil, sLeadInOutType, nil, dOffsetBetweenCuts) if not bOk then return bOk, sErr end end -- se necessario taglio verticale doppio, eseguo l'opposto if HeadCutType.bDoubleCut then -- gli accorciamenti vanno invertiti per il taglio opposto local dAccStartDoubleCut, dAccEndDoubleCut = dAccEnd, dAccStart local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutXOffset, dAccStartDoubleCut, dAccEndDoubleCut, '', b3Raw, true) if not bOk then return false, sErr end end -- taglio verticale local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutXOffset, dAccStart, dAccEnd, '', b3Raw, true) if not bOk then return bOk, sErr end end return true, sWarn end -- taglio a zero (con lama) per evitare problemi con grezzo più lungo del previsto. Se BigSection il pretaglio è già stato fatto. if not ( HeadCutType.bBigSectionCut) and BD.PRECUT_HEAD and HeadCutType.bNeedVerticalAddedCuts then dStartOffset = dOvmHead local bOkPrecut, sErrPrecut = MakeStandardCuts( Proc, b3Raw, 1, 0, PrecutType, Cutting1Data, Cutting2Data, dStartOffset) if not bOkPrecut then return false, sErrPrecut end end -- se necessari tagli in doppio, eseguo gli opposti if HeadCutType.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) * dOffsetBetweenCuts if i == 1 and HeadCutType.sType =='Precut' then dCutOffset = dStartOffset end local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.dSawDiam, MCH_MILL_FU.ORTHO_BACK, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStartDoubleCut, dAccEndDoubleCut, '', 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) * dOffsetBetweenCuts -- se trave larga effettuo tagli verticali aggiuntivi if HeadCutType.bNeedVerticalAddedCuts then local bOk, sErr = AddVerticalPreCuts( Proc, Cutting1Data.sCutting, dCutOffset, b3Raw, dOffsetBetweenCuts) if not bOk then return bOk, sErr end end if i == 1 and HeadCutType.sType =='Precut' then dCutOffset = dStartOffset end local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, '', b3Raw, true) 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 Cutting2Data.sCutting 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 = Cutting1Data.dMaxVertDepth + Cutting2Data.dMaxDepth - dDimZ if ( dExtra - 2 * BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL < 0) and not HeadCutType.bBigSectionCut then local sErr = 'Error : section too big for head cut' EgtOutLog( sErr) return false, sErr end -- calcolo extra taglio ed accorciamento local dCutExtra = -Cutting2Data.dMaxDepth + dExtra / 2 + BD.CUT_EXTRA_MIN local dCutExtra2 = -Cutting1Data.dMaxVertDepth + dExtra / 2 + BD.CUT_EXTRA_MIN local dAccStart = 0 local dVzLimDwnUp if BD.TURN then dVzLimDwnUp = -2 end -- taglio a zero (con lama) per evitare problemi con grezzo più lungo del previsto. Se BigSection il pretaglio è già stato fatto. if not ( HeadCutType.bBigSectionCut) and BD.PRECUT_HEAD and HeadCutType.bNeedVerticalAddedCuts then dStartOffset = dOvmHead local bOkPrecut, sErrPrecut = MakeStandardCuts( Proc, b3Raw, 1, 0, PrecutType, Cutting1Data, Cutting2Data, dStartOffset) if not bOkPrecut then return false, sErrPrecut end end -- eseguo i tagli da sotto necessari for i = nCuts, 1, -1 do local dCutOffset = ( i - 1) * dOffsetBetweenCuts if i == 1 and HeadCutType.sType =='Precut' then dCutOffset = dStartOffset end local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting2Data.sCutting, Cutting2Data.dSawDiam, MCH_MILL_FU.ORTHO_TOP, dVzLimDwnUp, dCutExtra2, BD.CUT_SIC, dCutOffset, dAccStart, 0, '', 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) * dOffsetBetweenCuts if i == 1 and HeadCutType.sType =='Precut' then dCutOffset = dStartOffset end -- se trave larga effettuo tagli verticali aggiuntivi if HeadCutType.bNeedVerticalAddedCuts then local bOk, sErr = AddVerticalPreCuts( Proc, Cutting1Data.sCutting, dCutOffset, b3Raw, dOffsetBetweenCuts) if not bOk then return bOk, sErr end end local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.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 --------------------------------------------------------------------- -- 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 -- eventuali informazioni sul tipo di finitura local nQ05 = EgtGetInfo( nOriId or GDB_ID.NULL, 'Q05', 'i') or 0 -- recupero la lavorazione -- TODO questa parte andrà cambiata quando si gestiranno i volumi liberi in cui girare da mlse local dMinWidthForBigBlade = 300 local dMaxHeightForBigBlade = 300 local sCutting if b3Raw:getDimY() > dMinWidthForBigBlade and b3Raw:getDimZ() < dMaxHeightForBigBlade then sCutting = ML.FindCutting( 'HeadSide', nil, nil, nil, 'Longest') else sCutting = ML.FindCutting( 'HeadSide') end 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 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 dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick 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 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 dMaxDepth2 = EgtTdbGetCurrToolMaxDepth() or dMaxDepth2 dSawThick2 = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick2 end end -- determino se lo spessore del materiale da rimuovere è eccessivo e quindi vanno fatti più tagli con offset local nCuts = max( ceil( dOvmHead / (( BD.MAX_LEN_SCRAP_START or BD.MAX_LEN_SCRAP) + 0.5)), 1) local dOffsL = dOvmHead / nCuts -- 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 + 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) and ( b3Raw:getDimY() < 2 * dDimYRef - BD.CUT_EXTRA_MIN + 10 * GEO.EPS_SMALL) -- verifico necessità di tagli aggiuntivi orizzontali o verticali local dMinOvmHeadForAddeddCuts = 10.123 local bNeedVerticalAddedCuts = ( Proc.Face[1].WidthTrimmed > BD.MAX_LEN_DICE) and ( dOvmHead > dMinOvmHeadForAddeddCuts - 10 * GEO.EPS_SMALL) local bNeedHorizontalAddedCuts = ( Proc.Face[1].HeightTrimmed > ( BD.MIN_HEIGHT_ADDED_CUTS or BD.MAX_LEN_DICE)) and not bBigSectionCut and ( dOvmHead > dMinOvmHeadForAddeddCuts - 10 * GEO.EPS_SMALL) and dOffsL < BD.MAX_DIM_DICE -- dati lavorazioni sopra e sotto local Cutting1Data = { sCutting = sCutting, dSawDiam = dSawDiam, dMaxDepth = dMaxDepth, dSawThick = dSawThick, dMaxVertDepth = dMaxVertDepth} local Cutting2Data = { sCutting = sCutting2, dSawDiam = dSawDiam2, dMaxDepth = dMaxDepth2, dSawThick = dSawThick2} -- dati sul taglio di testa da effettuare local HeadCutType = { bBigSectionCut = bBigSectionCut, bHorizCut = bHorizCut, bDoubleHorizCut = bDoubleHorizCut, bDoubleCut = bDoubleCut, bNeedVerticalAddedCuts = bNeedVerticalAddedCuts, bNeedHorizontalAddedCuts = bNeedHorizontalAddedCuts} -- 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 -- se taglio per sezioni alte e larghe if bBigSectionCut then if dOvmHead > 0 then -- se finitura con lama if nQ05 < 2 then 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 -- taglio a zero (con sega a catena o mix catena + lama) per evitare problemi con grezzo più lungo del previsto if BD.PRECUT_HEAD 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 SawingData = { sSawing = sSawing, dChainSawMaxMat = dChainSawMaxMat, dChainSawLen = dChainSawLen, bInvert = true} local dOffset = dOvmHead local bOkPrecut, sErrPrecut = Split.MakeBigSectionSplitting( Proc, b3Raw, dOffset, SawingData, Cutting2Data) if not bOkPrecut then return false, sErrPrecut end end -- controllo se è necessario un taglio con dicing o si deve proseguire ai casi standard if dMaxElev > dSawThickCheck then local bOk, sErr -- se trave larga effettuo tagli verticali aggiuntivi if bNeedVerticalAddedCuts 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 vtMove = Vector3d( dCutOffset, 0, 0) EgtMove( AddId, vtMove, 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, GDB_ID.ROOT) if AreSameVectorApprox( X_AX(), vtNLimitingSurf) then EgtInvertSurf( nLimitingSurf) end end -- tagli verticali bOk, sErr = AddVerticalPreCuts( AddProc, sCutting, 0, b3Raw, dOffsL) if not bOk then return bOk, sErr end -- tagli a cubetti con eventuale superficie limitante local sLeadInOutType = 'PerpendicularOutraw' bOk, sErr = Cut.Make( AddProc, nPhase, nRawId, nPartId, dOvmHead, nil, false, true, nil, nil, nil, nil, nLimitingSurf, sLeadInOutType) end -- tagli aggiuntivi non necessari else local sLeadInOutType = 'PerpendicularOutraw' bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, nil, false, true, nil, nil, nil, nil, nil, sLeadInOutType) end return bOk, sErr 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 = 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) return bOk, sErr end end end local bOk, sErr = MakeStandardCuts( Proc, b3Raw, nCuts, dOffsL, HeadCutType, Cutting1Data, Cutting2Data, nil, dOvmHead) -- alla fine del taglio si aggiungono gli smussi in testa local _, sErrHeadChamfer = MakeHeadChamfer( nOriId or Proc.Id, nPartId) if sErr then sErr = sErr..'\n'..sErrHeadChamfer else sErr = sErrHeadChamfer end return bOk, sErr end --------------------------------------------------------------------- return ProcessHeadCut