Files
DataBeam/LuaLibs/ProcessLongCut.lua
T
andrea.villa 29af699ad5 - LongCut e LongDoubleCut: migliorata spezzatura taglio passante con due spezzoni
- BeamExec: aggiunta scrittura parametro BARLEN nelle info del mach group
2023-10-24 14:28:35 +02:00

1872 lines
86 KiB
Lua

-- ProcessLongCut.lua by Egaltech s.r.l. 2023/08/01
-- Gestione calcolo taglio longitudinale per Travi
-- 2021/02/03 Corretto FaceUse con fresa orizzontale su taglio orizzontale.
-- 2021/05/18 Possibile taglio con lama anche di fianco su macchina con testa da sotto.
-- 2021/07/20 Possibile taglio con lama anche di fianco e da sotto su macchina con testa da sopra.
-- 2021/07/20 Con utensile di fianco e con determinati angoli e se altezza utensile è inferiore all'altezza faccia
-- è possibile fare doppio taglio opposto su tutte le facce(sopra, sotto e fianchi)
-- 2021/09/03 Gestione facce lunghe non passanti con taglio di lama
-- 2021/10/29 Aggiunta opzione tipo lavorazione 'LongCut'.
-- 2021/11/04 Migliorata gestione sicurezza aggiuntiva in fresate di fianco (distinzione tra larga come tutta la faccia o meno).
-- 2021/11/08 Se con lama e flag BD.USE_LONGCUT si lavora in direzione contraria allo standard.
-- 2022/03/07 Razionalizzata gestione casi con fresa di fianco. Aggiunta gestione Long2Cut anche con testa sotto.
-- 2022/07/14 Aggiunta limitazione lavorazione a sinistra anche se il grezzo successivo non ha lavorazioni (finale barra) ma è abbastanza lungo da poter essere riutilizzato (BD.MinRaw).
-- 2022/09/23 Modificato l'angolo per l'abilitazione della lama da sotto: ora interviene anche per facce verticali.
-- 2022/11/04 Aggiunto passaggio parametro bDownHead (Testa da Sotto) nelle chiamate a MakeSideFace.
-- 2022/11/28 Correzioni varie per attacco, pulizia spigoli, utilizzo H3.
-- 2022/11/30 Modifiche su SCC per TURN.
-- 2023/01/18 Aggiunta, se richiesta, una lavorazione ulteriore con sega a catena nei casi in cui la doppia lama non sia sufficiente.
-- 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/01/27 In caso di lavorazione aggiuntiva con fresa a catena il taglio con lama da sotto viene effettuato a step.
-- 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/15 Modifica alla lavorazione ulteriore con sega a catena per togliere il codolo e lasciare solo dei punti di supporto.
-- 2023/03/22 Correzione a SCC lama a seguito di modifiche alle direzioni dei tagli.
-- 2023/04/17 Gestione unificata SCC tramite funzione apposita GetSCC
-- 2023/05/03 Corretto SCC in caso di asse utensile allineato con Z.
-- 2023/05/19 Migliorato calcolo e verifica affondamento per lavorazione con lama con codolo in mezzo.
-- 2023/08/01 Ammesso uso lama da sotto fino a N +3deg in verticale.
-- 2023/09/26 Modificata chiamata a GetFaceWithMostAdj.
-- 2023/10/24 Migliorata spezzatura taglio passante con due spezzoni
-- Tabella per definizione modulo
local ProcessLongCut = {}
-- Include
require( 'EgtBase')
local BL = require( 'BeamLib')
local Fbs = require( 'FacesBySaw')
EgtOutLog( ' ProcessLongCut started', 1)
-- Dati
local BD = require( 'BeamData')
local ML = require( 'MachiningLib')
local dLimMinPiece = BD.LEN_SHORT_PART or 1000
---------------------------------------------------------------------
-- Riconoscimento della feature
function ProcessLongCut.Identify( Proc)
return (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10)
end
---------------------------------------------------------------------
-- Classificazione della feature
function ProcessLongCut.Classify( Proc)
-- se una sola faccia non ci sono limiti
if Proc.Fct == 1 then
return true, false
end
-- verifico la normale della faccia principale
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, 0, GDB_ID.ROOT)
if vtN:getZ() < - 0.5 then
return true, true
end
return true, false
end
---------------------------------------------------------------------
-- Estrazione dell'UUID utensile di una lavorazione
function GetToolUUID( sMachining)
if EgtMdbSetCurrMachining( sMachining) then
local sToolUUID = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
return sToolUUID
end
end
---------------------------------------------------------------------
-- Calcolo dei versori caratteristici della feature
function GetProcessSpecificVectors( Proc, nFacet, nFaceUse, bInvert, sMachining)
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacet, GDB_ID.ROOT)
local vtOrthO = BL.GetVersRef( nFaceUse)
local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, nFacet, vtOrthO, GDB_ID.ROOT)
local vtTg = ptP2 - ptP1 ; vtTg:normalize()
local dAllStart = 0
local dAllEnd = 0
-- se bilinea, scarto la parte più allineata con la direzione ortogonale (se deviazione angolare oltre 20 deg o lunghezza minore di dSawDiam/2 * cos( 20/2)) ma maggiore di un minimo
if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then
local vtTg1 = ptPm - ptP1 ; vtTg1:normalize()
local vtTg2 = ptP2 - ptPm ; vtTg2:normalize()
local dDist1 = dist( ptP1, ptPm)
local dDist2 = dist( ptP2, ptPm)
local dCosMax = 0.951 -- cos( 18°)
local dLenMin = 30
local dToolDiam = 400
if EgtMdbSetCurrMachining( sMachining) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
end
end
local dLenMax = max( 0.5 * dToolDiam * 0.17365 + 1, 2 * dLenMin)
--if vtTg1 * vtTg2 < dCosMax or ( dDist1 < dLenMax and dDist1 > dLenMin) or ( dDist2 < dLenMax and dDist2 > dLenMin) then
if vtTg1 * vtTg2 < dCosMax then
local dOrtho1 = abs( vtTg1 * vtOrthO)
local dOrtho2 = abs( vtTg2 * vtOrthO)
if dOrtho1 < dOrtho2 or ( abs( dOrtho1 - dOrtho2) < 0.1 and dDist1 > 4 * dDist2) then
if dDist1 > dLenMin or dDist1 > 0.5 * dDist2 then
ptP2 = Point3d( ptPm)
dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL
end
else
if dDist2 > dLenMin or dDist2 > 0.5 * dDist1 then
ptP1 = Point3d( ptPm)
dAllStart = - dDist1 - 10 * GEO.EPS_SMALL
end
end
vtTg = ptP2 - ptP1 ; vtTg:normalize()
end
end
local bWsRight = ( bInvert)
-- Versore di riferimento
local vtRef = Vector3d( vtTg)
vtRef:rotate( vtN, 90)
-- Versore esterno
local vtOut = vtRef - vtRef * vtTg * vtTg ; vtOut:normalize()
-- Versore ausiliario (direzione braccio)
local vtAux = Vector3d( vtN:getX(), vtN:getY(), 0) ; vtAux:normalize()
vtAux:rotate( Z_AX(), EgtIf( bWsRight, 90, -90))
if vtAux:isSmall() then
vtAux = Vector3d( vtOut:getX(), vtOut:getY(), 0) ; vtAux:normalize()
else
if abs( vtAux * vtOut) < GEO.EPS_SMALL then
if abs( vtTg:getZ()) > 0.5 then
if vtAux * vtRef < 0 then
vtAux = - vtAux
end
elseif vtAux * vtTg > 0 then
vtAux = - vtAux
end
elseif vtAux * vtOut < 0 then
vtAux = - vtAux
end
end
EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3)
return vtAux, vtRef, vtOut, vtTg
end
---------------------------------------------------------------------
-- Calcolo posizione braccio
function ProcessLongCut.GetSCC( Proc, nFacet, sMachining, nFaceUse, bInvert, nCuttingStep, nC, bAreCuttingStepsTowardsHead, bIsTopBlade, bCustUseBlade)
local nSCC
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacet, GDB_ID.ROOT)
local sToolUUID = GetToolUUID( sMachining)
local bIsBlade
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sToolUUID) or '') then
bIsBlade = ( ( EgtTdbGetCurrToolParam( MCH_TP.TYPE) & MCH_TF.SAWBLADE) ~= 0)
end
-- se Turn posiziono la testa per creare il minor ingombro possibile
if BD.TURN then
if nFaceUse == MCH_MILL_FU.ORTHO_DOWN or ( ( nFaceUse == MCH_MILL_FU.PARAL_FRONT or nFaceUse == MCH_MILL_FU.PARAL_BACK) and vtN:getZ() > -GEO.EPS_SMALL) then
nSCC = MCH_SCC.ADIR_ZP
elseif nFaceUse == MCH_MILL_FU.ORTHO_TOP or ( nFaceUse == MCH_MILL_FU.PARAL_FRONT or nFaceUse == MCH_MILL_FU.PARAL_BACK) then
nSCC = MCH_SCC.ADIR_ZM
elseif nFaceUse == MCH_MILL_FU.ORTHO_FRONT or ( ( nFaceUse == MCH_MILL_FU.PARAL_DOWN or nFaceUse == MCH_MILL_FU.PARAL_TOP) and vtN:getY() > -GEO.EPS_SMALL) then
nSCC = MCH_SCC.ADIR_YP
elseif nFaceUse == MCH_MILL_FU.ORTHO_BACK or ( nFaceUse == MCH_MILL_FU.PARAL_DOWN or nFaceUse == MCH_MILL_FU.PARAL_TOP) then
nSCC = MCH_SCC.ADIR_YM
end
-- se Fast e fresa con asse utensile diretto come Z posiziono l'aggregato in Ym per avere il minore ingombro possibile
elseif not BD.C_SIMM and not bIsBlade and AreSameVectorApprox( vtN, Z_AX()) then
nSCC = MCH_SCC.ADIR_YM
-- se Fast ( escluso caso speciale con taglio non passante e inclinato in X e escluso caso con lama esattamente diretta in Z) posiziono l'aggregato in X per ottimizzare il pinzaggio
elseif not BD.C_SIMM and ( not ( bCustUseBlade and abs(vtN:getX()) > 0.001) or not bIsBlade) and not ( bIsBlade and AreSameVectorApprox( vtN, Z_AX())) then
if bAreCuttingStepsTowardsHead then
nSCC = EgtIf( ( not ( nCuttingStep == 1 or nCuttingStep == nC - 1)), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
else
nSCC = EgtIf( ( not ( nCuttingStep == 1 or nCuttingStep == nC - 1)), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
end
-- per Fast ( caso speciale con taglio non passante e inclinato in X e caso lama diretta esattamente in Z)
elseif not BD.C_SIMM then
local vtAux = GetProcessSpecificVectors( Proc, nFacet, nFaceUse, bInvert, sMachining)
if bCustUseBlade then
nSCC = EgtIf( ( nFaceUse == MCH_MILL_FU.ORTHO_TOP or nFaceUse == MCH_MILL_FU.ORTHO_FRONT) and vtN:getY() > -GEO.EPS_SMALL, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
elseif ( abs( vtAux:getX()) > abs( vtAux:getY()) - GEO.EPS_SMALL) then
nSCC = EgtIf( ( vtAux:getX() > -GEO.EPS_SMALL), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)
else
nSCC = EgtIf( ( vtAux:getY() > -GEO.EPS_SMALL), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
end
-- per PF o simili e lama con aggregato lo posiziono per stare il più lontano possibile dalla trave
elseif ( bIsBlade and bIsTopBlade) then
if abs( vtN:getX()) > 0.001 then
local vtAux = GetProcessSpecificVectors( Proc, nFacet, nFaceUse, bInvert, sMachining)
nSCC = EgtIf( ( vtAux:getY() > -GEO.EPS_SMALL), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
else
nSCC = MCH_SCC.ADIR_XP
end
-- per PF o simili e lama senza aggregato o fresa non do alcuna preferenza
else
nSCC = MCH_SCC.NONE
end
return nSCC
end
-----------------------------------------------------------------------------------------------
local function MakeSideFace( nId, nFac, nSide, sMilling, dToolDiam, bForcedLim, dDistToMachine, bUnderDir)
if ( not BD.DOWN_HEAD or not BD.TURN) and nSide == -1 then
EgtOutLog( 'LongCut : side face finishing skipped , down head required')
return true
end
-- inserisco la lavorazione
local nM = 1
local nP = 1
local nFirstOverlap = 2
-- calcolo il numero di passata che devo fare per coprire l'impronta dells lama
if dDistToMachine and abs(dDistToMachine) > 0 then
nP = ceil( ( abs(dDistToMachine) + EgtIf( bForcedLim, 2 + nFirstOverlap, 2)) / ( dToolDiam - 2))
end
for i = 1, nP do
local sNameF = 'L2C_' .. ( EgtGetName( nId) or tostring( nId)) .. '_' .. tostring( nFac) .. '_' .. 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( {{ nId, nFac}})
-- uso della faccia
local nFaceUse
if bForcedLim then
nFaceUse = MCH_MILL_FU.ORTHO_LEFT
-- lato di lavoro e inversione
EgtSetMachiningParam( MCH_MP.INVERT, false)
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
else
nFaceUse = EgtIf( bUnderDir, MCH_MILL_FU.PARAL_TOP, MCH_MILL_FU.PARAL_DOWN)
if nSide == -2 then
nFaceUse = MCH_MILL_FU.PARAL_BACK
elseif nSide == 2 then
nFaceUse = MCH_MILL_FU.PARAL_FRONT
end
-- lato di lavoro e inversione
EgtSetMachiningParam( MCH_MP.INVERT, true)
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
end
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- modifico offset radiale
if i < nP or i == 1 then
EgtSetMachiningParam( MCH_MP.OFFSR, ((dToolDiam-2)*(i-1)) + EgtIf( bForcedLim, -nFirstOverlap, 0))
else
local dPrevStep = (dToolDiam-2)*(i-2)
EgtSetMachiningParam( MCH_MP.OFFSR, ( dDistToMachine + 2 - dToolDiam))
end
-- 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)
-- eseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
end
---------------------------------------------------------------------
local function MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown, sMasterCutting)
-- Recupero la lavorazione di lama o prendo quella passata
local sCutting
if sMasterCutting and #sMasterCutting > 0 then
sCutting = sMasterCutting
else
sCutting = ML.FindCutting( 'HeadSide', not bMillDown, bMillDown)
end
if not sCutting then
local sErr = 'Error : HeadSide (cutting) not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- valuto l'angolo tra le due facce
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT)
local ptPm = (ptP1+ptP2)/2
-- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia
-- laterale sul punto medio della linea in comune
local frFc = Frame3d( ptPm, vtN) ;
local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc)
dDepth = b3BoxLoc:getDimZ() or 0
-- recupero i dati dell'utensile
local dSawDiam = 400
local dSawThick = 0
local dMaxDepth = 0
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
end
end
local dExtraOffs = 0
-- se profondità superiore al massimo lama modifico elevazione
if dDepth > dMaxDepth then
dExtraOffs = dMaxDepth - dDepth
end
-- se devo ridurre l'affondamento
if bReduceDepth then
local dLimitDepth = 100
-- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm)
if abs(dExtraOffs) > 0 then
if dMaxDepth > dLimitDepth then
dExtraOffs = dLimitDepth - dDepth
end
else
if dDepth > dLimitDepth then
dExtraOffs = dLimitDepth - dDepth
else
dExtraOffs = - (dDepth/2)
end
end
end
-- eseguo il taglio
local bMadeASbyBld, sWarn, nIdMach = Fbs.MakeOne( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
if bMadeASbyBld then
sWarn = nil
if abs(dExtraOffs) > 0 then
sWarn = 'Warning : antisplint elevation is bigger than max tool depth'
end
end
return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs
end
---------------------------------------------------------------------
local function ManageAntiSplintBySaw( Proc, b3Raw, bIsU, vtN, nFacet, nFacInd, sWarn, bMillDown, bReduceDepth, sCutting)
local bMadeASbyBld = false
local nNumFac = EgtIf( bIsU, 2, 1)
local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra
-- se a U cerco di ottimizzare il lato di lavoro della lama
if bIsU then
if abs( vtN:getY()) > 0.996 then
nPrefSide = 0
elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then
-- se X è negativa allora devo tenere il motore a destra
if vtN:getX() < -(10 * GEO.EPS_SMALL) then
nPrefSide = 2
end
end
end
-- va eseguito sulle facce diverse dalla principale
local nPrevSCC = nil
for nFacet = 0, nNumFac do
if nFacet ~= nFacInd then
-- lavoro
local dSawThick = 0
local dMaxDepth = 200
local bAdj, dAng, dExtraOffs, sWarn2, nIdMach
bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, bAdj, dAng, dExtraOffs = MakeAntiSplintBySaw( Proc, nFacet, vtN, b3Raw, nFacInd, bReduceDepth, bMillDown, sCutting)
if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end
if sWarn2 then
if not sWarn then sWarn = '' end
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
end
-- se antischeggia veramente inserito perchè necessario
if nIdMach then
-- verifico se da invertire
local bInvertMach = false
local dDepth = 0
if bIsU then
if abs(vtN:getZ()) > 0.63 or abs(vtN:getY()) > 0.63 then
-- if abs(vtN:getZ()) > 0.7 or abs(vtN:getY()) > 0.7 then
-- prendo il vettore normale alla faccia
local _, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
-- se superficie principale parallela al piano XZ
if nPrefSide == 0 then
-- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto)
if vtNFc:getX() * vtNFc:getZ() > 0 then
nPrefSide = 2
-- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto)
else
nPrefSide = 1
end
end
-- se faccia verso X+ e mandrino verso sinistra
if vtNFc:getX() > 0 and nPrefSide == 1 then
-- se angolo interno e circa -90
if abs( dAng + 90) < 5 then
bInvertMach = true
end
-- se faccia verso X- e mandrino verso destra
elseif vtNFc:getX() < 0 and nPrefSide == 2 then
-- se angolo interno e circa -90
if abs( dAng + 90) < 5 then
bInvertMach = true
end
end
end
end
-- eseguo inversione
if bInvertMach then
local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT)
local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE)
local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE)
local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT)
if not bOrtUp then
-- assegno i parametri invertiti
EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS)
EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert)
-- setto l'offset pari allo spessore lama
EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick)
end
end
-- posizione del braccio : se primo taglio la recupero, altrimenti la imposto
if not nPrevSCC then
nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC)
else
EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC)
end
-- rieseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nIdMach, false)
return false, false, sErr
end
end
end
end
return bMadeASbyBld, true, sWarn
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
local function MakeByPocketing( Proc, nPhase, nRawId, nPartId)
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc, nPartId)
-- cerco la svuotatura opportuna
local sPocketing = ML.FindPocketing( 'OpenPocket', Proc.Box:getDimX())
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, 0}})
-- 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
---------------------------------------------------------------------
-- lavorazione faccia laterale con sega a catena
local function MakeSideFaceByChainSaw( nSurfId, dDepth, dOffs, dSal, dEal, bShortenStart, bShortenEnd)
-- Recupero i dati dell'utensile
local sSawing = ML.FindSawing( 'Sawing')
local dMaxMat = 0
local dSawCornerRad = 0
local dSawThick = 0
local dSawDiameter = 0
-- se non trova una lavorazione di sawing esco
if not sSawing then
local sErr = 'Error : Sawing not found in library'
EgtOutLog( sErr)
return false, sErr
else
if EgtMdbSetCurrMachining( sSawing) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick
dSawCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD) or dSawCornerRad
dSawDiameter = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiameter
end
end
end
-- inserisco la lavorazione di sawing
local sName = 'Csaw_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_1'
local nMchFId = EgtAddMachining( sName, sSawing)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ nSurfId, 0}})
-- imposto faceuse
local nFaceUse = MCH_MILL_FU.PARAL_DOWN
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- imposto angolo 3° asse rot
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 1))
local vtN = EgtSurfTmFacetNormVersor( nSurfId, 0, GDB_ID.ROOT)
local vtOrtho = BL.GetVersRef( nFaceUse)
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 1))
-- imposto eventuale sovramateriale
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
-- imposto tratti in cui la sega a catena non lavora per lasciare del materiale di supporto
local dSupportingWoodLength = 30
-- imposto allungamento percorso iniziale e finale
if bShortenStart then
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal - dSupportingWoodLength - dSawDiameter)
else
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
end
if bShortenEnd then
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal - dSupportingWoodLength - dSawDiameter)
else
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
end
-- imposto il lato di lavorazione
local nWorkSide = MCH_MILL_WS.RIGHT
EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide)
-- verifico se devo ridurre l'affondamento
if dMaxMat >= dDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
else
EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat)
sWarn = 'Warning : chainsaw elevation bigger than max tool depth'
EgtOutLog( sWarn)
end
-- eseguo
if not ML.ApplyMachining( true, false) then
if EgtGetOutstrokeInfo() then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
-- impostazione alternativa angolo 3° asse rot
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, BL.GetChainSawBlockedAxis( 2))
EgtSetMachiningParam( MCH_MP.INITANGS, BL.GetChainSawInitAngs( vtN, vtOrtho, 2))
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
if EgtIsMachiningEmpty() then
_, sWarn = EgtGetMachMgrWarning( 0)
EgtSetOperationMode( nMchFId, false)
return false, sWarn
end
--end
return true, sWarn
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId, bCustUseBlade, nCustForceUseBladeOnNCF)
-- recupero l'ingombro del grezzo di appartenenza
local b3Raw = EgtGetRawPartBBox( nRawId)
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
-- recupero lunghezza grezzo totale da info sulla macchinata
local dBarLen = EgtGetInfo( EgtGetCurrMachGroup(), 'BARLEN', 'd')
local dOvmHead = b3Raw:getMax():getX() - b3Solid:getMax():getX()
-- dati della faccia
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
local _, dLen, dWidth = EgtSurfTmFacetMinAreaRectangle( Proc.Id, 0, GDB_ID.ROOT)
-- limitazioni su inizio e fine derivanti da altre facce
local bLimXmin = false
local bLimXmax = false
if Proc.Fct >= 3 then
bLimXmin = true
bLimXmax = true
elseif Proc.Fct >= 2 then
local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
if vtN1:getX() > 0 then
bLimXmin = true
else
bLimXmax = true
end
end
-- Verifico lato di lavorazione (limite di lato a 45deg per FAST e 36deg per PF)
local nSide = 1
if vtN:getZ() < - 0.5 then
nSide = -1
elseif vtN:getY() < - EgtIf( BD.C_SIMM, 0.588, 0.7072) then
nSide = -2
elseif vtN:getY() > EgtIf( BD.C_SIMM, 0.588, 0.7072) then
nSide = 2
end
-- Verifico se largo come faccia
local bLarghAsFace = false
if nSide == 1 or nSide == -1 then
bLarghAsFace = ( Proc.Box:getDimY() > b3Solid:getDimY() - 20)
else
bLarghAsFace = ( Proc.Box:getDimZ() > b3Solid:getDimZ() - 20)
end
-- Determino se parte da sopra
local bTopStart = ( Proc.Box:getMax():getZ() > b3Solid:getMax():getZ() - 20)
-- Determino se parte da sotto
local bBottomStart = ( Proc.Box:getMin():getZ() < b3Solid:getMin():getZ() + 20)
-- Determino se lavorazione da davanti o da dietro
local bFront = ( vtN:getY() < 0)
-- Ottengo la distanza tra la fine del pezzo e il pezzo successivo o grezzo utilizzabile e non ancora separato
local dDistToNextPiece = BL.GetDistanceToNextPart( nRawId, nPhase)
local bForcedLim
local sWarn
----------------------------------------------------------------------------------------------------------------------------------------
-- 2020/09/15 Fabio Squaratti: se sono attivi entrambe i Q05 (lavorare con lama) e Q07 (lavorare con fresa di fianco anche da sopra)
-- allora vince il Q7, 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 terminali, l'utensile deve arrivare
-- fino al punto più vicino della faccia terminale (prima l'arretramento era sempre del raggio utensile).
-- Questo viene fatto se Q07=1 o fresa da sotto
----------------------------------------------------------------------------------------------------------------------------------------
local nUseBlade = 0
if bCustUseBlade then
nUseBlade = 1
-- leggo il parametro Q05 solo se è una vera longcut L010
elseif ProcessLongCut.Identify( Proc) then
nUseBlade = EgtGetInfo( Proc.Id, 'Q05', 'i') or 0
end
local bForceUseBladeOnNotThruFace
if nCustForceUseBladeOnNCF then
bForceUseBladeOnNotThruFace = nCustForceUseBladeOnNCF > 2
nUseBlade = EgtIf( nCustForceUseBladeOnNCF > 2, nCustForceUseBladeOnNCF-2, nCustForceUseBladeOnNCF)
else
-- bForceUseBladeOnNotThruFace = EgtGetInfo( Proc.Id, 'Q06', 'b') or false
-- non viene più usato un nuovo Q (Q06) ma dipende dal valore del Q05
-- con nuovi valori 3: come 1 ma con forza lama su facce chiuse; 4: come 2 ma con forza lama su facce chiuse
if nUseBlade > 2 then
nUseBlade = nUseBlade - 2
bForceUseBladeOnNotThruFace = true
end
end
-- se ho il parametro settato dal LapJoint (per ora è questo componente che setta questo parametro) allora setto a false l'uso della lama
-- perchè se ha questo parametro a true significa che la lama è forzata ad essere usata
local nUseMillOnSide
if nCustForceUseBladeOnNCF then
nUseMillOnSide = 0
else
nUseMillOnSide = EgtGetInfo( Proc.Id, 'Q07', 'i') or 0
end
-- se entrambe i Q sono attivi, disabilito lama
if nUseMillOnSide > 0 then
nUseBlade = 0
bForceUseBladeOnNotThruFace = false
end
local bCanUseBlade = false
local bCanUseUnderBlade = false
-- se lama abilitata per lavorare sopra e faccia da sopra
if nUseBlade == 1 and nSide == 1 then
bCanUseBlade = true
end
-- se lama abilitata per lavorare anche i fianchi e da sotto e non c'è testa da sotto
if nUseBlade == 2 and not BD.DOWN_HEAD then
if ( nSide == 1 or abs(nSide) == 2) and vtN:getZ() >= -0.0175 then
bCanUseBlade = true
end
end
-- se lama abilitata per lavorare i fianchi e da sotto e c'è testa da sotto
if nUseBlade == 2 and BD.DOWN_HEAD then
-- se faccia da sotto o di lato ma con versore Z negativo che supera i 30° da Z-
if ( nSide == -1 or abs(nSide) == 2) and vtN:getZ() <= -0.5 then
bCanUseUnderBlade = true
end
-- se faccia da sotto o di lato ma con versore Z sotto l'orizzontale abilito la lavorazione con lame mixate (limite 3 deg verso alto)
if ( nSide == -1 or abs(nSide) == 2) and vtN:getZ() <= 0.053 then
bCanUseUnderBlade = true
end
-- se faccia da sopra o di lato ma con versore Z negativo verifico che abbia un angolo compatibile (28deg) per non avere extracorsa
if ( nSide == 1 or abs(nSide) == 2) and vtN:getZ() >= -0.4695 then
bCanUseBlade = true
end
end
-- introduco messaggi di errore in caso sia settata la lama ma impossibile utilizzarla
-- se si toglie questa parte il processo continua utilizzandi però la fresa ma per il vincolo del parametro Q non è possibile
if nUseBlade == 2 and not BD.DOWN_HEAD and not bCanUseBlade then
local sErr = 'Error, impossible use blade on negative side face'
EgtOutLog( sErr)
return false, sErr
elseif nUseBlade == 1 and not bCanUseBlade then
local sErr = 'Error, impossible use blade'
EgtOutLog( sErr)
return false, sErr
elseif nUseBlade == 2 and BD.DOWN_HEAD and not bCanUseBlade and not bCanUseUnderBlade then
local sErr = 'Error, impossible use blade'
EgtOutLog( sErr)
return false, sErr
end
-- Se non limitato o forzato uso lama e da sopra e richiesto con doppio taglio di lama e superiore al limite minimo
if ( ( not bLimXmin and not bLimXmax) or bForceUseBladeOnNotThruFace) and ( bCanUseUnderBlade or bCanUseBlade) and nUseBlade > 0 and b3Solid:getDimX() > dLimMinPiece - 1 then
local sCutting
local dToolDiam = 0
local dThick = 0
local dMaxDepth = 0
local dMaxVertDepth = 0
local sCuttingDn
local dToolDiamDn = 0
local dThickDn = 0
local dMaxDepthDn = 0
-- recupero eventuale lavorazione con lama su testa da sotto
if bCanUseUnderBlade then
sCuttingDn = ML.FindCutting( 'HeadSide_H2', false, true)
if not sCuttingDn then
local sErr = 'Error : sawing HeadSide_H2 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
dThickDn = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThickDn
dMaxDepthDn = EgtTdbGetCurrToolMaxDepth() or dMaxDepthDn
end
end
end
-- recupero eventuale lavorazione con lama
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
dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dThick
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
dMaxVertDepth = dMaxDepth - ( BD.DECR_VERT_CUT or 0)
end
end
end
-- se la fine (a sinistra) non è limitata e ho un pezzo successivo o grezzo riutilizzabile meno distante di metà raggio, setto la fine come limitata
if (( bCanUseBlade or bCanUseUnderBlade) and ( dDistToNextPiece < dToolDiam/2 or dDistToNextPiece < dToolDiamDn/2)) and not bLimXmin then
if bForceUseBladeOnNotThruFace then
bForcedLim = true
bLimXmin = true
else
sWarn = 'Warning on saw cut : Cut machining can damage next piece'
EgtOutLog( sWarn)
end
end
-- disabilitato la selezione del codolo, prende sempre quello più piccolo. Non cancellare quello disabiliato in caso di ripristino
local dDimStrip = BD.DIM_STRIP_SMALL * EgtIf( nSide == -1, -1, 1)
-- determino gli estremi
local bStartFixed
local bEndFixed
local dStartAccDist
local dStartDist
local dEndAccDist
local dEndDist
local dStartAccDistUp = BD.LONGCUT_ENDLEN
local dStartDistUp = 0
local dEndAccDistUp = BD.LONGCUT_ENDLEN
local dEndDistUp = 0
local dStartAccDistDn = BD.LONGCUT_ENDLEN
local dStartDistDn = 0
local dEndAccDistDn = BD.LONGCUT_ENDLEN
local dEndDistDn = 0
if bForceUseBladeOnNotThruFace then
if bCanUseBlade then
bStartFixed = true
if bLimXmax then
local dRadius = dToolDiam / 2
local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2)
dStartDistUp = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1))
dStartAccDistUp = BD.LONGCUT_MAXLEN
bStartFixed = false
end
bEndFixed = true
if bLimXmin then
local dRadius = dToolDiam / 2
local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2)
dEndDistUp = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1))
dEndAccDistUp = BD.LONGCUT_MAXLEN
bEndFixed = false
end
end
if bCanUseUnderBlade then
bStartFixed = true
if bLimXmax then
local dRadius = dToolDiamDn / 2
local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2)
dStartDistDn = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1))
dStartAccDistDn = BD.LONGCUT_MAXLEN
bStartFixed = false
end
bEndFixed = true
if bLimXmin then
local dRadius = dToolDiamDn / 2
local dCat1 = dRadius - ( ( dWidth - dDimStrip) / 2)
dEndDistDn = sqrt( ( dRadius * dRadius) - (dCat1 * dCat1))
dEndAccDistDn = BD.LONGCUT_MAXLEN
bEndFixed = false
end
end
end
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 ( dato dal diametro utensile più grande)
if nCUp then
nC = nCUp
dC = dCUp
elseif nCDn then
nC = nCDn
dC = dCDn
end
-- nei casi in cui la doppia lama non sia sufficiente, se richiesto, attivo un'ulteriore lavorazione con sega a catena
-- solo per T010
local bFinishWithChainSaw = false
if ( Proc.Prc == 10 and not ProcessLongCut.Identify( Proc)) and bLarghAsFace and abs( nSide) == 2 and ( bCanUseBlade and bCanUseUnderBlade) and Proc.Fct == 1 then
bFinishWithChainSaw = EgtIf ( ( EgtGetInfo( Proc.Id, 'Q05', 'i') or 0) == 1, true, false)
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:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK))
nFaceUse2 = EgtIf( abs( vtN: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:getY()) > 0.01, MCH_MILL_FU.ORTHO_TOP, EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT))
nFaceUse2 = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK))
end
-- si percorrono i lati alto e basso della faccia
-- calcolo quanto è l'affondamento del taglio
local dMainMaxDepth = EgtIf( abs( vtN:getY()) < 1e-6, dMaxDepth, dMaxVertDepth)
local dOtherMaxDept = EgtIf( bCanUseUnderBlade, dMaxDepthDn, dMainMaxDepth)
local dCoeff = min( ( dWidth - dDimStrip) / ( dMainMaxDepth + dOtherMaxDept), 1)
local dOffsetTopBlade = dWidth - dCoeff * dMainMaxDepth
local dOffsetDownBlade = dWidth - dCoeff * dOtherMaxDept
local nStepDownBlade = 1
local dStepDownBlade = dOtherMaxDept
-- se lama da sotto verifico se la componente Y della profondità di taglio supera la capacità della lama
if ( nSide == -1 or abs(nSide) == 2) and bCanUseUnderBlade and ( dOffsetTopBlade - dDimStrip) > dOtherMaxDept then
if bFinishWithChainSaw then
local dHCutDownBlade = dWidth - dOffsetDownBlade
local dMaxStepDownBlade = 80
nStepDownBlade = ceil( dHCutDownBlade / dMaxStepDownBlade)
dStepDownBlade = dHCutDownBlade / nStepDownBlade
else
local dDelta = dWidth - dDimStrip - ( dMainMaxDepth + dOtherMaxDept)
local sErr = 'Error : side depth is bigger than total cut depth (Diff=' .. EgtNumToString( dDelta)..')'
EgtOutLog( sErr)
return false, sErr
end
else
bFinishWithChainSaw = false
end
local nM = 0
-- se abilitata la lavorazione di lama su faccia chiusa, aggiungo le eventuali lavorazioni di antischeggia
-- e di asporto dell'impronta lama
if bForceUseBladeOnNotThruFace and ( bLimXmin or bLimXmax) then
local nCountMilHead = 0
-- determino la massima elevazione
local dElev = BL.GetFaceElevation( Proc.Id, 0, nPartId)
-- recupero la lavorazione
local sMilling = ML.FindMilling( 'Long2Cut_H2', dElev, nil, nil, nil, not bCanUseUnderBlade, bCanUseUnderBlade)
if not sMilling then
local sErr = 'Error : milling Long2Cut (_H2) 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 ho facce di chiusura, per prima cosa faccio antischeggia
-- come richiesto da Fabio Squaratti il 03/09/2021
if ( bLimXmin and not bForcedLim) or bLimXmax then
local bOk, nFacet
bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, b3Raw, (( bLimXmin and not bForcedLim) and bLimXmax), vtN, nFacet, 0, sWarn, bCanUseUnderBlade, nil, sCutting)
if not bOk then return false, sWarn end
end
-- eventuale lavorazione della faccia limitante l'inizio
if not bStartFixed then
local vtIni = -X_AX()
for j = 1, Proc.Fct - 1 do
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT)
if vtIni * vtN > 0 and nCountMilHead < 2 then
MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, max(dStartDistUp,dStartDistDn), bCanUseUnderBlade)
nCountMilHead = nCountMilHead + 1
end
end
if bForcedLim and nCountMilHead < 1 then
MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, max(dStartDistUp,dStartDistDn), bCanUseUnderBlade)
nCountMilHead = nCountMilHead + 1
end
end
-- eventuale lavorazione della faccia limitante la fine
if not bEndFixed then
local vtFin = X_AX()
for j = 1, Proc.Fct - 1 do
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT)
if vtFin * vtN > 0 and nCountMilHead < 2 then
MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, max(dEndDistUp,dEndDistDn), bCanUseUnderBlade)
nCountMilHead = nCountMilHead + 1
end
end
if bForcedLim and nCountMilHead < 2 then
MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, max(dEndDistUp,dEndDistDn), bCanUseUnderBlade)
nCountMilHead = nCountMilHead + 1
end
end
end
-- inserisco tagli di lama
for i = 1, nC do
-- ciclo sulle passate
local dLioTang = 0
for k = 1, 2 do
local nStep = 1
if k == 2 then nStep = nStepDownBlade end
for Zstep = nStep, 1, -1 do
local dLioPerp = ( dWidth - dDimStrip) / 2 + BD.CUT_SIC
local bAddOpposite = true
local dAddExtraPerp = 0
-- se faccia da sotto e angolo inferiore ai 12° o faccia di fianco e angolo inferiore a 15° (al di sotto di questo angolo
-- l'attacco lama si comporta in modo diverso) allora calcolo il valore perpendicolare con la funzione CalcLeadInOutPerpGeom
if ( nSide == -1 and abs(vtN:getY()) >= 0.2079) or ( abs(nSide) == 2 and abs(vtN:getZ()) >= 0.2588) then
bAddOpposite = false
end
-- faccio in modo di calcolare il valore perpendicolare solo sulla faccia da sotto nel secondo passo o sulla faccia di fianco nel primo passo
if nSide == 1 or ( nSide == -1 and k == 1) or ( abs(nSide) == 2 and k == 2) then
bAddOpposite = false
end
if bAddOpposite then
-- controllo se devo aggiungere un extra all'attacco perpendicolare
if nSide == -1 then
if vtN:getY() > 0 then
dAddExtraPerp = Proc.Box:getMin():getY() - b3Solid:getMin():getY()
elseif vtN:getY() < 0 then
dAddExtraPerp = b3Solid:getMax():getY() - Proc.Box:getMax():getY()
end
elseif abs(nSide) == 2 then
dAddExtraPerp = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()
end
dLioPerp = dLioPerp + dAddExtraPerp
end
-- inserisco le parti di lavorazione
nM = nM + 1
local sNameF
local nMchFId
if ( k == 1 and bCanUseBlade) or ( k == 2 and ( bCanUseBlade and not bCanUseUnderBlade)) then
sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. 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
dEndDist = dEndDistUp
dEndAccDist = dEndAccDistUp
dStartDist = dStartDistUp
dStartAccDist = dStartAccDistUp
elseif ( k == 2 and bCanUseUnderBlade) or ( k == 1 and ( bCanUseUnderBlade and not bCanUseBlade)) then
sNameF = 'L2CD_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. 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
dEndDist = dEndDistDn
dEndAccDist = dEndAccDistDn
dStartDist = dStartDistDn
dStartAccDist = dStartAccDistDn
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, 0}})
-- settaggio di workside, uso faccia e eventuale inversione
-- limito opportunamente la lavorazione
local dSalInner, dSalOuter = - dEndAccDist - ( i - 2) * dC, -dEndDist
local dEalInner, dEalOuter = - dStartAccDist - ( nC - i - 1) * dC, -dStartDist
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
local nFaceUseCurrent
if bCanUseBlade and bCanUseUnderBlade then
dSal, dEal = dEal, dSal
if k == 1 then
bIsTopBladeCurrent = true
nFaceUseCurrent = nFaceUse2
else
bIsTopBladeCurrent = false
nFaceUseCurrent = nFaceUse
end
elseif bCanUseUnderBlade then
if k == 1 then
bIsTopBladeCurrent = false
nFaceUseCurrent = nFaceUse
else
bIsTopBladeCurrent = false
nFaceUseCurrent = nFaceUse2
end
else
if k == 1 then
bIsTopBladeCurrent = true
nFaceUseCurrent = nFaceUse
else
bIsTopBladeCurrent = true
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) ~= 2 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
-- step sempre positivi
local bAreCuttingStepsTowardsHead = true
-- calcolo SCC
local nSCC = ProcessLongCut.GetSCC( Proc, 0, EgtIf( bIsTopBladeCurrent, sCutting, sCuttingDn), nFaceUseCurrent, bInvert, i, nC, bAreCuttingStepsTowardsHead, bIsTopBladeCurrent, bCustUseBlade)
-- 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
local dOffset = EgtIf( k == 1, dOffsetTopBlade, dOffsetDownBlade + dStepDownBlade * ( Zstep - 1))
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
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- eseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
end
end
-- se richiesto aggiungo la lavorazione con sega a catena
if bFinishWithChainSaw then
local dChainSawOverMaterial = 0
local dChainSawDepth = dOffsetDownBlade + BD.CUT_EXTRA
dEndDist = dEndDistUp
dEndAccDist = dEndAccDistUp
dStartDist = dStartDistUp
dStartAccDist = dStartAccDistUp
for i = nC, 1, -1 do
local bFirstCut = ( i == nC)
local bLastCut = ( i == 1)
local dSal = EgtIf( bFirstCut, -dEndDist, - dEndAccDist - ( nC - i - 1) * dC)
local dEal = EgtIf( bLastCut, -dStartDist, - dStartAccDist - ( i - 2) * dC)
local bShortenStartOrEnd = true
local bChainSawOk, sErr = MakeSideFaceByChainSaw( Proc.Id, dChainSawDepth, dChainSawOverMaterial, dSal, dEal, bShortenStartOrEnd, bShortenStartOrEnd)
if not bChainSawOk then return false, sErr end
end
end
-- se non è sotto e non uso fresa di fianco: lavorazione Long2Cut
elseif ( nSide ~= - 1 or BD.DOWN_HEAD) and nUseMillOnSide == 0 then
-- determino la massima elevazione
local dElev = BL.GetFaceElevation( Proc.Id, 0, nPartId)
-- recupero la lavorazione
local bDownHead = ( nSide == - 1)
sMchType = EgtIf( bDownHead, 'Long2Cut_H2', 'Long2Cut')
-- rimossa l'esclusione della terza testa a seguito di modifica della testa stessa che la rende utilizzabile in tutti i casi
--local bExcludeH3 = bLarghAsFace and abs( nSide) ~= 1
local sMilling = ML.FindMilling( sMchType, dElev, nil, nil, nil, not bDownHead, bDownHead, nil, bExcludeH3)
if not sMilling then
local sErr = 'Error : milling '..sMchType..' 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 o grezzo riutilizzabile meno distante di metà raggio, setto la fine come limitata
if dDistToNextPiece < dToolDiam/2 and not bLimXmin then
bForcedLim = true
bLimXmin = true
end
-- se chiuso e corto, applico svuotatura con fresa opportuna
if bLimXmin and bLimXmax and Proc.Box:getDimX() < 2 * dToolDiam then
return MakeByPocketing( Proc, nPhase, nRawId, nPartId)
end
-- determino l'utilizzo della faccia
local nFaceUse = EgtIf( abs( vtN:getY()) > 0.01, MCH_MILL_FU.ORTHO_DOWN, EgtIf( bFront, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK))
-- determino il lato di attacco (0:xMin, 1:xMax)
local nStartSide = 0
if nFaceUse == MCH_MILL_FU.ORTHO_DOWN and not bFront then
nStartSide = 1
elseif nFaceUse ~= MCH_MILL_FU.ORTHO_DOWN then
if ( bFront and nSide == -1) or ( not bFront and nSide == 1) then
nStartSide = 1
end
end
-- determino gli estremi
local dStartDist = 0
local dStartAccDist = BD.LONGCUT_ENDLEN
local bStartFixed = true
if ( bLimXmin and nStartSide == 0) or ( bLimXmax and nStartSide == 1) then
dStartDist = dToolDiam / 2
dStartAccDist = BD.LONGCUT_MAXLEN
bStartFixed = false
end
local dEndDist = 0
local dEndAccDist = BD.LONGCUT_ENDLEN
local bEndFixed = true
if ( bLimXmin and nStartSide == 1) or ( bLimXmax and nStartSide == 0) then
dEndDist = dToolDiam / 2
dEndAccDist = BD.LONGCUT_MAXLEN
bEndFixed = false
end
-- determino 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 + 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
-- se c'è del grezzo aggiuntivo e, considerando il grezzo mi resta abbastanza materiale per pinzare, allora faccio spezzatura asimmetrica
if BD.MIN_CLAMPING_LEN and ( dBarLen - dLen) > dOvmHead + 100 * GEO.EPS_SMALL and ( dBarLen - dStartAccDist > BD.MIN_CLAMPING_LEN) then
dStartAccDist = dBarLen/2
dEndAccDist = dLen - dStartAccDist
-- se sono sul fronte, la spezzatura assimmetrica è inversa
if Proc.AffectedFaces.Front then
dStartAccDist, dEndAccDist = dEndAccDist, dStartAccDist
end
else
dStartAccDist = dLen/2
dEndAccDist = dStartAccDist
end
end
else
nC = 1
dStartAccDist = 0
dEndAccDist = 0
end
end
-- si percorre il lato basso della faccia
local nM = 0
local nCountMilHead = 0
for i = 1, nC do
-- ciclo sulle passate
local nO = 1
local dStep = 0
if dWidth + 2 * BD.CUT_EXTRA > 0.8 * dToolDiam then
nO = ceil(( dWidth + 2 * BD.CUT_EXTRA) / ( 0.6 * dToolDiam))
if nO > 1 then
dStep = ( dWidth + 2 * BD.CUT_EXTRA) / nO
end
end
for k = nO, 1, -1 do
-- inserisco le parti di lavorazione
nM = nM + 1
local sNameF = 'L2CH_' .. ( 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
-- correggo l'attacco se necessario
if i == 1 and not bStartFixed then
if nO == 1 or EgtGetMachiningParam( MCH_MP.LITANG) ~= 0 then
EgtSetMachiningParam( MCH_MP.LIELEV, 0)
EgtSetMachiningParam( MCH_MP.LITANG, 0)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
EgtSetMachiningParam( MCH_MP.LIPERP, dWidth + BD.CUT_EXTRA + ( BD.CUT_SIC or 20))
end
elseif i == nC and not bEndFixed then
if nO == 1 or EgtGetMachiningParam( MCH_MP.LOTANG) ~= 0 then
EgtSetMachiningParam( MCH_MP.LOELEV, 0)
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LI.LINEAR)
EgtSetMachiningParam( MCH_MP.LOPERP, dWidth + BD.CUT_EXTRA + ( BD.CUT_SIC or 20))
end
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, 0}})
-- inverto se utensile antiorario per garantire senso di percorrenza migliore
local bInvert = EgtMdbGetCurrMachiningParam( MCH_MP.SPEED) < 0
-- setto workside e eventuale inversione
if bInvert then
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
EgtSetMachiningParam( MCH_MP.INVERT, true)
else
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
EgtSetMachiningParam( MCH_MP.INVERT, false)
end
-- limito opportunamente la lavorazione
local dSal = EgtIf( i == 1, -dStartDist, - dStartAccDist - ( i - 2) * dC)
local dEal = EgtIf( i == nC, -dEndDist, - dEndAccDist - ( nC - i - 1) * dC)
if bInvert then
dSal, dEal = dEal, dSal
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
-- imposto offset radiale
EgtSetMachiningParam( MCH_MP.OFFSR, ( k - 1) * dStep - BD.CUT_EXTRA)
-- Posizione braccio portatesta
local bAreCuttingStepsTowardsHead = ( nStartSide == 0)
local nSCC = ProcessLongCut.GetSCC( Proc, 0, sMilling, nFaceUse, bInvert, i, nC, bAreCuttingStepsTowardsHead, nil, nil)
-- imposto posizione braccio porta testa per non ingombrare agli estremi
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- imposto uso della faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- verifico massimo affondamento rispetto ad elevazione
if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then
sWarn = 'Warning in LongCut : depth (' .. EgtNumToString( dElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
end
local dDepth = min( 0, dMaxDepth - dElev )
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
-- eventuale nota utente per disabilitare controllo ingresso e uscita in grezzo
if k < nO then
local sNotes = 'OutRaw=3;'
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
end
-- eseguo
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
-- eventuale lavorazione della faccia limitante l'inizio
if i == 1 and not bStartFixed then
-- per il lato sotto il vettore è opposto
local vtIni = EgtIf( bFront, X_AX(), -X_AX())
if nSide == -1 then
vtIni = -1 * vtIni
end
for j = 1, Proc.Fct - 1 do
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT)
if vtIni * vtN > 0 and nCountMilHead < 2 then
MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, nil, bDownHead)
nCountMilHead = nCountMilHead + 1
end
end
if bForcedLim and nCountMilHead < 1 then
MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, nil, bDownHead)
nCountMilHead = nCountMilHead + 1
end
end
end
-- eventuale lavorazione della faccia limitante la fine
if not bEndFixed then
-- per il lato sotto il vettore è opposto
local vtFin = EgtIf( bFront, -X_AX(), X_AX())
if nSide == -1 then
vtFin = -1 * vtFin
end
for j = 1, Proc.Fct - 1 do
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, j, GDB_ID.ROOT)
if vtFin * vtN > 0 and nCountMilHead < 2 then
MakeSideFace( Proc.Id, j, nSide, sMilling, dToolDiam, nil, nil, bDownHead)
nCountMilHead = nCountMilHead + 1
end
end
if bForcedLim and nCountMilHead < 2 then
MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bForcedLim, nil, bDownHead)
nCountMilHead = nCountMilHead + 1
end
end
-- altrimenti è con fresa di fianco (Long2CutSide) o da sotto (Long2CutDown)
else
-- 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
-- recupero i dati dell'utensile
local dToolDiam = 0
local dToolLength = 0
local dMaxDepth = 0
local dThDiam = 0
local dThLen = 0
if sMilling and 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 sMillingDn 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
-- distanza dalle eventuali facce estreme
local dDistToEnd = dToolDiam / 2
local dDistToEndDn = dToolDiamDn / 2
-- calcolo l'elevazione della faccia principale
local dFacElev = BL.GetFaceElevation( Proc.Id, 0, nPartId)
-- se fresa di fianco o da sotto calcolo quanto l'utensile può andare vicino all'estremo con l'elevazione della faccia minore del raggio utensile
if ( nUseMillOnSide <= 1 or nSide == -1) and dFacElev < dToolDiam / 2 then
dDistToEnd = sqrt( dFacElev * ( dToolDiam - dFacElev))
end
if nUseMillOnSide <= 1 and dFacElev < dToolDiamDn / 2 then
dDistToEndDn = sqrt( dFacElev * ( dToolDiamDn - dFacElev))
end
-- se la fine è già limitata allora setto per arretrare del raggio utensile
if bLimXmin 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
bLimXmin = true
end
-- larghezza faccia
local _, _, dWidth = BL.GetFaceHvRefDim( Proc.Id, 0)
-- aggiuntivo sull'affondamento
local dAgg = BD.CUT_EXTRA
-- determino gli estremi
local dStartDist = 0
local dStartAccDist = BD.LONGCUT_ENDLEN
local bStartFixed = true
if ( bLimXmin and bFront) or ( bLimXmax and not bFront) then
if ( bLimXmin and bFront) then
dStartDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd)
else
dStartDist = dDistToEnd
end
dStartAccDist = BD.LONGCUT_MAXLEN
bStartFixed = false
end
local dEndDist = 0
local dEndAccDist = BD.LONGCUT_ENDLEN
local bEndFixed = true
if ( bLimXmin and not bFront) or ( bLimXmax and bFront) then
if ( bLimXmin and not bFront) then
dEndDist = EgtIf( nExtendMach == 2, dDistToEnd - dDistToNextPiece + 0.5, dDistToEnd)
else
dEndDist = dDistToEnd
end
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
-- verifico se posso farlo da una sola parte o se necessario da due parti
local dMaxDepthZ = dMaxDepth
local dMaxDepthDnZ = dMaxDepthDn
local CosA = abs( vtN:getZ())
if CosA >= 0.05 then
local SinA = sqrt( 1 - CosA * CosA)
local dRad = dThDiam / 2 - dToolDiam / 2 + BD.COLL_SIC
dMaxDepthZ = dMaxDepthZ - ( dRad * CosA / SinA)
if sMillingDn then
local dRadDn = dThDiamDn / 2 - dToolDiamDn / 2
dMaxDepthDnZ = dMaxDepthDnZ - ( dRadDn * CosA / SinA)
end
end
local dMaxDepthY = dMaxDepth
local dMaxDepthDnY = dMaxDepthDn
local SinA = abs( vtN:getZ())
if SinA >= 0.05 then
local CosA = sqrt( 1 - SinA * SinA)
local dRad = dThDiam / 2 - dToolDiam / 2 + BD.COLL_SIC
dMaxDepthY = dMaxDepthY - ( dRad * CosA / SinA)
if sMillingDn then
local dRadDn = dThDiamDn / 2 - dToolDiamDn / 2
dMaxDepthDnY = dMaxDepthDnY - ( dRadDn * CosA / SinA)
end
end
local nPass = 0
local vdMaxD = { 0, 0}
local vnHead = { 0, 0}
-- con testa da sopra
if nSide == 1 or ( sMilling and abs( nSide) == 2 and ( bTopStart or abs( vtN:getY()) < 0.866)) or not sMillingDn then
vnHead = { 1, 1}
-- se faccia sopra
if nSide == 1 then
vdMaxD[1] = EgtIf( bLarghAsFace, dMaxDepthY, dMaxDepthZ)
if dWidth + dAgg <= vdMaxD[1] then
nPass = 1
else
nPass = 2
dAgg = BD.CUT_EXTRA_MIN
vdMaxD[2] = dMaxDepthY
end
-- se altrimenti faccia sotto
elseif nSide == -1 then
if dWidth + dAgg <= dMaxDepthY or abs( vtN:getY()) > EgtIf( BD.C_SIMM, 0.588, 0.7072) then
nPass = 1
vdMaxD[1] = dMaxDepthY
else
nPass = 2
vdMaxD[1] = dMaxDepthY
local dDelta = b3Solid:getDimY() - Proc.Box:getDimY()
if bLarghAsFace then
vdMaxD[2] = min( dMaxDepthY, dMaxDepth - dDelta * abs( vtN:getZ()) - BD.COLL_SIC)
else
vdMaxD[2] = min( dMaxDepthZ, dToolLength - 5 - dDelta / abs( vtN:getZ()) - BD.COLL_SIC)
end
if vdMaxD[2] < 0 then nPass = 1 end
if nPass == 2 then dAgg = BD.CUT_EXTRA_MIN end
end
-- altrimenti faccia di fianco
else
nPass = 1
local dDelta = b3Solid:getMax():getZ() - Proc.Box:getMax():getZ()
if abs( vtN:getY()) < 0.866 then
vdMaxD[1] = dMaxDepthY
elseif bTopStart then
vdMaxD[1] = min( dMaxDepthZ, dMaxDepth - dDelta * abs( vtN:getY()) - BD.COLL_SIC)
else
vdMaxD[1] = min( dMaxDepthY, dToolLength - 5 - dDelta * abs( vtN:getY()) - BD.COLL_SIC)
end
if vdMaxD[1] < 0 then nPass = 0 end
end
-- eventuale errore per lavorazione saltata
if nPass == 0 then
local sErr = 'Error in '..sMchType..' : impossible machining'
EgtOutLog( sErr)
return false, sErr
end
-- eventuale avviso per lavorazione incompleta
if dWidth + nPass * dAgg > vdMaxD[1] + vdMaxD[2] then
sWarn = 'Warning in '..sMchType..' : depth is bigger than max tool depth'
end
-- con testa da sotto
else
vnHead = { 2, 2}
-- se faccia sotto
if nSide == -1 then
vdMaxD[1] = EgtIf( bLarghAsFace, dMaxDepthDnY, dMaxDepthDnZ)
if dWidth + dAgg <= vdMaxD[1] then
nPass = 1
else
nPass = 2
dAgg = BD.CUT_EXTRA_MIN
vdMaxD[2] = dMaxDepthDnY
end
-- altrimenti faccia di fianco
else
nPass = 1
local dDelta = Proc.Box:getMin():getZ() - b3Solid:getMin():getZ()
if bBottomStart then
vdMaxD[1] = min( dMaxDepthDnZ, dMaxDepthDn - dDelta * abs( vtN:getY()) - BD.COLL_SIC)
else
vdMaxD[1] = min( dMaxDepthDnY, dToolLengthDn - 5 - dDelta * abs( vtN:getY()) - BD.COLL_SIC)
end
if vdMaxD[1] < 0 then nPass = 0 end
end
-- eventuale errore per lavorazione saltata
if nPass == 0 then
local sErr = 'Error in '..sMchType..' : impossible machining'
EgtOutLog( sErr)
return false, sErr
end
-- eventuale avviso per lavorazione incompleta
if dWidth + nPass * dAgg > vdMaxD[1] + vdMaxD[2] then
sWarn = 'Warning in '..sMchType..' : depth is bigger than max tool depth'
end
end
-- profondità passate
local vdDepth = {}
vdDepth[1] = min( dWidth + dAgg, vdMaxD[1])
vdDepth[2] = min( dWidth + dAgg - vdDepth[1], vdMaxD[2])
-- ciclo sulle parti
local nM = 0
local bMakeMillHeadEnd
local bMakeMillHeadStart
local dLioPerp1 = dFacElev + BD.COLL_SIC
local dLioPerp2 = dWidth * EgtIf( abs( vtN:getZ()) < GEO.EPS_SMALL, 1, sqrt( 1 - vtN:getZ() * vtN:getZ()) / abs( vtN:getZ())) + BD.COLL_SIC
-- valore sovrapposizione tra passate
local dOverLapExtend = 2 * BD.CUT_EXTRA_MIN
for j = 1, nC do
-- Limitazioni della lavorazione
local nPos = EgtIf( bFront, j, nC - j + 1)
local dSal = EgtIf( nPos == 1, -dEndDist, -dEndAccDist - ( nPos - 2) * dC + dOverLapExtend)
local dEal = EgtIf( nPos == nC, -dStartDist, -dStartAccDist - ( nC - nPos - 1) * dC + dOverLapExtend)
-- Posizione braccio portatesta
--local nSCC
for k = 1, nPass do
-- inserisco le parti di lavorazione
nM = nM + 1
local sNameF = EgtIf( vnHead[k] ~= 2, sPrefix, sPrefixDn) .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM)
local nMchFId = EgtAddMachining( sNameF, EgtIf( vnHead[k] ~= 2, sMilling, sMillingDn))
if not nMchFId then
local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMillingDn
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, 0}})
-- imposto uso faccia
local nFaceUse = EgtIf( vnHead[k] ~= 2, MCH_MILL_FU.PARAL_DOWN, MCH_MILL_FU.PARAL_TOP)
if AreSameOrOppositeVectorApprox( vtN, Z_AX()) then nFaceUse = MCH_MILL_FU.PARAL_BACK end
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- imposto lato di lavoro e inversione
local bInvert
if k == 1 then
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
bInvert = true
else
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
bInvert = false
dSal, dEal = dEal, dSal
end
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
-- limito opportunamente la lavorazione
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
-- assegno affondamento
EgtSetMachiningParam( MCH_MP.DEPTH, vdDepth[k])
-- assegno attacco perpendicolare
EgtSetMachiningParam( MCH_MP.LIPERP, dLioPerp1)
EgtSetMachiningParam( MCH_MP.LOPERP, dLioPerp1)
-- step sempre negativi
local bAreCuttingStepsTowardsHead = false
-- calcolo SCC
local nSCC = ProcessLongCut.GetSCC( Proc, 0, EgtIf( vnHead[k] ~= 2, sMilling, sMillingDn), nFaceUse, bInvert, j, nC, bAreCuttingStepsTowardsHead, nil, nil)
-- imposto posizione braccio porta testa
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- eseguo
if not ML.ApplyMachining( true, false) then
-- se feature orientata su faccia da sotto provo a cambiare l'attacco
if nSide == -1 then
EgtSetMachiningParam( MCH_MP.LIPERP, min( dLioPerp1, dLioPerp2))
EgtSetMachiningParam( MCH_MP.LOPERP, min( dLioPerp1, dLioPerp2))
if not ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
-- esco se non sono nella seconda lavorazione o non nella faccia da sotto
if k < 2 or ( nSide ~= - 1 and not BD.DOWN_HEAD) then
return false, sErr
end
end
else
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
-- esco se non sono nella seconda lavorazione o non nella faccia da sotto
if k < 2 or ( nSide ~= - 1 and not BD.DOWN_HEAD) then
return false, sErr
end
end
end
-- eventuale lavorazione della faccia limitante la fine
if j == EgtIf( bFront , 1, nC) and not bEndFixed and bRemoveToolRadius then
local vtFin = EgtIf( bFront, -X_AX(), X_AX())
for i = 1, Proc.Fct - 1 do
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT)
if vtFin * vtN > 0 and not bMakeMillHeadEnd then
MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam)
bMakeMillHeadEnd = true
end
end
if bRemoveToolRadius and not bMakeMillHeadEnd then
MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius)
end
end
-- eventuale lavorazione della faccia limitante l'inizio
if j == EgtIf( bFront , nC, 1) and not bStartFixed and bRemoveToolRadius then
local vtIni = EgtIf( bFront, X_AX(), -X_AX())
for i = 1, Proc.Fct - 1 do
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i, GDB_ID.ROOT)
if vtIni * vtN > 0 and not bMakeMillHeadStart then
MakeSideFace( Proc.Id, i, nSide, sMilling, dToolDiam)
bMakeMillHeadStart = true
end
end
if bRemoveToolRadius and not bMakeMillHeadStart then
MakeSideFace( Proc.Id, 0, nSide, sMilling, dToolDiam, bRemoveToolRadius)
end
end
end
end
end
return true, sWarn
end
---------------------------------------------------------------------
return ProcessLongCut