970 lines
48 KiB
Lua
970 lines
48 KiB
Lua
-- 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')
|
|
|
|
if BD.PRECUT_TAIL == nil then
|
|
BD.PRECUT_TAIL = true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- 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, dOvmTail)
|
|
-- 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 coda
|
|
local function MakeTailChamfer( idProc, nPartId, dDepthTailChamfer)
|
|
-- 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.LEFT))
|
|
|
|
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 MakeTailChamfer : 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 MakeTailChamfer : 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 = 'TailCham_' .. ( 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, dDepthTailChamfer + 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
|
|
|
|
---------------------------------------------------------------------
|
|
-- lavorazione con sega a catena per sezioni alte e larghe
|
|
local function MakeCutByChainSaw( nSurfId, sSawing, nFaceUse, dDepth, sNotes, dRadialOffset, bExtendStartEnd, bInvert)
|
|
-- 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))
|
|
-- se il taglio è un precut, sto 10mm più all'interno per essere sicuro di tagliare effettivamente qualcosa
|
|
if BD.PRECUT_TAIL and sNotes and sNotes:find( 'Precut;') then
|
|
dRadialOffset = dRadialOffset - 10
|
|
end
|
|
-- imposto offset radiale per mantenere il materiale in coda per la finitura
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dRadialOffset)
|
|
-- 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)
|
|
if bInvert and bInvert == true then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
end
|
|
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
|
|
|
|
---------------------------------------------------------------------
|
|
-- split per sezioni grandi con sega a catena o mix catena + lama
|
|
function ProcessSplit.MakeBigSectionSplitting( Proc, b3Raw, dOffset, SawingData, Cutting2Data)
|
|
local sNotes = ''
|
|
if SawingData.bSplit ~= nil then
|
|
sNotes = 'Precut;'
|
|
end
|
|
local bigSectionSplitType
|
|
-- se pezzo non troppo alto, taglio singolo da sopra
|
|
if b3Raw:getDimZ() + BD.CUT_EXTRA_MIN < SawingData.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( SawingData.dChainSawMaxMat, SawingData.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( SawingData.dChainSawMaxMat, SawingData.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 < Cutting2Data.dMaxDepth + SawingData.dChainSawMaxMat + 10 * GEO.EPS_SMALL) then
|
|
bigSectionSplitType = "double horizontal"
|
|
end
|
|
|
|
-- in base alle scelte precedenti, applico le lavorazioni
|
|
if bigSectionSplitType == "single horizontal" then
|
|
local dCutDepth = b3Raw:getDimZ() + BD.CUT_EXTRA_MIN
|
|
local sNotesSplit = EgtIf( SawingData.bSplit, 'Split;', sNotes)
|
|
-- 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 SawingData.dChainSawLen > dMinLengthLongChainSaw - 10 * GEO.EPS_SMALL then
|
|
bExtendStartEnd = true
|
|
end
|
|
local bOk, sErr = MakeCutByChainSaw( Proc.Id, SawingData.sSawing, MCH_MILL_FU.PARAL_TOP, dCutDepth, sNotesSplit, dOffset, bExtendStartEnd, SawingData.bInvert)
|
|
if not bOk then return bOk, sErr end
|
|
elseif bigSectionSplitType == "single vertical" then
|
|
local dCutDepth = b3Raw:getDimY() + BD.CUT_EXTRA_MIN
|
|
local sNotesSplit = EgtIf( SawingData.bSplit, 'Split;', sNotes)
|
|
local bOk, sErr = MakeCutByChainSaw( Proc.Id, SawingData.sSawing, MCH_MILL_FU.PARAL_FRONT, dCutDepth, sNotesSplit, dOffset, nil, SawingData.bInvert)
|
|
if not bOk then return bOk, sErr end
|
|
elseif bigSectionSplitType == "double vertical" then
|
|
local dCutDepth = 0.5 * b3Raw:getDimY() + BD.CUT_EXTRA_MIN
|
|
local sNotesSplit = EgtIf( SawingData.bSplit, 'Presplit;', sNotes)
|
|
local bOk, sErr = MakeCutByChainSaw( Proc.Id, SawingData.sSawing, MCH_MILL_FU.PARAL_BACK, dCutDepth, sNotesSplit, dOffset, nil, SawingData.bInvert)
|
|
if not bOk then return bOk, sErr end
|
|
sNotesSplit = EgtIf( SawingData.bSplit, 'Split;', sNotes)
|
|
bOk, sErr = MakeCutByChainSaw( Proc.Id, SawingData.sSawing, MCH_MILL_FU.PARAL_FRONT, dCutDepth, sNotesSplit, dOffset, nil, SawingData.bInvert)
|
|
if not bOk then return bOk, sErr end
|
|
elseif bigSectionSplitType == "double horizontal" then
|
|
-- sega a catena da sopra
|
|
local dChainSawCutDepth = b3Raw:getDimZ() + BD.CUT_EXTRA_MIN - Cutting2Data.dMaxDepth
|
|
local sNotesSplit = EgtIf( SawingData.bSplit, 'Presplit;', sNotes)
|
|
local bOk, sErr = MakeCutByChainSaw( Proc.Id, SawingData.sSawing, MCH_MILL_FU.PARAL_TOP, dChainSawCutDepth, sNotesSplit, dOffset, nil, SawingData.bInvert)
|
|
if not bOk then return bOk, sErr end
|
|
-- lama da sotto
|
|
local dCutExtra = -dChainSawCutDepth + BD.CUT_EXTRA_MIN
|
|
local dVzLimDwnUp
|
|
if BD.TURN then dVzLimDwnUp = -2 end
|
|
local sNotes = EgtIf( SawingData.bSplit, 'Split;', sNotes)
|
|
local bMaximizeVerticalDepth = true
|
|
bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting2Data.sCutting, Cutting2Data.dSawDiam, MCH_MILL_FU.ORTHO_TOP, dVzLimDwnUp, dCutExtra, BD.CUT_SIC, dOffset, 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
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- tagli verticali aggiuntivi
|
|
local function AddVerticalPreCuts( Proc, sCutting, dCutXOffset, b3Raw, sNotes, 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 verticali
|
|
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, sNotes, 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, TailCutType, Cutting1Data, Cutting2Data, dStartOffset, dLenEndRaw)
|
|
if not TailCutType.sType then
|
|
TailCutType.sType = ''
|
|
end
|
|
local PrecutType = { bBigSectionCut = TailCutType.bBigSectionCut, bHorizCut = TailCutType.bHorizCut, bDoubleHorizCut = TailCutType.bDoubleHorizCut, bDoubleCut = TailCutType.bDoubleCut, bSplit = TailCutType.bSplit, sType = 'Precut', bNeedVerticalAddedCuts = false, bNeedHorizontalAddedCuts = false}
|
|
if not TailCutType.bDoubleHorizCut then
|
|
-- flag di lavorazione faccia
|
|
local nOrthoOpposite = EgtIf( TailCutType.bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_BACK)
|
|
-- calcolo extra taglio ed accorciamento
|
|
local dCutExtra = 0
|
|
local dAccStart = 0
|
|
local dAccEnd = 0
|
|
if TailCutType.bBigSectionCut and BD.C_SIMM and b3Raw:getDimZ() > BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL then
|
|
-- qui arrivano sezioni molto grandi su macchine tipo PF con materiale da asportare inferiore allo spessore lama
|
|
local dSawRad = Cutting1Data.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( TailCutType.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( TailCutType.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
|
|
if TailCutType.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 TailCutType.bBigSectionCut and BD.PRECUT_TAIL then
|
|
dStartOffset = dLenEndRaw
|
|
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, 'Precut;', b3Raw, nil, nil, nil, sLeadInOutType, nil, dOffsetBetweenCuts)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
-- se necessario taglio verticale doppio, eseguo l'opposto
|
|
if TailCutType.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_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 and TailCutType.sType ~= 'Precut' then
|
|
sInfo = 'Cut'
|
|
end
|
|
local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutXOffset, dAccStart, dAccEnd, sInfo, b3Raw, true)
|
|
if not bOk then return false, 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 TailCutType.bBigSectionCut and BD.PRECUT_TAIL and TailCutType.bNeedVerticalAddedCuts then
|
|
dStartOffset = dLenEndRaw
|
|
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 TailCutType.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 TailCutType.sType =='Precut' then
|
|
dCutOffset = dStartOffset
|
|
end
|
|
local sNotes = EgtIf( TailCutType.bSplit, 'Presplit;', 'Precut;')
|
|
local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, Cutting1Data.sCutting, Cutting1Data.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) * dOffsetBetweenCuts
|
|
-- se trave larga effettuo tagli verticali aggiuntivi
|
|
if TailCutType.bNeedVerticalAddedCuts then
|
|
local sSpecNotes = EgtIf( TailCutType.bSplit, 'Presplit;', 'Precut;')
|
|
local bOk, sErr = AddVerticalPreCuts( Proc, Cutting1Data.sCutting, dCutOffset, b3Raw, sSpecNotes, dOffsetBetweenCuts)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
if i == 1 and TailCutType.sType =='Precut' then
|
|
dCutOffset = dStartOffset
|
|
end
|
|
local sNotes
|
|
if TailCutType.bSplit then
|
|
sNotes = EgtIf( i == 1, 'Split;', 'Presplit;')
|
|
else
|
|
sNotes = EgtIf( i == 1 and TailCutType.sType ~= 'Precut', 'Cut;', 'Precut;')
|
|
end
|
|
-- se primo taglio da sopra e PF o ONE richiedo risalita preliminare a Zmax
|
|
if i == nCuts and TailCutType.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, Cutting1Data.sCutting, Cutting1Data.dSawDiam, nOrthoOpposite, nil, dCutExtra, BD.CUT_SIC, dCutOffset, dAccStart, dAccEnd, sNotes, 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 TailCutType.bBigSectionCut then
|
|
local sErr = 'Error : section too big for tail 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
|
|
-- limiti da sotto
|
|
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 TailCutType.bBigSectionCut and BD.PRECUT_TAIL and TailCutType.bNeedVerticalAddedCuts then
|
|
dStartOffset = dLenEndRaw
|
|
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 TailCutType.sType =='Precut' then
|
|
dCutOffset = dStartOffset
|
|
end
|
|
local sNotes = EgtIf( TailCutType.bSplit, 'Presplit;', 'Precut;')
|
|
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, 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) * dOffsetBetweenCuts
|
|
if i == 1 and TailCutType.sType =='Precut' then
|
|
dCutOffset = dStartOffset
|
|
end
|
|
-- se trave larga effettuo tagli verticali aggiuntivi
|
|
if TailCutType.bNeedVerticalAddedCuts then
|
|
local sSpecNotes = EgtIf( TailCutType.bSplit, 'Presplit;', 'Precut;')
|
|
local bOk, sErr = AddVerticalPreCuts( Proc, Cutting1Data.sCutting, dCutOffset, b3Raw, sSpecNotes, dOffsetBetweenCuts)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
local sNotes
|
|
if TailCutType.bSplit then
|
|
sNotes = EgtIf( i == 1, 'Split;', 'Presplit;')
|
|
else
|
|
sNotes = EgtIf( i == 1 and TailCutType.sType ~= 'Precut', 'Cut;', 'Precut;')
|
|
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, sNotes, b3Raw)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
end
|
|
|
|
return true
|
|
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, dOvmTail)
|
|
if not bOkc then return bOkc, sErrC end
|
|
end
|
|
-- 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( 'TailSide', nil, nil, nil, 'Longest')
|
|
else
|
|
sCutting = ML.FindCutting( 'TailSide')
|
|
end
|
|
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
|
|
-- 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
|
|
-- 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 + 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)
|
|
-- dati geometrici del taglio
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- 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
|
|
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)
|
|
else
|
|
dLenEndRaw = min( dOvmTail, abs( ptC:getX() - b3Raw:getMin():getX()))
|
|
end
|
|
end
|
|
-- determino la necessità di tagli aggiuntivi
|
|
local dMinTailScrapForAdditionalCuts = 10.123
|
|
local bNeedVerticalAddedCuts = not bSplit and ( Proc.Face[1].WidthTrimmed > BD.MAX_LEN_DICE) and ( dLenEndRaw > dMinTailScrapForAdditionalCuts - 10 * GEO.EPS_SMALL)
|
|
local bNeedHorizontalAddedCuts = not bSplit and not bBigSectionCut and
|
|
( Proc.Face[1].HeightTrimmed > ( BD.MIN_HEIGHT_ADDED_CUTS or BD.MAX_LEN_DICE) + 100 * GEO.EPS_SMALL) and
|
|
( dLenEndRaw > dMinTailScrapForAdditionalCuts - 10 * GEO.EPS_SMALL) and
|
|
dOffsL < BD.MAX_DIM_DICE
|
|
-- dati lavorazioni sopra e sotto
|
|
local Cutting1Data = { sCutting = sCutting, dSawDiam = dSawDiam, dMaxDepth = dSawMaxDepth, dSawThick = dSawThick, dMaxVertDepth = dMaxVertDepth}
|
|
local Cutting2Data = { sCutting = sCutting2, dSawDiam = dSawDiam2, dMaxDepth = dSawMaxDepth2, dSawThick = dSawThick2}
|
|
local SawingData = { sSawing = sSawing, dChainSawMaxMat = dChainSawMaxMat, dChainSawLen = dChainSawLen, bSplit = bSplit or false}
|
|
-- dati sul taglio di coda da effettuare
|
|
local TailCutType = { bBigSectionCut = bBigSectionCut, bHorizCut = bHorizCut, bDoubleHorizCut = bDoubleHorizCut, bDoubleCut = bDoubleCut, bSplit = bSplit, bNeedVerticalAddedCuts = bNeedVerticalAddedCuts, bNeedHorizontalAddedCuts = bNeedHorizontalAddedCuts}
|
|
-- se taglio per pezzi alti e larghi
|
|
local nNewPhase = 0
|
|
if bBigSectionCut then
|
|
local bFinishingNeeded = false
|
|
if bSplit then
|
|
-- assegno offset in lunghezza
|
|
local dTailOffset = 0
|
|
if dOvmTail > BD.OVM_CHAIN_HBEAM then
|
|
dTailOffset = dOvmTail - BD.OVM_CHAIN_HBEAM
|
|
bFinishingNeeded = true
|
|
end
|
|
-- split per grande sezione
|
|
local bOk, sErr, nNewPhase2 = ProcessSplit.MakeBigSectionSplitting( Proc, b3Raw, dTailOffset, SawingData, Cutting2Data)
|
|
if nNewPhase2 then
|
|
nNewPhase = nNewPhase2
|
|
end
|
|
if not bOk then
|
|
return bOk, sErr, nNewPhase
|
|
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 = max( min( dSawThick, dSawThick2), dOvmTail)
|
|
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_TAIL and not bSplit then
|
|
local dTailOffset = dLenEndRaw
|
|
local bOkPrecut, sErrPrecut = ProcessSplit.MakeBigSectionSplitting( Proc, b3Raw, dTailOffset, SawingData, Cutting2Data)
|
|
if not bOkPrecut then
|
|
return false, sErrPrecut
|
|
end
|
|
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 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 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, GDB_ID.ROOT)
|
|
if AreOppositeVectorApprox( X_AX(), vtNLimitingSurf) then EgtInvertSurf( nLimitingSurf) end
|
|
end
|
|
-- tagli verticali
|
|
bOk, sErr = AddVerticalPreCuts( AddProc, sCutting, 0, b3Raw, sNotes, dOffsL)
|
|
if not bOk then return bOk, sErr end
|
|
-- tagli a cubetti con eventuale superficie limitante
|
|
local sLeadInOutType = 'PerpendicularOutraw'
|
|
bOk, sErr = Cut.Make( AddProc, nNewPhase, nRawId, nPartId, dMaxElev, nil, false, true, b3Raw, sNotes, dCurrOvmT, nil, nLimitingSurf, sLeadInOutType)
|
|
end
|
|
-- tagli aggiuntivi non necessari
|
|
else
|
|
local sLeadInOutType = 'PerpendicularOutraw'
|
|
bOk, sErr = Cut.Make( Proc, nNewPhase, nRawId, nPartId, dMaxElev, nil, false, true, b3Raw, sNotes, dCurrOvmT, nil, nil, sLeadInOutType)
|
|
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
|
|
|
|
local bOk, sErr = MakeStandardCuts( Proc, b3Raw, nCuts, dOffsL, TailCutType, Cutting1Data, Cutting2Data, nil, dLenEndRaw)
|
|
|
|
-- se smussi in coda da aggiungere
|
|
local dDepthTailChamfer = EgtGetInfo( nOriId or Proc.Id, 'Q08', 'd') or 0
|
|
if dDepthTailChamfer > 100 * GEO.EPS_SMALL then
|
|
-- creo subito nuova fase qui, a meno che non sia stata già creata
|
|
if nNewPhase == 0 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
|
|
-- alla fine del taglio si aggiungono gli smussi in testa
|
|
local _, sErrHeadChamfer = MakeTailChamfer( nOriId or Proc.Id, nPartId, dDepthTailChamfer)
|
|
if sErr then
|
|
sErr = sErr..'\n'..sErrHeadChamfer
|
|
else
|
|
sErr = sErrHeadChamfer
|
|
end
|
|
end
|
|
|
|
return bOk, sErr, nNewPhase
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessSplit
|