Files
DataBeam/LuaLibs/ProcessTyroleanDovetail.lua
T
luca.mazzoleni f8c40739da - in attacchi tangenziali solo da un lato alcune correzioni
- aggiunta la raccolta delle Affected Faces a tutti i casi in cui si crea una feature a posteriori (non presente nel btl)
2024-08-19 17:37:16 +02:00

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
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 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