e6a3e0c519
- in LapJoint se arriva da Cut si applica sempre svuotatura - in LapJoint se birdsmouth a L si applica svuotatura anche in caso di elevazione non raggiunta (non si tenta la fresatura che fallirebbe non trovando facce sul lato lungo)
889 lines
42 KiB
Lua
889 lines
42 KiB
Lua
-- ProcessCut.lua by Egaltech s.r.l. 2023/08/01
|
|
-- Gestione calcolo singoli tagli di lama per Travi
|
|
-- 2021/05/18 I due tagli con testa da sotto di un cubetto sono fatti di seguito.
|
|
-- 2021/06/06 Correzioni per tagli con testa da sotto.
|
|
-- 2021/07/14 Migliorie per tagli con testa da sotto.
|
|
-- 2021/09/19 Tagli da sotto non sbiechi favorita posizione da sopra di testa.
|
|
-- 2021/10/06 Piccola correzione a tagli di cubetti con testa da sotto.
|
|
-- 2022/01/26 Taglio da sotto orizzontale deve avere direzione di riferimento ortogonale -Z.
|
|
-- 2022/02/02 Modifiche per tagli di coda spostati prima come lavorazione su pezzi a caduta.
|
|
-- 2022/02/06 Correzioni per tagli di coda spostati prima.
|
|
-- 2022/05/31 Alcune modifiche per utilizzare la ProcessCut.Make in ProcessSplit e ProcessHeadCut, per le sezioni alte e larghe.
|
|
-- 2022/06/10 Aggiunto il parametro dOvmTail per gestire sovramateriali in coda diversi da OVM_MID (sezioni alte e larghe).
|
|
-- 2022/06/28 Modificata determinazione taglio bFromBottom in MakeFromTop.
|
|
-- 2022/07/18 Se Q04=1, aggiunto LongCut anche dal lato per macchine tipo PF1250.
|
|
-- 2022/08/12 I tagli di lama inclinati in coda ora partono dal centro e non dall'esterno.
|
|
-- 2022/08/24 Disabilitato il dicing per i tagli meno spessi della lama.
|
|
-- 2022/08/25 In caso di AdvTail con taglio lungo Y la profondità di lavorazione è opportunamente diminuita.
|
|
-- 2022/08/30 Modificata la condizione che determina l'utilizzo della testa da sotto. Ora controlla se la trave è più grande del doppio della massima larghezza del cubetto.
|
|
-- 2022/09/23 Corretta la condizione per cui è richiesto l'aggiornamento del grezzo.
|
|
-- 2023/01/26 Migliorata la direzione di lavoro della lama in alcuni casi in cui il truciolo veniva scaricato dal lato errato.
|
|
-- 2023/06/19 Aggiunti tagli speciali per evitare il rischio che il cubetto rimanga appoggiato al motore.
|
|
-- 2023/08/01 Correzione su offset per taglio doppio di lato.
|
|
-- 2023/08/01 In caso di pezzi alti su macchina tipo PF i tagli doppi di lato non vengono usati, si usa il metodo standard.
|
|
-- 2023/09/12 In MakeFromTop abbassato a 590 mm il limite per convertire in LongCut.
|
|
-- 2023/10/27 In MakeFromTop corretto massimo materiale in caso di lavorazione da sotto.
|
|
-- 2023/12/07 Correzione in Classify in scelta ribaltamento trave quando si è in condizioni downUp.
|
|
-- 2024/01/18 Gestita superficie limitante opzionale da passare a diceCut.
|
|
-- 2024/05/10 In MakeFromTop ricalcolo direzione di lavorazione su facce a cubetti
|
|
|
|
-- Tabella per definizione modulo
|
|
local ProcessCut = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
local Fbs = require( 'FacesBySaw')
|
|
local DC = require( 'DiceCut')
|
|
local LongCut = require( 'ProcessLongCut')
|
|
|
|
EgtOutLog( ' ProcessCut started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function ProcessCut.Identify( Proc)
|
|
-- se richiesto si forza fresatura
|
|
Proc.bForceMill = ( ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) and ( ( EgtGetInfo( Proc.Id, 'Q07', 'd') or 0) == 1))
|
|
|
|
if Proc.bForceMill then
|
|
return false
|
|
else
|
|
return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessCut.Classify( Proc, b3Raw)
|
|
-- se PF con testa da sotto o TURN, ammessa qualunque orientazione
|
|
if ( BD.C_SIMM and BD.DOWN_HEAD) or BD.TURN then
|
|
return true
|
|
end
|
|
-- recupero i dati del taglio
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
if vtN:getZ() <= - 0.5 and abs( vtN:getY()) > 0.1 or ( vtN:getZ() <= - 0.174 and abs( vtN:getY()) > 0.866) then
|
|
-- calcolo le massime estensioni lineari orizzontale e verticale della faccia
|
|
local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw)
|
|
-- confronto queste estensioni con la massima dimensione del DiceCut (impossibile lavorare se entrambe maggiori)
|
|
if DimH > BD.MAX_DIM_DICE and DimV > BD.MAX_DIM_DICE then
|
|
return true, true
|
|
end
|
|
end
|
|
-- se è un taglio da sotto, lo verifico
|
|
local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw)
|
|
local bDownCut = ( vtN:getZ() <= dNzLimDwnUp)
|
|
if bDownCut then
|
|
-- recupero i dati della lama
|
|
local sCutType = EgtIf( Proc.Head, 'HeadSide', 'TailSide')
|
|
local sCutting = ML.FindCutting( sCutType, true, false)
|
|
local dMaxDepth = 0
|
|
local dMaxMat = 0
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
|
|
end
|
|
end
|
|
-- calcolo l'ingombro orizzontale della faccia
|
|
local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0)
|
|
-- confronto questo ingombro con il doppio della massima dimensione del DiceCut (impossibile lavorare sotto da sopra se più di 2 tagli oppure se tipo PF, taglio inclinato in Y e non taglio singolo orizzontale)
|
|
if DimH > 2 * BD.MAX_DIM_DICE or ( BD.C_SIMM and abs( vtN:getY()) > 0.1 and dMaxMat < DimH + BD.CUT_EXTRA) then
|
|
return true, true
|
|
end
|
|
end
|
|
return true, false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Piano di taglio della feature
|
|
function ProcessCut.GetCutPlane( Proc)
|
|
if ProcessCut.Identify( Proc) then
|
|
return EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
else
|
|
return nil, nil
|
|
end
|
|
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( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- verifico che lo smusso sia richiesto
|
|
local dDepth = EgtGetInfo( Proc.Id, '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( Proc.Id, '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 + Proc.Id end
|
|
if Aux2Id then Aux2Id = Aux2Id + Proc.Id 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( nMch2Id, false)
|
|
return false, sErr
|
|
end
|
|
return true, nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Aggiornamento ingombro
|
|
local function UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw)
|
|
-- eventuale segnalazione ingombro di testa o coda (se non chiamata da altre feature)
|
|
local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * b3Raw:getDimZ())
|
|
local dMinZ = max( BD.MIN_HEIGHT, 0.35 * b3Raw:getDimZ())
|
|
if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinZ then
|
|
if Proc.Head then
|
|
local dOffs = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()
|
|
if vtN:getZ() > 0.5 then
|
|
dOffs = dOffs - 0.6 * Proc.Box:getDimX()
|
|
elseif vtN:getZ() < -0.5 then
|
|
dOffs = dOffs - EgtIf( BD.PRESS_ROLLER, 0.4, 0.2) * Proc.Box:getDimX()
|
|
elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then
|
|
dOffs = dOffs - 0.3 * Proc.Box:getDimX()
|
|
end
|
|
BL.UpdateHCING( nRawId, dOffs)
|
|
elseif Proc.Tail then
|
|
local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX()
|
|
if vtN:getZ() > 0.5 then
|
|
dOffs = dOffs - 0.6 * Proc.Box:getDimX()
|
|
elseif vtN:getZ() < -0.5 then
|
|
dOffs = dOffs - EgtIf( BD.PRESS_ROLLER, 0.4, 0.2) * Proc.Box:getDimX()
|
|
elseif ( abs( vtN:getY()) > 0.9 and vtN:getZ() > 0.2) then
|
|
dOffs = dOffs - 0.3 * Proc.Box:getDimX()
|
|
end
|
|
BL.UpdateTCING( nRawId, dOffs)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione con testa da sopra
|
|
local function MakeFromTop( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut, bForced, b3Raw, sNotes, nLimitingSurf, bForceTangentLeadInOut)
|
|
-- ingombro del grezzo
|
|
b3Raw = b3Raw or EgtGetRawPartBBox( nRawId)
|
|
-- ingombro del pezzo
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- dati geometrici del taglio
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- limiti di taglio (se molto di lato e inclinati sono permessi fino a -45deg)
|
|
local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN)
|
|
local bDownCut = ( vtN:getZ() <= dNzLimDwnUp)
|
|
if bFromBottom == nil then
|
|
bFromBottom = ( vtN:getZ() > 0.25 and b3Solid:getDimX() < BD.LEN_SHORT_PART and not Proc.AdvTail and vtN:getX() < 0 and abs( vtN:getY()) < 0.259)
|
|
end
|
|
local dMinFeatureLengthForLongCut = EgtIf( BD.C_SIMM, 590, 400)
|
|
-- verifico se da considerare taglio lungo ( non da sotto, inclinato non più di 30deg, largo come la trave e abbastanza lungo)
|
|
local bLongCut = ( not bDownCut and vtN:getZ() > 0.865 and
|
|
Proc.Box:getDimY() > b3Solid:getDimY() - 10 * GEO.EPS_SMALL and
|
|
( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > dMinFeatureLengthForLongCut))
|
|
-- verifico se da considerare taglio lungo dal lato, solo per macchine tipo PF1250, inclinato non più di 30deg
|
|
local bLongCutFromSide = ( not bDownCut and ( BD.C_SIMM and BD.DOWN_HEAD and ( abs(vtN:getY()) > 0.865) and
|
|
Proc.Box:getDimZ() > b3Solid:getDimZ() - 10 * GEO.EPS_SMALL) and
|
|
( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > dMinFeatureLengthForLongCut))
|
|
-- se taglio lungo e Q04 = 1 allora lancio il processo dell'L10
|
|
local bNoDicing = EgtGetInfo( Proc.Id, 'Q04', 'i') == 1
|
|
if bNoDicing then
|
|
if bLongCut then
|
|
local bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId, true)
|
|
return bOk, sErr, bNoDicing
|
|
elseif bLongCutFromSide then
|
|
local bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId, false, 2)
|
|
return bOk, sErr, bNoDicing
|
|
end
|
|
-- se non passa dal LongCut rimetto a false perchè ha fatto un taglio standard
|
|
bNoDicing = false
|
|
end
|
|
-- se pezzo ancora attaccato alla trave, per non rovinare quello successivo
|
|
local bFillAreaPiece
|
|
local bFillTail
|
|
if not BL.IsSplittedPartPhase( nPhase) then
|
|
-- se non da sotto
|
|
if not bDownCut then
|
|
bFillAreaPiece = bCustDiceCut
|
|
-- se true il controllo è già stato fatto dal modulo che ha chiamato il ProcessCut
|
|
if not bFillAreaPiece then
|
|
-- se poco inclinata ( inclinazione inferiore a 21.56 deg)
|
|
if vtN:getZ() > 0.93 then
|
|
-- si possono far partire i tagli a cubetti dalla testa
|
|
bFillAreaPiece = bLongCut
|
|
-- se praticamente verticale di fianco ( inclinazione inferiore a 21.56deg)
|
|
elseif abs( vtN:getY()) > 0.93 then
|
|
-- se la faccia occupa tutta la trave in X e Z o occupa sicuramente la faccia in Z e almeno 3/4 della faccia in X e sborda in X,
|
|
if ( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) or
|
|
( ( abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getX() - b3Solid:getMax():getX()) < 10*GEO.EPS_SMALL) and
|
|
Proc.Box:getDimX() > 0.90 * b3Solid:getDimX())) and
|
|
abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL then
|
|
local sErr = 'Error : Impossible to machine by orientation (on side A)'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
-- se quasi orizzontale ( inclinazione inferiore a 30)
|
|
if vtN:getZ() > 0.866 then
|
|
-- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti
|
|
if ( abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL) and
|
|
abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL and b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then
|
|
bFillTail = true
|
|
end
|
|
-- se verticale quasi completamente di fianco ( inclinazione inferiore a 30)
|
|
elseif abs( vtN:getY()) > 0.866 then
|
|
-- se la faccia termina davanti o dietro la trave e arriva in coda e non interessa la faccia inferiore, forzo il taglio a cubetti a partire dal davanti
|
|
if ( abs( Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()) < 10*GEO.EPS_SMALL or abs( Proc.Box:getMax():getZ() - b3Solid:getMax():getZ()) < 10*GEO.EPS_SMALL) and
|
|
abs( Proc.Box:getMin():getX() - b3Solid:getMin():getX()) < 10*GEO.EPS_SMALL then
|
|
local sErr = 'Error : Impossible to machine by orientation (on side B)'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- se vero taglio, eventuale inserimento smussi
|
|
if ProcessCut.Identify( Proc) then
|
|
local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
if not bOkc then return bOkc, sErrC end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 2
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
local dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0)
|
|
-- determino la direzione di taglio preferenziale
|
|
local frFac, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw)
|
|
local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA and not bDownCut) or
|
|
( dCutV < 0.8 * dMaxVertDepth - BD.CUT_EXTRA and b3Solid:getDimZ() < 0.8 * dMaxVertDepth - BD.CUT_EXTRA)
|
|
local bVertCutOk = ( dCutH < dMaxDepth - BD.CUT_EXTRA)
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico se necessari tagli supplementari o se presente superficie limitante
|
|
EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3)
|
|
local vCuts = {}
|
|
if not Proc.AdvTail and ( dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxVertDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC) then
|
|
local ptExtra, vtExtra
|
|
local bAutoCalcSurf = true
|
|
if bFillAreaPiece or bFillTail then
|
|
local ptMiddle = ( b3Solid:getMin() + b3Solid:getMax()) / 2
|
|
ptExtra = Point3d( b3Solid:getMin():getX() + 5*GEO.EPS_SMALL, ptMiddle:getY(), ptMiddle:getZ())
|
|
vtExtra = X_AX()
|
|
bAutoCalcSurf = false
|
|
-- superficie limitante
|
|
elseif nLimitingSurf then
|
|
ptExtra, vtExtra = EgtSurfTmFacetCenter( nLimitingSurf, 0, GDB_ID.ROOT)
|
|
end
|
|
-- verifico elevazione max del materiale tagliato
|
|
local dMaxElev
|
|
if vtN:getX() > 0 then
|
|
if bForced then
|
|
dMaxElev = b3Raw:getMax():getX() - Proc.Box:getMin():getX()
|
|
else
|
|
dMaxElev = b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
end
|
|
else
|
|
if bForced then
|
|
dMaxElev = Proc.Box:getMax():getX() - b3Raw:getMin():getX()
|
|
else
|
|
dMaxElev = Proc.Box:getMax():getX() - b3Solid:getMin():getX()
|
|
end
|
|
end
|
|
-- per macchina TURN (ma non OikosX) aggiusto massima dimensione cubetto
|
|
local dNewDiceDim
|
|
if BD.TURN and BD.TURN ~= 2 then
|
|
local dDimRef = GEO.INFINITO
|
|
if abs( vtN:getZ()) < 0.003 then
|
|
dDimRef = b3Raw:getDimZ()
|
|
elseif abs( vtN:getY()) < 0.003 then
|
|
dDimRef = b3Raw:getDimY()
|
|
end
|
|
if dDimRef + BD.CUT_EXTRA < dMaxDepth then
|
|
dNewDiceDim = - ( dMaxDepth - BD.CUT_EXTRA)
|
|
end
|
|
end
|
|
-- se il taglio è più spesso della lama abilito il dicing, altrimenti no
|
|
if dMaxElev > dSawThick then
|
|
vCuts = DC.GetDice( nAddGrpId, EgtIf( bForced, b3Raw, b3Solid), ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA, dNewDiceDim)
|
|
-- se taglio sborda in coda e non è stato inserito nessun taglio a cubetti, lo rilancio con le dimensioni customizzate
|
|
if ( bFillTail or bCustDiceCut) and #vCuts == 0 then
|
|
vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA, Proc.Box:getDimY())
|
|
end
|
|
end
|
|
end
|
|
-- se il ProcessCut viene lanciato dal ProcessSawCut e non ci sono tagli a cubetti, esco
|
|
if bCustDiceCut and #vCuts == 0 then
|
|
return false, -1
|
|
end
|
|
|
|
-- per caso speciale in cui c'è il rischio che il cubetto rimanga appoggiato sul motore, faccio solo i tagli perpendicolari seguiti da due tagli verticali laterali
|
|
local bDangerousReliefCut = false
|
|
-- verifico che i tagli perpendicolari siano perpendicolari al lato più vicino a Z
|
|
local nFirstPerpendicularCut = ( #vCuts > 0 and ( vCuts[1][1] or vCuts[3][1]))
|
|
if nFirstPerpendicularCut then
|
|
local frFace = BL.GetFaceHvRefDim( Proc.Id, 0)
|
|
local vtTemp = EgtSurfTmFacetNormVersor( nFirstPerpendicularCut, 0, GDB_ID.ROOT) ^ frFace:getVersX()
|
|
if not ( vtTemp:isSmall()) and not ( bDownCut or bFromBottom) and not bLongCut and ( not BD.C_SIMM or b3Raw:getDimZ() < BD.MIN_DIM_HBEAM + 10 * GEO.EPS_SMALL) then
|
|
bDangerousReliefCut = true
|
|
end
|
|
end
|
|
|
|
--DC.PrintOrderCut( vCuts)
|
|
if #vCuts > 0 then
|
|
-- sistemo posizione nel DB e nome
|
|
local bOrthInv = false
|
|
for i = 1, #vCuts do
|
|
for j = 1, #vCuts[i] do
|
|
EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id))
|
|
EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId)
|
|
if ( i % 2) == 1 then
|
|
local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
|
|
if ( vtN:getY() > 0.766 and vtO:getY() < -0.05) or
|
|
( vtN:getY() < -0.766 and vtO:getY() > 0.05) then
|
|
EgtInvertSurf( vCuts[i][j])
|
|
bOrthInv = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- eseguo
|
|
for i = 1, #vCuts do
|
|
-- determino il modo di tagliare
|
|
local vtOrthoO
|
|
local bNoPerpCuts = false
|
|
if i % 2 == 1 then
|
|
vtOrthoO = Vector3d( vtN)
|
|
else
|
|
local vtO
|
|
if #vCuts[i-1] > 0 then
|
|
vtO = EgtSurfTmFacetNormVersor( vCuts[i-1][1], 0, GDB_ID.ROOT)
|
|
elseif vCuts[i+1] and #vCuts[i+1] > 0 then
|
|
-- lunghezza faccia nell'eventuale direzione ortogonale
|
|
local asseX = EgtSurfTmFacetNormVersor( vCuts[i+1][1], 0, GDB_ID.ROOT)
|
|
local asseY = asseX ^ vtN
|
|
local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY)
|
|
local b3Fac = EgtGetBBoxRef( vCuts[i][1], GDB_BB.STANDARD, Frame)
|
|
-- se lunghezza inferiore al limite, accetto la direzione
|
|
if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then
|
|
vtO = asseX
|
|
else
|
|
bNoPerpCuts = true
|
|
end
|
|
else
|
|
bNoPerpCuts = true
|
|
end
|
|
if vtO then
|
|
vtOrthoO = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1)
|
|
else
|
|
-- ricalcolo tipo taglio perché "bHorizCut" è calcolato sulla feature, mentre il cubetto potrebbe essere lavorato in un altro modo
|
|
local _, dLen, dWidth = BL.GetFaceHvRefDim( vCuts[i][1], 0, b3Raw)
|
|
local bCutDirection = bHorizCut
|
|
-- se bisogna tagliare di fianco ma la lunghezza faccia è più del massimo materiale, forzo lavorazione da sopra
|
|
if not bHorizCut and dLen > dMaxDepth then
|
|
bCutDirection = true
|
|
end
|
|
|
|
if bCutDirection then
|
|
vtOrthoO = Z_AX()
|
|
else
|
|
if vtN:getZ() < dNzLimDwnUp then
|
|
vtOrthoO = EgtIf( vtN:getY() > -0.02, -Y_AX(), Y_AX())
|
|
else
|
|
vtOrthoO = EgtIf( vtN:getY() > 0.02, Y_AX(), -Y_AX())
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local dDiceFaceMaxH = 0
|
|
local dDiceFaceMinH = GEO.INFINITO
|
|
if ( i % 2) == 0 and bDangerousReliefCut then
|
|
for j = 1, #vCuts[i] do
|
|
local _, dDiceFaceH, dDiceFaceV = BL.GetFaceHvRefDim( vCuts[i][j], 0)
|
|
dDiceFaceMaxH = max( dDiceFaceMaxH, dDiceFaceH)
|
|
-- calcolo lato orizzontale minore ipotizzando sia un trapezio
|
|
local dDiceFaceH2 = ( 2 * EgtSurfArea( vCuts[i][j]) ) / dDiceFaceV - dDiceFaceH
|
|
dDiceFaceMinH = min( dDiceFaceMinH, dDiceFaceH2)
|
|
end
|
|
end
|
|
-- caso speciale con rischio cubetto sul motore
|
|
if ( i % 2) == 0 and bDangerousReliefCut and ( dMaxDepth > dDiceFaceMaxH - 0.5 * dDiceFaceMinH + BD.CUT_EXTRA_MIN) then
|
|
local bDoubleCut = false
|
|
local dCutExtra = BD.CUT_EXTRA
|
|
if dMaxDepth < dDiceFaceMaxH + BD.CUT_EXTRA then
|
|
bDoubleCut = true
|
|
dCutExtra = - 0.5 * dDiceFaceMinH + BD.CUT_EXTRA_MIN
|
|
end
|
|
local nSurfToCut = EgtSurfTmBySewing( nAddGrpId, vCuts[i], false)
|
|
local nFaceUseCut1, nFaceUseCut2 = MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT
|
|
if Proc.Tail then
|
|
nFaceUseCut1, nFaceUseCut2 = nFaceUseCut2, nFaceUseCut1
|
|
end
|
|
if bDoubleCut then
|
|
local bOk, sErr = Fbs.MakeOne( nSurfToCut, 0, sCutting, dSawDiam, nFaceUseCut1, nil, dCutExtra, BD.CUT_SIC, 0, 0, 0, '', b3Raw, true)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
local bOk2, sErr2 = Fbs.MakeOne( nSurfToCut, 0, sCutting, dSawDiam, nFaceUseCut2, nil, dCutExtra, BD.CUT_SIC, 0, 0, 0, '', b3Raw)
|
|
if not bOk2 then return false, sErr2 end
|
|
-- caso standard
|
|
else
|
|
-- lavoro la faccia
|
|
for j = 1, #vCuts[i] do
|
|
-- se taglio dal basso
|
|
if bDownCut then
|
|
-- se strato pari composto da 1 o 2 elementi
|
|
if ( i % 2) == 0 and #vCuts[i] <= 2 then
|
|
-- il primo elemento prende la direzione prevista, il secondo quella opposta
|
|
local vtNewOrthoO = Vector3d( vtOrthoO)
|
|
local dVzLimDwnUp = dNzLimDwnUp
|
|
if j ~= 1 then
|
|
vtNewOrthoO = -vtOrthoO
|
|
if BD.GetNzLimDownUp then
|
|
dVzLimDwnUp = BD.GetNzLimDownUp( b3Raw, vtN, V_NULL(), true)
|
|
elseif not BD.C_SIMM and not BD.TURN and abs( vtN:getY()) > 0.05 then
|
|
dVzLimDwnUp = -0.708
|
|
end
|
|
end
|
|
local bSpecialTangentLeadInOut = ( i % 2 == 0) and ( Proc.AffectedFaces.Left or Proc.AffectedFaces.Right)
|
|
local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtNewOrthoO, dVzLimDwnUp, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, 0, nil, b3Raw, nil, nil, bSpecialTangentLeadInOut)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
-- tutti gli altri casi vengono saltati
|
|
-- caso generale
|
|
else
|
|
-- in generale sta sollevato di pochissimo
|
|
local dExtraCut = -0.1
|
|
-- se tagli paralleli
|
|
if ( i % 2) == 0 then
|
|
-- se non ci sono tagli ortogonali devo affondare
|
|
if bNoPerpCuts then
|
|
dExtraCut = BD.CUT_EXTRA
|
|
-- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama
|
|
elseif bOrthInv then
|
|
dExtraCut = dSawThick
|
|
-- se ultimo taglio, devo affondare
|
|
elseif j == #vCuts[i] then
|
|
dExtraCut = BD.CUT_EXTRA
|
|
end
|
|
end
|
|
local dVzLimDwnUp = dNzLimDwnUp
|
|
if BD.GetNzLimDownUp then
|
|
dVzLimDwnUp = BD.GetNzLimDownUp( b3Raw, vtN, V_NULL(), true)
|
|
elseif not BD.C_SIMM and not BD.TURN and vtN:getZ() > 0.707 then
|
|
dVzLimDwnUp = -0.708
|
|
end
|
|
local bSpecialTangentLeadInOut = ( i % 2 == 0) and ( Proc.AffectedFaces.Left or Proc.AffectedFaces.Right)
|
|
local vtOrthoOAlternative
|
|
if ( i % 2 == 0) and ( Proc.Fct == 1) and bNoPerpCuts then
|
|
vtOrthoOAlternative = - vtOrthoO
|
|
end
|
|
bForceTangentLeadInOut = bForceTangentLeadInOut and ( ( i % 2) ~= 0)
|
|
local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, dVzLimDwnUp, dExtraCut, BD.CUT_SIC, 0, 0, 0, sNotes, b3Raw, nil, nil, bSpecialTangentLeadInOut, bForceTangentLeadInOut, vtOrthoOAlternative)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti tagli diretti della faccia
|
|
else
|
|
-- impostazioni
|
|
local dVzLimDwnUp = dNzLimDwnUp
|
|
local dCutExtra = BD.CUT_EXTRA
|
|
if Proc.AdvTail then
|
|
if bHorizCut then dVzLimDwnUp = -0.01 end
|
|
dCutExtra = -BD.ADVANCE_TAIL_OFFS
|
|
end
|
|
-- lavoro la faccia
|
|
local vtOrthoO
|
|
if bFromBottom and dCutV < dMaxDepth - BD.CUT_EXTRA and vtN:getZ() > 0 then
|
|
vtOrthoO = -Z_AX()
|
|
elseif bHorizCut and ( not bVertCutOk or b3Solid:getDimX() > BD.LEN_SHORT_PART or Proc.AdvTail or ( vtN:getX() > 0 and vtN:getZ() <= 0.708) or ( abs( vtN:getY()) < 0.1 and vtN:getZ() <= 0)) then
|
|
vtOrthoO = Z_AX()
|
|
elseif b3Solid:getDimX() < BD.LEN_SHORT_PART and not Proc.AdvTail and abs( vtN:getY()) > 0.259 and
|
|
vtN:getZ() > -0.174 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
if Proc.Head then
|
|
vtOrthoO = X_AX()
|
|
else
|
|
vtOrthoO = -X_AX()
|
|
end
|
|
elseif vtN:getZ() < dVzLimDwnUp and abs( vtN:getY()) > 0.259 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
if Proc.Head then
|
|
vtOrthoO = X_AX()
|
|
else
|
|
vtOrthoO = -X_AX()
|
|
end
|
|
else
|
|
if vtN:getZ() < dVzLimDwnUp or Proc.Tail or ( Proc.Head and abs( vtN:getY()) > 0.01) then
|
|
vtOrthoO = EgtIf( vtN:getY() > -0.02, -Y_AX(), Y_AX())
|
|
elseif Proc.Head then
|
|
vtOrthoO = EgtIf( vtN:getY() > -0.02, Y_AX(), -Y_AX())
|
|
else
|
|
vtOrthoO = EgtIf( vtN:getY() > 0.02, Y_AX(), -Y_AX())
|
|
end
|
|
-- se è una lavorazione da anticipare diminuisco la profondità del taglio per evitare collisioni con l'albero della lama
|
|
if Proc.AdvTail then
|
|
local _, dH = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw)
|
|
dCutExtra = min( -BD.ADVANCE_TAIL_OFFS, -dH + dMaxDepth)
|
|
end
|
|
end
|
|
-- taglio
|
|
local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, dVzLimDwnUp, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione con testa da sotto
|
|
local function MakeFromDown( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- ingombro del grezzo
|
|
local b3Raw = EgtGetRawPartBBox( nRawId)
|
|
-- ingombro del pezzo
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- dati geometrici del taglio
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- se vero taglio, eventuale inserimento smussi
|
|
if ProcessCut.Identify( Proc) then
|
|
local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
if not bOkc then return bOkc, sErrC end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 2
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
|
|
dSawThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dSawThick
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
local dMaxVertDepth = dMaxDepth
|
|
-- determino la direzione di taglio preferenziale
|
|
local frFac, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw)
|
|
local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA) or Proc.AdvTail
|
|
-- recupero gruppo per geometria addizionale
|
|
local nAddGrpId = BL.GetAddGroup( nPartId)
|
|
if not nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- verifico se necessari tagli supplementari
|
|
EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3)
|
|
local vCuts = {}
|
|
if not Proc.AdvTail and ( dCutH > dMaxDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC or dCutV > dMaxVertDepth - BD.CUT_EXTRA - 3 * BD.COLL_SIC) then
|
|
local ptExtra, vtExtra
|
|
local bAutoCalcSurf = true
|
|
if bFillAreaPiece or bFillTail then
|
|
local ptMiddle = ( b3Solid:getMin() + b3Solid:getMax()) / 2
|
|
ptExtra = Point3d( b3Solid:getMin():getX() + 5 * GEO.EPS_SMALL, ptMiddle:getY(), ptMiddle:getZ())
|
|
vtExtra = X_AX()
|
|
bAutoCalcSurf = false
|
|
end
|
|
vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxVertDepth - BD.CUT_EXTRA, nil ,true)
|
|
end
|
|
--DC.PrintOrderCut( vCuts)
|
|
if #vCuts > 0 then
|
|
-- sistemo posizione nel DB e nome
|
|
local bOrthInv = false
|
|
for i = 1, #vCuts do
|
|
for j = 1, #vCuts[i] do
|
|
EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id))
|
|
EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId)
|
|
if ( i % 2) == 1 then
|
|
local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
|
|
if ( vtN:getY() > 0.707 and vtO:getY() < -0.05) or
|
|
( vtN:getY() < -0.707 and vtO:getY() > 0.05) then
|
|
EgtInvertSurf( vCuts[i][j])
|
|
bOrthInv = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- eseguo (facendo di seguito i due tagli di ogni singolo cubetto)
|
|
for i = 1, #vCuts, 2 do
|
|
-- determino il modo di tagliare dei perpendicolari
|
|
local vtOrthoO_1 = Vector3d( vtN)
|
|
-- determino il modo di tagliare dei paralleli
|
|
local vtOrthoO_2
|
|
local bNoPerpCuts_2 = false
|
|
local vtO
|
|
if #vCuts[i] > 0 then
|
|
vtO = EgtSurfTmFacetNormVersor( vCuts[i][1], 0, GDB_ID.ROOT)
|
|
elseif vCuts[i+2] and #vCuts[i+2] > 0 then
|
|
-- lunghezza faccia nell'eventuale direzione ortogonale
|
|
local asseX = EgtSurfTmFacetNormVersor( vCuts[i+2][1], 0, GDB_ID.ROOT)
|
|
local asseY = asseX ^ vtN
|
|
local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY)
|
|
local b3Fac = EgtGetBBoxRef( vCuts[i+1][1], GDB_BB.STANDARD, Frame)
|
|
-- se lunghezza inferiore al limite, accetto la direzione
|
|
if b3Fac:getDimX() < dMaxDepth - BD.CUT_EXTRA then
|
|
vtO = asseX
|
|
else
|
|
bNoPerpCuts_2 = true
|
|
end
|
|
else
|
|
bNoPerpCuts_2 = true
|
|
end
|
|
if vtO then
|
|
vtOrthoO_2 = Vector3d( vtO) * EgtIf( bOrthInv, -1, 1)
|
|
else
|
|
if bHorizCut then
|
|
vtOrthoO_2 = -Z_AX()
|
|
elseif vtN:getY() > -0.02 then
|
|
if not Proc.Head then
|
|
vtOrthoO_2 = -Y_AX()
|
|
else
|
|
vtOrthoO_2 = Y_AX()
|
|
end
|
|
else
|
|
vtOrthoO_2 = -Y_AX()
|
|
end
|
|
end
|
|
-- lavoro le coppie di facce del singolo cubetto
|
|
for j = 1, max( #vCuts[i], #vCuts[i+1]) do
|
|
-- extra taglio per perpendicolari
|
|
local dExtraCut_1 = -0.1
|
|
-- extra taglio per paralleli
|
|
local dExtraCut_2 = -0.1
|
|
-- se non ci sono tagli ortogonali devo affondare
|
|
if bNoPerpCuts_2 then
|
|
dExtraCut_2 = BD.CUT_EXTRA
|
|
-- se altrimenti tagli ortogonali invertiti, devo approfondire dello spessore lama
|
|
elseif bOrthInv then
|
|
dExtraCut_2 = dSawThick
|
|
-- se ultimo taglio, devo affondare
|
|
elseif j == #vCuts[i+1] then
|
|
dExtraCut_2 = BD.CUT_EXTRA
|
|
end
|
|
-- taglio perpendicolare (limite Vz Down Up messo a -2 per non farlo mai intervenire)
|
|
if vCuts[i][j] then
|
|
local bSpecialTangentLeadInOut = ( i % 2 == 0) and ( Proc.AffectedFaces.Left or Proc.AffectedFaces.Right)
|
|
local bOk, sErr = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO_1, -2, dExtraCut_1, BD.CUT_SIC, 0, 0, 0, nil, b3Raw, nil, nil, bSpecialTangentLeadInOut)
|
|
if not bOk then
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
-- taglio parallelo (limite Vz Down Up messo a -2 per non farlo mai intervenire)
|
|
if vCuts[i+1][j] then
|
|
local bSpecialTangentLeadInOut = ( i % 2 == 0) and ( Proc.AffectedFaces.Left or Proc.AffectedFaces.Right)
|
|
local bOk, sErr = Fbs.MakeOne( vCuts[i+1][j], 0, sCutting, dSawDiam, vtOrthoO_2, -2, dExtraCut_2, BD.CUT_SIC, 0, 0, 0, nil, b3Raw, nil, nil, bSpecialTangentLeadInOut)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti tagli diretti della faccia
|
|
else
|
|
-- lavoro la faccia
|
|
local vtOrthoO
|
|
if bHorizCut and ( b3Solid:getDimX() > BD.LEN_SHORT_PART or Proc.AdvTail or vtN:getX() > 0) then
|
|
vtOrthoO = -Z_AX()
|
|
elseif b3Solid:getDimX() < BD.LEN_SHORT_PART and not Proc.AdvTail and abs( vtN:getY()) > 0.259 and vtN:getZ() > -0.174 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
if Proc.Head then
|
|
vtOrthoO = X_AX()
|
|
else
|
|
vtOrthoO = -X_AX()
|
|
end
|
|
elseif abs( vtN:getY()) > 0.259 and abs( vtN:getY()) > abs( vtN:getZ()) and dCutH < dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
if Proc.Head then
|
|
vtOrthoO = X_AX()
|
|
else
|
|
vtOrthoO = -X_AX()
|
|
end
|
|
elseif vtN:getY() > -0.02 then
|
|
if Proc.Head then
|
|
vtOrthoO = -Y_AX()
|
|
else
|
|
vtOrthoO = Y_AX()
|
|
end
|
|
else
|
|
if Proc.Head then
|
|
vtOrthoO = Y_AX()
|
|
else
|
|
vtOrthoO = -Y_AX()
|
|
end
|
|
end
|
|
-- taglio (limite Vz Down Up messo a -2 per non farlo mai intervenire)
|
|
local dCutExtra = BD.CUT_EXTRA
|
|
if Proc.AdvTail then
|
|
dCutExtra = min( -BD.ADVANCE_TAIL_OFFS, dMaxVertDepth - dCutV)
|
|
end
|
|
local bOk, sErr = Fbs.MakeOne( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, -2, dCutExtra, BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut, bForced, b3Raw, sNotes, dOvmTail, bUpdateIng, nLimitingSurf, bForceTangentLeadInOut)
|
|
-- sovramateriale di coda
|
|
dOvmTail = dOvmTail or BD.OVM_MID
|
|
-- ingombro del grezzo
|
|
b3Raw = b3Raw or EgtGetRawPartBBox( nRawId)
|
|
-- ingombro del pezzo
|
|
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
|
|
-- dati geometrici del taglio
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- se taglio di testa
|
|
if not bForced then
|
|
if not BL.IsCutNeeded( Proc, b3Raw, dOvmHead, dOvmTail) then
|
|
return true
|
|
end
|
|
end
|
|
-- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -20deg e sbandato oltre 1deg oppure sezione più larga di 2 cubetti o pezzo corto)
|
|
local bDownHead = ( BD.DOWN_HEAD and vtN:getZ() < -0.341 and
|
|
( abs( vtN:getY()) > 0.017 or b3Raw:getDimY() > 2 * ( BD.MAX_DIM_DICE - BD.CUT_EXTRA_MIN) or b3Raw:getDimX() < BD.LEN_SHORT_PART))
|
|
local bDownTurn = ( BD.TURN and vtN:getZ() < -0.017)
|
|
local bTopHead = ( BD.DOWN_HEAD and ( vtN:getZ() > -0.342 or not bDownHead))
|
|
-- recupero la lavorazione
|
|
local sCutType = EgtIf( Proc.Head, 'HeadSide', 'TailSide')
|
|
local sCutting
|
|
local bH2
|
|
sCutting, bH2 = ML.FindCutting( sCutType, bTopHead, bDownHead)
|
|
bDownHead = bH2 and bDownHead
|
|
if not sCutting then
|
|
local sErr = 'Error : cutting not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local bNoDicing = false
|
|
-- se taglio con testa da sopra
|
|
if not bDownHead and not bDownTurn then
|
|
local bOk, sErr, bNoDicing2 = MakeFromTop( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut, bForced, b3Raw, sNotes, nLimitingSurf, bForceTangentLeadInOut)
|
|
bNoDicing = bNoDicing2
|
|
if not bOk then return false, sErr end
|
|
-- altrimenti taglio con testa da sotto
|
|
else
|
|
local bOk, sErr = MakeFromDown( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
-- Aggiornamento ingombro (se vero taglio o richiesto)
|
|
-- Se lascio il cordolo (bNoDicing) non aggiorno il grezzo perchè lo scarto rimane attaccato
|
|
if ( ProcessCut.Identify( Proc) or bUpdateIng) and not bNoDicing then
|
|
UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw)
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessCut
|