Files
DataBeam/LuaLibs/ProcessLongDoubleCut.lua
T
Dario Sassi d720a98ac0 DataBeam :
- aggiunta gestione scelta utensile in base al raggio in mortase con coda di rondine
- corretta gestione estremi di taglio doppio longitudinale.
2020-10-28 08:20:33 +00:00

869 lines
39 KiB
Lua

-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2020/10/27
-- Gestione calcolo doppio taglio longitudinale per Travi
-- 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, nSide, sMilling, dToolDiam)
-- 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( nSide == 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, 0)
EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
local function MakeByPocketing( Proc, nPhase, nRawId, nPartId, nFacInd, dFacElev)
-- cerco la svuotatura opportuna
local sPocketing = ML.FindPocketing( 'OpenPocket', Proc.Box:getDimX())
if not sPocketing then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing 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 in process ' .. tostring( Proc.Id) .. ' : 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 EgtApplyMachining( true, false) then
-- provo ad allargare leggermente la tasca
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
return true, sWarn
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId)
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() > -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 bInt, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFaceLong[1], tFaceLong[2], GDB_ID.ROOT)
local bConvex
local bOrtho
local ptM
if bInt then
bConvex = ( dAng >= 0)
bOrtho = ( abs( dAng + 90) < 1)
ptM = ( ptP1 + ptP2) / 2
else
bConvex = true
bOrtho = false
ptM = ( ptC[1] + ptC[2]) / 2
end
local ptRef = ( ptC[1] + ptC[2]) / 2
-- analisi del taglio
local vOrd = {}
local vFaceUse = {}
if nSide == 1 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() < ptM:getY(), { 1, 2}, { 2, 1})
vFaceUse = { BL.GetNearestParalOpposite( ptC[1] - ptM), BL.GetNearestParalOpposite( ptC[2] - ptM)}
else
local bFront = ( vtN[1]:getY() < 0)
if bFront then
vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 1, 2}, { 2, 1})
vFaceUse = { BL.GetNearestOrthoOpposite( ptC[1] - ptM), BL.GetNearestOrthoOpposite( ptC[2] - ptM)}
else
vOrd = EgtIf( ptC[1]:getZ() < ptM: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])
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
local dDistToNextPiece = EgtGetInfo( nRawId, 'BDST', 'd') or 5.4
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 rggio utensile).
-- Questo viene fatto se Q03=1 o fresa da sotto
----------------------------------------------------------------------------------------------------------------------------------------
local bUseBlade = EgtGetInfo( Proc.Id, 'Q01', 'i') == 1
local nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0
-- se entrambe i Q sono attivi, disabilito lama
if nUseMillOnSide > 0 then bUseBlade = false end
-- Se senza facce limitanti, da sopra e richiesto con doppio taglio di lama
if nFaceLimit == 0 and nSide == 1 and bUseBlade and b3Solid:getDimX() > dLimMinPiece - 1 then
-- recupero la lavorazione
local sCutting = ML.FindCutting( 'HeadSide')
if not sCutting then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' sawing not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dToolDiam = 0
local dMaxDepth = 0
local dToolThick = 0
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick
end
end
-- se la distanza dal pezzo successivo è inferiore della metà lama, do un warning
if dDistToNextPiece < dToolDiam/2 then
sWarn = 'Warning on saw cut : Cut machining can damage next piece'
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
end
-- determino numero di parti
local dStartAccDist = BD.LONGCUT_ENDLEN
local dEndAccDist = BD.LONGCUT_ENDLEN
local nC = ceil( ( dLen - dStartAccDist - dEndAccDist) / BD.LONGCUT_MAXLEN)
local dC = 0
if nC > 0 then
dC = ( dLen - dStartAccDist - dEndAccDist) / nC
if dC < min( dStartAccDist, dEndAccDist) then
dC = dLen / ( nC + 2)
dStartAccDist = dC
dEndAccDist = dC
end
nC = nC + 2
else
if dLen > min( dStartAccDist, dEndAccDist) then
nC = 2
dStartAccDist = dLen / 2
dEndAccDist = dStartAccDist
else
nC = 1
dStartAccDist = 0
dEndAccDist = 0
end
end
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 = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
-- ciclo sulle due facce
for j = 1, #vOrd do
-- determino se lavorazione da davanti o da dietro
local bFront = ( vtN[vOrd[j]]:getY() < 0)
-- determino l'utilizzo della faccia
local 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))
local 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))
-- ciclo sulle passate
local dOffset = ( vWidth[vOrd[j]] + BD.DIM_STRIP_SMALL) / 2 ;
local dLioTang = 0
local dLioPerp = ( vWidth[vOrd[j]] - BD.DIM_STRIP_SMALL) / 2 + BD.CUT_SIC ;
for k = 1, 2 do
-- inserisco le parti di lavorazione
nM = nM + 1
local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) .. '_' .. tostring(j)
local nMchFId = EgtAddMachining( sNameF, sCutting)
if not nMchFId then
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, 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 ( not bFront and k == 1) or ( bFront and k == 2) then
dSal, dEal = dEal, dSal
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
-- 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)
-- imposto uso della faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( k == 1, nFaceUse, nFaceUse2))
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
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 = EgtIf( ( BD.C_SIMM or i == 1 or i == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
-- ciclo sulle due facce
for j = 1, #vOrd do
-- determino se lavorazione da davanti o da dietro
local bFront = ( vtN[vOrd[j]]:getY() < 0)
-- determino l'utilizzo della faccia
local 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))
local 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))
-- ciclo sulle passate
local dOffset
local dLioPerp
if j == 1 then -- il primo taglio lo faccio completo
dOffset = 0
dLioPerp = vWidth[vOrd[j]] + BD.CUT_SIC
else -- il secondo ridotto della distanza minima e della componente spessore della lama
dOffset = BD.DIM_STRIP_SMALL + ((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 = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring(j)
local nMchFId = EgtAddMachining( sNameF, sCutting)
if not nMchFId then
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sCutting
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, 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 ( bFront) then
dSal, dEal = dEal, dSal
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
-- 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)
-- imposto uso della faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse2)
-- eseguo
if not EgtApplyMachining( 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 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)
dElev = max( dFacElev1, dFacElev2)
-- recupero la lavorazione
local sMilling = ML.FindMilling( 'Long2Cut', dElev)
if not sMilling then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library'
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 la fine (a sinistra) non è limitata e ho un pezzo successivo più distante da metà raggio. setto la fine come limitata
if dDistToNextPiece < dToolDiam/2 and nFaceLimit < 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, tFaceLong[1], dFacElev1)
-- svuotatura della seconda faccia longitudinale
if not bOk then return bOk, sErr end
return MakeByPocketing( Proc, nPhase, nRawId, nPartId, 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 passo in più
local dMinDist = EgtIf( min( dStartAccDist, dEndAccDist) / 2 > 300 , 300, min( dStartAccDist, dEndAccDist) / 2)
if dC < dMinDist then
dC = dLen / ( nC + 2)
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
-- se facce ortogonali (concave), lavoro solo quella con versore maggiormente verso l'alto
local nIni, nFin = 1, 2
if bOrtho then
if vtN[vOrd[1]]:getZ() >= vtN[vOrd[2]]:getZ() then
nFin = 1
else
nIni = 2
end
end
-- ciclo sulle parti
local nM = 0
for j = 1, nC do
-- su entrambe le facce
for i = nIni, nFin do
-- 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)
local dEal = EgtIf( nPos == nC, - EgtIf( i == nIni, dEndDist, dStartDist), - EgtIf( i == nIni, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC)
-- Posizione braccio portatesta
local nSCC = EgtIf( ( BD.C_SIMM or j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
-- Verifico se da fare di fianco perchè normale troppo verso il basso (minore di -30deg)
local bSide = ( vtN[vOrd[i]]:getZ() < -0.5)
-- 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
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)
-- imposto uso faccia
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, imposto offset longitudinale
if bSide 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)
-- eseguo
if not EgtApplyMachining( 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)
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)
end
end
end
-- altrimenti è sotto : lavorazione 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 sMilling
local sPrefix
if nSide ~= - 1 then
sMilling = ML.FindMilling( 'Long2CutSide')
sPrefix = 'L2CS_'
nExtendMach = nUseMillOnSide
if nUseMillOnSide == 2 then
bRemoveToolRadius = true
-- nExtendMach = 0 -- arretro la lavorazione del raggio utensile (se non ha facce limite)
end
-- lavorazione da sotto
else
sMilling = ML.FindMilling( 'Long2CutDown')
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
end
if not sMilling then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dToolDiam = 0
local dMaxDepth = 0
local dThDiam = 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
dThDiam = EgtTdbGetCurrToolThDiam() or dThDiam
end
end
local dDistToEnd = dToolDiam / 2
-- 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
-- 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)
local dFacElev = max( dFacElev1, dFacElev2)
if dFacElev < dDistToEnd then
dDistToEnd = sqrt( ( ( dToolDiam / 2) * ( dToolDiam / 2)) - ( ( dToolDiam / 2 - dFacElev) * (dToolDiam / 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 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
if bStartFixed and bEndFixed then
dC = ( dLen - dStartAccDist - dEndAccDist) / nC
elseif bStartFixed then
dC = ( dLen - dStartAccDist) / ( nC + 1)
dEndAccDist = dC
elseif bEndFixed then
dC = ( dLen - dEndAccDist) / ( nC + 1)
dStartAccDist = dC
else
dC = dLen / ( nC + 2)
dStartAccDist = dC
dEndAccDist = dC
end
nC = nC + 2
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
-- su entrambe le facce
for i = 1, 2 do
-- Limitazioni della lavorazione
local nPos = EgtIf( i == 1, j, nC - j + 1)
local dSal = EgtIf( nPos == 1, - EgtIf( i == 1, dStartDist, dEndDist), - EgtIf( i == 1, dStartAccDist, dEndAccDist) - ( nPos - 2) * dC)
local dEal = EgtIf( nPos == nC, - EgtIf( i == 1, dEndDist, dStartDist), - EgtIf( i == 1, dEndAccDist, dStartAccDist) - ( nC - nPos - 1) * dC)
-- Posizione braccio portatesta
local nSCC = MCH_SCC.ADIR_XP
-- 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
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)
-- imposto uso faccia
if nUseMillOnSide > 0 and nSide ~= -1 then
if nSide == 1 then
if bConvex then
if vtN[vOrd[i]]:getZ() > 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
else
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
end
else
if bConvex then
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
if vtN[vOrd[i]]:getZ() >= 0 then
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
end
else
-- lascio lo stesso le lavorazioni anche se viene intercettato l'errore
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
if vtN[vOrd[i]]:getZ() < 0 then
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dEal)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dSal)
end
end
end
else
EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]])
end
-- imposto lato di lavoro e inversione
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
EgtSetMachiningParam( MCH_MP.INVERT, true)
-- nel caso concavo, devo impostare la lunghezza di attacco ortogonale
if not bConvex then
local dNz = vtN[vOrd[i]]:getZ()
local dLioPerp = vWidth[vOrd[i]] * sqrt( 1 - dNz * dNz) / abs( dNz) + 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 * abs( vtN[vOrd[i]]:getY() / vtN[vOrd[i]]:getZ()))
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
local dDepth = min( dMaxDepth - dCollSic, vWidth[vOrd[i]] + dAgg)
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
-- eseguo
if not EgtApplyMachining( 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