Files
DataBeam/LuaLibs/ProcessCut.lua
T
Dario Sassi 031ad00966 DataBeam :
- aggiunto controllo file macchina mlde per ricalcolo
- modifiche per PF1250.
2021-02-22 10:56:12 +00:00

719 lines
30 KiB
Lua

-- ProcessCut.lua by Egaltech s.r.l. 2021/02/21
-- Gestione calcolo singoli tagli di lama per Travi
-- Tabella per definizione modulo
local ProcessCut = {}
-- Include
require( 'EgtBase')
local BL = require( 'BeamLib')
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)
return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10)
end
---------------------------------------------------------------------
-- Classificazione della feature
function ProcessCut.Classify( Proc, b3Raw)
-- se PF con testa da sotto, ammessa qualunque orientazione
if BD.C_SIMM and BD.DOWN_HEAD 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 then
local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0)
if DimH > BD.MAX_DIM_DICE then
return true, true
end
end
-- verifico se c'è un taglio da sotto e se è nei limiti
local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw)
local bDownCut = ( vtN:getZ() <= dNzLimDwnUp)
if bDownCut then
local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, 0)
-- confronto anche qua la distanza maggiore della faccia con la massima distanza del DiceCut
-- e se il rapporto supera il 2 (implica che genera 3 tagli) dichiaro impossibile la lavorazione
if DimH and BD.MAX_DIM_DICE and abs( BD.MAX_DIM_DICE) > 20 * GEO.EPS_SMALL and abs( DimH / BD.MAX_DIM_DICE) > 2 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 EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchId, false)
return false, sErr
end
-- Inserisco la lavorazione del lato opposto
local sName2 = 'SJN_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMch2Id = EgtAddMachining( sName2, sMilling)
if not nMch2Id then
local sErr = 'Error adding machining ' .. sName2 .. '-' .. sMilling
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ AuxId, -1}})
-- inverto direzione utensile
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
-- assegno affondamento e offset radiale
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth + dExtra)
EgtSetMachiningParam( MCH_MP.OFFSR, dExtra)
-- assegno lato di lavoro
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchId, 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())
if ProcessCut.Identify( Proc) and Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < b3Raw:getMin():getZ() + dMinHIng 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 - 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 - 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)
-- ingombro del grezzo
local b3Raw = EgtGetRawPartBBox( nRawId)
-- ingombro del pezzo
local Ls = EgtGetFirstNameInGroup( nPartId, 'Box')
local b3Solid = EgtGetBBoxGlob( Ls 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)
-- limiti di taglio (se molto di lato e inclinati sono permessi fino a -45deg)
local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw)
if not BD.C_SIMM and abs( vtN:getX()) < 0.5 then dNzLimDwnUp = -0.707 end
local bDownCut = ( vtN:getZ() <= dNzLimDwnUp)
if bFromBottom == nil then bFromBottom = ( b3Solid:getDimX() < BD.LEN_SHORT_PART and vtN:getX() < 0 and vtN:getZ() > 0.25) end
-- verifico se da considerare taglio lungo ( non da sotto, inclinato meno di 21.56deg, largo come la trave e abbastanza lungo)
local bLongCut = ( not bDownCut and vtN:getZ() > 0.93 and
Proc.Box:getDimY() > b3Solid:getDimY() - 10 * GEO.EPS_SMALL and
( Proc.Box:getDimX() > 0.75 * b3Solid:getDimX() or Proc.Box:getDimX() > 1500.000))
-- se taglio lungo e Q04 = 1 allora lancio il processo dell'L10
if bLongCut and EgtGetInfo( Proc.Id, 'Q04', 'i') == 1 then
return LongCut.Make( Proc, nPhase, nRawId, nPartId, true)
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.75 * 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)'
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)'
EgtOutLog( sErr)
return false, sErr
end
end
end
end
-- se vero taglio, eventuale inserimento smussi
if Proc.Prc == 10 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 _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0)
local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA and not bDownCut)
-- verifico se necessari tagli supplementari
EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3)
local vCuts = {}
if 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( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxDepth - BD.CUT_EXTRA)
-- 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( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxDepth - BD.CUT_EXTRA, Proc.Box:getDimY())
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
--DC.PrintOrderCut( vCuts)
if #vCuts > 0 then
-- 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
-- sistemo posizione nel DB e nome
local bOrthInv = false
for i = 1, #vCuts do
for j = 1, #vCuts[i] do
EgtRelocateGlob( vCuts[i][j], nAddGrpId)
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
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
if bHorizCut then
vtOrthoO = Z_AX()
elseif vtN:getY() > -0.02 then
if not Proc.Head then
vtOrthoO = -Y_AX()
else
vtOrthoO = Y_AX()
end
else
vtOrthoO = -Y_AX()
end
end
end
-- 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 not BD.C_SIMM then dVzLimDwnUp = -0.707 end
end
local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtNewOrthoO, dVzLimDwnUp, BD.CUT_EXTRA_MIN, BD.CUT_SIC, 0, 0, nil, b3Raw)
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 not BD.C_SIMM and vtN:getZ() > 0.707 then dVzLimDwnUp = -0.708 end
local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, dVzLimDwnUp, dExtraCut, BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then
return bOk, sErr
end
end
end
end
-- altrimenti tagli diretti della faccia
else
-- lavoro la faccia
local vtOrthoO
if bFromBottom and dCutV < dMaxVertDepth - BD.CUT_EXTRA and vtN:getZ() > 0 then
vtOrthoO = -Z_AX()
elseif bHorizCut and ( b3Solid:getDimX() > BD.LEN_SHORT_PART or vtN:getX() > 0) then
vtOrthoO = Z_AX()
elseif b3Solid:getDimX() < BD.LEN_SHORT_PART 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() < dNzLimDwnUp 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
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
local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, dNzLimDwnUp, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then
return bOk, sErr
end
end
-- Aggiornamento ingombro
UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw)
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 Ls = EgtGetFirstNameInGroup( nPartId, 'Box')
local b3Solid = EgtGetBBoxGlob( Ls 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 vero taglio, eventuale inserimento smussi
if Proc.Prc == 10 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 _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0)
local bHorizCut = ( dCutV < dMaxVertDepth - BD.CUT_EXTRA)
-- verifico se necessari tagli supplementari
EgtOutLog( string.format( 'MaxDepth=%.1f MaxVertDepth=%.1f CutH=%.1f CutV=%.1f', dMaxDepth, dMaxVertDepth, dCutH, dCutV), 3)
local vCuts = {}
if 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( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, bAutoCalcSurf, ptExtra, vtExtra, dMaxDepth - BD.CUT_EXTRA)
end
--DC.PrintOrderCut( vCuts)
if #vCuts > 0 then
-- 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
-- sistemo posizione nel DB e nome
local bOrthInv = false
for i = 1, #vCuts do
for j = 1, #vCuts[i] do
EgtRelocateGlob( vCuts[i][j], nAddGrpId)
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
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
if bHorizCut then
vtOrthoO = Z_AX()
elseif vtN:getY() > -0.02 then
if not Proc.Head then
vtOrthoO = -Y_AX()
else
vtOrthoO = Y_AX()
end
else
vtOrthoO = -Y_AX()
end
end
end
-- lavoro la faccia
for j = 1, #vCuts[i] do
-- 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
-- taglio (limite Vz Down Up messo a -2 per non farlo mai intervenire)
local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, -2, dExtraCut, BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then
return bOk, sErr
end
end
end
-- altrimenti tagli diretti della faccia
else
-- lavoro la faccia
local vtOrthoO
if bHorizCut and ( b3Solid:getDimX() > BD.LEN_SHORT_PART or vtN:getX() > 0) then
vtOrthoO = Z_AX()
elseif b3Solid:getDimX() < BD.LEN_SHORT_PART 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 bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, vtOrthoO, -2, BD.CUT_EXTRA, BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then
return bOk, sErr
end
end
-- Aggiornamento ingombro
UpdateEncumbrance( Proc, vtN, dOvmHead, nRawId, b3Solid, b3Raw)
return true
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut)
-- ingombro del grezzo
local b3Raw = EgtGetRawPartBBox( nRawId)
-- dati geometrici del taglio
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
-- se taglio di testa
if Proc.Head then
-- se coincide con il taglio di separazione precedente, non va fatto
if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then
return true
end
-- altrimenti taglio di coda
else
-- se coincide con taglio di separazione, non va fatto
if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then
return true
end
end
-- se coincide con un taglio frontale non va fatto
if Proc.CutFront then
return true
end
-- abilitazione lavorazione da sotto (testa da sotto e direzione normale sotto -20deg)
local bTopHead = ( BD.DOWN_HEAD and vtN:getZ() > -0.342)
local bDownHead = ( BD.DOWN_HEAD and vtN:getZ() < -0.342)
-- recupero la lavorazione
local sCutType = EgtIf( Proc.Head, 'HeadSide', 'TailSide')
local sCutting = ML.FindCutting( sCutType .. EgtIf( bDownHead, '_H2', ''))
if not sCutting and bTopHead then
sCutting = ML.FindCutting( sCutType)
bDownHead = false
end
if not sCutting then
local sErr = 'Error : cutting not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- se taglio con testa da sopra
if not bDownHead then
return MakeFromTop( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut)
else
return MakeFromDown( sCutting, Proc, nPhase, nRawId, nPartId, dOvmHead, bFromBottom, bCustDiceCut)
end
end
---------------------------------------------------------------------
return ProcessCut