Files
DataBeam/LuaLibs/ProcessDoubleCut.lua
T

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