0d5e2737e4
- su Tenoni aggiunta gestione smusso, migliorata scelta tra sopra e sotto per il punto di inizio e in VerifyOrientation aggiunta trave medio alta - su SawCut aggiunta gestione testa da sotto - su Cut allargati i limiti di lunghezza per tagli verticali inclinati di fianco.
244 lines
11 KiB
Lua
244 lines
11 KiB
Lua
-- ProcessSawCut.lua by Egaltech s.r.l. 2022/12/19
|
|
-- Gestione calcolo taglio di lama per Travi
|
|
-- 2022/06/10 Aggiunto il parametro dOvmTail per gestire sovramateriali in coda diversi da OVM_MID (sezioni alte e larghe).
|
|
-- 2022/12/19 Aggiunta gestione testa da sotto.
|
|
|
|
-- Tabella per definizione modulo
|
|
local ProcessSawCut = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
local DC = require( 'DiceCut')
|
|
local Cut = require( 'ProcessCut')
|
|
local LongCut = require( 'ProcessLongCut')
|
|
|
|
EgtOutLog( ' ProcessSawCut started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function ProcessSawCut.Identify( Proc)
|
|
return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 13)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessSawCut.Classify( Proc, b3Raw)
|
|
-- recupero i dati del versore direzione di accesso della lavorazione
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if not AuxId then return false end
|
|
AuxId = AuxId + Proc.Id
|
|
local vtDir = EgtSV( AuxId, GDB_ID.ROOT)
|
|
return true, ( vtDir:getZ() <= - 0.5)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function ProcessSawCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, dOvmTail)
|
|
-- sovramateriale di coda
|
|
dOvmTail = dOvmTail or BD.OVM_MID
|
|
-- 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 on process ' .. tostring( Proc.Id) .. ' part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero e verifico l'entità vettore
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId or EgtGetType( AuxId) ~= GDB_TY.GEO_VECTOR then
|
|
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing access direction'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local vtDir = EgtSV( AuxId, GDB_ID.ROOT)
|
|
-- dati geometrici del taglio
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
local frFace = Frame3d( ptC, vtDir ^ vtN, vtDir, vtN)
|
|
local b3Face = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFace)
|
|
local dLen = b3Face:getDimX()
|
|
local dWidth = b3Face:getDimY()
|
|
-- 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()) < dOvmTail + 10 * GEO.EPS_SMALL then
|
|
return true
|
|
end
|
|
end
|
|
-- recupero flag per inizio e fine interni
|
|
local bInside = (( EgtGetInfo( Proc.Id, 'Q01', 'i') or 0) ~= 0)
|
|
-- abilitazione lavorazione da sotto
|
|
local bDownHead = ( BD.DOWN_HEAD and vtDir:getZ() < -0.341)
|
|
local bTopHead = ( BD.DOWN_HEAD and ( vtDir:getZ() > -0.342 or not bDownHead))
|
|
-- recupero la lavorazione
|
|
local sCutting
|
|
sCutting, bDownHead = ML.FindCutting( 'HeadSide', bTopHead, bDownHead)
|
|
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 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
|
|
-- determino se lavorazione da davanti o da dietro e se da sotto
|
|
local bFront = ( vtDir ^ vtN):getX() > 0
|
|
local bDownUp = ( not bDownHead and vtN:getZ() < -0.259)
|
|
local bFillAreaPiece
|
|
-- se non da sotto
|
|
if not bDownUp then
|
|
-- se poco inclinata ( inclinazione inferiore a 21.56 deg)
|
|
if vtN:getZ() > 0.93 then
|
|
-- verifico se la superfice è prevelentemente orizzontale con Z positiva e occupa tutta la trave o occupa sicuramente la faccia in Y
|
|
-- e almeno 3/4 della lunghezza in X e sborda in X e non interessa la faccia inferiore,
|
|
-- si possono far partire i tagli a cubetti dalla testa o lasciare il cordoncino centrale
|
|
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() or Proc.Box:getDimX() > 1500.000))) and
|
|
abs( Proc.Box:getMin():getY() - b3Solid:getMin():getY()) < 10*GEO.EPS_SMALL and abs( Proc.Box:getMax():getY() - b3Solid:getMax():getY()) < 10*GEO.EPS_SMALL and
|
|
b3Solid:getMin():getZ() < Proc.Box:getMin():getZ() - 100 * GEO.EPS_SMALL then
|
|
bFillAreaPiece = true
|
|
end
|
|
-- 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() or Proc.Box:getDimX() > 1500.000))) 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 ho il parametro Q04 = 1 e il taglio copre la lunghezza della trave allora lancio il processo dell'L10
|
|
local nAsLongCut = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0
|
|
if nAsLongCut == 1 and bFillAreaPiece then
|
|
return LongCut.Make( Proc, nPhase, nRawId, nPartId, true)
|
|
-- se non ho taglio lungo passo al Cut per taglio a cubetti
|
|
elseif bFillAreaPiece and abs(( vtDir ^ vtN):getY()) > 0.866 then
|
|
local bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, 0, false, true)
|
|
-- se è andata a buon fine oppure ha fallito esco
|
|
-- nel caso non ha fatto i tagli a cubetti (sErr vale -1) continuo
|
|
if bOk or ( not bOk and type(sErr) ~= 'number') then
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
-- determino affondamento e distanza interna da inizio e fine
|
|
local dDepth = min( dWidth, dMaxDepth - BD.COLL_SIC)
|
|
local dInsDist = 0
|
|
if bInside then
|
|
dInsDist = sqrt( dSawDiam * dDepth - dDepth * dDepth)
|
|
if 2 * dInsDist > dLen - 2 then
|
|
dInsDist = ( dLen - 2) / 2
|
|
dDepth = dSawDiam / 2 - sqrt( dSawDiam * dSawDiam / 4 - dInsDist * dInsDist)
|
|
end
|
|
end
|
|
-- determino numero di parti
|
|
local dStartAccDist = BD.LONGCUT_ENDLEN
|
|
local dEndAccDist = BD.LONGCUT_ENDLEN
|
|
local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN)
|
|
local dC = 0
|
|
if nC > 0 then
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = min( dC, dStartAccDist)
|
|
dEndAccDist = min( dC, dEndAccDist)
|
|
dC = ( dLen - dStartAccDist - dEndAccDist) / nC
|
|
nC = nC + 2
|
|
else
|
|
if dLen > min( dStartAccDist, dEndAccDist) then
|
|
nC = 2
|
|
dStartAccDist = dLen / 2
|
|
dEndAccDist = dStartAccDist
|
|
else
|
|
nC = 1
|
|
dStartAccDist = 0
|
|
dEndAccDist = 0
|
|
end
|
|
end
|
|
-- determino l'utilizzo della faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( vtDir)
|
|
if bDownUp then
|
|
nFaceUse = BL.GetOrtupOpposite( nFaceUse)
|
|
end
|
|
-- si percorrono i lati alto e basso della faccia
|
|
for i = 1, nC do
|
|
-- Posizione braccio portatesta
|
|
local nSCC = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
|
|
if abs( vtDir:getY()) > 0.5 then
|
|
nSCC = EgtIf( vtDir:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
end
|
|
-- ciclo sulle passate
|
|
local dOffset = dWidth - dDepth ;
|
|
local dLioTang = 0
|
|
local dLioPerp = dDepth + BD.CUT_SIC ;
|
|
-- inserisco le parti di lavorazione
|
|
local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nC)
|
|
local nMchFId = EgtAddMachining( sNameF, sCutting)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, 0}})
|
|
-- limito opportunamente la lavorazione
|
|
local dSal = EgtIf( i == 1, -dInsDist, -dStartAccDist - ( i - 2) * dC)
|
|
local dEal = EgtIf( i == nC, -dInsDist, -dEndAccDist - ( nC - i - 1) * dC)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- imposto offset radiale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffset)
|
|
-- imposto offset longitudinale
|
|
if Proc.Grp == 0 then
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, EgtIf( bDownUp, dSawThick / 2, -dSawThick / 2))
|
|
end
|
|
-- imposto lato di lavoro e inversione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bFront ~= bDownUp, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT))
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bFront)
|
|
-- imposto attacco/uscita
|
|
EgtSetMachiningParam( MCH_MP.LITANG, dLioTang)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, dLioTang)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp)
|
|
-- imposto posizione braccio porta testa per non ingombrare agli estremi
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto uso della faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessSawCut
|