1638 lines
78 KiB
Lua
1638 lines
78 KiB
Lua
-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2022/11/30
|
|
-- Gestione calcolo doppio taglio longitudinale per Travi
|
|
-- 2021/05/18 Possibile taglio con lama anche di fianco su macchina con testa da sotto.
|
|
-- 2021/06/29 Corretta gestione caso equivalente a due smussi.
|
|
-- 2021/10/29 Aggiunta opzione tipo lavorazione 'LongCut'.
|
|
-- 2021/11/08 Se con lama e flag BD.USE_LONGCUT si lavora in direzione contraria allo standard.
|
|
-- 2022/02/08 Sistemate lunghezze fresature quando due sole.
|
|
-- 2022/02/15 Sistemati commenti.
|
|
-- 2022/03/20 Tolta da scelta milling tipo Long2CutDown controllo max diametro fresa.
|
|
-- 2022/05/27 Corretto ordine per casi sui lati.
|
|
-- 2022/06/29 Corretto calcolo lunghezza attacco/uscita perpendicolare per lavorazioni di fianco.
|
|
-- 2022/11/30 Modifiche su SCC per TURN.
|
|
-- 2023/01/26 Rimossa la pulitura della faccia laterale nel caso in cui la feature abbia almeno una faccia rivolta verso il basso.
|
|
-- 2023/01/27 In MakeSideFace il prolungamento di uscita è ora fissato a 10 mm.
|
|
-- 2023/02/15 Migliorato verso di avanzamento della lama.
|
|
-- 2023/02/21 Verso di avanzamento della lama migliorato anche con lama LC.
|
|
-- 2023/02/22 Nuova gestione del verso di avanzamento ottimale che contempla tutti i casi.
|
|
-- 2023/03/06 Correzione per i casi con lavorazione limitata.
|
|
-- 2023/03/23 Correzione per caso con doppia lama da sotto.
|
|
|
|
-- Tabella per definizione modulo
|
|
local ProcessLong2Cut = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
|
|
EgtOutLog( ' ProcessLongDoubleCut started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
local dLimMinPiece = BD.LEN_SHORT_PART or 1000
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function ProcessLong2Cut.Identify( Proc)
|
|
return ( Proc.Grp == 0 and Proc.Prc == 12)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Identificazione delle facce della feature.
|
|
-- Ritorna quattro valori :
|
|
-- flag delle facce limitanti (0= no, 1= a destra, 2= a sinistra, 3= entrambe)
|
|
-- vettore indici facce longitudinali
|
|
-- vettore dei centri delle facce longitudinali
|
|
-- vettore dei centri delle normali
|
|
local function IdentifyFaces( Proc)
|
|
|
|
local nFaceLimit = 0
|
|
local tFaceLong = {}
|
|
local tptC = {}
|
|
local tvtN = {}
|
|
|
|
-- verifico le normali delle facce
|
|
local nFacetCnt = EgtSurfTmFacetCount( Proc.Id)
|
|
for i = 1, nFacetCnt do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
|
|
-- se è una faccia limite a sinistra
|
|
if vtN:getX() > GEO.EPS_SMALL then
|
|
nFaceLimit = nFaceLimit | 2
|
|
-- se è una faccia limite a destra
|
|
elseif vtN:getX() < -GEO.EPS_SMALL then
|
|
nFaceLimit = nFaceLimit | 1
|
|
-- altrimenti è una faccia longitudinale
|
|
else
|
|
local nInd = #tFaceLong + 1
|
|
tFaceLong[nInd] = i-1
|
|
tptC[nInd], tvtN[nInd] = EgtSurfTmFacetCenter( Proc.Id, ( i-1), GDB_ID.ROOT)
|
|
end
|
|
end
|
|
return nFaceLimit, tFaceLong, tptC, tvtN
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessLong2Cut.Classify( Proc)
|
|
|
|
local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0
|
|
|
|
-- se richiesto utensile di fianco
|
|
if nUseMillOnSide > 0 then
|
|
|
|
-- carico i dati delle face già inserite nelle opportune tabelle
|
|
local nFaceLimit, tFaceLong, _, vtN = IdentifyFaces( Proc)
|
|
|
|
-- verifico posizione (+1=sopra, -1=sotto, 0=sui lati)
|
|
local nSide = 0
|
|
if vtN[1]:getZ() > -10 * GEO.EPS_SMALL and vtN[2]:getZ() > -10 * GEO.EPS_SMALL then
|
|
nSide = 1
|
|
elseif vtN[1]:getZ() < 10 * GEO.EPS_SMALL and vtN[2]:getZ() < 10 * GEO.EPS_SMALL then
|
|
nSide = -1
|
|
end
|
|
-- angolo diedro per stabilire se taglio convesso
|
|
local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT)
|
|
local bConvex
|
|
if bAdj then
|
|
bConvex = ( dAng >= 0)
|
|
else
|
|
bConvex = true
|
|
end
|
|
-- se feature di fianco e facce concave per lavorazione impossibile
|
|
-- if nSide == 0 and not bConvex then
|
|
-- -- do errore perchè su un lato entra nel pezzo (entra nel lato sopra)
|
|
-- Proc.ErrMsg = 'Error : impossible to machinine with tool on side'
|
|
-- return false, false
|
|
-- end
|
|
end
|
|
|
|
return true, false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
function ProcessLong2Cut.GetLongFacesCount( Proc)
|
|
local nLongFaces = 0
|
|
local nFacetCnt = EgtSurfTmFacetCount( Proc.Id)
|
|
for i = 1, nFacetCnt do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
|
|
if abs( vtN:getX()) < GEO.EPS_SMALL then
|
|
nLongFaces = nLongFaces + 1
|
|
end
|
|
end
|
|
return nLongFaces
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeSideFace( nId, nFac, nSideLimitingFace, sMilling, dToolDiam, nL2CSide, bIsAnyFaceUpsideDown)
|
|
if ( not BD.DOWN_HEAD or not BD.TURN) and bIsAnyFaceUpsideDown then
|
|
EgtOutLog( 'Long2Cut : side face finishing skipped , down head required')
|
|
return true
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac)
|
|
local nMchFId = EgtAddMachining( sNameF, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nId, nFac}})
|
|
-- lato di lavoro e inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- uso della faccia
|
|
local nFaceUse = EgtIf( nSideLimitingFace == 1, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.ORTHO_LEFT)
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- annullo offset radiale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, 0)
|
|
-- attacco e uscita
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, 2)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 10)
|
|
-- se faccia di fianco e testa da sotto, aumento la sicurezza
|
|
if nL2CSide == 0 and BD.DOWN_HEAD then
|
|
EgtSetMachiningParam( MCH_MP.STARTPOS, 80)
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
local function MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, nFacInd, dFacElev)
|
|
-- cerco la svuotatura opportuna
|
|
local bDownHead = nSide ~=1 and BD.DOWN_HEAD
|
|
local sPockType = EgtIf( bDownHead, 'OpenPocket_H2', 'OpenPocket')
|
|
local sPocketing = ML.FindPocketing( sPockType, Proc.Box:getDimX(), nil, nil, not bDownHead, bDownHead)
|
|
if not sPocketing then
|
|
local sErr = 'Error : OpenPocket not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth)
|
|
end
|
|
end
|
|
-- inserisco la lavorazione
|
|
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 false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT)
|
|
-- imposto attacco per tasca aperta
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
-- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente
|
|
local sWarn
|
|
if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev)
|
|
dFacElev = dMaxDepth
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dFacElev, 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 false, sErr
|
|
end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcBladeUse( bUseBlade, bDown_Head, nSide, vtN1, vtN2, bConvex, nOrd, bFront, dCustomAngle)
|
|
|
|
local bCanUseBlade = false
|
|
local bCanUseUnderBlade = false
|
|
|
|
-- se lama abilitata e faccia da sopra
|
|
if bUseBlade and nSide == 1 then
|
|
bCanUseBlade = true
|
|
end
|
|
-- se lama abilitata e non c'è testa da sotto
|
|
if bUseBlade and not bDown_Head then
|
|
if nSide >= 0 then
|
|
if nSide > 0 and ( ( vtN1 and vtN1:getZ() >= -0.0175) or ( vtN2 and vtN2:getZ() >= -0.0175)) then
|
|
bCanUseBlade = true
|
|
elseif nSide == 0 then
|
|
if ( ( vtN1 and vtN1:getZ() >= -0.0175) or ( vtN2 and vtN2:getZ() >= -0.0175)) then
|
|
bCanUseBlade = true
|
|
elseif not bConvex and nOrd and (( nOrd == 1 and bFront) or ( nOrd == 2 and not bFront)) and ( vtN1 and vtN1:getZ() >= -0.0175) then
|
|
bCanUseBlade = true
|
|
elseif not bConvex and nOrd and (( nOrd == 2 and bFront) or ( nOrd == 1 and not bFront)) and ( vtN1 and vtN1:getZ() >= -0.5) then
|
|
bCanUseBlade = true
|
|
elseif bConvex and ( vtN1 and vtN1:getZ() >= -0.0175) then
|
|
bCanUseBlade = true
|
|
end
|
|
end
|
|
else
|
|
if bConvex then
|
|
if vtN1 and vtN2 then
|
|
if vtN1:getZ() >= -0.5 then
|
|
if vtN2:getZ() >= -0.5 then
|
|
bCanUseBlade = true
|
|
end
|
|
else
|
|
if vtN2:getZ() >= -0.0175 then
|
|
bCanUseBlade = true
|
|
end
|
|
end
|
|
else
|
|
if ( vtN1 and vtN1:getZ() >= EgtIf( dCustomAngle, dCustomAngle, -0.5)) then
|
|
bCanUseBlade = true
|
|
end
|
|
end
|
|
else
|
|
if ( vtN1 and vtN1:getZ() >= EgtIf( dCustomAngle, dCustomAngle, -0.5)) and ( not vtN2 or vtN2:getZ() >= -0.5) then
|
|
bCanUseBlade = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- se lama abilitata e c'è testa da sotto
|
|
if bUseBlade and bDown_Head then
|
|
-- se faccia da sotto o di lato ma con versore Z negativo che supera i 30° da Z-
|
|
if nSide <= 0 and ( ( vtN1 and vtN1:getZ() <= -0.5) or ( vtN2 and vtN2:getZ() <= -0.5)) then
|
|
bCanUseUnderBlade = true
|
|
end
|
|
-- se faccia da sotto o di lato ma con versore Z negativo abilito la lavorazione con lame mixate
|
|
if nSide <= 0 and ( ( vtN1 and vtN1:getZ() <= -0.0175) or ( vtN2 and vtN2:getZ() <= -0.0175)) then
|
|
bCanUseUnderBlade = true
|
|
end
|
|
-- se faccia da sopra o di lato ma con versore Z negativo verifico che abbia un angolo compatibile per non avere extracorsa
|
|
if nSide >= 0 and ( ( vtN1 and vtN1:getZ() > -0.4695) or ( vtN2 and vtN2:getZ() > -0.4695)) then
|
|
bCanUseBlade = true
|
|
end
|
|
-- se faccia da sotto ma con versore Z negativo verifico che abbia un angolo compatibile per non avere extracorsa
|
|
if nSide < 0 and ( ( vtN1 and vtN1:getZ() > -0.4695) or ( vtN2 and vtN2:getZ() > -0.4695)) then
|
|
bCanUseBlade = true
|
|
end
|
|
end
|
|
|
|
return bCanUseBlade, bCanUseUnderBlade
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId, bForcedBladeMaster, nUseSideToolMaster)
|
|
|
|
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
-- carico i dati delle face già inserite nelle opportune tabelle
|
|
local nFaceLimit, tFaceLong, ptC, vtN = IdentifyFaces( Proc)
|
|
local dLen = Proc.Box:getDimX()
|
|
|
|
-- verifico posizione (+1=sopra, -1=sotto, 0=sui lati)
|
|
local nSide = 0
|
|
if vtN[1]:getZ() > 0.0175 and vtN[2]:getZ() > 0.0175 then
|
|
nSide = 1
|
|
elseif vtN[1]:getZ() < -0.0175 and vtN[2]:getZ() < -0.0175 then
|
|
nSide = -1
|
|
end
|
|
local bIsAnyFaceUpsideDown = vtN[1]:getZ() < -0.0175 or vtN[2]:getZ() < -0.0175
|
|
|
|
-- angolo diedro per stabilire se taglio convesso
|
|
local bInt, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT)
|
|
local bConvex
|
|
local bOrtho
|
|
local ptM
|
|
local ptRef = ( ptC[1] + ptC[2]) / 2
|
|
if bInt then
|
|
bConvex = ( dAng >= 0)
|
|
bOrtho = ( abs( dAng + 90) < 1)
|
|
ptM = ( ptP1 + ptP2) / 2
|
|
else
|
|
ptM = ptRef
|
|
local vtM1 = ptC[1] - ptM ; vtM1:normalize()
|
|
local vtM2 = ptC[2] - ptM ; vtM2:normalize()
|
|
bConvex = ( vtM1 * vtN[1] > 0 and vtM2 * vtN[2] > 0)
|
|
bOrtho = false
|
|
dAng = acos( vtN[1] * vtN[2])
|
|
-- se facce contrapposte e quindi concavo, angolo sempre negativo
|
|
if not bConvex and dAng > 0 then dAng = -dAng end
|
|
end
|
|
|
|
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = BL.GetDistanceToNextPart( nRawId, nPhase)
|
|
local bForcedLim
|
|
local sWarn
|
|
----------------------------------------------------------------------------------------------------------------------------------------
|
|
-- 2020/09/17 Fabio Squaratti: se sono attivi entrambe i Q01 (lavorare con lama) e Q03 (lavorare con fresa di fianco anche da sopra)
|
|
-- allora vince il Q3, cioè si utilizza la fresa di fianco ( per i tagli da sopra)
|
|
-- 2020/09/17 Fabio Squaratti: se lavorazione con fresa di fianco e se ci sono delle facce laterali, l'utensile deve arrivare
|
|
-- fino al punto più vicino della faccia laterale (prima l'arretramento era sempre del raggio utensile).
|
|
-- Questo viene fatto se Q03=1 o fresa da sotto
|
|
----------------------------------------------------------------------------------------------------------------------------------------
|
|
local bUseBlade
|
|
local nUseMillOnSide
|
|
-- se presenti utilizzo i parametri dell'eventuale lua "padre"
|
|
if bForcedBladeMaster ~= nil then
|
|
bUseBlade = bForcedBladeMaster
|
|
else
|
|
bUseBlade = EgtGetInfo( Proc.Id, 'Q01', 'i') == 1
|
|
end
|
|
if nUseSideToolMaster ~= nil then
|
|
nUseMillOnSide = nUseSideToolMaster
|
|
else
|
|
nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0
|
|
end
|
|
|
|
-- se entrambe i Q sono attivi, disabilito lama
|
|
if nUseMillOnSide > 0 then bUseBlade = false end
|
|
-- verifico se posso usare lame
|
|
local bCanUseBlade, bCanUseUnderBlade = CalcBladeUse( bUseBlade, BD.DOWN_HEAD, nSide, vtN[1], vtN[2], bConvex)
|
|
-- introduco messaggi di errore in caso sia settata la lama ma impossibile utilizzarla
|
|
-- se si toglie questa parte il processo continua utilizzando però la fresa ma per il vincolo del parametro Q non è possibile
|
|
if bUseBlade and not BD.DOWN_HEAD and not bCanUseBlade then
|
|
local sErr = 'Error, impossible use blade on too negative face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
elseif bUseBlade and BD.DOWN_HEAD and not bCanUseBlade and not bCanUseUnderBlade then
|
|
local sErr = 'Error, impossible use blade'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- analisi del taglio
|
|
local vOrd = {}
|
|
local vFaceUse = {}
|
|
if nSide == 1 or ( nSide == -1 and ( BD.DOWN_HEAD or BD.TURN)) then
|
|
vOrd = EgtIf( ptC[1]:getY() < ptRef:getY(), { 1, 2}, { 2, 1})
|
|
vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)}
|
|
elseif nSide == -1 then
|
|
vOrd = EgtIf( ptC[1]:getY() < ptRef:getY(), { 1, 2}, { 2, 1})
|
|
vFaceUse = { BL.GetNearestParalOpposite( ptC[1] - ptM), BL.GetNearestParalOpposite( ptC[2] - ptM)}
|
|
else
|
|
local bFront = ( ( vtN[1]:getY() + vtN[2]:getY()) < 0)
|
|
if bFront then
|
|
vOrd = EgtIf( ptC[1]:getZ() < ptRef:getZ(), { 1, 2}, { 2, 1})
|
|
vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)}
|
|
else
|
|
vOrd = EgtIf( ptC[1]:getZ() < ptRef:getZ(), { 2, 1}, { 1, 2})
|
|
vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)}
|
|
end
|
|
end
|
|
local vWidth = {}
|
|
_, _, vWidth[1] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[1])
|
|
_, _, vWidth[2] = BL.GetFaceHvRefDim( Proc.Id, tFaceLong[2])
|
|
|
|
-- Se senza facce limitanti, da sopra o ( da tutte i lati con testa da sotto) e taglio di lama e lunghezza facce maggiore del parametro lunghezza minima
|
|
if nFaceLimit == 0 and ( bCanUseUnderBlade or bCanUseBlade) and bUseBlade and Proc.Box:getDimX() > dLimMinPiece - 1 then
|
|
|
|
local sCutting
|
|
local dToolDiam = 0
|
|
local dToolThick = 0
|
|
local dMaxDepth = 0
|
|
local sCuttingDn
|
|
local dToolDiamDn = 0
|
|
local dToolThickDn = 0
|
|
local dMaxDepthDn = 0
|
|
-- recupero la lavorazione
|
|
if bCanUseUnderBlade then
|
|
sCuttingDn = ML.FindCutting( 'HeadSide_H2', false, true)
|
|
if not sCuttingDn then
|
|
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing underneath not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
if EgtMdbSetCurrMachining( sCuttingDn) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn
|
|
dToolThickDn = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThickDn
|
|
dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn
|
|
end
|
|
end
|
|
end
|
|
if bCanUseBlade then
|
|
local sCutType = EgtIf( BD.USE_LONGCUT, 'LongCut', 'HeadSide')
|
|
sCutting = ML.FindCutting( sCutType)
|
|
if not sCutting then
|
|
local sErr = 'Error : sawing '..sCutType..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
if EgtMdbSetCurrMachining( sCutting) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
|
|
dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
end
|
|
end
|
|
end
|
|
-- se la distanza dal pezzo successivo è inferiore della metà lama, do un warning
|
|
if ( bCanUseBlade or bCanUseUnderBlade) and ( dDistToNextPiece < dToolDiam/2 or dDistToNextPiece < dToolDiamDn/2) then
|
|
sWarn = 'Warning : Cut machining can damage next piece'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- determino gli estremi
|
|
local dStartAccDist
|
|
local dEndAccDist
|
|
local dStartAccDistUp = BD.LONGCUT_ENDLEN
|
|
local dEndAccDistUp = BD.LONGCUT_ENDLEN
|
|
local dStartAccDistDn = BD.LONGCUT_ENDLEN
|
|
local dEndAccDistDn = BD.LONGCUT_ENDLEN
|
|
local nC
|
|
local dC
|
|
|
|
local nCUp
|
|
local dCUp
|
|
-- determino numero di parti
|
|
if bCanUseBlade then
|
|
nCUp = ceil( ( dLen - dStartAccDistUp - dEndAccDistUp) / BD.LONGCUT_MAXLEN)
|
|
dCUp = 0
|
|
if nCUp > 0 then
|
|
dCUp = ( dLen - dStartAccDistUp - dEndAccDistUp) / nCUp
|
|
if dCUp < min( dStartAccDistUp, dEndAccDistUp) then
|
|
dCUp = dLen / ( nCUp + 2)
|
|
dStartAccDistUp = dCUp
|
|
dEndAccDistUp = dCUp
|
|
end
|
|
nCUp = nCUp + 2
|
|
else
|
|
if dLen > min( dStartAccDistUp, dEndAccDistUp) then
|
|
nCUp = 2
|
|
dStartAccDistUp = dLen / 2
|
|
dEndAccDistUp = dStartAccDistUp
|
|
else
|
|
nCUp = 1
|
|
dStartAccDistUp = 0
|
|
dEndAccDistUp = 0
|
|
end
|
|
end
|
|
end
|
|
local nCDn
|
|
local dCDn
|
|
if bCanUseUnderBlade then
|
|
nCDn = ceil( ( dLen - dStartAccDistDn - dEndAccDistDn) / BD.LONGCUT_MAXLEN)
|
|
dCDn = 0
|
|
if nCDn > 0 then
|
|
dCDn = ( dLen - dStartAccDistDn - dEndAccDistDn) / nCDn
|
|
if dCDn < min( dStartAccDistDn, dEndAccDistDn) then
|
|
dCDn = dLen / ( nCDn + 2)
|
|
dStartAccDistDn = dCDn
|
|
dEndAccDistDn = dCDn
|
|
end
|
|
nCDn = nCDn + 2
|
|
else
|
|
if dLen > min( dStartAccDistDn, dEndAccDistDn) then
|
|
nCDn = 2
|
|
dStartAccDistDn = dLen / 2
|
|
dEndAccDistDn = dStartAccDistDn
|
|
else
|
|
nCDn = 1
|
|
dStartAccDistDn = 0
|
|
dEndAccDistDn = 0
|
|
end
|
|
end
|
|
end
|
|
-- prendo il valore minimo di passi
|
|
if nCUp then
|
|
nC = nCUp
|
|
dC = dCUp
|
|
elseif nCDn then
|
|
nC = nCDn
|
|
dC = dCDn
|
|
end
|
|
|
|
-- uso codolo piccolo
|
|
local dDimStrip = BD.DIM_STRIP_SMALL * EgtIf( nSide == -1, -1, 1)
|
|
local nM = 0
|
|
-- se convesso lavoro ogni faccia in due metà lasciando attaccata la parte centrale
|
|
if bConvex then
|
|
-- si percorrono i lati alto e basso della faccia
|
|
for i = 1, nC do
|
|
-- Posizione braccio portatesta
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
nSCC = EgtIf( ( i == 1 or i == nC - 1), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
end
|
|
local nCountToShift = 0
|
|
local bChangeBlade
|
|
local bMachDownGen
|
|
-- ciclo sulle due facce
|
|
for j = 1, #vOrd do
|
|
local nIdPrev
|
|
local nIdNext
|
|
nCountToShift = nCountToShift + 1
|
|
-- determino se lavorazione da davanti o da dietro
|
|
local bFront = ( vtN[vOrd[j]]:getY() < 0)
|
|
-- determino se posso usare lame sulla faccia specifica
|
|
bCanUseBlade, bCanUseUnderBlade = CalcBladeUse( bUseBlade, BD.DOWN_HEAD, nSide, vtN[vOrd[j]], nil, bConvex, j, bFront)
|
|
if not bCanUseUnderBlade and not bCanUseBlade then
|
|
local sErr = 'Error : impossible use blade on too negative face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local nFaceUse
|
|
local nFaceUse2
|
|
-- se ho solo lama da sotto
|
|
if bCanUseUnderBlade and not bCanUseBlade then
|
|
-- determino l'utilizzo della faccia
|
|
nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK))
|
|
nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT))
|
|
else
|
|
-- determino l'utilizzo della faccia
|
|
nFaceUse = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT))
|
|
nFaceUse2 = EgtIf( abs( vtN[vOrd[j]]:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK))
|
|
end
|
|
-- se lama da sotto verifico se la componente Y della profondità di taglio supera la capacità della lama
|
|
if nSide <= 0 and bCanUseUnderBlade then
|
|
if (( vWidth[vOrd[j]] - dDimStrip) / 2) > dMaxDepthDn then
|
|
local sErr = 'Error : side depth is bigger than underneath blade cut depth'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
local dOffset = ( vWidth[vOrd[j]] + dDimStrip) / 2 ;
|
|
local dLioTang = 0
|
|
local nFaceSide = 0
|
|
if vtN[vOrd[j]]:getZ() > 0.707 then
|
|
nFaceSide = 1
|
|
elseif vtN[vOrd[j]]:getZ() < -0.707 then
|
|
nFaceSide = -1
|
|
end
|
|
-- ricavo box della faccia
|
|
local b3Fac = EgtSurfTmGetFacetBBoxGlob( Proc.Id, vOrd[j]-1, GDB_BB.STANDARD)
|
|
-- ciclo sulle passate
|
|
for k = 1, 2 do
|
|
local dLioPerp = ( vWidth[vOrd[j]] - dDimStrip) / 2 + BD.CUT_SIC
|
|
-- inserisco le parti di lavorazione
|
|
nM = nM + 1
|
|
local sNameF
|
|
local nMchFId
|
|
local sCuttingName
|
|
local bMachDown
|
|
if bCanUseBlade and not bCanUseUnderBlade then
|
|
sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCutting)
|
|
sCuttingName = sCutting
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistUp
|
|
dStartAccDist = dStartAccDistUp
|
|
elseif bCanUseUnderBlade and not bCanUseBlade then
|
|
sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCuttingDn)
|
|
sCuttingName = sCuttingDn
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistDn
|
|
dStartAccDist = dStartAccDistDn
|
|
bMachDown = true
|
|
-- entrambe le possibilità di lama
|
|
else
|
|
-- se di fronte e prima faccia o dietro e seconda faccia, sta lavorando quella più in basso in Z (posizione)
|
|
if ( ( bFront and j == 1) or ( not bFront and j == 2)) and k == 1 then
|
|
-- prediligo quella inferiore
|
|
sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCuttingDn)
|
|
sCuttingName = sCuttingDn
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistDn
|
|
dStartAccDist = dStartAccDistDn
|
|
bMachDown = true
|
|
-- se di fronte e prima faccia o dietro e seconda faccia, sta lavorando quella più in basso in Z (posizione)
|
|
elseif ( ( bFront and j == 1) or ( not bFront and j == 2)) and k == 2 then
|
|
sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCuttingDn)
|
|
sCuttingName = sCuttingDn
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistDn
|
|
dStartAccDist = dStartAccDistDn
|
|
bMachDown = true
|
|
-- se di fronte e seconda faccia o dietro e prima faccia, sta lavorando la faccia più in alto in Z (posizione)
|
|
elseif ( ( bFront and j == 2) or ( not bFront and j == 1)) and k == 1 then
|
|
sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCutting)
|
|
sCuttingName = sCutting
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistUp
|
|
dStartAccDist = dStartAccDistUp
|
|
-- se di fronte e seconda faccia o dietro e prima faccia, sta lavorando la faccia più in alto in Z (posizione)
|
|
elseif ( ( bFront and j == 2) or ( not bFront and j == 1)) and k == 2 then
|
|
sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCutting)
|
|
sCuttingName = sCutting
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistUp
|
|
dStartAccDist = dStartAccDistUp
|
|
end
|
|
end
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCuttingName
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
if j == 1 and k == 1 then
|
|
bMachDownGen = bMachDown
|
|
else
|
|
if bMachDownGen ~= bMachDown then
|
|
bChangeBlade = true
|
|
end
|
|
end
|
|
local bAddOpposite = true
|
|
local dAddExtraPerp = 0
|
|
if ( nFaceSide == -1 and abs(vtN[vOrd[j]]:getY()) >= 0.2079) then
|
|
bAddOpposite = false
|
|
end
|
|
if ( nFaceSide == 0 and abs(vtN[vOrd[j]]:getZ()) >= 0.2588) then
|
|
bAddOpposite = false
|
|
end
|
|
if ( nFaceSide == 1 and not bMachDown) or ( nFaceSide == -1 and bMachDown) or ( nFaceSide == -1 and k == 1) then
|
|
bAddOpposite = false
|
|
end
|
|
if bAddOpposite then
|
|
-- controllo se devo aggiungere un extra all'attacco perpendicolare
|
|
if nFaceSide == -1 then
|
|
if vtN[vOrd[j]]:getY() > 0 then
|
|
dAddExtraPerp = b3Fac:getMin():getY() - b3Solid:getMin():getY()
|
|
elseif vtN[vOrd[j]]:getY() < 0 then
|
|
dAddExtraPerp = b3Solid:getMax():getY() - b3Fac:getMax():getY()
|
|
end
|
|
elseif nFaceSide == 0 then
|
|
if ( ( bFront and j == 1) or ( not bFront and j == 2)) and vtN[vOrd[j]]:getZ() <= 0 and k == 2 then
|
|
dAddExtraPerp = b3Solid:getMax():getZ() - b3Fac:getMax():getZ()
|
|
elseif ( ( bFront and j == 2) or ( not bFront and j == 1)) and vtN[vOrd[j]]:getZ() >= 0 and k == 1 then
|
|
dAddExtraPerp = b3Fac:getMin():getZ() - b3Solid:getMin():getZ()
|
|
end
|
|
end
|
|
dLioPerp = dLioPerp + dAddExtraPerp
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}})
|
|
|
|
-- settaggio di workside, uso faccia e eventuale inversione
|
|
-- limito opportunamente la lavorazione
|
|
local dSalInner, dSalOuter = - dEndAccDist - ( i - 2) * dC, 0
|
|
local dEalInner, dEalOuter = - dStartAccDist - ( nC - i - 1) * dC, 0
|
|
local dSal = EgtIf( i == 1, dSalOuter, dSalInner)
|
|
local dEal = EgtIf( i == nC, dEalOuter, dEalInner)
|
|
if ( bFront and k == 1) or ( not bFront and k == 2) then
|
|
dSal, dEal = dEal, dSal
|
|
end
|
|
|
|
-- verifico lama in uso e imposto uso faccia
|
|
local bIsTopBladeCurrent = not bMachDown
|
|
local nFaceUseCurrent
|
|
if bCanUseBlade and bCanUseUnderBlade then
|
|
if nSide == -1 then
|
|
dSal, dEal = dEal, dSal
|
|
if k == 1 then
|
|
nFaceUseCurrent = nFaceUse2
|
|
else
|
|
nFaceUseCurrent = nFaceUse
|
|
end
|
|
else
|
|
if k == 1 then
|
|
nFaceUseCurrent = nFaceUse
|
|
else
|
|
nFaceUseCurrent = nFaceUse2
|
|
end
|
|
end
|
|
elseif bCanUseUnderBlade then
|
|
if k == 1 then
|
|
nFaceUseCurrent = nFaceUse
|
|
else
|
|
nFaceUseCurrent = nFaceUse2
|
|
end
|
|
else
|
|
if k == 1 then
|
|
nFaceUseCurrent = nFaceUse
|
|
else
|
|
nFaceUseCurrent = nFaceUse2
|
|
end
|
|
end
|
|
|
|
-- recupero alcune informazioni utili dalla lavorazione attuale
|
|
local bIsCurrentBladeCCW
|
|
if bIsTopBladeCurrent then
|
|
EgtMdbSetCurrMachining( sCutting)
|
|
else
|
|
EgtMdbSetCurrMachining( sCuttingDn)
|
|
end
|
|
bIsCurrentBladeCCW = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) < 0
|
|
|
|
-- imposto la direzione di lavoro per avere scarico del truciolo ottimale
|
|
local nWorkSide, bInvert
|
|
if ( not bIsTopBladeCurrent and abs( nSide) ~= 0) or ( bCanUseBlade and bCanUseUnderBlade and nSide == -1) then
|
|
if bIsCurrentBladeCCW then
|
|
nWorkSide = MCH_MILL_WS.LEFT
|
|
bInvert = true
|
|
dSal, dEal = dEal, dSal
|
|
else
|
|
nWorkSide = MCH_MILL_WS.RIGHT
|
|
bInvert = false
|
|
end
|
|
else
|
|
if bIsCurrentBladeCCW then
|
|
nWorkSide = MCH_MILL_WS.LEFT
|
|
bInvert = false
|
|
else
|
|
nWorkSide = MCH_MILL_WS.RIGHT
|
|
bInvert = true
|
|
dSal, dEal = dEal, dSal
|
|
end
|
|
end
|
|
|
|
-- setto la lavorazione con i valori calcolati
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide)
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUseCurrent)
|
|
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- imposto offset radiale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, EgtIf( nSide == -1, -dOffset, dOffset))
|
|
-- 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)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- se sono alla seconda faccia scambio le ultime due lavorazione per ottimizzare i percorosi
|
|
if nCountToShift == 2 then
|
|
-- se prima porzione di faccia memorizzo l'id della lavorazione
|
|
if k == 1 then
|
|
nIdPrev = nMchFId
|
|
else
|
|
nIdNext = nMchFId
|
|
end
|
|
-- alla fine della seconda porzione della seconda faccia se non ho cambiato utensile tra le facce sposta la prima dopo la seconda
|
|
if nIdPrev and nIdNext and k == 2 and not bChangeBlade then
|
|
EgtRelocateGlob( nIdPrev, nIdNext, GDB_IN.AFTER)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- altrimenti concavo
|
|
else
|
|
-- si percorrono i lati alto e basso della faccia
|
|
for i = 1, nC do
|
|
-- Posizione braccio portatesta
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
nSCC = EgtIf( ( i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
|
|
end
|
|
-- ciclo sulle due facce
|
|
for j = 1, #vOrd do
|
|
-- determino se lavorazione da davanti o da dietro
|
|
local bFront = ( vtN[vOrd[j]]:getY() < 0)
|
|
local OthFace = abs(j-3)
|
|
local dSinLimit
|
|
-- se faccia da sotto e Z centro faccia è minore del centro altra faccia, segno il limite angolare da passare
|
|
-- dovrebbe essere il limite angolare della testa 1 in sottosquadra
|
|
if nSide == -1 and not BD.DOWN_HEAD then
|
|
if ptC[vOrd[j]]:getZ() < ptC[vOrd[OthFace]]:getZ() - 1. then
|
|
dSinLimit = -0.0157
|
|
else
|
|
dSinLimit = -0.5
|
|
end
|
|
end
|
|
-- determino se posso usare lame sulla faccia specifica
|
|
bCanUseBlade, bCanUseUnderBlade = CalcBladeUse( bUseBlade, BD.DOWN_HEAD, nSide, vtN[vOrd[j]], nil, bConvex, j, bFront, dSinLimit)
|
|
if not bCanUseUnderBlade and not bCanUseBlade then
|
|
local sErr = 'Error : impossible use blade on too negative face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se lama da sotto verifico se la componente Y della profondità di taglio supera la capacità della lama
|
|
if nSide <= 0 and bCanUseUnderBlade then
|
|
if ( vWidth[vOrd[j]] / 2) > dMaxDepthDn then
|
|
local sErr = 'Error : side depth is bigger than underneath blade cut depth'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- ciclo sulle passate
|
|
local dOffset
|
|
local dLioPerp
|
|
if j == 1 then -- il primo taglio lo faccio completo se angolo interno maggiore di 90
|
|
-- se angolo interno inferiore di 90° calcolo l'arretramento della lama + un piccolo delta di 0.3
|
|
if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then
|
|
dOffset = 0.3 + ((dToolThick* vtN[vOrd[1]]) * vtN[vOrd[2]] * vtN[vOrd[2]]):len()
|
|
else
|
|
dOffset = 0
|
|
end
|
|
dLioPerp = vWidth[vOrd[j]] + BD.CUT_SIC
|
|
else -- il secondo ridotto della distanza minima e della componente spessore della lama
|
|
dOffset = dDimStrip + ((dToolThick* vtN[vOrd[1]]) - (dToolThick* vtN[vOrd[1]]) * vtN[vOrd[2]] * vtN[vOrd[2]]):len()
|
|
dLioPerp = vWidth[vOrd[j]] - dOffset + BD.CUT_SIC
|
|
end
|
|
local dLioTang = 0
|
|
local sNameF
|
|
local nMchFId
|
|
nM = nM + 1
|
|
if bCanUseBlade then
|
|
sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCutting)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistUp
|
|
dStartAccDist = dStartAccDistUp
|
|
elseif bCanUseUnderBlade then
|
|
sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sCuttingDn)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCuttingDn
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- setto le variabili delle distanze dagli estremi
|
|
dEndAccDist = dEndAccDistDn
|
|
dStartAccDist = dStartAccDistDn
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, vOrd[j]-1}})
|
|
-- limito opportunamente la lavorazione
|
|
local dSal = EgtIf( i == nC, 0, - dEndAccDist - ( nC - i - 1) * dC)
|
|
local dEal = EgtIf( i == 1, 0, - dStartAccDist - ( i - 2) * dC)
|
|
if j == 2 then
|
|
dSal, dEal = dEal, dSal
|
|
end
|
|
if nSide == -1 and BD.DOWN_HEAD then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
end
|
|
-- imposto offset radiale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffset)
|
|
-- 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)
|
|
-- determino e imposto l'utilizzo della faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[j]])
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut
|
|
elseif ( nSide ~= -1 or BD.DOWN_HEAD or BD.TURN) and nUseMillOnSide == 0 then
|
|
-- determino la massima elevazione
|
|
local dElev = 0
|
|
local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[1], nPartId)
|
|
local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[2], nPartId)
|
|
-- 03/12/2020
|
|
-- se facce concave e a 90 gradi, prendo l'elevazione minima
|
|
if bOrtho then
|
|
dElev = min( dFacElev1, dFacElev2)
|
|
else
|
|
dElev = max( dFacElev1, dFacElev2)
|
|
end
|
|
-- recupero la lavorazione
|
|
local sMilling
|
|
local bDownHead = ( nSide == -1 and BD.DOWN_HEAD)
|
|
sMilling = ML.FindMilling( 'Long2Cut', dElev, nil, nil, nil, not bDownHead, bDownHead)
|
|
|
|
if not sMilling then
|
|
local sErr = 'Error : Long2Cut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se angolo compreso è inferiore ai 90 gradi do errore
|
|
if dAng and dAng < - ( 90 + 10 * GEO.EPS_ANG_SMALL) then
|
|
local sErr = 'Error : Impossible use a mill with angle less than 90'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dToolDiam = 0
|
|
local dMaxDepth = 0
|
|
if EgtMdbSetCurrMachining( sMilling) 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
|
|
end
|
|
-- se ho un pezzo successivo più distante di metà raggio : setto la fine come limitata
|
|
if dDistToNextPiece < dToolDiam/2 then
|
|
bForcedLim = true
|
|
nFaceLimit = nFaceLimit | 2
|
|
end
|
|
-- se chiuso e corto, applico svuotatura con fresa opportuna
|
|
if nFaceLimit == 3 and Proc.Box:getDimX() < 2 * dToolDiam then
|
|
-- svuotatura della prima faccia longitudinale
|
|
local bOk, sErr = MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, tFaceLong[1], dFacElev1)
|
|
-- svuotatura della seconda faccia longitudinale
|
|
if not bOk then return bOk, sErr end
|
|
return MakeByPocketing( Proc, nPhase, nRawId, nPartId, nSide, tFaceLong[2], dFacElev2)
|
|
end
|
|
-- determino gli estremi
|
|
local dStartDist = 0
|
|
local dStartAccDist = BD.LONGCUT_ENDLEN
|
|
local bStartFixed = true
|
|
-- se ho faccia limite a destra
|
|
if nFaceLimit == 1 or nFaceLimit == 3 then
|
|
dStartDist = dToolDiam / 2
|
|
dStartAccDist = BD.LONGCUT_MAXLEN
|
|
bStartFixed = false
|
|
end
|
|
local dEndDist = 0
|
|
local dEndAccDist = BD.LONGCUT_ENDLEN
|
|
local bEndFixed = true
|
|
-- se ho faccia limite a sinistra
|
|
if nFaceLimit >= 2 then
|
|
dEndDist = dToolDiam / 2
|
|
dEndAccDist = BD.LONGCUT_MAXLEN
|
|
bEndFixed = false
|
|
end
|
|
-- determino il numero di parti in cui dividere la lavorazione
|
|
local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN)
|
|
local dC = 0
|
|
if nC > 0 then
|
|
local nIncStep = 2
|
|
if bStartFixed and bEndFixed then
|
|
dC = ( dLen - dStartAccDist - dEndAccDist) / nC
|
|
-- se distanza rimanente è < della metà del minimo della distanza estremi allora aggiungo un solo passo in più
|
|
local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2)
|
|
if dC < dMinDist then
|
|
dC = dLen / ( nC + 1)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
nIncStep = 1
|
|
elseif dC < min( dStartAccDist, dEndAccDist) then
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
elseif bStartFixed then
|
|
dC = ( dLen - dStartAccDist) / ( nC + 1)
|
|
dEndAccDist = dC
|
|
if dC < dStartAccDist then
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
elseif bEndFixed then
|
|
dC = ( dLen - dEndAccDist) / ( nC + 1)
|
|
dStartAccDist = dC
|
|
if dC < dEndAccDist then
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
else
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
nC = nC + nIncStep
|
|
else
|
|
if dLen > min( dStartAccDist, dEndAccDist) then
|
|
nC = 2
|
|
if bStartFixed and not bEndFixed then
|
|
dStartAccDist = min( dStartAccDist, dLen/2)
|
|
dEndAccDist = dLen - dStartAccDist
|
|
elseif not bStartFixed and bEndFixed then
|
|
dEndAccDist = min( dEndAccDist, dLen/2)
|
|
dStartAccDist = dLen - dEndAccDist
|
|
else
|
|
dStartAccDist = dLen/2
|
|
dEndAccDist = dStartAccDist
|
|
end
|
|
else
|
|
nC = 1
|
|
dStartAccDist = 0
|
|
dEndAccDist = 0
|
|
end
|
|
end
|
|
local nIni, nFin = 1, 2
|
|
local dLimitAngle = -0.5 - 20 * GEO.EPS_SMALL
|
|
-- se facce ortogonali (concave), mantengo la lavorazione di testa sulla faccia più grande purchè non superi di 30 gradi il sottosquadra
|
|
if bOrtho then
|
|
if vtN[vOrd[1]]:getZ() > 0.001 and vtN[vOrd[2]]:getZ() > 0.001 then
|
|
if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then
|
|
nFin = 1
|
|
else
|
|
nIni = 2
|
|
end
|
|
else
|
|
if vtN[vOrd[1]]:getZ() < dLimitAngle then
|
|
nIni = 2
|
|
elseif vtN[vOrd[2]]:getZ() < dLimitAngle then
|
|
nFin = 1
|
|
else
|
|
if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then
|
|
if vtN[vOrd[2]]:getZ() < dLimitAngle then
|
|
nFin = 1
|
|
else
|
|
nIni = 2
|
|
end
|
|
else
|
|
if vtN[vOrd[1]]:getZ() < dLimitAngle then
|
|
nIni = 2
|
|
else
|
|
nFin = 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if nIni == 2 then
|
|
dStartDist, dEndDist = dEndDist, dStartDist
|
|
dStartAccDist, dEndAccDist = dEndAccDist, dStartAccDist
|
|
end
|
|
-- ciclo sulle parti
|
|
local nM = 0
|
|
for j = 1, nC do
|
|
-- su entrambe le facce
|
|
for i = nIni, nFin do
|
|
-- valore sovrapposizione tra passate con fresa di fianco
|
|
local dOverLapExtend = 2
|
|
-- Verifico se da fare di fianco perchè normale troppo verso il basso (minore di -30deg)
|
|
local bSide = ( vtN[vOrd[i]]:getZ() < dLimitAngle and not ( nSide == -1 and ( BD.DOWN_HEAD or BD.TURN)))
|
|
-- Limitazioni della lavorazione
|
|
local nPos = EgtIf( i == 1, j, nC - j + 1)
|
|
local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC + EgtIf( bSide, dOverLapExtend, 0))
|
|
local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC + EgtIf( bSide, dOverLapExtend, 0))
|
|
-- Posizione braccio portatesta
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if not BD.TURN then
|
|
nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
|
|
else
|
|
if nSide == 1 then
|
|
nSCC = EgtIf( vtN[vOrd[i]]:getY() < 0, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
elseif nSide == -1 then
|
|
nSCC = EgtIf( vtN[vOrd[i]]:getY() < 0, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
else
|
|
nSCC = EgtIf( vtN[vOrd[i]]:getZ() < 0, MCH_SCC.ADIR_ZM, MCH_SCC.ADIR_ZP)
|
|
end
|
|
end
|
|
end
|
|
if bSide and not bConvex then
|
|
dSal, dEal = dEal, dSal
|
|
end
|
|
-- ciclo sulle passate
|
|
local nO = 1
|
|
local dStep = 0
|
|
local dAgg = EgtIf( bConvex, 2 * BD.CUT_EXTRA, BD.CUT_EXTRA)
|
|
local dLargh = vWidth[vOrd[i]]
|
|
if not bSide and dLargh > 0.8 * dToolDiam then
|
|
nO = ceil( dLargh / ( 0.6 * dToolDiam))
|
|
if nO > 1 then
|
|
dStep = dLargh / nO
|
|
end
|
|
end
|
|
for k = 1, nO do
|
|
-- inserisco le parti di lavorazione
|
|
nM = nM + 1
|
|
local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM)
|
|
local nMchFId = EgtAddMachining( sNameF, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}})
|
|
-- limito opportunamente la lavorazione
|
|
if ( nSide == -1 and BD.DOWN_HEAD) then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
end
|
|
-- imposto posizione braccio porta testa per non ingombrare agli estremi
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- imposto uso faccia
|
|
EgtOutLog( 'FaceUse='..tostring( vFaceUse[vOrd[i]]))
|
|
--EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bSide, BL.GetParallelOpposite( vFaceUse[vOrd[i]]), vFaceUse[vOrd[i]]))
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bSide, MCH_MILL_FU.PARAL_DOWN, vFaceUse[vOrd[i]]))
|
|
-- imposto lato di lavoro e inversione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bSide, true, false))
|
|
-- imposto offset radiale (nullo se concavo o di lato)
|
|
local dOffsR = EgtIf( k < nO, ( nO - k) * dStep, EgtIf( bConvex, - BD.CUT_EXTRA, 0))
|
|
if bSide then dOffsR = 0 end
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffsR)
|
|
-- se di lato e convesso, imposto offset longitudinale
|
|
if bSide and bConvex then
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, - BD.CUT_EXTRA)
|
|
end
|
|
-- attacco e uscita
|
|
local dLioPerp = EgtIf( bSide, dToolDiam, dLargh - dOffsR + BD.CUT_SIC)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp)
|
|
-- se faccia di fianco e testa da sotto, aumento la sicurezza
|
|
if nSide == 0 and BD.DOWN_HEAD then
|
|
EgtSetMachiningParam( MCH_MP.STARTPOS, 80)
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra)
|
|
if bConvex and j == 1 and not bStartFixed then
|
|
MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam, nSide, bIsAnyFaceUpsideDown)
|
|
end
|
|
-- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra)
|
|
if bConvex and j == nC and not bEndFixed then
|
|
MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam, nSide, bIsAnyFaceUpsideDown)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- altrimenti lavorazione di fianco : Long2CutSide o Long2CutDown
|
|
else
|
|
-- da Analisi con Fabio Squaratti 15/09/2020
|
|
-- variabile che indica se ripassare sul raggio rimasto dalla lavorazione di fianco
|
|
local bRemoveToolRadius
|
|
-- se nExtendMach = 0 la lavorazione rimane arretrata dalla fine della faccia del raggio utensile
|
|
-- se nExtendMach = 1 la lavorazione arriva fino alla fine faccia (se non ha facce limite) ignorando il pezzo successivo
|
|
-- se nExtendMach = 2 la lavorazione viene estesa ma arretra per non segnare il pezzo successivo (se non ha facce limite)
|
|
local nExtendMach
|
|
-- recupero la lavorazione
|
|
local sMchType, sMchTypeDn
|
|
local sMilling, sMillingDn
|
|
local sPrefix, sPrefixDn
|
|
if nSide ~= - 1 then
|
|
sMchType = 'Long2CutSide'
|
|
sMilling = ML.FindMilling( sMchType)
|
|
sPrefix = 'L2CS_'
|
|
nExtendMach = nUseMillOnSide
|
|
if nUseMillOnSide == 2 then
|
|
bRemoveToolRadius = true
|
|
end
|
|
-- se testa da sotto
|
|
if nSide ~= 1 and BD.DOWN_HEAD then
|
|
sMchTypeDn = 'Long2CutSide_H2'
|
|
sMillingDn = ML.FindMilling( sMchTypeDn, nil, nil, nil, nil, false, true)
|
|
sPrefixDn = 'L2CSH2_'
|
|
end
|
|
-- lavorazione da sotto
|
|
else
|
|
sMchType = 'Long2CutDown'
|
|
sMilling = ML.FindMilling( sMchType)
|
|
sPrefix = 'L2CD_'
|
|
nExtendMach = 1
|
|
if nUseMillOnSide ~= 1 then
|
|
nExtendMach = 2 -- arretro il minimo indispensabile per non segnare il pezzo successivo (se non ha facce limite)
|
|
end
|
|
-- se testa da sotto
|
|
if BD.DOWN_HEAD then
|
|
sMchTypeDn = 'Long2CutDown_H2'
|
|
sMillingDn = ML.FindMilling( sMchTypeDn, nil, nil, nil, nil, false, true)
|
|
sPrefixDn = 'L2CDH2_'
|
|
end
|
|
end
|
|
if not sMilling and ( nSide == 1 or not BD.DOWN_HEAD) then
|
|
local sErr = 'Error : milling '..sMchType..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
if not sMilling and not sMillingDn then
|
|
local sErr = 'Error : milling '..sMchType..' and '..sMchTypeDn..' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se angolo compreso è inferiore ai 90 gradi do errore
|
|
if dAng < - ( 90 + 10 * GEO.EPS_SMALL) then
|
|
local sErr = 'Error : Impossible use a mill with angle less than 90'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dToolDiam = 0
|
|
local dToolLength = 0
|
|
local dMaxDepth = 0
|
|
local dThDiam = 0
|
|
local dThLen = 0
|
|
local dExtraForSafety = EgtIf( BD.DOWN_HEAD, 8.5, 6.5) -- corrisponde al doppio valore di sicurezza dell'mlpe + 0.5
|
|
if EgtMdbSetCurrMachining( sMilling) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
|
|
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
|
|
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
|
|
dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam
|
|
dThLen = EgtTdbGetCurrToolThLength() or dThLen
|
|
end
|
|
end
|
|
-- recupero i dati dell'utensile da sotto
|
|
local dToolDiamDn = 0
|
|
local dToolLengthDn = 0
|
|
local dMaxDepthDn = 0
|
|
local dThDiamDn = 0
|
|
local dThLenDn = 0
|
|
if nSide ~= 1 and BD.DOWN_HEAD and EgtMdbSetCurrMachining( sMillingDn) then
|
|
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
|
|
dToolDiamDn = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiamDn
|
|
dToolLengthDn = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLengthDn
|
|
dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn
|
|
dThDiamDn = (EgtTdbGetCurrToolThDiam() or dThDiamDn)
|
|
dThLenDn = EgtTdbGetCurrToolThLength() or dThLenDn
|
|
end
|
|
end
|
|
local dDistToEnd = dToolDiam / 2
|
|
local dDistToEndDn = dToolDiamDn / 2
|
|
-- calcolo l'elevazione della faccia principale
|
|
local dFacElev1 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[1]], nPartId)
|
|
local dFacElev2 = BL.GetFaceElevation( Proc.Id, tFaceLong[vOrd[2]], nPartId)
|
|
-- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino al limite se l'elevazione della faccia è minore del raggio utensile
|
|
if nUseMillOnSide <= 1 or nSide == -1 then
|
|
local dFacElev = max( dFacElev1, dFacElev2)
|
|
if dFacElev < dDistToEnd then
|
|
dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 2 - dFacElev)))
|
|
end
|
|
if dFacElev < dDistToEndDn then
|
|
dDistToEndDn = sqrt( ( ( dToolDiamDn / 2) * ( dToolDiamDn / 2)) - ( ( dToolDiamDn / 2 - dFacElev) * (dToolDiamDn / 2 - dFacElev)))
|
|
end
|
|
end
|
|
-- se la fine è già limitata allora setto per arretrare del raggio utensile
|
|
if nFaceLimit >= 2 then
|
|
nExtendMach = 0
|
|
-- se la fine non è limitata e ho un pezzo successivo distante meno di metà raggio. setto la fine come limitata
|
|
elseif ( dDistToNextPiece < dDistToEnd or dDistToNextPiece < dDistToEndDn) and nExtendMach ~= 1 then
|
|
nFaceLimit = nFaceLimit + 2
|
|
end
|
|
-- aggiuntivo sull'affondamento
|
|
local dAgg = EgtIf( bConvex, BD.CUT_EXTRA, 0)
|
|
-- determino gli estremi
|
|
local dStartDist = 0
|
|
local dStartAccDist = BD.LONGCUT_ENDLEN
|
|
local bStartFixed = true
|
|
-- se ho facce limite a destra
|
|
if nFaceLimit == 1 or nFaceLimit == 3 then
|
|
dStartDist = dDistToEnd
|
|
dStartAccDist = BD.LONGCUT_MAXLEN
|
|
bStartFixed = false
|
|
end
|
|
local dEndDist = 0
|
|
local dEndAccDist = BD.LONGCUT_ENDLEN
|
|
local bEndFixed = true
|
|
-- se ho facce limite a sinistra
|
|
if nFaceLimit >= 2 then
|
|
dEndDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd)
|
|
dEndAccDist = BD.LONGCUT_MAXLEN
|
|
bEndFixed = false
|
|
end
|
|
-- determino il numero di parti in cui dividere la lavorazione
|
|
local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN)
|
|
local dC = 0
|
|
if nC > 0 then
|
|
local nIncStep = 2
|
|
if bStartFixed and bEndFixed then
|
|
dC = ( dLen - dStartAccDist - dEndAccDist) / nC
|
|
-- se distanza rimanente è < della metà del minimo della distanza estremi allora aggiungo un solo passo in più
|
|
local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2)
|
|
if dC < dMinDist then
|
|
dC = dLen / ( nC + 1)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
nIncStep = 1
|
|
elseif dC < min( dStartAccDist, dEndAccDist) then
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
elseif bStartFixed then
|
|
dC = ( dLen - dStartAccDist) / ( nC + 1)
|
|
dEndAccDist = dC
|
|
if dC < dStartAccDist then
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
elseif bEndFixed then
|
|
dC = ( dLen - dEndAccDist) / ( nC + 1)
|
|
dStartAccDist = dC
|
|
if dC < dEndAccDist then
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
else
|
|
dC = dLen / ( nC + 2)
|
|
dStartAccDist = dC
|
|
dEndAccDist = dC
|
|
end
|
|
nC = nC + nIncStep
|
|
else
|
|
if dLen > min( dStartAccDist, dEndAccDist) then
|
|
nC = 2
|
|
if bStartFixed and not bEndFixed then
|
|
dStartAccDist = min( dStartAccDist, dLen/2)
|
|
dEndAccDist = dLen - dStartAccDist
|
|
elseif not bStartFixed and bEndFixed then
|
|
dEndAccDist = min( dEndAccDist, dLen/2)
|
|
dStartAccDist = dLen - dEndAccDist
|
|
else
|
|
dStartAccDist = dLen/2
|
|
dEndAccDist = dStartAccDist
|
|
end
|
|
else
|
|
nC = 1
|
|
dStartAccDist = 0
|
|
dEndAccDist = 0
|
|
end
|
|
end
|
|
-- ciclo sulle parti
|
|
local nM = 0
|
|
for j = 1, nC do
|
|
local nIni, nFin = 1, 2
|
|
local nDir = 1
|
|
-- se facce ortogonali (concave) controllo se con la lavorazione della prima faccia il diametro copre la seconda (e non la eseguo)
|
|
if bOrtho then
|
|
-- se da sotto scelgo la faccia (lavorata col fianco utensile) con direzione più sottosquadra
|
|
if nSide == -1 and vtN[vOrd[1]]:getZ() < -0.001 and vtN[vOrd[2]]:getZ() < -0.001 then
|
|
-- se gli angoli delle due facce sono uguali ( sotto il grado di differenza) sgelgo la faccia più vicina a un fianco
|
|
if abs(vtN[vOrd[1]]:getZ() - vtN[vOrd[2]]:getZ()) < 0.017 then
|
|
-- se punto medio più vicino al lato dietro
|
|
if b3Solid:getMax():getY() - ptM:getY() < ptM:getY() - b3Solid:getMin():getY() then
|
|
-- se prima faccia più vicina alla faccia dietro eseguo prima questa
|
|
if ptC[vOrd[1]]:getY() > ptC[vOrd[2]]:getY() then
|
|
if dToolDiam > vWidth[vOrd[2]] then
|
|
nFin = 1
|
|
end
|
|
-- se è più lontana inverto la direzione di lavoro
|
|
else
|
|
-- inverto la direzione di lavorazione delle facce
|
|
nDir = -1
|
|
nIni, nFin = 2, 1
|
|
if dToolDiam > vWidth[vOrd[1]] then
|
|
nFin = 2
|
|
end
|
|
end
|
|
-- altrimenti punto medio più vicino al lato davanti
|
|
else
|
|
-- se prima faccia più vicina alla faccia dietro inverto la direzione di lavorazione
|
|
if ptC[vOrd[1]]:getY() > ptC[vOrd[2]]:getY() then
|
|
-- inverto la direzione di lavorazione delle facce
|
|
nDir = -1
|
|
nIni, nFin = 2, 1
|
|
if dToolDiam > vWidth[vOrd[1]] then
|
|
nFin = 2
|
|
end
|
|
else
|
|
if dToolDiam > vWidth[vOrd[2]] then
|
|
nFin = 1
|
|
end
|
|
end
|
|
end
|
|
elseif vtN[vOrd[2]]:getZ() < vtN[vOrd[1]]:getZ() then
|
|
-- inverto la direzione di lavorazione delle facce
|
|
nDir = -1
|
|
nIni, nFin = 2, 1
|
|
if dToolDiam > vWidth[vOrd[1]] then
|
|
nFin = 2
|
|
end
|
|
else
|
|
if dToolDiam > vWidth[vOrd[2]] then
|
|
nFin = 1
|
|
end
|
|
end
|
|
-- in tutti gli altri casi
|
|
else
|
|
if dToolDiam > vWidth[vOrd[2]] then
|
|
nFin = 1
|
|
end
|
|
end
|
|
end
|
|
-- ciclo sulle facce selezionate
|
|
for i = nIni, nFin, nDir do
|
|
-- valore sovrapposizione tra passate
|
|
local dOverLapExtend = 2
|
|
-- Limitazioni della lavorazione
|
|
local nPos = EgtIf( i == 1, j, nC - j + 1)
|
|
local dSal = EgtIf( nPos == 1, - EgtIf( i == nIni, dStartDist, dEndDist), - EgtIf( i == nIni, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC + dOverLapExtend)
|
|
local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC + dOverLapExtend)
|
|
-- Posizione braccio portatesta
|
|
local nSCC = EgtIf( BD.C_SIMM, MCH_SCC.NONE, MCH_SCC.ADIR_XP)
|
|
-- inserisco le parti di lavorazione
|
|
nM = nM + 1
|
|
local sNameF
|
|
local nMchFId
|
|
local bUseDownHead
|
|
local bFront = (vtN[vOrd[i]]:getY() < 0)
|
|
if BD.DOWN_HEAD and nSide ~= 1 then
|
|
local ptC3 = EgtSurfTmFacetCenter( Proc.Id, tFaceLong[vOrd[i]], GDB_ID.ROOT)
|
|
local ptDir = ptC3 - ptM ; ptDir:normalize()
|
|
-- se concave e dal versore Z della faccia (> -20°) o convesso e versore Z ( > -30°) decido se eseguire la lavoraione con la testa da sopra o da sotto
|
|
if ( not bConvex and vtN[vOrd[i]]:getZ() > -0.9397 and ptDir:getZ() > 0) or
|
|
( bConvex and vtN[vOrd[i]]:getZ() > -0.866 and ptDir:getZ() > 0) then
|
|
sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sMilling)
|
|
bUseDownHead = false
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
else
|
|
sNameF = sPrefixDn .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sMillingDn)
|
|
bUseDownHead = true
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMillingDn
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
else
|
|
sNameF = sPrefix .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM)
|
|
nMchFId = EgtAddMachining( sNameF, sMilling)
|
|
bUseDownHead = false
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, tFaceLong[vOrd[i]]}})
|
|
-- limito opportunamente la lavorazione
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
-- imposto posizione braccio porta testa per non ingombrare agli estremi
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- se fresa di fianco e non da sotto
|
|
if nUseMillOnSide > 0 and nSide ~= -1 then
|
|
if bConvex then
|
|
local vFaceUse2
|
|
-- se da sopra
|
|
if nSide == 1 then
|
|
if vtN[vOrd[i]]:getZ() > 0.866 then
|
|
vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 1, 2)], vtN[EgtIf(vOrd[i] == 1, 2, 1)])
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
end
|
|
-- altrimenti è di fianco
|
|
else
|
|
if vtN[vOrd[i]]:getY() > 0.866 then
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_TOP)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
end
|
|
end
|
|
-- se concavo
|
|
else
|
|
local vFaceUse2
|
|
-- se da sopra
|
|
if nSide == 1 then
|
|
vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)], vtN[EgtIf(vOrd[i] == 1, 1, 2)])
|
|
-- altrimenti è di fianco
|
|
else
|
|
vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)])
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
end
|
|
else
|
|
-- se con fresa di fianco
|
|
if nUseMillOnSide > 0 then
|
|
if bConvex then
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
if vtN[vOrd[i]]:getZ() >= 0 then
|
|
if BD.DOWN_HEAD and nSide ~= 1 then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
end
|
|
end
|
|
else
|
|
-- lascio lo stesso le lavorazioni anche se viene intercettato l'errore
|
|
local vFaceUse2 = BL.GetNearestParalOpposite( vtN[EgtIf(vOrd[i] == 1, 2, 1)], vtN[EgtIf(vOrd[i] == 1, 1, 2)])
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse2)
|
|
if vtN[vOrd[i]]:getZ() < 0 then
|
|
if BD.DOWN_HEAD and nSide ~= 1 then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
-- se faccia da sotto
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]])
|
|
end
|
|
end
|
|
-- imposto lato di lavoro e inversione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- calcolo la componente dNz non in base alla classificazione della feature (sopra, sotto, fianchi) ma alla componente maggiore
|
|
-- local dNz = EgtIf( nSide == 0, vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ())
|
|
-- local dNz = EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ())
|
|
local dNz = EgtIf( abs(nSide) == 1, vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ())
|
|
local dNzMin = EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getY(), vtN[vOrd[i]]:getZ())
|
|
-- nel caso concavo, devo impostare la lunghezza di attacco ortogonale
|
|
if not bConvex then
|
|
local dLioPerp = EgtIf( i == 1, dFacElev1, dFacElev2) + BD.COLL_SIC
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp)
|
|
end
|
|
-- verifico massimo affondamento (tengo conto dell'inclinazione utensile e della pinza con estremità conica)
|
|
-- 08/09/2020 tolti i 3mm ( per la ghiera smussata) perchè nella verifica collisione vine creato un cilindro non smussato che rileva la collisione
|
|
-- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * abs( vtN[vOrd[i]]:getY() / vtN[vOrd[i]]:getZ()) - 3)
|
|
-- local dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( vtN[vOrd[i]]:getY() / dNz)))
|
|
local dCollSic
|
|
local dDepth
|
|
-- assegno affondamento
|
|
local dExtraElev = 0
|
|
-- se uso testa da sotto
|
|
if bUseDownHead then
|
|
dCollSic = max( BD.COLL_SIC, ( dThDiamDn - dToolDiamDn) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getZ(), vtN[vOrd[i]]:getY()) / dNz)))
|
|
if vWidth[vOrd[i]] + dAgg > dMaxDepthDn - dCollSic then
|
|
sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepthDn - dCollSic, 1) .. ')'
|
|
end
|
|
dDepth = min( dMaxDepthDn - dCollSic, vWidth[vOrd[i]] + dAgg)
|
|
dDepth2 = vWidth[vOrd[i]] + dAgg - dDepth
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth - dExtraElev)
|
|
else
|
|
dCollSic = max( BD.COLL_SIC, ( dThDiam - dToolDiam) / 2 * EgtIf( abs(dNz) < GEO.EPS_SMALL, 1, abs( EgtIf( abs(vtN[vOrd[i]]:getY()) >= abs(vtN[vOrd[i]]:getZ()), vtN[vOrd[i]]:getZ(), vtN[vOrd[i]]:getY()) / dNz)))
|
|
if vWidth[vOrd[i]] + dAgg > dMaxDepth - dCollSic then
|
|
sWarn = 'Warning in LongDoubleCut : depth (' .. EgtNumToString( vWidth[vOrd[i]] + dAgg, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth - dCollSic, 1) .. ')'
|
|
end
|
|
dDepth = min( dMaxDepth - dCollSic, vWidth[vOrd[i]] + dAgg)
|
|
dDepth2 = vWidth[vOrd[i]] + dAgg - dDepth
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth - dExtraElev)
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- se facce principali convesse, eventuale lavorazione della faccia limitante l'inizio (a destra)
|
|
if bConvex and j == 1 and not bStartFixed and bRemoveToolRadius then
|
|
MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], 1, sMilling, dToolDiam)
|
|
end
|
|
-- se facce principali convesse, eventuale lavorazione della faccia limitante la fine (a sinistra)
|
|
if bConvex and j == nC and not bEndFixed and bRemoveToolRadius then
|
|
MakeSideFace( Proc.Id, tFaceLong[vOrd[i]], -1, sMilling, dToolDiam)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessLong2Cut
|