Files
DataBeam/LuaLibs/ProcessDovetail.lua
T
Dario Sassi 4ba7936167 DataBeam :
- aggiunta gestione feature Dovetail (1/2/3/4-138-X)
- correzioni e migliorie varie.
2020-04-25 09:51:20 +00:00

1831 lines
84 KiB
Lua

-- ProcessDovetail.lua by Egaltech s.r.l. 2020/04/23
-- Gestione calcolo giunzione coda di rondine
-- Tabella per definizione modulo
local ProcessDovetail = {}
-- Include
require( 'EgtBase')
local BL = require( 'BeamLib')
local DC = require( 'DiceCut')
local Cut = require( 'ProcessCut')
EgtOutLog( ' ProcessDovetail started', 1)
-- Dati
local BD = require( 'BeamData')
local ML = require( 'MachiningLib')
-- variabili assegnazione parametri Q
local sForceUseBlade = '' -- i
local sDepthChamferMill = '' -- d
local sPreemptiveChamfer = '' -- i
local sUseMill = '' -- i
local sUseRoughTool = '' -- i
local sUseRoughToolWithBAxis90 = '' -- i
local sUseRoughToolWithBAxis0 = '' -- i
local sInsertBoreOnCorner = '' -- 1
local sMakeContourWithSmallTool = '' -- i
local sMakeOnlyContourOrFullPocket = '' -- i
local sMakeBySideRoughTool = '' -- i
local sAntisplintMode = '' -- i
---------------------------------------------------------------------
-- Riconoscimento della feature
function ProcessDovetail.Identify( Proc)
return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 138)
end
---------------------------------------------------------------------
local function AssignQValues( Proc)
-- reset delle variabili assegnazione parametri Q
sForceUseBlade = ''
sDepthChamferMill = ''
sPreemptiveChamfer = ''
sUseMill = ''
sUseRoughTool = ''
sUseRoughToolWithBAxis90 = ''
sUseRoughToolWithBAxis0 = ''
sInsertBoreOnCorner = ''
sMakeContourWithSmallTool = ''
sMakeOnlyContourOrFullPocket = ''
sMakeBySideRoughTool = ''
sAntisplintMode = ''
if Proc.Prc == 138 then
sUseRoughTool = 'Q02' -- d
end
end
---------------------------------------------------------------------
local function EvaluateQParam( Proc, sUseRoughTool)
local nChamfer = 0
local bForceUseRough = false
-- verifico se devo usare il truciolatore
-- 2020-03-20 forzata disabilitazione uso truciolatore se parametro Q non è presente
if #sUseRoughTool == 0 or EgtGetInfo( Proc.Id, sUseRoughTool, 'i') == 2 then
bForceUseRough = true
end
return nChamfer, bForceUseRough
end
---------------------------------------------------------------------
local function OrderFaces( Proc, nFacetCnt, vtN)
local dMinXFace = 1
local dPosXFace = 0
local dNegXFace = 0
local vFaceOrd = { 0, 0, 0}
if nFacetCnt <= 2 then
-- ordino le facce (1=faccia ausiliaria, 2=interna, 3=intermedia)
for i = 1, nFacetCnt do
if abs( vtN[i]:getX()) < dMinXFace then
dMinXFace = abs( vtN[i]:getX())
vFaceOrd[3] = i
end
end
if vFaceOrd[3] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face'
EgtOutLog( sErr)
return false, sErr
end
for i = 1, nFacetCnt do
if i ~= vFaceOrd[3] then
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT)
if bTouch and dAng < 0 then
vFaceOrd[2] = i
end
end
end
elseif nFacetCnt == 3 then
-- ordino le facce (1=altra intermedia, 2=interna, 3=intermedia)
for i = 1, nFacetCnt do
if abs( vtN[i]:getX()) < dMinXFace then
dMinXFace = abs( vtN[i]:getX())
vFaceOrd[3] = i
end
if abs( vtN[i]:getX()) > dPosXFace then
dPosXFace = abs( vtN[i]:getX())
vFaceOrd[2] = i
end
end
if vFaceOrd[3] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face'
EgtOutLog( sErr)
return false, sErr
end
if vFaceOrd[2] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face'
EgtOutLog( sErr)
return false, sErr
end
for i = 1, nFacetCnt do
if i ~= vFaceOrd[3] and i ~= vFaceOrd[2] then
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[2] - 1, GDB_ID.ROOT)
if bTouch and dAng < 0 then
vFaceOrd[1] = i
end
end
end
else
-- ordino le facce (1=laterale positiva 2=altra intermedia, 3=intermedia, 4=laterale negativa)
for i = 1, nFacetCnt do
if vtN[i]:getX() > dPosXFace then
dPosXFace = vtN[i]:getX()
vFaceOrd[1] = i
end
if ( vtN[i]:getX()) < dNegXFace then
dNegXFace = vtN[i]:getX()
vFaceOrd[4] = i
end
end
if vFaceOrd[1] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing side positive face'
EgtOutLog( sErr)
return false, sErr
end
if vFaceOrd[4] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing side negative face'
EgtOutLog( sErr)
return false, sErr
end
local nMidFace = 3
for i = 1, nFacetCnt do
if i ~= vFaceOrd[1] and i ~= vFaceOrd[4] then
vFaceOrd[nMidFace] = i
nMidFace = nMidFace - 1
end
end
if vFaceOrd[2] == 0 or vFaceOrd[3] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing middle face'
EgtOutLog( sErr)
return false, sErr
end
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT)
if bTouch and dAng < 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' wrong angle between middle faces'
EgtOutLog( sErr)
return false, sErr
end
end
return true, '', vFaceOrd
end
---------------------------------------------------------------------
local function VerifyIfRoughMill( dLargeface, vtN, bCalcElev, dAngOnSide)
local bUseRoughMill = false
local sMilling
-- recupero la lavorazione
if dAngOnSide then
if bCalcElev then
local dCollSic = BD.COLL_SIC
-- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra
if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end
sMilling = ML.FindMilling( 'ProfTCone', dLargeface + dCollSic)
else
sMilling = ML.FindMilling( 'ProfTCone')
end
else
if bCalcElev then
local dCollSic = BD.COLL_SIC
-- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra
if abs( vtN:getX()) > 0.7 or abs( vtN:getY()) > 0.7 or abs( vtN:getZ()) > 0.7 then dCollSic = 0 end
sMilling = ML.FindMilling( 'Long2Cut', dLargeface + dCollSic)
else
sMilling = ML.FindMilling( 'Long2Cut')
end
dAngOnSide = 0
end
if sMilling then
-- recupero i dati dell'utensile
local dToolDiam = 100
local dToolLength = 0
local dMaxDepth = 0
local dMaxMat = 50
local dSideAngle = 0
local dStepmach = 0
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
dToolLength = EgtTdbGetCurrToolParam( MCH_TP.LEN) or dToolLength
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle
-- ottengo il passo della lavorazione
dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStepmach
end
end
if dStepmach <= 0.1 then
dStepmach = dMaxMat * 0.5
end
-- se ho già fatto la ricerca lavorazione considerando l'elevazione controllo solo l'angolo
if bCalcElev then
-- se angolo spoglia compatibile
if abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL then
return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach
end
else
-- se altezza taglio utensile maggiore altezza faccia e angolo spoglia compatibile
if ( dMaxDepth >= dLargeface + 10 * GEO.EPS_SMALL) and ( abs( dSideAngle - dAngOnSide) < GEO.EPS_SMALL) then
return true, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach
end
end
end
return false
end
---------------------------------------------------------------------
-- Verifica se feature di testa
function ProcessDovetail.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
-- se una sola faccia
if Proc.Fct == 1 then
local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
if vtN0:getX() > 0.1 then
return true
end
end
-- verifico se è in testa
if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then
return false
end
-- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave
if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 *b3Raw:getDimX()) then
return false
end
-- se una o due facce ora è sicuramente di testa
if Proc.Fct <= 2 then
return true
end
-- deve avere la normale principale diretta verso la testa
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
if vtN:getZ() < BD.NZ_MINA and nFacInd2 then
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
nFacInd, nFacInd2 = nFacInd2, nFacInd
end
if vtN:getX() < 0.499 then
return false
elseif Proc.Fct >= 5 then
return true
end
-- deve occupare la maggior parte dell'area
if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then
return true
end
-- non è di testa
return false
end
---------------------------------------------------------------------
-- Verifica se feature di coda
function ProcessDovetail.IsTailFeature( Proc, b3Raw)
-- se una sola faccia
if Proc.Fct == 1 then
local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
if vtN0:getX() < -0.1 then
return true
end
end
-- verifico se è in coda
if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then
return false
end
-- la sua lunghezza non deve superare il massimo e 60% della lunghezza della trave
if Proc.Box:getDimX() > min( BD.MAX_LEN_HTFEA, 0.6 * b3Raw:getDimX()) then
return false
end
-- recupero identificativo del pezzo
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
-- se due facce e interessa veramente la coda, allora di coda
if Proc.Fct <= 2 then
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then
return true
end
end
-- deve avere la normale principale diretta verso la coda
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc.Id, nPartId)
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
if vtN:getZ() < BD.NZ_MINA and nFacInd2 then
ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd2, GDB_ID.ROOT)
nFacInd, nFacInd2 = nFacInd2, nFacInd
end
if vtN:getX() > -0.499 then
return false
else
return true
end
end
---------------------------------------------------------------------
-- Classificazione della feature
function ProcessDovetail.Classify( Proc, b3Raw)
-- in base al tipo di feature attribuisco il significato dei parametri Q
AssignQValues( Proc)
-- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore
local _, bForceUseRough = EvaluateQParam( Proc, sUseRoughTool)
-- verifico le normali delle facce
local nFacetCnt = EgtSurfTmFacetCount( Proc.Id)
local nFlatFaceNeg
local bDown = false
-- individuo se c'è faccia rastremata verso Z-
for i = 1, nFacetCnt do
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
if vtN:getZ() < -1 + GEO.EPS_SMALL then
nFlatFaceNeg = i-1
break
end
end
-- se trovata faccia rastremata rivolta verso Z-
-- verifico se lunghezza faccia piatta è compatibile con il taglio di lama
if nFlatFaceNeg then
-- se >= a 3 facce sicuramente è gruppo 3 o 4, setto il ribaltamento senza ulteriori controlli
if nFacetCnt >= 3 then
bDown = true
-- altrimenti faccio controllo di lavorabilità da sotto e setto eventuale ribaltamento
-- ( può essere gruppi 1 o 2, oppure gruppo 3 o 4 ma spostati verso le teste)
else
-- prendo le dimensioni della faccia
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT)
local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1)
local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT)
-- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama e non fattibile con truciolatore
-- quindi setto il ribaltamento
if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then
bDown = true
else
local dDist = dist( ptP1, ptP2)
local dLargeface
local dDeltadH = abs( dDist - dH)
local dDeltadV = abs( dDist - dV)
-- prendo la dimensione diversa dalla lunghezza di adiacenza
if dDeltadH < dDeltadV then
dLargeface = dV
else
dLargeface = dH
end
local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUseRough = VerifyIfRoughMill( dLargeface, rfFac:getVersZ(), true)
-- se forzato uso truciolatore
if bForceUseRough then
bDown = not bUseRough
-- altrimenti uso misto tra lama e truciolatore
else
bDown = not bUseBlade and not bUseRough
end
end
end
-- altrimenti controllo la componente in Z delle facce
else
local vtN = {}
for i = 1, nFacetCnt do
_, vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
for i = 1, nFacetCnt do
local nFacet = i-1
-- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso,
if abs(vtN[i]:getZ()) > abs(vtN[i]:getX()) and abs(vtN[i]:getZ()) > abs(vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then
-- se ho due facce e feature agli estremi verifico che la lunghezza faccia sia compatibile col taglio di lama
-- o con truciolatore in base al valore del Q
if nFacetCnt == 2 and ( Proc.Head or Proc.Tail) then
-- prendo le dimensioni della faccia
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
local nOtherFace = EgtIf( nFacet == 0, nFacet + 1, nFacet - 1)
local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT)
-- se angolo interno acuto
if dAng < 0 and dAng < -90 - 5 * GEO.EPS_SMALL then
-- se forzato truciolatore allora controllo se posso fare con utensile tronco di cono
local dLargeface = Proc.Box:getDimX()
local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true, (90+dAng))
-- se forzato uso truciolatore
if bForceUseRough then
bDown = not bUseRough
-- altrimenti uso misto tra lama e truciolatore
else
bDown = not bUseBlade and not bUseRough
end
-- altrimenti angolo interno a 90
else
local dDist = dist( ptP1, ptP2)
local dLargeface
local dDeltadH = abs( dDist - dH)
local dDeltadV = abs( dDist - dV)
-- prendo la dimensione diversa dalla lunghezza di adiacenza
if dDeltadH < dDeltadV then
dLargeface = dV
else
dLargeface = dH
end
-- se (anche) la direzione in z dell'altra faccia è negativa verifico se posso farla di fresa (in base alle impostazioni del Q)
if vtN[nOtherFace+1]:getZ() < -0.001 then
-- se forzato uso truciolatore verifico se posso fare di truciolatore
if bForceUseRough then
local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true)
bDown = not bUseRough
-- altrimenti posso usare lama, ma (anche) la direzione in z dell'altra faccia è negativa, quindi non è lavorabile, setto il ribaltamento
else
bDown = true
end
else
local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true)
-- se forzato uso truciolatore
if bForceUseRough then
bDown = not bUseRough
-- altrimenti uso misto tra lama e truciolatore
else
bDown = not bUseBlade and not bUseRough
end
end
end
elseif nFacetCnt == 3 and ( Proc.Head or Proc.Tail) then
-- ordino le 3 facce: (1=altra intermedia, 2=interna, 3=intermedia)
local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN)
if not bOk1 then return bOk1 end
-- se le due facce intermedie sono compatibili con la lunghezza lama da sotto
-- prendo le dimensioni della facce
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vFaceOrd[3]-1, GDB_ID.ROOT)
local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3]-1, vFaceOrd[1]-1, GDB_ID.ROOT)
-- prendo la dimensione uguale dalla lunghezza di adiacenza
local dLargeface = dist( ptP1, ptP2)
local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUseRough = VerifyIfRoughMill( dLargeface, X_AX(), true)
-- se forzato uso truciolatore e non riesco a farlo
if bForceUseRough then
bDown = not bUseRough
-- altrimenti uso misto tra lama e truciolatore
else
bDown = not bUseBlade and not bUseRough
end
elseif not Proc.Head and not Proc.Tail then
bDown = true
end
end
end
end
return true, bDown
end
---------------------------------------------------------------------
local function MakeCutsByDice( Proc, b3Raw, vCuts, nAddGrpId, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim)
-- sistemo posizione nel DB e nome
for i = 1, #vCuts do
for j = 1, #vCuts[i] do
EgtRelocateGlob( vCuts[i][j], nAddGrpId)
EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id))
EgtSetInfo( vCuts[i][j], 'TASKID', Proc.TaskId)
end
end
-- calcolo secondo riferimento per testa o coda
local vtRef2 = EgtIf( bHead, X_AX(), -X_AX())
-- eseguo
for i = 1, #vCuts do
local vtOrthoO
if i % 2 == 1 then
vtOrthoO = Vector3d( vtRef)
else
if #vCuts[i-1] > 0 then
vtOrthoO = Vector3d( EgtIf( vtRef2, vtRef2, vtRef))
else
local vtO
for j = 1, #vCuts[i-1] do
_, vtO = EgtSurfTmFacetCenter( vCuts[i-1][j], 0, GDB_ID.ROOT)
break
end
if vtO then
vtOrthoO = Vector3d( vtO)
else
vtOrthoO = Y_AX()
end
end
end
local dExtraTrim = 0
-- lavoro la faccia
for j = 1, #vCuts[i] do
-- se ultimo taglio del penultimo gruppo o ultimo taglio dell'ultimo gruppo
-- cioè non i tagli intermedi, aggiungo extratrim minimo
if ( ( i == (#vCuts-1)) or ( i == #vCuts)) and j == #vCuts[i] then
dExtraTrim = dFinalExtraTrim
-- se tagli non a contatto con le facce o tagli paralleli setto nessun extratrim
elseif i < (#vCuts-1) or (i == #vCuts) then
dExtraTrim = dNullExtraTrim
-- altrimenti tagli ortogonali a contatto con la faccia aggiungo extratrim
else
dExtraTrim = dMiddleExtraTrim
end
local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -(dTrim+dExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then
return bOk, sErr
end
end
end
return true
end
---------------------------------------------------------------------
local function CutChainFacesByBlade( Proc, nCFaceSide, nCFaceInt1, nCFaceInt2, sCutting, bHead, vtRef, dTrim, dDepth)
-- inserisco la lavorazione di taglio per la laterale negativa
local sName = 'Cut_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. EgtIf( nCFaceSide > 0, tostring( nCFaceSide) .. '_', '') .. tostring( nCFaceInt1) .. '-' .. tostring( nCFaceInt2)
local nMchFId = EgtAddMachining( sName, sCutting)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting
EgtOutLog( sErr)
return false, sErr
end
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, nCFaceInt1 - 1},{ Proc.Id, nCFaceInt2 - 1}})
-- imposto uso faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT))
local nSCC = EgtIf( vtRef:getY() > 0, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
-- imposto posizione braccio porta testa
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- affondamento aggiuntivo
EgtSetMachiningParam( MCH_MP.OFFSR, -dTrim)
-- offset longitudinale
EgtSetMachiningParam( MCH_MP.OFFSL, 0)
-- imposto inversione e lato correzione
EgtSetMachiningParam( MCH_MP.INVERT, true)
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
-- imposto affondamento
if dDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
else
EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH')
end
-- imposto attacco/uscita
EgtSetMachiningParam( MCH_MP.LITANG, 0)
EgtSetMachiningParam( MCH_MP.LIPERP, 100)
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
EgtSetMachiningParam( MCH_MP.LOPERP, 100)
local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt1 - 1, GDB_ID.ROOT)
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, nCFaceInt2 - 1, GDB_ID.ROOT)
local dNyMax = EgtIf( abs( vtN1:getY()) > abs( vtN2:getY()), vtN1:getY(), vtN2:getY())
local dNzMax = EgtIf( abs( vtN1:getZ()) > abs( vtN2:getZ()), vtN1:getZ(), vtN2:getZ())
if dNzMax < 0 and dNyMax < 0 then
EgtSetMachiningParam( MCH_MP.LITANG, 340)
EgtSetMachiningParam( MCH_MP.LIPERP, -100)
elseif dNzMax < 0 and dNyMax > 0 then
EgtSetMachiningParam( MCH_MP.LOTANG, 340)
EgtSetMachiningParam( MCH_MP.LOPERP, -100)
end
-- imposto allungamenti iniziale e finale
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 50)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 50)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
return true
end
---------------------------------------------------------------------
local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt)
-- dati delle facce
local ptC = {}
local vtN = {}
for i = 1, nFacetCnt do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
-- recupero la geometria ausiliaria
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
if AuxId then AuxId = AuxId + Proc.Id end
-- ordino le facce, se 2 facce: (1=faccia ausiliaria, 2=interna, 3=intermedia)
-- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia)
local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN)
if not bOk1 then return bOk1, sErr1 end
-- determino se di testa o di coda
local bHead
if vtN[vFaceOrd[2]] then
bHead = ( vtN[vFaceOrd[2]]:getX() > 0)
else
if AuxId then
local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT)
bHead = ( vtNx:getX() > 0)
end
end
-- vettore di riferimento per le facce ortogonali all'asse trave
local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ())
vtRef:normalize()
local vtRef2nd
if nFacetCnt > 2 and vFaceOrd[1] ~= 0 then
vtRef2nd = Vector3d( 0, vtN[vFaceOrd[1]]:getY(), vtN[vFaceOrd[1]]:getZ())
vtRef2nd:normalize()
end
-- recupero la lavorazione
local sCutting = ML.FindCutting( 'HeadSide')
if not sCutting then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dSawDiam = 400
local dToolThick = 0
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick
end
end
-- recupero gruppo per geometria addizionale
local nAddGrpId = BL.GetAddGroup( nPartId)
if not nAddGrpId then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup'
EgtOutLog( sErr)
return false, sErr
end
-- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato
local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), 'b')
-- taglio sulla faccia esterna
if AuxId and not bAuxMachined then
-- in generale va fatto
local bCut = true
local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT)
-- se di testa e coincide con inizio grezzo, non va fatto
if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then
bCut = false
end
-- se di coda e coincide con taglio di separazione, non va fatto
if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then
bCut = false
end
-- se va fatto, inserisco la lavorazione
if bCut then
local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail}
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0)
-- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta
if bOk then
bAuxMachined = true
EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true)
else
return bOk, sErr
end
end
end
-- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli
-- se angolo tra le due facce ottuso la distanza può essere messa a 0
local dTrim
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[3] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT)
if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then
dTrim = 0
else
dTrim = ((dToolThick* vtN[vFaceOrd[3]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len()
end
local dFinalExtraTrim = 0.1
local dMiddleExtraTrim = 0.3
local dNullExtraTrim = 0
-- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti
local vCuts = {}
if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then
vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]])
elseif vFaceOrd[3] ~= 0 then
vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true)
end
if #vCuts > 0 then
local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts, nAddGrpId, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim)
if not bOk then return false, sErr end
end
if vFaceOrd[1] ~= 0 then
bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vFaceOrd[1] - 1, vFaceOrd[2] - 1, GDB_ID.ROOT)
if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then
dTrim = 0
else
dTrim = ((dToolThick* vtN[vFaceOrd[1]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len()
end
end
local vCuts2 = {}
if vFaceOrd[2] ~= 0 and vFaceOrd[1] ~= 0 then
vCuts2 = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]])
elseif vFaceOrd[1] ~= 0 then
vCuts2 = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], true)
end
if #vCuts2 > 0 then
local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts2, nAddGrpId, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim)
if not bOk then return false, sErr end
end
-- se una parte non ha fatto tagli
if #vCuts == 0 or #vCuts2 == 0 then
-- taglio sulla faccia esterna
if AuxId and not bAuxMachined then
-- in generale va fatto
local bCut = true
local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT)
-- se di testa e coincide con inizio grezzo, non va fatto
if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then
bCut = false
end
-- se di coda e coincide con taglio di separazione, non va fatto
if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then
bCut = false
end
-- se va fatto, inserisco la lavorazione
if bCut then
local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail}
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0)
-- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta
if bOk then
bAuxMachined = true
EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true)
else
return bOk, sErr
end
end
end
local bIntCut = false
-- se non ha fatto nessun taglio a cubetti e ho 3 facce
-- taglio sulla faccia interna ( concatenando le due facce intermedie e lama che contorna queste)
if #vCuts == 0 and #vCuts2 == 0 and nFacetCnt > 2 then
-- lavoro la faccia interna (di fondo) indirettamente lavorando le due facce intermedie
local bOk, sErr = CutChainFacesByBlade( Proc, 0, vFaceOrd[3], vFaceOrd[1], sCutting, bHead, vtRef, ( dTrim + dFinalExtraTrim))
if not bOk then return false, sErr end
-- taglio sulla faccia intermedia
if vFaceOrd[3] ~= 0 then
-- calcolo secondo testa o coda
local vtRef2 = EgtIf( bHead, X_AX(), -X_AX())
-- inserisco la lavorazione
local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then return bOk, sErr end
end
-- taglio sulla seconda faccia intermedia
if vFaceOrd[1] ~= 0 then
-- calcolo secondo testa o coda
local vtRef2 = EgtIf( bHead, X_AX(), -X_AX())
-- inserisco la lavorazione
local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then return bOk, sErr end
end
else
if vFaceOrd[2] ~= 0 then
-- inserisco la lavorazione
local nDirVect = BL.GetNearestOrthoOpposite( vtRef)
local bOk, sNameOrErr
bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nDirVect, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then return bOk, sNameOrErr end
if #sNameOrErr > 0 then bIntCut = true end
end
-- taglio sulla faccia intermedia
if vFaceOrd[3] ~= 0 then
-- calcolo secondo testa o coda
local vtRef2 = EgtIf( bHead, X_AX(), -X_AX())
-- se non ho il taglio sulla faccia interna
if not bIntCut then
local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[3] - 1)
if DimV > DimH then
vtRef2 = Vector3d( frHV:getVersX())
end
end
-- inserisco la lavorazione
local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then return bOk, sErr end
end
end
end
-- aggiornamento ingombro di testa o coda
if Proc.Head and AuxId then
local dHCI = 00
-- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2
if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then
local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD)
if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end
-- altrimenti di fianco
else
dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()
end
BL.UpdateHCING( nRawId, dHCI)
elseif Proc.Tail and AuxId then
local dTCI = 0
-- se la feature è orientata sopra o sotto, la componente Z (del versore della faccia intermedia) è preponderante sulle altre 2
if ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getX())) and ( abs( vtN[vFaceOrd[3]]:getZ()) > abs( vtN[vFaceOrd[3]]:getY())) then
local b3Fac1 = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD)
if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Solid:getMin():getX() end
-- altrimenti di fianco
else
dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX()
end
BL.UpdateTCING( nRawId, dTCI)
end
return true
end
---------------------------------------------------------------------
local function MakeMillCut( Proc, i, j, k, sMilling,
nFacInd, vFaceOrd, TabNAD, rfFac, dOffs,
dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep,
bPrevByBlade, bUCut, bHead, vtRef)
local sWarn = ''
local bUnderCut = bUCut
-- inserisco la lavorazione di fresatura
-- per evitare nomi lavorazioni coincidenti, concateno anche il Proc.Id se il nome (del Proc.Id) è presente
local s2ndName = EgtGetName( Proc.Id) or ''
local sName = EgtIf( bUnderCut, 'MillTCone_', 'Mill_') .. ( EgtIf( #s2ndName > 0, s2ndName, tostring( Proc.Id))) .. ( EgtIf( #s2ndName > 0, '_' .. tostring( Proc.Id), '')) .. '_' .. tostring(i) .. '_' .. tostring(j)
local kStep = k or 0
if kStep > 0 then
sName = sName .. '_' .. tostring(k)
end
local nMchId = EgtAddMachining( sName, sMilling)
if not nMchId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
EgtOutLog( sErr)
return false, sErr
end
local vtDirRef
-- imposto i parametri lavorazione in base alle facce lavorate
if vFaceOrd and #vFaceOrd > 0 then
-- aggiungo geometria e imposto uso faccia
EgtSetMachiningGeometry( {{ Proc.Id, vFaceOrd[3]-1},{ Proc.Id, vFaceOrd[1]-1}})
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHead, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT))
-- setto vettore direzione per posizione braccio porta testa
vtDirRef = vtRef
-- imposto lato corezione e inversione percorso
if kStep % 2 == 1 then
-- imposto lato sinistro
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
-- imposto inversione
EgtSetMachiningParam( MCH_MP.INVERT, true)
else
-- imposto lato destro
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
-- tolgo inversione
EgtSetMachiningParam( MCH_MP.INVERT, false)
end
-- imposto affondamento
EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH' .. EgtIf( dOffs < 0, '', '-') .. EgtNumToString( dOffs, 4))
else
-- aggiungo geometria e imposto uso faccia
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
local nFaceUse = BL.GetNearestOrthoOpposite( Vector3d( TabNAD[j][1]:getX(), 0, 0))
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- setto vettore direzione per posizione braccio porta testa
vtDirRef = rfFac:getVersZ()
-- imposto lato corezione e inversione percorso
if kStep % 2 == 1 then
-- imposto lato destro
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
-- imposto inversione
EgtSetMachiningParam( MCH_MP.INVERT, true)
else
-- imposto lato sinistro
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
-- tolgo inversione
EgtSetMachiningParam( MCH_MP.INVERT, false)
end
-- imposto affondamento
EgtSetMachiningParam( MCH_MP.DEPTH, dOffs)
end
-- imposto posizione braccio porta testa
local nSCC = EgtIf( vtDirRef:getY() > (100 * GEO.EPS_ZERO), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
--imposto passo 0
EgtSetMachiningParam( MCH_MP.STEP, 0)
-- imposto offset radiale in base all'angolo tra le due facce e alla posizione in Z + il passo laterale
dOffrRad = dOffrRad + dAddOffsRad
-- per le passate intermedie aggiungo un delta sull'offset radiale perchè c'è già il taglio di lama precedente
EgtSetMachiningParam( MCH_MP.OFFSR, dOffrRad + EgtIf( bPrevByBlade and ( i < nStep) and ( kStep < 1), 0.5, 0))
-- imposto offset longotudinale a 0
EgtSetMachiningParam( MCH_MP.OFFSL, 0)
-- imposto gli attacchi
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 0)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, ( dToolDiam * 0.75))
EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( dToolDiam * 0.75))
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill solo in ultima passata in Z locale
local sUserNotes
if i < nStep then
sUserNotes = 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';'
else
sUserNotes = 'VMRS=0;'
sUserNotes = sUserNotes .. 'MaxElev=' .. EgtNumToString( dStep, 1) .. ';'
end
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchId, false)
return false, sErr
else
_, sWarn = EgtGetMachMgrWarning( 0)
if EgtIsMachiningEmpty() then
EgtSetOperationMode( nMchId, false)
end
end
return true, sWarn
end
---------------------------------------------------------------------
local function MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces,
vFaceOrd, bHead, sMillingMaster, dToolDiamMaster, dMaxMatMaster,
dSideAngleMaster, dStepmachMaster, nMainFace, dElevMain)
local sWarn = ''
local sMilling
local dToolDiam = 100
local dMaxMat = 50
local dSideAngle = 0
local dStepmach = 0
local bUCutMax
-- dati della facce
local vtN = {}
local ptC = {}
for i = 1, nFacetCnt do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
-- se non ho passato la lavorazione ( già verificata)
if not sMillingMaster then
-- se il flg del sottosquadra è nil, cerco se tra le facce c'è un angolo sottosquadra
if bUCut == nil then
for i = 1, nFacetCnt do
for j = i+1, nFacetCnt do
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, (i-1), (j-1), GDB_ID.ROOT)
if bAdj and dAng and dAng < -90 - ( 10 * GEO.EPS_SMALL) then
bUCut = true
break
end
end
end
end
-- recupero l'angolo di spoglia dell'utensile a tronco di cono
-- recupero la lavorazione
local sMchFind = 'Long2Cut'
if bUCut then
sMchFind = 'ProfTCone'
end
sMilling = ML.FindMilling( sMchFind)
if not sMilling then
local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id)
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
dToolDiam = 100
dMaxMat = 50
dSideAngle = 0
dStepmach = 0
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle
-- ottengo il passo della lavorazione
dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStepmach
end
end
if dStepmach <= 0.1 then
dStepmach = dMaxMat * 0.5
end
else
sMilling = sMillingMaster
dToolDiam = dToolDiamMaster
dMaxMat = dMaxMatMaster
dSideAngle = dSideAngleMaster
dStepmach = dStepmachMaster
end
local nFacInd, dFacElev
if nMainFace and dElevMain then
nFacInd = nMainFace
dFacElev = dElevMain
else
-- se devo lavorare facce concatenate
if bJoinFaces then
nFacInd = vFaceOrd[2] - 1
-- calcolo l'elevazione
local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]])
if dLenIn > 0 then
dFacElev = dLenIn
elseif dLedOut then
dFacElev = dLedOut
end
else
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, sin(dSideAngle))
if not nFacInd or nFacInd < 0 then
-- provo eliminando i sottosquadra
nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, nPartId, false, -2)
if not nFacInd or nFacInd < 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' MachSideFaces could not find reference face'
EgtOutLog( sErr)
return false, sErr
else
bUCutMax = true
end
end
end
end
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
local TabNAD = {}
local bPrevByBlade = false
-- se non ho la forzatura a usare solo truciolatore e tagli lama consentiti
-- inserisco tagli di lama come antischeggia sulle altre facce
if not bForceUseRough and bUseBlade then
-- recupero la lavorazione
local sCutting = ML.FindCutting( 'HeadSide')
if not sCutting then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dSawDiam = 400
local dToolThick = 0
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick
end
end
-- controllo versore faccia di riferimento, è lungo l'asse trave
local vtRef = Vector3d( vtN[nFacInd+1])
if not AreSameVectorApprox( vtN[nFacInd+1], X_AX()) and not AreSameVectorApprox( vtN[nFacInd+1], -X_AX()) then
-- vettore di riferimento per le facce ortogonali all'asse trave
vtRef = Vector3d( 0, vtN[nFacInd+1]:getY(), vtN[nFacInd+1]:getZ())
end
vtRef:normalize()
-- ciclo inserimento tagli antischeggia sulle facce
for i = 1, nFacetCnt do
if ( i - 1) == nFacInd then
TabNAD[i] = { vtN[i]}
else
local dExtraZed = EgtIf( bForceMakeMill, 1, 0.1)
-- calcolo da distanza di arretramento della lama per non incidere nelle superfici di arrivo dei tagli
-- se angolo tra le due facce ottuso la distanza può essere messa a 0
local dTrim
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT)
if dAng then
TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)}
end
if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then
dTrim = 0
dExtraZed = 0.1
else
dTrim = ((dToolThick* vtN[nFacInd+1]) * vtN[i] * vtN[i]):len()
end
-- inserisco la lavorazione
local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef)
local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + dExtraZed), BD.CUT_SIC, 0, 0, nil, b3Raw)
if not bOk then return bOk, sNameOrErr end
bPrevByBlade = true
end
end
-- altrimenti solo taglio truciolatore
else
for i = 1, nFacetCnt do
if ( i - 1) == nFacInd then
TabNAD[i] = { vtN[i]}
else
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT)
if dAng then
TabNAD[i] = { vtN[i], dAng, dist( ptP1, ptP2)}
end
end
end
end
local vtRef
-- se devo lavorare facce concatenate
if bJoinFaces then
-- vettore di riferimento per le facce ortogonali all'asse trave
vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ())
vtRef:normalize()
end
-- creo percorsi di lavorazione
local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach)
local dStep = dFacElev / nStep
local dLargeVal
local nLenSideMax
-- se non devo fare fresature
if not bForceMakeMill then nStep = 0 end
for i = 1, nStep do
local dOffs = ( i * dStep) - dFacElev
if i == nStep then dOffs = 0 end
local dOffsSide = 0
local dDelta = 100000
local dElevface
for j = 1, nFacetCnt do
if (j-1) ~= nFacInd then
local dParzElev = dOffs
-- calcolo la larghezza (solo 1 volta)
if i == 1 then
-- se ho un sottosquadra maggiore dell'angolo di spoglia utensile
if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then
dParzElev = dFacElev
end
if bJoinFaces then
-- calcolo l'elevazione di ogni singola faccia dal punto medio
local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptC[j], vtN[j])
if dLenIn > 0 then
dElevface = dLenIn
elseif dLedOut then
dElevface = dLedOut
end
if not dLargeVal or dElevface > dLargeVal then
dLargeVal = dElevface
end
else
local dDeltadH = abs( TabNAD[j][3] - dH)
local dDeltadV = abs( TabNAD[j][3] - dV)
if dDeltadH < dDeltadV then
if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then
dDelta = dDeltadH
dLargeVal = dV
nLenSideMax = j
end
else
if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then
dDelta = dDeltadV
dLargeVal = dH
nLenSideMax = j
end
end
end
end
-- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo)
dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev)
end
end
local dRefLarge
-- se ho facce concatenate verifico che la massima larghezza sia comunque superiore al diametro utensile
if bJoinFaces then
dRefLarge = dToolDiam
dLargeVal = EgtIf( dLargeVal > ( dToolDiam + dOffsSide), dLargeVal, dToolDiam + dOffsSide)
else
dRefLarge = EgtIf( nFacetCnt == 2, dToolDiam, ( 2 * dToolDiam))
end
-- se ho 2 facce o la larghezza è più grande dell'utensile allora posso lavorare il passo
if nFacetCnt == 2 or ( dLargeVal - dOffsSide) >= dToolDiam then
-- se ho facce concatenate
if bJoinFaces then
local dOffrRad = 0
-- se larghezza faccia consente passi laterali extra
if ( dLargeVal - dOffsSide) > dRefLarge then
local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5)
local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide
for k = nStepSide, 1, -1 do
local dAddOffsRad = ( k * dStepSide)
-- inserisco la lavorazione di fresatura
local bOk, sErr = MakeMillCut( Proc, i, 1, k, sMilling,
nFacInd, vFaceOrd, TabNAD, rfFac, dOffs,
dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep,
bPrevByBlade, bUCut, bHead, vtRef)
if not bOk then
return false, sErr
end
sWarn = sErr
end
end
-- inserisco la lavorazione di fresatura a contatto con la faccia
local bOk, sErr = MakeMillCut( Proc, i, 1, nil, sMilling,
nFacInd, vFaceOrd, TabNAD, rfFac, dOffs,
dOffrRad, 0, nStep, dToolDiam, dStep,
bPrevByBlade, bUCut, bHead, vtRef)
if not bOk then
return false, sErr
end
sWarn = sErr
else
for j = 1, nFacetCnt do
if (j-1) ~= nFacInd then
-- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia
local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs)
if bUCutMax and ( 90 + TabNAD[j][2]) < dSideAngle then
dOffrRad = -( tan( 90 + TabNAD[j][2]) * dFacElev)
end
-- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra
if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then
local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5)
local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide
for k = nStepSide, 1, -1 do
local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0)
-- inserisco la lavorazione di fresatura
local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling,
nFacInd, nil, TabNAD, rfFac, dOffs,
dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep,
bPrevByBlade, bUCut)
if not bOk then
return false, sErr
end
sWarn = sErr
end
end
-- inserisco la lavorazione di fresatura a contatto con la faccia
local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling,
nFacInd, nil, TabNAD, rfFac, dOffs,
dOffrRad, 0, nStep, dToolDiam, dStep,
bPrevByBlade, bUCut)
if not bOk then
return false, sErr
end
sWarn = sErr
end
end
end
-- altrimenti passo saltato esco con errore
else
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool'
EgtOutLog( sErr)
return false, sErr
end
end
return true, sWarn
end
---------------------------------------------------------------------
local function Mach2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough)
-- verifico le normali delle facce
-- individuo se c'è faccia rastremata verso Z-
local nFlatFaceNeg
local vtN = {}
local ptC = {}
for i = 1, nFacetCnt do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
if vtN[i]:getZ() < -1 + GEO.EPS_SMALL then
nFlatFaceNeg = i-1
end
end
-- se trovata faccia rastremata rivolta verso Z- faccio controllo di lavorabilità da sotto
if nFlatFaceNeg then
-- prendo le dimensioni della faccia
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFlatFaceNeg, GDB_ID.ROOT)
local nOtherFace = EgtIf( nFlatFaceNeg == 0, nFlatFaceNeg + 1, nFlatFaceNeg - 1)
local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFlatFaceNeg, nOtherFace, GDB_ID.ROOT)
local dDist = dist( ptP1, ptP2)
local dLargeface
local dDeltadH = abs( dDist - dH)
local dDeltadV = abs( dDist - dV)
-- prendo la dimensione diversa dalla lunghezza di adiacenza
if dDeltadH < dDeltadV then
dLargeface = dV
else
dLargeface = dH
end
local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUseRough, sMilling = VerifyIfRoughMill( dLargeface, rfFac:getVersZ(), true)
-- se non forzato truciolatore provo la lama
if not bForceUseRough and bUseBlade then
return MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough)
-- altrimenti provo con il truciolatore
else
-- se non ho la lavorazione esco
if not sMilling then
local sErr = 'Error, machining or tool not found ' .. sName .. '-' .. sMilling
EgtOutLog( sErr)
return false, sErr
end
-- inserisco la lavorazione di fresatura
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
local nMchFId = EgtAddMachining( sName, sMilling)
if not nMchFId then
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
EgtOutLog( sErr)
return false, sErr
end
-- Calcolo uso faccia
local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ())
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, nFlatFaceNeg}})
-- imposto uso faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.ADIR_YM
if rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then
nSCC = MCH_SCC.ADIR_YP
end
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- applico allungamento iniziale e finale
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
-- eseguo
if not EgtApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
end
-- altrimenti non ho faccia (antivento) da sotto
else
for i = 1, nFacetCnt do
local nFacet = i-1
-- se versore z è preponderante sulle altre componenti del vettore ed è verso il basso,
if abs(vtN[i]:getZ()) > abs(vtN[i]:getX()) and abs(vtN[i]:getZ()) > abs(vtN[i]:getY()) and vtN[i]:getZ() < -0.5 then
-- lavoro con lama o truciolatore in base al Q
-- prendo le dimensioni della faccia
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacet, GDB_ID.ROOT)
local nOtherFace = EgtIf( nFacet == 0, nFacet + 1, nFacet - 1)
local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT)
local dLargeface = Proc.Box:getDimX()
local bUseBlade = ( dLargeface <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL)
local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL)
local bForceMakeMill = bUCut or bForceUseRough
-- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono
-- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia)
local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil))
-- se devo farlo con fresatura
if bForceMakeMill then
-- se non ho lavorazione (se per esempio l'angolo di spoglia utensile non è uguale a quello tra le due facce) do errore
if not sMilling then
local sErr = 'Error, machining or tool not found ' .. sName
EgtOutLog( sErr)
return false, sErr
end
-- genero lavorazioni
local bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
bUseBlade, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dStepmach, nOtherFace, dLargeface)
if not bOk then return false, sErr end
elseif bUseBlade then
local bOk, sErr = MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough)
-- se fallita di lama e di fresa è fattibile, eseguo con la fresa
if not bOk and sMilling then
-- genero lavorazioni
bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
bUseBlade, true, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dStepmach, nOtherFace, dLargeface)
if not bOk then return false, sErr end
else
return false, sErr
end
end
return true
-- altrimenti non in Z negativa
else
-- se nessuna entità ha z negativa
if i == nFacetCnt then
-- verifico angolo tra le facce
local nOtherFace = nFacet - 1
local bAdj , ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacet, nOtherFace, GDB_ID.ROOT)
local dLargeface = Proc.Box:getDimX()
-- ordino le facce, se 2 facce: (1=faccia ausiliaria, 2=interna, 3=intermedia)
local bOk, sErr, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN)
if not bOk then return bOk, sErr end
local bUCut = ( dAng < 0) and ( dAng < -90 - 5 * GEO.EPS_SMALL)
local bOCut = ( dAng < 0) and ( dAng > -90 + 5 * GEO.EPS_SMALL)
local bForceMakeMill = bUCut or bForceUseRough
-- 2020.04.18 da indicazioni di Fabio Sq. : se angolo interno acuto lo lavoro con utensile a tronco di cono
-- e, se consentito uso lama, preceduto anche due tagli antischeggia (solo in caso di 3 facce, con 2 facce disattivo gli antischeggia)
-- se devo farlo con fresatura
if bForceMakeMill then
local bOk, sErr
bOk = false
-- se angolo ( tra le due facce è) ottuso
if bOCut then
local ptPs = ( ptP1 + ptP2) / 2
-- calcolo l'elevazione di ogni singola faccia dal punto medio della linea di adiacenza
-- prendo l'elevazione sul punto medio della prima faccia
local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[2]])
if dLenIn > 0 then
dLargeface = dLenIn
elseif dLedOut then
dLargeface = dLedOut
end
-- verifico la possibilità di lavorare con utensile
local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, vtN[vFaceOrd[2]], true)
-- se ho trovato lavorazione applicata a faccia definita
if sMilling then
-- genero lavorazioni
bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dStepmach, vFaceOrd[2]-1, dLargeface)
end
-- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima
if not bOk then
-- genero lavorazioni
bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false)
end
if not bOk then return false, sErr end
-- prendo l'elevazione sul punto medio della seconda faccia
dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptPs, vtN[vFaceOrd[3]])
if dLenIn > 0 then
dLargeface = dLenIn
elseif dLedOut then
dLargeface = dLedOut
end
-- verifico la possibilità di lavorare con utensile
bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, vtN[vFaceOrd[3]], true)
-- se ho trovato lavorazione applicata a faccia definita
if sMilling then
-- genero lavorazioni
bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dStepmach, vFaceOrd[3]-1, dLargeface)
end
-- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima
if not bOk then
-- genero lavorazioni
bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false)
end
if not bOk then return false, sErr end
else
-- verifico la possibilità di lavorare con utensile (orizzontale)
local bUseRough, sMilling, dToolDiam, dToolLength, dMaxDepth, dMaxMat, dSideAngle, dStepmach = VerifyIfRoughMill( dLargeface, X_AX(), true, EgtIf( bUCut, ( 90 + dAng), nil))
-- se ho trovato lavorazione applicata a faccia definita
if sMilling then
-- genero lavorazioni
bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dStepmach, vFaceOrd[2]-1, dLargeface)
end
-- se fallito provo sempre con la lavorazione calcolata sull'elevazioe minima
if not bOk then
-- genero lavorazioni
bOk, sErr = MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false)
end
if not bOk then return false, sErr end
end
else
return MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough)
end
end
end
end
end
return true
end
---------------------------------------------------------------------
local function MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, bSkipHead)
-- settaggio flag adatti per il concatenamento delle facce intermedie
local bUseBlade = false
local bForceMakeMill = bForceUseRough
local bUCut = false
local bOCut = false
local bJoinFaces = true
local vFaceOrd
local bHead
-- dati delle facce
local vtN = {}
for i = 1, nFacetCnt do
_, vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
if not bSkipHead then
-- recupero la geometria ausiliaria
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
if AuxId then AuxId = AuxId + Proc.Id end
-- ordino le facce, se 2 facce: (1=faccia ausiliaria, 2=interna, 3=intermedia)
-- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia)
local bOk1, sErr1
bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN)
if not bOk1 then return bOk1, sErr1 end
-- determino se di testa o di coda
if vtN[vFaceOrd[2]] then
bHead = ( vtN[vFaceOrd[2]]:getX() > 0)
else
if AuxId then
local vtNx = EgtSurfTmFacetNormVersor( AuxId, 0, GDB_ID.ROOT)
bHead = ( vtNx:getX() > 0)
end
end
-- recupero la lavorazione per lavorare la geometria ausiliaria
local sCutting = ML.FindCutting( 'HeadSide')
if not sCutting then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dSawDiam = 400
local dToolThick = 0
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick
end
end
-- recupero gruppo per geometria addizionale
local nAddGrpId = BL.GetAddGroup( nPartId)
if not nAddGrpId then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup'
EgtOutLog( sErr)
return false, sErr
end
-- cerco se nelle note del layer c'è già la nota che indica che l'aux è già stato lavorato
local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring( AuxId or 0), 'b')
-- taglio sulla faccia esterna
if AuxId and not bAuxMachined then
-- in generale va fatto
local bCut = true
local ptCAux, vtNAux = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT)
-- se di testa e coincide con inizio grezzo, non va fatto
if bHead and AreSameVectorApprox( vtNAux, X_AX()) and abs( ptCAux:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then
bCut = false
end
-- se di coda e coincide con taglio di separazione, non va fatto
if not bHead and AreSameVectorApprox( vtNAux, - X_AX()) and abs( ptCAux:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then
bCut = false
end
-- se va fatto, inserisco la lavorazione
if bCut then
local CutProc = { Id = AuxId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg, Head = Proc.Head, Tail = Proc.Tail}
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0)
-- se taglio applicato setto la nota al gruppo Mach per non doverla lavorare una seconda volta
if bOk then
bAuxMachined = true
EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true)
else
return bOk, sErr
end
end
end
-- altrimenti non sono di testa
else
-- abilito la lama per i tagli antischeggia
bUseBlade = true
-- abilito la fresatura
bForceMakeMill = true
-- disabilito il concatenamento delle facce intermedie
bJoinFaces = false
-- annullo il flag del sottosquadra per forzare la ricerca all'interno della funzione
bUCut = nil
end
-- lavoro le restanti facce
return MachSideFaces( Proc, nPartId, b3Raw, nFacetCnt, bForceUseRough,
bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces,
vFaceOrd, bHead)
end
---------------------------------------------------------------------
local function MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, nSidePosFct, nMiddleFct, nSideNegFct, vtRef, nFacetCnt)
local sWarn = ''
-- recupero la lavorazione
local sMchFind = 'Long2Cut'
local sMilling = ML.FindMilling( sMchFind)
if not sMilling then
local sErr = 'Milling not found in library : Error on Dovetail ' .. tostring( Proc.Id)
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dToolDiam = 100
local dMaxMat = 50
local dSideAngle = 0
local dStepmach = 0
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle
-- ottengo il passo della lavorazione
dStepmach = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dStepmach
end
end
if dStepmach <= 0.1 then
dStepmach = dMaxMat * 0.5
end
local nFacInd = nMiddleFct - 1
local dFacElev
-- calcolo elevazione
local dLenIn, dLedOut = BL.GetPointDirDepth( nPartId, ptC[nMiddleFct], vtN[nMiddleFct])
if dLenIn > 0 then
dFacElev = dLenIn
elseif dLedOut then
dFacElev = dLedOut
end
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
local TabNAD = {}
TabNAD[nMiddleFct] = { vtN[nMiddleFct]}
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (nSideNegFct-1), GDB_ID.ROOT)
if dAng then
TabNAD[nSideNegFct] = { vtN[nSideNegFct], dAng, dist( ptP1, ptP2)}
end
bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (nSidePosFct-1), GDB_ID.ROOT)
if dAng then
TabNAD[nSidePosFct] = { vtN[nSidePosFct], dAng, dist( ptP1, ptP2)}
end
-- creo percorsi di lavorazione
local nStep = ceil( ( dFacElev - 10 * GEO.EPS_SMALL) / dStepmach)
local dStep = dFacElev / nStep
local dLargeVal
local nLenSideMax
for i = 1, nStep do
local dOffs = ( i * dStep) - dFacElev
if i == nStep then dOffs = 0 end
local dOffsSide = 0
local dDelta = 100000
local dElevface
for j = 1, nFacetCnt do
if j == nSideNegFct or j == nSidePosFct then
local dParzElev = dOffs
-- calcolo la larghezza (solo 1 volta)
if i == 1 then
local dDeltadH = abs( TabNAD[j][3] - dH)
local dDeltadV = abs( TabNAD[j][3] - dV)
if dDeltadH < dDeltadV then
if dDeltadH < dDelta - 10 * GEO.EPS_SMALL then
dDelta = dDeltadH
dLargeVal = dV
nLenSideMax = j
end
else
if dDeltadV < dDelta - 10 * GEO.EPS_SMALL then
dDelta = dDeltadV
dLargeVal = dH
nLenSideMax = j
end
end
end
-- valori negativi di offset corrispondono ad un allargamento (perchè dParzElev è negativo)
dOffsSide = dOffsSide + ( tan( 90 + TabNAD[j][2]) * dParzElev)
end
end
local dRefLarge = ( 2 * dToolDiam)
-- se la larghezza è più grande dell'utensile allora posso lavorare il passo
if ( dLargeVal - dOffsSide) >= dToolDiam then
for j = 1, nFacetCnt do
if j == nSideNegFct or j == nSidePosFct then
-- calcolo l'offset radiale in base all'affondamento e all'angolo spoglia
local dOffrRad = ( tan( 90 + TabNAD[j][2]) * dOffs)
-- se lato lavorato è il più lungo e la larghezza cava consente passi laterali extra
if j == nLenSideMax and ( dLargeVal - dOffsSide) > dRefLarge then
local nStepSide = ceil( ( ( dLargeVal - dOffsSide - dRefLarge) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5)
local dStepSide = ( dLargeVal - dOffsSide - dRefLarge) / nStepSide
for k = nStepSide, 1, -1 do
local dAddOffsRad = ( k * dStepSide) + EgtIf( k == nStepSide, ( dToolDiam * 0.1), 0)
-- inserisco la lavorazione di fresatura
local bOk, sErr = MakeMillCut( Proc, i, j, k, sMilling,
nFacInd, nil, TabNAD, rfFac, dOffs,
dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep,
true, false)
if not bOk then
return false, sErr
end
sWarn = sErr
end
end
-- inserisco la lavorazione di fresatura a contatto con la faccia
local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling,
nFacInd, nil, TabNAD, rfFac, dOffs,
dOffrRad, 0, nStep, dToolDiam, dStep,
true, false)
if not bOk then
return false, sErr
end
sWarn = sErr
end
end
-- altrimenti passo saltato esco con errore
else
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool'
EgtOutLog( sErr)
return false, sErr
end
end
return true, sWarn
end
---------------------------------------------------------------------
local function MakeMoreFces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, bUseBlade)
local ptC = {}
local vtN = {}
-- dati delle facce e ordinamento facce { }
for i = 1, nFacetCnt do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
-- ordino le 4 facce: ( 1=laterale positiva 2=altra intermedia, 3=intermedia, 4=laterale negativa)
local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, nFacetCnt, vtN)
if not bOk1 then return bOk1 end
-- vettori di riferimento per le facce ortogonali all'asse trave
local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ())
vtRef:normalize()
local vtRef2nd = Vector3d( 0, vtN[vFaceOrd[2]]:getY(), vtN[vFaceOrd[2]]:getZ())
vtRef2nd:normalize()
-- se non forzato uso truciolatore e abilitato il taglio di lama faccio le due pareti con antischeggia
-- lavoro le facce laterali indirettamente lavorando le due facce intermedie
if not bForceUseRough and bUseBlade then
-- recupero la lavorazione con lama
local sCutting = ML.FindCutting( 'HeadSide')
if not sCutting then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library'
EgtOutLog( sErr)
return false, sErr
end
-- recupero i dati dell'utensile
local dSawDiam = 400
local dToolThick = 0
if EgtMdbSetCurrMachining( sCutting) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam
dToolThick = EgtTdbGetCurrToolParam(MCH_TP.THICK) or dToolThick
end
end
local dTrim = -0.3
-- se ho la faccia laterale negativa
if vFaceOrd[4] ~= 0 then
-- inserisco la lavorazione di taglio per la faccia laterale negativa, faccio in modo che la testa rimanga nella stessa posizione per entrambe i tagli
local bOk, sErr = CutChainFacesByBlade( Proc, vFaceOrd[4], vFaceOrd[3], vFaceOrd[2], sCutting, true, vtRef, dTrim, dToolThick)
if not bOk then return false, sErr end
end
-- se ho la faccia laterale positiva
if vFaceOrd[1] ~= 0 then
-- inserisco la lavorazione di taglio per la faccia laterale positiva
local bOk, sErr = CutChainFacesByBlade( Proc, vFaceOrd[1], vFaceOrd[3], vFaceOrd[2], sCutting, true, vtRef, dTrim)
if not bOk then return false, sErr end
end
end
-- lavoro le facce intermedie
if vFaceOrd[3] ~= 0 then
-- inserisco la lavorazione di fresatura per la faccia intermedia
local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[1], vFaceOrd[3], vFaceOrd[4], vtRef, nFacetCnt)
if not bOk then return false, sErr end
end
if vFaceOrd[2] ~= 0 then
-- inserisco la lavorazione di fresatura per la faccia intermedia
local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[1], vFaceOrd[2], vFaceOrd[4], vtRef, nFacetCnt)
if not bOk then return false, sErr end
end
return true
end
---------------------------------------------------------------------
local function Mach_3_MoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRoughm, bSkipHead)
-- se non sono in testa o coda
if bSkipHead then
local bUseBlade = true
return MakeMoreFces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, bUseBlade)
else
if bForceUseRough then
return MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough)
else
return MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt)
end
end
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
function ProcessDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
-- recupero l'ingombro del grezzo di appartenenza
local b3Raw = EgtGetRawPartBBox( nRawId)
-- in base al tipo di feature attribuisco il significato dei parametri Q
AssignQValues( Proc)
-- verifico se sono presenti i parametri Q per l'uso forzato del truciolatore
local _, bForceUseRough = EvaluateQParam( Proc, sUseRoughTool)
-- ingombro del pezzo
local Ls = EgtGetFirstNameInGroup( nPartId, 'Box')
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
if not b3Solid then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found'
EgtOutLog( sErr)
return false, sErr
end
-- verifico che ci siano almeno due facce (altrimenti non è da lavorare)
local nFacetCnt = EgtSurfTmFacetCount( Proc.Id)
if nFacetCnt < 2 then
local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough'
EgtOutLog( sErr)
return false, sErr
end
-- se ho due facce ( allora è di testa)
if nFacetCnt == 2 then
return Mach2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough)
-- altrimenti se ha 3 facce ma è di testa
elseif nFacetCnt == 3 and ( Proc.Head or Proc.Tail) then
return Mach_3_MoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough)
elseif nFacetCnt == 3 then
return MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, true)
else
return Mach_3_MoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, bForceUseRough, true)
end
return true
end
---------------------------------------------------------------------
return ProcessDovetail