49f5ba9cc9
- aggiunta gestione UNLOAD da btm (come per LOAD90) - ora UserNotes presenti nelle levarazioni in libreria vengono conservate.
723 lines
31 KiB
Lua
723 lines
31 KiB
Lua
-- ProcessTyroleanDovetail.lua by Egaltech s.r.l. 2022/03/21
|
|
-- Gestione calcolo giunzione tirolese
|
|
-- 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 ProcessTyroleanDovetail = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
local Fbs = require( 'FacesBySaw')
|
|
local DC = require( 'DiceCut')
|
|
local Cut = require( 'ProcessCut')
|
|
|
|
EgtOutLog( ' ProcessTyroleanDovetail started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
-- variabili assegnazione parametri Q
|
|
local sDepthChamferMill = '' -- d
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function ProcessTyroleanDovetail.Identify( Proc)
|
|
return (( Proc.Grp == 1 or Proc.Grp == 2 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 136)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AssignQValues( Proc)
|
|
|
|
-- reset delle variabili assegnazione parametri Q
|
|
sDepthChamferMill = ''
|
|
|
|
if Proc.Prc == 136 then
|
|
sDepthChamferMill = 'Q01' -- d
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestElleShape3( Proc)
|
|
-- valida solo nel caso di tre facce
|
|
if Proc.Fct ~= 3 then return false end
|
|
-- determino se L con una faccia terminale o U con tre facce
|
|
local bIsL = true
|
|
for i = 1, 3 do
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( Proc.Id, i - 1)[1]
|
|
-- le conto
|
|
local nCount = 0
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
nCount = nCount + 1
|
|
end
|
|
end
|
|
if nCount == 1 then
|
|
bIsL = false
|
|
break
|
|
end
|
|
end
|
|
return bIsL
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessTyroleanDovetail.Classify( Proc, b3Raw)
|
|
-- 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 ho 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)
|
|
local dDist = dist( ptP1, ptP2)
|
|
local dLargeface
|
|
local dDelta = 100000
|
|
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 lunghezza faccia maggiore di taglio lama da sotto setto il ribaltamento
|
|
if dLargeface > BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then
|
|
bDown = true
|
|
end
|
|
-- se angolo tra le facce è maggiore di 90 non è raggiungibile dalla lama setto il ribaltamento
|
|
if dAng < 0 and dAng > -90 + 5 * GEO.EPS_SMALL then
|
|
bDown = true
|
|
end
|
|
end
|
|
-- altrimenti controllo la componente in Z delle facce
|
|
else
|
|
for i = 1, nFacetCnt do
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT)
|
|
-- altrimenti se versore z è preponderante sulle altre componenti del vettore ed è verso il basso,
|
|
-- considerazioni: al momento non è possibile sapere se ci sono due rastremature o una quindi se è rivolta verso il basso
|
|
-- viene dato errore, altrimenti si potrebbe imporre la rotazione di 180 (ovviamente con una sola rastrematura rivolta verso il basso)
|
|
if abs(vtN:getZ()) > abs(vtN:getX()) and abs(vtN:getZ()) > abs(vtN:getY()) and vtN:getZ() < -0.5 then
|
|
-- se con due facce e corto è fattibile
|
|
if nFacetCnt < 3 and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()) then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return true, bDown
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function EvaluateQParam( Proc, sDephtCham)
|
|
local nChamfer = 0
|
|
-- verifico che lo smusso sia richiesto
|
|
local dDepth = EgtGetInfo( Proc.Id, sDephtCham, 'd') or 0
|
|
if dDepth > 0 then
|
|
nChamfer = 1
|
|
end
|
|
|
|
return nChamfer, dDepth
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, dOvmTail)
|
|
|
|
-- 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 (1=faccia ausiliaria, 2=interna, 3=intermedia)
|
|
local vFaceOrd = { 0, 0, 0}
|
|
local dMinZedFace = 1
|
|
for i = 1, nFacetCnt do
|
|
local dXVal = EgtIf( abs( vtN[i]:getX()) < GEO.EPS_SMALL, 0, abs( vtN[i]:getX()))
|
|
if dXVal < dMinZedFace then
|
|
dMinZedFace = 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, 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
|
|
-- 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()
|
|
-- 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 : 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()) < dOvmTail + 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, CutId = Proc.CutId, TaskId = Proc.TaskId, PartId = Proc.PartId}
|
|
CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc)
|
|
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- 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( 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
|
|
-- 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
|
|
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 = 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
|
|
else
|
|
-- 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()) < dOvmTail + 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, CutId = Proc.CutId, TaskId = Proc.TaskId, PartId = Proc.PartId}
|
|
CutProc.AffectedFaces = BL.GetProcessAffectedFaces( CutProc)
|
|
local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- 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
|
|
-- taglio sulla faccia interna
|
|
local bIntCut = false
|
|
if vFaceOrd[2] ~= 0 then
|
|
-- inserisco la lavorazione
|
|
local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef)
|
|
local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, 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
|
|
|
|
-- 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, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep)
|
|
local sWarn = ''
|
|
-- 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 = 'MillTCone_' .. ( 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
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( TabNAD[j][1])
|
|
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)
|
|
if kStep % 2 == 1 then
|
|
-- imposto lato destro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, 2)
|
|
-- imposto inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
else
|
|
-- imposto lato sinistro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, 1)
|
|
-- tolgo inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
end
|
|
-- imposto affondamento in base al passo del ciclo
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dOffs)
|
|
--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( ( 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 = EgtGetMachiningParam( MCH_MP.USERNOTES) or ''
|
|
if i < nStep then
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'MaxElev', EgtNumToString( dStep, 1))
|
|
else
|
|
sUserNotes = EgtSetValInNotes( sUserNotes, 'VMRS', 0)
|
|
sUserNotes = EgtSetValInNotes( 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 MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt)
|
|
|
|
local sWarn = ''
|
|
-- 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
|
|
-- recupero l'angolo di spoglia dell'utensile a tronco di cono
|
|
-- recupero la lavorazione
|
|
local sMchFind = 'ProfTCone'
|
|
local sMilling = ML.FindMilling( sMchFind)
|
|
if not sMilling then
|
|
local sErr = 'Milling not found in library : Error on TyroleanDovetail ' .. 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
|
|
local bUCutMax
|
|
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)
|
|
end
|
|
end
|
|
if dStepmach <= 0.1 then
|
|
dStepmach = dMaxMat * 0.5
|
|
end
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local 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) .. ' MakeMachByMill could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
else
|
|
bUCutMax = true
|
|
end
|
|
end
|
|
-- verifico se sono presenti i parametri Q per la profondità smusso e
|
|
-- per eseguire in esclusiva solo lo smusso
|
|
local nChamfer, dDepthCham = EvaluateQParam( Proc, sDepthChamferMill)
|
|
-- dati della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- verifico se U
|
|
local bIsU = ( Proc.Fct == 3 and not TestElleShape3( Proc))
|
|
-- verifico se due facce o L con una o due facce di terminazione
|
|
local bIsL = ( Proc.Fct == 2 or TestElleShape3( Proc))
|
|
-- faccio tagli di lama come antischeggia sulle altre 2 facce
|
|
-- 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
|
|
-- vettore di riferimento per le facce ortogonali all'asse trave
|
|
local vtRef = Vector3d( 0, vtN:getY(), vtN:getZ())
|
|
vtRef:normalize()
|
|
local TabNAD = {}
|
|
-- ciclo inserimento tagli antischeggia sulle facce
|
|
for i = 1, nFacetCnt do
|
|
if (i-1) ~= nFacInd then
|
|
-- 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 _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, (i-1), GDB_ID.ROOT)
|
|
local dTrim
|
|
local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, (i-1), GDB_ID.ROOT)
|
|
if dAng then
|
|
TabNAD[i] = { vtN2, dAng, dist( ptP1, ptP2)}
|
|
end
|
|
if bTouch and dAng < 0 and dAng > -90 - 5 * GEO.EPS_SMALL then
|
|
dTrim = 0
|
|
else
|
|
dTrim = ((dToolThick* vtN) * vtN2 * vtN2):len()
|
|
end
|
|
-- inserisco la lavorazione
|
|
local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef)
|
|
local bOk, sNameOrErr = Fbs.MakeOne( Proc.Id, (i-1), sCutting, dSawDiam, nOrthoOpposite, nil, -(dTrim + 1), BD.CUT_SIC, 0, 0, 0, nil, b3Raw)
|
|
if not bOk then return bOk, sNameOrErr end
|
|
end
|
|
end
|
|
-- creo percorsi di lavorazione
|
|
-- local nCountSkipStep = 0
|
|
-- local nMaxSkippedStep = 0
|
|
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
|
|
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
|
|
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
|
|
-- se la larghezza è più grande dell'utensile allora posso lavorare il passo
|
|
if ( dLargeVal - dOffsSide) >= dToolDiam then
|
|
-- resetto il contatore skip
|
|
-- nCountSkipStep = 0
|
|
for j = 1, nFacetCnt do
|
|
if (j-1) ~= nFacInd then
|
|
-- calcolo l'offset radiale in base all'affondamento
|
|
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
|
|
-- inserisco la lavorazione di fresatura
|
|
local bOk, sErr = MakeMillCut( Proc, i, j, nil, sMilling, nFacInd, TabNAD, rfFac, dOffs, dOffrRad, 0, nStep, dToolDiam, dStep)
|
|
if not bOk then
|
|
return false, sErr
|
|
else
|
|
sWarn = sErr
|
|
end
|
|
-- se lato lavorato è il più lungo e la larghezza cava consente passi interni
|
|
if j == nLenSideMax and ( dLargeVal - dOffsSide) > 2*dToolDiam then
|
|
local nStepSide = ceil( ( ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) - 10 * GEO.EPS_SMALL) / dToolDiam * 0.5)
|
|
local dStepSide = ( dLargeVal - dOffsSide - ( 2 * dToolDiam)) / nStepSide
|
|
for k = 1, nStepSide 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, TabNAD, rfFac, dOffs, dOffrRad, dAddOffsRad, nStep, dToolDiam, dStep)
|
|
if not bOk then
|
|
return false, sErr
|
|
else
|
|
sWarn = sErr
|
|
end
|
|
end
|
|
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
|
|
|
|
-- se ho saltato più di un passo invalido le lavorazioni
|
|
-- if nMaxSkippedStep >= 2 or ( nStep >= nMaxSkippedStep and nMaxSkippedStep >= 1) then
|
|
-- local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' geometry to small for tool'
|
|
-- EgtOutLog( sErr)
|
|
-- return false, sErr
|
|
-- end
|
|
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
function ProcessTyroleanDovetail.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)
|
|
-- 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
|
|
local bOk, sErr = MakeMachByBlade( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt, dOvmTail)
|
|
if not bOk then return bOk, sErr end
|
|
else
|
|
local bOk, sErr = MakeMachByMill( Proc, nPhase, nRawId, nPartId, dOvmHead, b3Raw, b3Solid, nFacetCnt)
|
|
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 ProcessTyroleanDovetail
|