605 lines
28 KiB
Lua
605 lines
28 KiB
Lua
-- ProcessDoubleCut.lua by Egaltech s.r.l. 2023/03/22
|
|
-- Gestione calcolo doppi tagli di lama per Travi
|
|
-- 2022/08/29 Implementata la fresatura dal lato per tagli problematici per PF1250.
|
|
-- 2023/03/22 Eliminata SetOpenSide locale, si usa quella di libreria.
|
|
-- 2023/12/07 Correzione in Classify in scelta ribaltamento trave quando si è in condizioni downUp
|
|
|
|
-- Tabella per definizione modulo
|
|
local ProcessDoubleCut = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
local Fbs = require( 'FacesBySaw')
|
|
local DC = require( 'DiceCut')
|
|
local Cut = require( 'ProcessCut')
|
|
|
|
EgtOutLog( ' ProcessDoubleCut started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function ProcessDoubleCut.Identify( Proc)
|
|
return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessDoubleCut.Classify( Proc, b3Raw)
|
|
--se una faccia, uso la classificazione dei tagli singoli
|
|
if Proc.Fct == 1 then return Cut.Classify( Proc, b3Raw) end
|
|
-- 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
|
|
-- determino se convesso o concavo
|
|
local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
local bConvex = ( not bAdj or ( dAng > 0))
|
|
-- se convesso
|
|
if bConvex then
|
|
-- recupero i dati di ogni singola faccia
|
|
for i = 1, 2 do
|
|
local nFac = i - 1
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFac, 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 la massima estensione orizzontale lineare della faccia
|
|
local _, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, nFac, b3Raw)
|
|
-- confronto questa estensione con la massima dimensione del DiceCut (impossibile lavorare se maggiore)
|
|
if DimH > BD.MAX_DIM_DICE and DimV > BD.MAX_DIM_DICE then
|
|
return true, true
|
|
end
|
|
end
|
|
local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN)
|
|
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 = BL.GetFaceHvRefDim( Proc.Id, nFac)
|
|
-- 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
|
|
end
|
|
return true, false
|
|
-- altrimenti concavo, verifico le normali delle facce per tagli da sotto
|
|
else
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
local vtX = vtN[1] ^ vtN[2] ; vtX:normalize()
|
|
local vtY = { vtX ^ vtN[1], - vtX ^ vtN[2]}
|
|
for i = 1, 2 do
|
|
local dNzLimDwnUp = BL.GetNzLimDownUp( b3Raw, vtN[i], vtY[i])
|
|
local bDownCut = ( vtN[i]:getZ() <= dNzLimDwnUp)
|
|
if bDownCut then
|
|
-- dimensione della faccia perpendicolarmente alla linea di intersezione tra le facce
|
|
local frRef = Frame3d( ptC[i], ptC[i] + 100 * vtX, ptC[i] + 100 * vtY[i])
|
|
local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, i-1, GDB_BB.STANDARD, frRef)
|
|
-- dimensione dell'altra faccia perpendicolarmente alla linea di intersezione tra le facce
|
|
local frRef2 = Frame3d( ptC[3-i], ptC[3-i] + 100 * vtX, ptC[3-i] + 100 * vtY[3-1])
|
|
local b3Ref2 = EgtSurfTmGetFacetBBoxRef( Proc.Id, 2-i, GDB_BB.STANDARD, frRef2)
|
|
-- se faccia grande
|
|
if b3Ref:getDimY() > BD.MAX_DIM_DICE then
|
|
-- se altra faccia piccola
|
|
if b3Ref2:getDimY() < BD.MAX_DIM_DICE then
|
|
return true, true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return true, false
|
|
end
|
|
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 l'entità curva associata
|
|
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
|
|
if AuxId then AuxId = AuxId + Proc.Id end
|
|
if not AuxId then return true end
|
|
if ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then
|
|
local sErr = 'Error : missing profile geometry'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
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 direzione orizzontale o anche testa da sotto (non propago la segnalazione a TS3)
|
|
local bVert = ( abs( vtExtr:getZ()) > 0.1)
|
|
if bVert and not BD.DOWN_HEAD then
|
|
local sWarn = 'Warning : skipped not horizontal chamfer'
|
|
EgtOutLog( sWarn)
|
|
return true
|
|
end
|
|
-- eseguo lo smusso solo se feature larga come la trave
|
|
if ( not bVert and dWidth < b3Raw:getDimY() - 1) or ( bVert and dWidth < b3Raw:getDimZ() - 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 (Mark) not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local sMillingDw = ML.FindMilling( 'Mark_H2', nil, nil, nil, nil, false, true)
|
|
if bVert and not sMillingDw then
|
|
local sErr = 'Error : milling (Mark_H2) 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, EgtIf( not bVert or vtExtr:getZ() > 0.1, sMilling, sMillingDw))
|
|
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, EgtIf( not bVert or vtExtr:getZ() < -0.1, sMilling, sMillingDw))
|
|
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
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyPocket( Proc, dDiam, dDepth, dMaxTotLen, sMchFindMaster, bPocketDown)
|
|
-- tipo di svuotatura
|
|
local sMchFind = EgtIf( sMchFindMaster and #sMchFindMaster > 0, sMchFindMaster, 'Pocket')
|
|
-- ricerca della svuotatura
|
|
local sPocketing
|
|
if dDepth then
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.8 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.6 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.4 * dDepth, dMaxTotLen, not bPocketDown, bPocketDown) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen)
|
|
else
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen)
|
|
end
|
|
if not sPocketing then
|
|
return false
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local bUsePocketing = false
|
|
local dMaxDepth = 0
|
|
local dToolDiam = 0
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
bUsePocketing = true
|
|
end
|
|
return bUsePocketing, sPocketing, dMaxDepth, dToolDiam
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeBySidePocket( Proc, nPhase, nRawId, nPartId, nAddGrpId, b3Solid)
|
|
local nFirstMachId
|
|
local sWarn
|
|
local sMchFind = 'OpenPocket'
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt
|
|
local bBadMach = false
|
|
-- ottengo le dimensioni del tunnel
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, nSurfInt = BL.GetTunnelDimension( Proc, nPartId)
|
|
-- posso utilizzare utensile con diametro doppio della dimensione minima
|
|
dDimMin = min( 2 * dDimMin, BD.MAXDIAM_POCK_CORNER)
|
|
local nPathInt
|
|
-- verifico se è presente la testa da sotto e se è necessario usarla
|
|
bMillDown = ( BD.DOWN_HEAD == true and abs( vtOrtho:getZ()) >= 0.707)
|
|
-- cerco l'utensile di svuotatura per la testa sopra
|
|
local bMakePocket, sPocketing, dMaxDepth, dDiamTool = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind)
|
|
local bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn
|
|
-- cerco anche l'utensile per la testa sotto, nel caso servisse
|
|
if bMillDown then
|
|
bMakePocketDn, sPocketingDn, dMaxDepthDn, dDiamToolDn = VerifyPocket( Proc, dDimMin, dDepth / 2, nil, sMchFind, true)
|
|
-- se è negativo inverto il versore e la faccia
|
|
if vtOrtho:getZ() < 0 then
|
|
vtOrtho = -vtOrtho
|
|
EgtInvertSurf( nSurfInt)
|
|
end
|
|
end
|
|
if bMakePocket then
|
|
-- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale)
|
|
-- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura
|
|
-- e assegno l'estrusione
|
|
nPathInt = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId)
|
|
EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB)
|
|
BL.SetOpenSide( nPathInt, b3Solid)
|
|
-- variabili per parametri lavorazione
|
|
local dMachDepth
|
|
local dElev = 0
|
|
local bDoubleSide
|
|
local bOneShot
|
|
local bComplete = true
|
|
-- imposto altezza aggiuntiva di elevazione
|
|
local dCollSic = BL.CalcCollisionSafety( vtOrtho)
|
|
-- se possibile svuotare completamente da una sola parte
|
|
if dMaxDepth > ( dDepth + BD.CUT_EXTRA + dCollSic) then
|
|
dMachDepth = ( dDepth / 2) + BD.CUT_EXTRA
|
|
dElev = dDepth + BD.CUT_EXTRA
|
|
bOneShot = true
|
|
else
|
|
-- se direzione verso la verticale setto max affondamento possibile ed
|
|
-- emetto messaggio di warning perché non lavorabile interamente
|
|
if abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then
|
|
dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
bComplete = false
|
|
-- altrimenti setto il flag per fare la svuotatura da due parti
|
|
else
|
|
-- se l'altezza utensile riesce a lavorare completamente da due parti
|
|
if dMaxDepth > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then
|
|
dMachDepth = BD.CUT_EXTRA_MIN
|
|
dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN
|
|
-- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione
|
|
else
|
|
dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
-- se molto inclinato rispetto alla normale della faccia di riferimento, lavorazione non idonea per probabili collisioni
|
|
local vtRef = Y_AX()
|
|
if abs( vtOrtho:getX()) > abs( vtOrtho:getY()) and abs( vtOrtho:getX()) > abs( vtOrtho:getZ()) then
|
|
vtRef = X_AX()
|
|
elseif abs( vtOrtho:getZ()) > abs( vtOrtho:getX()) and abs( vtOrtho:getZ()) > abs( vtOrtho:getY()) then
|
|
vtRef = Z_AX()
|
|
end
|
|
if abs( vtOrtho * vtRef) < 0.5 then
|
|
bBadMach = true
|
|
end
|
|
end
|
|
bDoubleSide = true
|
|
end
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nPathInt, -1}})
|
|
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
|
|
local bInvertMach
|
|
if vtOrtho:getZ() < BD.NZ_MINA and abs(vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
|
|
elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL and not ( -(vtOrtho:getZ()) < BD.NZ_MINA) then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameOrOppositeVectorApprox( vtOrtho, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtOrtho:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtOrtho:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
-- inverto il percorso di lavorazione per lavorare sinistro
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- imposto affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
-- se posso applicare la svuotatura sul lato opposto
|
|
if bDoubleSide then
|
|
-- se ho la lavorazione da sotto ricalcolo in base a questa lavorazione
|
|
if bMakePocketDn then
|
|
-- sPocketing = sPocketingDn
|
|
-- dMaxDepth = dMaxDepthDn
|
|
-- dDiamTool = dDiamToolDn
|
|
-- se l'altezza utensile riesce a lavorare completamente da due parti
|
|
if dMaxDepthDn > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then
|
|
dMachDepth = BD.CUT_EXTRA_MIN
|
|
dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN
|
|
-- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione
|
|
else
|
|
dMachDepth = dMaxDepthDn - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepthDn
|
|
bComplete = false
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
else
|
|
-- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura
|
|
-- setto i parametri affondamento ed emetto warning
|
|
if dMaxDepth < ( dDepth / 2) + BD.CUT_EXTRA + dCollSic then
|
|
dMachDepth = dMaxDepth - (dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
bComplete = false
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, EgtIf( bMakePocketDn, sPocketingDn, sPocketing))
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. EgtIf( bMakePocketDn, sPocketingDn, sPocketing)
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nPathInt, -1}})
|
|
-- imposto direzione utensile opposta
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameVectorApprox( vtOrtho, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtOrtho:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtOrtho:getY() < GEO.EPS_SMALL then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
-- inverto il percorso di lavorazione per lavorare sinistro
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- imposo affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';'
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
end
|
|
return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId
|
|
end
|
|
return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLundIdFace, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function ProcessDoubleCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- se singola faccia, passo a quella lavorazione
|
|
if Proc.Fct == 1 then return Cut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, nil, nil, bForced, b3Raw, sNotes, dOvmTail, true) end
|
|
-- 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 delle facce
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- normale media per capire se taglio di testa o di coda
|
|
local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize()
|
|
local bHead = ( vtNm:getX() > 0)
|
|
-- angolo diedro per stabilire se taglio convesso
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
local bConvex = true
|
|
local bOnY = true
|
|
local ptPs = ( ptC[1] + ptC[2]) / 2
|
|
if bAdj then
|
|
local vtDir = ptP1 - ptP2 ; vtDir:normalize()
|
|
bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY()))
|
|
ptPs = ( ptP1 + ptP2) / 2
|
|
bConvex = ( dAng > 0)
|
|
end
|
|
-- determino quale faccia è più grande
|
|
local _, dB1, dH1 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0)
|
|
local _, dB2, dH2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 1)
|
|
local nBigInd = EgtIf( dB1 * dH1 >= dB2 * dH2, 1, 2)
|
|
local nSmaInd = 3 - nBigInd
|
|
-- inserimento smussi
|
|
local bOkc, sErrC = MakeChamfer( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
if not bOkc then return bOkc, sErrC end
|
|
-- 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
|
|
-- se convesso, lo tratto come due tagli singoli
|
|
if bConvex then
|
|
-- lavoro per prima la faccia più diretta in alto
|
|
local vOrd = { 1, 2}
|
|
if vtN[2]:getZ() > vtN[1]:getZ() then
|
|
vOrd = { 2, 1}
|
|
end
|
|
-- creo piano di taglio coincidente con la prima faccia e lo lavoro
|
|
local AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[1]], vtN[vOrd[1]], b3Solid, GDB_RT.GLOB)
|
|
if AddId then
|
|
EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id))
|
|
EgtSetInfo( AddId, 'TASKID', Proc.TaskId)
|
|
local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD)
|
|
-- applico lavorazione
|
|
local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Add, Fct = 1, Flg = Proc.Flg,
|
|
Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId}
|
|
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, nil, nil, bForced, b3Raw, sNotes, dOvmTail, true)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
-- creo piano di taglio coincidente con la seconda faccia e lo lavoro
|
|
AddId = EgtSurfTmPlaneInBBox( nAddGrpId, ptC[vOrd[2]], vtN[vOrd[2]], b3Solid, GDB_RT.GLOB)
|
|
if AddId then
|
|
EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id))
|
|
EgtSetInfo( AddId, 'TASKID', Proc.TaskId)
|
|
local b3Add = EgtGetBBoxGlob( AddId, GDB_BB.STANDARD)
|
|
-- applico lavorazione
|
|
local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Add, Fct = 1, Flg = Proc.Flg,
|
|
Head = Proc.Head, Tail = Proc.Tail, CutId = Proc.CutId, TaskId = Proc.TaskId}
|
|
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead, nil, nil, bForced, b3Raw, sNotes, dOvmTail, true)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
-- altrimenti concavo
|
|
else
|
|
-- eseguo
|
|
local sCutType = EgtIf( bHead, 'HeadSide', 'TailSide')
|
|
local bDownHead = ( BD.DOWN_HEAD and vtNm:getZ() < BD.NZ_MINB)
|
|
-- per tutte le macchine tranne la Fast, controllo se ci sono tagli troppo inclinati e troppo profondi per la lama
|
|
-- in tal caso richiamo la lavorazione con fresa dal lato
|
|
if BD.C_SIMM and not bDownHead then
|
|
local sCutting = ML.FindCutting( sCutType, nil, bDownHead)
|
|
if not sCutting then
|
|
local sErr = 'Error : cutting not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
local _, _, dDimV1 = BL.GetFaceHvRefDim( Proc.Id, 0, b3Raw)
|
|
local _, _, dDimV2 = BL.GetFaceHvRefDim( Proc.Id, 1, b3Raw)
|
|
local bFace1TooLongForBlade, bFace2TooLongForBlade = ( dDimV1 >= dMaxDepth), ( dDimV2 >= dMaxDepth)
|
|
local dFace1Ang, dFace2Ang = vtN[1]:getZ(), vtN[2]:getZ()
|
|
if bFace1TooLongForBlade and dFace1Ang < ( BD.CUT_VZ_MIN or -0.484) or bFace2TooLongForBlade and dFace2Ang < ( BD.CUT_VZ_MIN or -0.484) then
|
|
local bOk, sErr = MakeBySidePocket( Proc, nPhase, nRawId, nPartId, nAddGrpId, b3Solid)
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
local bOk, sErr = Fbs.MakeTwo( Proc, nPhase, nRawId, nPartId, dOvmHead, sCutType, false, bDownHead)
|
|
if not bOk then return bOk, sErr end
|
|
-- segnalazione ingombro di testa o coda
|
|
if Proc.Head then
|
|
-- intersezioni con linee a metà altezza appena dentro dal davanti e dal dietro
|
|
local ptRef = b3Raw:getCenter() - 0.5 * b3Raw:getDimX() * X_AX()
|
|
local ptL1 = ptRef - ( 0.5 * b3Raw:getDimY() - 0.1) * Y_AX()
|
|
local ptL2 = ptRef + ( 0.5 * b3Raw:getDimY() - 0.1) * Y_AX()
|
|
local bInt1, IntTy1, IntPar1 = EgtLineSurfTmInters( ptL1, X_AX(), Proc.Id, GDB_ID.ROOT)
|
|
local bInt2, IntTy2, IntPar2 = EgtLineSurfTmInters( ptL2, X_AX(), Proc.Id, GDB_ID.ROOT)
|
|
local dMinPar = b3Raw:getDimX()
|
|
if IntPar1 and #IntPar1 > 0 then
|
|
dMinPar = min( dMinPar, IntPar1[1])
|
|
end
|
|
if IntPar2 and #IntPar2 > 0 then
|
|
dMinPar = min( dMinPar, IntPar2[1])
|
|
end
|
|
local dOffs = b3Raw:getDimX() - dMinPar
|
|
BL.UpdateHCING( nRawId, dOffs)
|
|
elseif Proc.Tail then
|
|
-- accetto approssimazione più grezza
|
|
local dOffs = Proc.Box:getMax():getX() - b3Solid:getMin():getX()
|
|
if vtNm:getZ() > 0.5 then
|
|
dOffs = 0.4 * dOffs
|
|
elseif abs( vtNm:getZ()) > 0.35 then
|
|
dOffs = 0.75 * dOffs
|
|
end
|
|
BL.UpdateTCING( nRawId, dOffs)
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessDoubleCut
|