Files
DataBeam/LuaLibs/ProcessDovetail.lua
2024-11-15 15:45:40 +01:00

1785 lines
80 KiB
Lua

-- ProcessDovetail.lua by Egaltech s.r.l. 2021/02/04
-- Gestione calcolo giunzione coda di rondine
-- 2022/06/10 Aggiunto il parametro dOvmTail per gestire sovramateriali in coda diversi da OVM_MID (sezioni alte e larghe)
-- 2023/09/26 Modificata chiamata a GetFaceWithMostAdj.
-- Tabella per definizione modulo
local ProcessDovetail = {}
-- Include
require( 'EgtBase')
local BL = require( 'BeamLib')
local Fbs = require( 'FacesBySaw')
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 sUseRoughTool = '' -- 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
sUseRoughTool = ''
if Proc.Prc == 138 then
sUseRoughTool = 'Q02' -- d
end
end
---------------------------------------------------------------------
local function EvaluateQParam( Proc, sUseRoughTool)
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 bForceUseRough
end
---------------------------------------------------------------------
local function OrderFaces( Proc, vtN)
local dMinXFace = 0.99
local dPosXFace = 0
local dNegXFace = 0
local vFaceOrd = { 0, 0, 0}
-- se 2 facce : ordine (1=0, 2=interna, 3=intermedia)
if #vtN <= 2 then
for i = 1, #vtN do
local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX()))
if dXVal < dMinXFace then
dMinXFace = dXVal
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, #vtN 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
-- se 3 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia)
elseif #vtN == 3 then
for i = 1, #vtN do
local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX()))
if dXVal < dMinXFace then
dMinXFace = dXVal
vFaceOrd[3] = i
end
if dXVal > dPosXFace then
dPosXFace = dXVal
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, #vtN 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
-- se 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna)
else
for i = 1, #vtN do
if vtN[i]:getX() > dPosXFace then
dPosXFace = vtN[i]:getX()
vFaceOrd[2] = i
end
if vtN[i]:getX() < dNegXFace then
dNegXFace = vtN[i]:getX()
vFaceOrd[4] = i
end
end
if vFaceOrd[2] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing internal face'
EgtOutLog( sErr)
return false, sErr
end
if vFaceOrd[4] == 0 then
local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing external face'
EgtOutLog( sErr)
return false, sErr
end
local nMidFace = 3
for i = 1, #vtN do
if i ~= vFaceOrd[2] and i ~= vFaceOrd[4] then
vFaceOrd[nMidFace] = i
nMidFace = 1
end
end
if vFaceOrd[1] == 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[1] - 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 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 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 dMachStep = 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
dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep
end
end
if dMachStep <= 0.1 then
dMachStep = 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, dMachStep
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, dMachStep
end
end
end
return false
end
---------------------------------------------------------------------
local function AddFaceToSurf( Proc, nPartId, b3Solid)
-- recupero gruppo per geometria addizionale
local nAddGrpId = BL.GetAddGroup( nPartId)
if not nAddGrpId then
local sErr = 'Error : missing AddGroup'
EgtOutLog( sErr)
return false, sErr
end
local nNewProc = EgtCopyGlob( Proc.Id, nAddGrpId) or GDB_ID.NULL
-- punto medio sulla faccia
local ptN = Point3d( b3Solid:getMin():getX(), ( b3Solid:getMin():getY() + b3Solid:getMax():getY())/2, ( b3Solid:getMin():getZ() + b3Solid:getMax():getZ())/2)
-- creo superficie intermedia
local nSurfInt = EgtSurfTmPlaneInBBox( nAddGrpId, ptN, -X_AX(), b3Solid, GDB_ID.ROOT)
-- se esiste la superfice aggiunta, la ritaglio la superficie con le facce
if nSurfInt then
-- inverto la normale
EgtInvertSurf( nSurfInt)
for i = 1, Proc.Fct do
local ptN, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT)
EgtCutSurfTmPlane( nSurfInt, ptN, -vtN, false, GDB_ID.ROOT)
end
-- unisco la nuova superfice
if nSurfInt then
local bOk = EgtSurfTmAdd( nNewProc, nSurfInt)
if bOk then
EgtErase( nSurfInt)
Proc.Id = nNewProc
Proc.Fct = EgtSurfTmFacetCount( nNewProc)
end
end
end
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, 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)
-- recupero identificativo del pezzo
local nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
-- se una sola faccia
if Proc.Fct == 1 then
local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
if vtN0:getX() < -0.1 then
-- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione
if b3Solid:getDimX() > BD.LEN_SHORT_PART then
return true
else
-- aggiungo faccia
AddFaceToSurf( Proc, nPartId, b3Solid)
return false
end
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
-- se due facce e interessa veramente la coda, allora di coda
if Proc.Fct <= 2 then
if Proc.Box:getMin():getX() < b3Solid:getMin():getX() + 1. then
-- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione
if b3Solid:getDimX() > BD.LEN_SHORT_PART then
return true
else
-- aggiungo faccia
AddFaceToSurf( Proc, nPartId, b3Solid)
return false
end
end
end
-- deve avere la normale principale diretta verso la coda
local nFacInd, dElev, nFacInd2, dElev2 = BL.GetFaceWithMostAdj( Proc, 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
-- controllo se il pezzo + piccolo e serve la lavorazione prima del taglio di separazione
if b3Solid:getDimX() > BD.LEN_SHORT_PART then
return true
else
-- aggiungo faccia
AddFaceToSurf( Proc, nPartId, b3Solid)
return false
end
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 nFlatFaceNeg
local bDown = false
-- individuo se c'è faccia rivolta verso Z-
for i = 1, Proc.Fct do
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
if vtN:getZ() < -0.99 then
nFlatFaceNeg = i - 1
break
end
end
-- se trovata faccia rivolta verso Z-
if nFlatFaceNeg then
-- se 3 o più facce sicuramente è in mezzo, setto il ribaltamento senza ulteriori controlli
if Proc.Fct >= 3 then
bDown = true
-- altrimenti è in testa o coda e verifico se lavorabile da sotto
else
-- prendo le dimensioni della faccia
local nOtherFace = 1 - nFlatFaceNeg
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
if dAng > -89.99 and dAng < 0 then
bDown = true
-- altrimenti, verifico se lunghezza faccia piatta è compatibile con il taglio di lama
else
local dLargeFace = Proc.Box:getDimX()
local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUseRough = VerifyIfRoughMill( dLargeFace, -Z_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
-- altrimenti controllo la componente in Z delle facce
else
local vtN = {}
for i = 1, Proc.Fct do
vtN[i] = EgtSurfTmFacetNormVersor( Proc.Id, i - 1, GDB_ID.ROOT)
end
for i = 1, Proc.Fct 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 Proc.Fct == 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 Proc.Fct == 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, 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, 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
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
vtOrthoO = Vector3d( vtRef2)
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 = Fbs.MakeOne( vCuts[i][j], 0, sCutting, dSawDiam, vtOrthoO, nil, -( dTrim + dExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
if not bOk then
return bOk, sErr
end
end
end
return true
end
---------------------------------------------------------------------
local function MachChainFacesByBlade( 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, 180)
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
EgtSetMachiningParam( MCH_MP.LOPERP, 180)
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 bHead == ( dNyMax < 0) then
EgtSetMachiningParam( MCH_MP.LITANG, 340)
EgtSetMachiningParam( MCH_MP.LIPERP, -100)
elseif dNzMax < 0 and bHead == ( 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 ML.ApplyMachining( true, false) then
local _, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nMchFId, false)
return false, sErr
end
return true
end
---------------------------------------------------------------------
local function MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid)
-- dati delle facce
local ptC = {}
local vtN = {}
for i = 1, Proc.Fct do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN)
if not bOk1 then return bOk1, sErr1 end
---- determino se di testa o di coda
local bHead = ( vtN[vFaceOrd[2]]:getX() > 0)
-- 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 Proc.Fct > 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
-- calcolo la 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 > -89.9 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
-- recupero gruppo per geometria addizionale
local nAddGrpId = BL.GetAddGroup( nPartId)
if not nAddGrpId then
local sErr = 'Error : missing AddGroup'
EgtOutLog( sErr)
return false, sErr
end
-- se 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( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]])
elseif vFaceOrd[3] ~= 0 then
vCuts = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], true)
end
if #vCuts > 0 then
local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts, 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 > -89.9 then
dTrim = 0
else
dTrim = ((dToolThick* vtN[vFaceOrd[1]]) * vtN[vFaceOrd[2]] * vtN[vFaceOrd[2]]):len()
end
end
-- se esistono faccia interna ed altra intermedia, verifico se richiedono taglio a cubetti
local vCuts2 = {}
if vFaceOrd[2] ~= 0 and vFaceOrd[1] ~= 0 then
vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]])
elseif vFaceOrd[1] ~= 0 then
vCuts2 = DC.GetDice( nAddGrpId, b3Solid, ptC[vFaceOrd[1]], vtN[vFaceOrd[1]], true)
end
if #vCuts2 > 0 then
local bOk, sErr = MakeCutsByDice( Proc, b3Raw, vCuts2, bHead, vtRef, dFinalExtraTrim, dNullExtraTrim, dMiddleExtraTrim, sCutting, dSawDiam, dTrim)
if not bOk then return false, sErr end
end
-- se non ha fatto nessun taglio a cubetti e ho 3 facce
if #vCuts == 0 and #vCuts2 == 0 and Proc.Fct > 2 then
-- lavoro la faccia interna (di fondo) indirettamente lavorando le due facce intermedie
local bOk, sErr = MachChainFacesByBlade( 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 = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 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 = Fbs.MakeOne( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
if not bOk then return bOk, sErr end
end
-- se altrimenti non ha fatto una parte dei tagli a cubetti
elseif #vCuts == 0 and #vCuts2 == 0 then
local bIntCut = false
if vFaceOrd[2] ~= 0 then
-- inserisco la lavorazione
local nDirVect = BL.GetNearestOrthoOpposite( vtRef)
local bOk, sNameOrErr
bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nDirVect, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 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 = Fbs.MakeOne( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, vtRef2, nil, -(dTrim + dFinalExtraTrim), BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
if not bOk then return bOk, sErr end
end
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( TabNAD[j][1])
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, ( 60 + 0.5 * dToolDiam))
EgtSetMachiningParam( MCH_MP.ENDADDLEN, ( 60 + 0.5 * dToolDiam))
-- 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 ML.ApplyMachining( 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, dMachStepMaster, nMainFace, dElevMain)
local sWarn = ''
local sMilling
local dToolDiam = 100
local dSideAngle = 0
local dMaxMat = 50
local dMaxDepth = 50
local dMachStep = 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 flag 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.1 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
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam
dSideAngle = EgtTdbGetCurrToolParam( MCH_TP.SIDEANG) or dSideAngle
dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT) or dMaxMat
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep
end
end
if dMachStep <= 0.1 then
dMachStep = dMaxMat * 0.5
end
else
sMilling = sMillingMaster
dToolDiam = dToolDiamMaster
dMaxMat = dMaxMatMaster
dSideAngle = dSideAngleMaster
dMachStep = dMachStepMaster
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, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]])
if dLenIn > 0 then
dFacElev = dLenIn
elseif dLenOut then
dFacElev = dLenOut
end
else
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc, nPartId, false, sin(dSideAngle))
if not nFacInd or nFacInd < 0 then
-- provo eliminando i sottosquadra
nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc, 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 = Fbs.MakeOne( Proc.Id, ( i - 1), sCutting, dSawDiam, nOrthoOpposite, nil, -( dTrim + dExtraZed), BD.CUT_SIC, 0, 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) / dMachStep)
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, dLenOut = BL.GetPointDirDepth( nPartId, ptC[j], vtN[j])
if dLenIn > 0 then
dElevface = dLenIn
elseif dLenOut then
dElevface = dLenOut
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 Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough)
-- verifico le normali delle facce
-- individuo se c'è faccia rivolta verso Z-
local nFlatFaceNeg
local vtN = {}
local ptC = {}
for i = 1, Proc.Fct do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT)
if vtN[i]:getZ() < -0.99 then
nFlatFaceNeg = i - 1
end
end
-- se trovata faccia rivolta verso Z- faccio controllo di lavorabilità da sotto
if nFlatFaceNeg then
-- prendo le dimensioni della faccia
local dLargeFace = Proc.Box:getDimX()
local bUseBlade = ( dLargeFace <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
local bUseRough, sMilling = VerifyIfRoughMill( dLargeFace, -Z_AX(), true)
-- se non forzato truciolatore provo la lama
if not bForceUseRough and bUseBlade then
return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid)
-- altrimenti provo con il truciolatore
else
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
-- se non ho la lavorazione esco
if not sMilling then
local sErr = 'Error, machining or tool not found ' .. sName
EgtOutLog( sErr)
return false, sErr
end
-- inserisco la lavorazione di fresatura
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 nOtherInd = 2 - nFlatFaceNeg
local nFaceUse = BL.GetNearestParalOpposite( vtN[nOtherInd])
-- aggiungo geometria
EgtSetMachiningGeometry( {{ Proc.Id, nFlatFaceNeg}})
-- imposto uso faccia
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
-- imposto inversione e lato correzione
EgtSetMachiningParam( MCH_MP.INVERT, true)
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
-- annullo offset radiale
EgtSetMachiningParam( MCH_MP.OFFSR, 0)
-- applico allungamento iniziale e finale
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
-- imposto posizione braccio porta testa
local nSCC = MCH_SCC.ADIR_YP
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
-- eseguo
if not ML.ApplyMachining( 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, Proc.Fct 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 = 1 - nFacet
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, dMachStep = 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, Proc.Fct, bForceUseRough,
bUseBlade, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dMachStep, nOtherFace, dLargeFace)
if not bOk then return false, sErr end
elseif bUseBlade then
local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid)
-- 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, Proc.Fct, bForceUseRough,
bUseBlade, true, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dMachStep, 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 == Proc.Fct 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=0, 2=interna, 3=intermedia)
local bOk, sErr, vFaceOrd = OrderFaces( Proc, 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)
-- 2021.02.04 FS ha chiesto di fare con lama anche i concavi (vecchio controllo : bUCut or bForceUseRough)
local bForceMakeMill = bForceUseRough
-- 2020.04.28 FS 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, dMachStep = 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, Proc.Fct, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dMachStep, 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, Proc.Fct, 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, dMachStep = 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, Proc.Fct, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dMachStep, 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, Proc.Fct, 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, dMachStep = 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, Proc.Fct, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false,
nil, nil, sMilling, dToolDiam, dMaxMat,
dSideAngle, dMachStep, 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, Proc.Fct, bForceUseRough,
true, bForceMakeMill, bUCut, bOCut, false)
end
if not bOk then return false, sErr end
end
else
return MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid)
end
end
end
end
end
return true
end
---------------------------------------------------------------------
local function MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, dOvmTail)
-- recupero la geometria ausiliaria
local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i')
if not AuxId then return true end
AuxId = AuxId + Proc.Id
-- recupero il centro e la normale della faccia ausiliaria
local ptC, vtN = EgtSurfTmFacetCenter( AuxId, 0, GDB_ID.ROOT)
if not vtN then
local sErr = 'Error : wrong Normal of AuxSurface'
EgtOutLog( sErr)
return false, sErr
end
-- verifico se di testa o coda
local bHead = ( vtN:getX() > 0)
-- recupero la lavorazione per la geometria ausiliaria
local sCutting = ML.FindCutting( 'HeadSide')
if not sCutting then
local sErr = 'Error : 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 : missing AddGroup'
EgtOutLog( sErr)
return false, sErr
end
-- verifico se già fatto con altro componente della stessa feature
local bAuxMachined = EgtGetInfo( nAddGrpId, 'AuxId.'..tostring( AuxId), 'b')
if bAuxMachined then return true end
-- verifico se coincide con taglio di testa
if bHead and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then
return true
end
-- verifico se coincide con taglio di coda
if not bHead and AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < dOvmTail + 10 * GEO.EPS_SMALL then
return true
end
-- inserisco la lavorazione
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, PartId = Proc.PartId}
CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc)
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead)
if not bOk then return bOk, sErr end
-- imposto la nota nel gruppo aggiuntivo di lavorazione per evitare di tagliare una seconda volta
EgtSetInfo( nAddGrpId, 'AuxId.'..tostring(AuxId or 0), true)
return true
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 dMachStep = 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
dMachStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMachStep
end
end
if dMachStep <= 0.1 then
dMachStep = dMaxMat * 0.5
end
local nFacInd = nMiddleFct - 1
local dFacElev
-- calcolo elevazione
local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[nMiddleFct], vtN[nMiddleFct])
if dLenIn > 0 then
dFacElev = dLenIn
elseif dLenOut then
dFacElev = dLenOut
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 or 0) - 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) / dMachStep)
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 = EgtIf( nSideNegFct, ( 2 * dToolDiam), 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 * EgtIf( nSideNegFct, 0.5, 1))
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 MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade)
local ptC = {}
local vtN = {}
-- dati delle facce e ordinamento facce { }
for i = 1, Proc.Fct do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
-- ordino le 4 facce : ordine (1=altra intermedia, 2=interna, 3=intermedia, 4=esterna)
local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN)
if not bOk1 then return bOk1, sErr1 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[1]]:getY(), vtN[vFaceOrd[1]]: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 = MachChainFacesByBlade( Proc, vFaceOrd[4], vFaceOrd[3], vFaceOrd[1], sCutting, true, vtRef, dTrim, dToolThick)
if not bOk then return false, sErr end
end
-- se ho la faccia laterale positiva
if vFaceOrd[2] ~= 0 then
-- inserisco la lavorazione di taglio per la faccia laterale positiva
local bOk, sErr = MachChainFacesByBlade( Proc, vFaceOrd[2], vFaceOrd[3], vFaceOrd[1], 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[2], vFaceOrd[3], vFaceOrd[4], vtRef, Proc.Fct)
if not bOk then return false, sErr end
end
if vFaceOrd[1] ~= 0 then
-- inserisco la lavorazione di fresatura per la faccia intermedia
local bOk, sErr = MachUFaces( Proc, nPartId, b3Raw, vtN, ptC, vFaceOrd[2], vFaceOrd[1], vFaceOrd[4], vtRef, Proc.Fct)
if not bOk then return false, sErr end
end
return true
end
---------------------------------------------------------------------
local function MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bInMiddle)
-- flag per lavorazioni sulla testa o coda
local bUseBlade = false
local bForceMakeMill = bForceUseRough
local bUCut = false
local bOCut = false
local bJoinFaces = true
-- modifiche ai flag per lavorazione in mezzo
if bInMiddle then
-- 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
-- dati delle facce
local ptC = {}
local vtN = {}
for i = 1, Proc.Fct do
ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT)
end
-- ordino le facce, se 3 facce: (1=altra intermedia, 2=interna, 3=intermedia)
local bOk1, sErr1, vFaceOrd = OrderFaces( Proc, vtN)
if not bOk1 then return bOk1, sErr1 end
-- verifica se di testa o coda
local bHead = false
if not bInMiddle then
bHead = ( vtN[vFaceOrd[2]]:getX() > 0)
end
-- se non in mezzo può essere necessario lavorare come in mezzo
if not bInMiddle then
-- calcolo l'elevazione
local dSideElev = 0
local dLenIn, dLenOut = BL.GetPointDirDepth( nPartId, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]])
if dLenIn > 0 then
dSideElev = dLenIn
elseif dLenOut then
dSideElev = dLenOut
end
-- determino il massimo affondamento con l'utensile
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 dMaxDepth = 10
if EgtMdbSetCurrMachining( sMilling) then
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then
dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth
end
end
-- se l'elevazione supera l'affondamento, lavoro perpendicolare all'asse trave
if dSideElev > dMaxDepth then
return MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, bUseBlade)
end
end
-- lavoro le restanti facce in modo standard
return MachSideFaces( Proc, nPartId, b3Raw, Proc.Fct, bForceUseRough,
bUseBlade, bForceMakeMill, bUCut, bOCut, bJoinFaces,
vFaceOrd, bHead)
end
---------------------------------------------------------------------
-- Applicazione della lavorazione
function ProcessDovetail.Make( Proc, nPhase, nRawId, nPartId, dOvmHead, dOvmTail)
-- sovramateriale di coda
dOvmTail = dOvmTail or BD.OVM_MID
-- 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)
if Proc.Fct < 2 then
local sErr = 'Not executed ' .. tostring( Proc.Id) .. ' number of faces not enough'
EgtOutLog( sErr)
return false, sErr
end
-- se ha due facce ( allora è di testa o coda)
if Proc.Fct == 2 then
-- eventuale taglio di testa o coda
local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, dOvmTail)
if not bAuxOk then return bAuxOk, sAuxErr end
-- lavorazione della feature
local bOk, sErr = Make2Faces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough)
if not bOk then return bOk, sErr end
-- se ha 3 facce ed è di testa o coda
elseif Proc.Fct == 3 and ( Proc.Head or Proc.Tail) then
-- eventuale taglio di testa o coda
local bAuxOk, sAuxErr = MakeAuxCut( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, dOvmTail)
if not bAuxOk then return bAuxOk, sAuxErr end
-- lavorazione della feature
if bForceUseRough then
local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough)
if not bOk then return bOk, sErr end
else
local bOk, sErr = MakeByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid)
if not bOk then return bOk, sErr end
end
-- se ha 3 facce (e interna)
elseif Proc.Fct == 3 then
local bOk, sErr = MakeByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true)
if not bOk then return bOk, sErr end
-- altrimenti 4 facce (e interna)
else
local bOk, sErr = MakeMoreFaces( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, bForceUseRough, true)
if not bOk then return bOk, sErr end
end
-- aggiornamento ingombro di testa o coda
if Proc.Head then
local dHCI = b3Solid:getMax():getX() - Proc.Box:getMin():getX()
BL.UpdateHCING( nRawId, dHCI)
elseif Proc.Tail then
local dTCI = Proc.Box:getMax():getX() - b3Solid:getMin():getX()
BL.UpdateTCING( nRawId, dTCI)
end
return true
end
---------------------------------------------------------------------
return ProcessDovetail