b51487f5af
- modifiche per ottimizzazione con più teste - modifiche per compilazione.
5166 lines
221 KiB
Lua
5166 lines
221 KiB
Lua
-- ProcessLapJoint.lua by Egaltech s.r.l. 2022/01/28
|
|
-- Gestione calcolo mezzo-legno per Travi
|
|
-- 2019/10/08 Agg. gestione OpenPocket.
|
|
-- 2021/01/24 Con sega a catena ora sempre impostato asse A.
|
|
-- 2021/02/03 Corretto riconoscimento feature di coda.
|
|
-- 2021/02/04 Razionalizzata gestione forzatura lama. Corretta gestione diametro minimo utensile per svuotatura.
|
|
-- 2021/03/04 Due facce con testa da sotto.
|
|
-- 2021/03/20 Piccole correzioni.
|
|
-- 2021/03/22 Modificata gestione caso due facce lunghe come la trave con trave corta.
|
|
-- 2021/04/13 Modificata gestione fessura U con sega a catena (corta ora ok, lunga ancora da correggere).
|
|
-- 2021/04/14 Correzioni ribasso a U con fresa da sotto.
|
|
-- 2021/04/15 Aggiunta gestione massima lunghezza fresa da sotto su svuotature.
|
|
-- 2021/04/21 Anche feature lunga con due facce con opzione lama ora si taglia con lama.
|
|
-- 2021/04/23 Corretto caso con antischeggia non inseriti perchè inutili.
|
|
-- 2021/04/27 Antischeggia solo se feature trasversali.
|
|
-- 2021/05/12 Semplificata gestione diametro minimo utensile per svuotatura.
|
|
-- 2021/06/04 Su U passante con faccia perpendicolare aggiunta si forza Pocket.
|
|
-- 2021/06/11 Su U passante e profonda se non bastano due svuotature su faccia ortogonale si fa anche la faccia di fondo per quanto possibile.
|
|
-- 2021/06/21 Nel caso precedente si fa la terza svuotatura anche se è possibile fare una sola delle prime due (altra da sotto).
|
|
-- 2021/06/21 Gestione ripresa spigoli o contorno con fresa più piccola ( diametro < 3/4 utensile svuotatura) attivata da parametro Q.
|
|
-- 2021/07/02 Migliorie e correzioni su svuotature e pulitura spigoli.
|
|
-- 2021/07/15 Aggiunti antischeggia con fresa.
|
|
-- 2021/09/08 Aggiunta gestione parametro Q04 per i tagli di lama lungo facce lunghe (con o senza facce di chiusura)
|
|
-- 2021/09/21 Aggiunta lavorazione/opzione "lamello" con le feature 16, 30, 32, 39,
|
|
-- che si attiva abilitando il check al tipo milling: SideMillAsBlade (SideMillAsBlade_2)
|
|
-- 2021/09/23 Gestione migliorata lavorazioni BH (blockhaus) su macchina fast BH,
|
|
-- migliorata applicazione lavorazioni BH su feature lunghe lavorte a passi
|
|
-- 2021/10/06 Ad antischeggia con lama in presenza di testa da sotto aggiunta preferenza a testa da sopra.
|
|
-- 2021/10/19 Corretta gestione inversione per Tunnel. OpenPocket anche se spezzato ma 1 o 2 facce. Introdotta lunghezza minima per lamello.
|
|
-- 2021/10/21 Migliorato controllo affondamento utensile in U lavorato da 3 parti (anche da sotto).
|
|
-- 2021/10/27 Migliorato calcolo asse tunnel o similare.
|
|
-- 2021/11/02 In svuotatura con lati aperti diametro fresa non superiore al doppio del lato piccolo.
|
|
-- 2021/11/15 Quando si usa sega a catena uso Q10 come massima elevazione.
|
|
-- 2021/11/22 Corretta segnalazione warning su foro di L20 e L25.
|
|
-- 2021/12/17 Lettura parametri Q una volta sola all'inizio.
|
|
-- 2022/01/13 Estrapolazione da MakeMoreFaces() di MakeTwoFaces() e MakeThreeFaces(), e varie ottimizzazioni.
|
|
-- 2022/01/19 Cambiata % lunghezza pezzo per spezzatura. Tolta correzione spessore fresa a disco con superficie da lavorare verso Z-.
|
|
-- 2022/01/26 Migliorato controllo uso testa da sotto nel caso due facce con lama.
|
|
-- 2022/01/28 Aggiunte funzioni DoClean, DoPocketing, DoHeadChainSaw, DoSideChainSaw e DoHeadCut.
|
|
|
|
-- Tabella per definizione modulo
|
|
local ProcessLapJoint = {}
|
|
|
|
-- Include
|
|
require( 'EgtBase')
|
|
local BL = require( 'BeamLib')
|
|
local Fbs = require( 'FacesBySaw')
|
|
local Cut = require( 'ProcessCut')
|
|
local DoubleCut = require( 'ProcessDoubleCut')
|
|
local LongCut = require( 'ProcessLongCut')
|
|
local Long2Cut = require( 'ProcessLongDoubleCut')
|
|
|
|
EgtOutLog( ' ProcessLapJoint started', 1)
|
|
|
|
-- Dati
|
|
local BD = require( 'BeamData')
|
|
local ML = require( 'MachiningLib')
|
|
|
|
-- variabili assegnazione parametri Q
|
|
local Q_FORCE_BLADE = nil -- i
|
|
local Q_DEPTH_CHAMFER = 0.0 -- d
|
|
local Q_MAX_ELEVATION = 0.0 -- d
|
|
local Q_ONLY_CHAMFER = 0 -- i
|
|
local Q_USE_MILL = 0 -- i
|
|
local Q_USE_ROUGH_TOOL = 0 -- i
|
|
local Q_USE_ROUGH_TOOL_B90 = 0 -- i
|
|
local Q_USE_ROUGH_TOOL_B0 = 0 -- i
|
|
local Q_BORE_ON_CORNER = 0 -- i
|
|
local Q_CONTOUR_SMALL_TOOL = 0 -- i
|
|
local Q_ONLY_CONTOUR = 0 -- i
|
|
local Q_SIDE_ROUGH_TOOL = 0 -- i
|
|
local Q_ANTISPLINT_TYPE = 0 -- i
|
|
local Q_BLADE_ON_ALONG_FACE = 0 -- i
|
|
|
|
-- variabile smussi
|
|
local _bMadeChamfer
|
|
local _nChamfer, _dDepthCham, _sErrCham, _bForceUseBlade
|
|
|
|
-- Settaggi interni
|
|
local _bTrySidePocketAtFirst = true
|
|
local _nPhase, _nRawId, _nPartId, _dOvmHead
|
|
local _b3Raw, _b3Solid
|
|
local _nAddGrpId
|
|
|
|
|
|
---------------------------------------------------------------------
|
|
-- Riconoscimento della feature
|
|
function ProcessLapJoint.Identify( Proc)
|
|
return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 33) or
|
|
(( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34) or
|
|
( Proc.Grp == 4 and Proc.Prc == 37) or
|
|
( Proc.Grp == 4 and Proc.Prc == 39) or
|
|
( Proc.Grp == 4 and Proc.Prc == 120))
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function AssignQValues( Proc)
|
|
-- reset assegnazione parametri Q
|
|
Q_FORCE_BLADE = nil
|
|
Q_BLADE_ON_ALONG_FACE = 0
|
|
Q_DEPTH_CHAMFER = 0.0
|
|
Q_ONLY_CHAMFER = 0
|
|
Q_USE_MILL = 0
|
|
Q_USE_ROUGH_TOOL = 0
|
|
Q_USE_ROUGH_TOOL_B90 = 0
|
|
Q_USE_ROUGH_TOOL_B0 = 0
|
|
Q_BORE_ON_CORNER = 0
|
|
Q_CONTOUR_SMALL_TOOL = 0
|
|
Q_ONLY_CONTOUR = 0
|
|
Q_SIDE_ROUGH_TOOL = 0
|
|
Q_ANTISPLINT_TYPE = 0
|
|
Q_MAX_ELEVATION = EgtGetInfo( Proc.Id, 'Q10', 'd') or 0.0
|
|
|
|
if ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16 then
|
|
Q_FORCE_BLADE = EgtGetInfo( Proc.Id, 'Q01', 'i') -- can be nil
|
|
Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q04', 'd') or 0.0
|
|
Q_ONLY_CHAMFER = EgtGetInfo( Proc.Id, 'Q05', 'i') or 0
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17 then
|
|
Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0.0
|
|
Q_ONLY_CHAMFER = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20 then
|
|
Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q01', 'd') or 0.0
|
|
Q_USE_MILL = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0
|
|
Q_USE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0
|
|
Q_USE_ROUGH_TOOL_B90 = EgtGetInfo( Proc.Id, 'Q04', 'i') or 0
|
|
Q_USE_ROUGH_TOOL_B0 = EgtGetInfo( Proc.Id, 'Q05', 'i') or 0
|
|
Q_BORE_ON_CORNER = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 25 then
|
|
Q_BORE_ON_CORNER = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30 then
|
|
Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0
|
|
Q_ONLY_CONTOUR = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0
|
|
Q_SIDE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q03', 'i') or 0
|
|
Q_BLADE_ON_ALONG_FACE = EgtGetInfo( Proc.Id, 'Q04', 'i') or 0
|
|
Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0
|
|
Q_DEPTH_CHAMFER = EgtGetInfo( Proc.Id, 'Q07', 'd') or 0.0
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32 then
|
|
Q_SIDE_ROUGH_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0
|
|
Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q02', 'i') or 0
|
|
Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0
|
|
elseif ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 34 then
|
|
Q_CONTOUR_SMALL_TOOL = EgtGetInfo( Proc.Id, 'Q01', 'i') or 0
|
|
Q_ANTISPLINT_TYPE = EgtGetInfo( Proc.Id, 'Q06', 'i') or 0
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function EvaluateChamfer()
|
|
local sErr
|
|
-- verifico che lo smusso sia richiesto
|
|
local nChamfer = 0
|
|
if Q_DEPTH_CHAMFER > 0 then
|
|
nChamfer = 1
|
|
end
|
|
-- verifico se posso fare solo lo smusso
|
|
if Q_ONLY_CHAMFER == 1 then
|
|
if Q_DEPTH_CHAMFER > 0 then
|
|
nChamfer = nChamfer + 1
|
|
-- altrimenti se non ho l'affondamento esco
|
|
else
|
|
sErr = 'Error : no chamfer depth'
|
|
EgtOutLog( sErr)
|
|
return -1, dDepth, sErr
|
|
end
|
|
end
|
|
-- verifico se devo usare lama invece della sega-catena
|
|
-- 2020-03-20 forzata abilitazione uso lama se parametro Q non è presente
|
|
-- xxxx-xx-xx tolta la preferenza alla lama in favore della sega-catena per un caso particolare
|
|
-- 2021-02-15 re-introdotta la preferenza alla lama se non c'è il parametro Q. Rimane da
|
|
-- implementare un ulteriore parametro per poter scegliere di prediligere la sega-catena o no al fine di continuare
|
|
-- a cambiare il codice per gestire il caso particolare
|
|
local bForceUseBlade = false
|
|
if Q_FORCE_BLADE == nil or Q_FORCE_BLADE == 1 then
|
|
bForceUseBlade = true
|
|
end
|
|
|
|
return nChamfer, dDepth, sErr, bForceUseBlade
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function InitGlob( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
if not Proc then
|
|
return false, 'Error : Proc is missing'
|
|
end
|
|
|
|
-- setto a nil la variabile smussi
|
|
_bMadeChamfer = nil
|
|
_nPhase = nPhase
|
|
_nRawId = nRawId
|
|
_nPartId = nPartId
|
|
_dOvmHead = dOvmHead
|
|
|
|
if _nRawId then
|
|
-- recupero l'ingombro del grezzo di appartenenza
|
|
_b3Raw = EgtGetRawPartBBox( _nRawId)
|
|
end
|
|
|
|
if not _nPartId then
|
|
_nPartId = EgtGetParent( EgtGetParent( Proc.Id) or GDB_ID.NULL)
|
|
end
|
|
|
|
if _nPartId then
|
|
-- recupero gruppo per geometria addizionale
|
|
_nAddGrpId = BL.GetAddGroup( _nPartId)
|
|
-- recupero l'ingombro della trave
|
|
_b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( _nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD)
|
|
else
|
|
local sErr = 'Error : part ID not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
if not _b3Solid then
|
|
local sErr = 'Error : part box not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
if not _nAddGrpId then
|
|
local sErr = 'Error : missing AddGroup'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- leggo i valori dei parametri Q
|
|
AssignQValues( Proc)
|
|
-- verifico se sono presenti i parametri per la profondità smusso e
|
|
-- per eseguire in esclusiva solo lo smusso
|
|
_nChamfer, _dDepthCham, _sErrCham, _bForceUseBlade = EvaluateChamfer()
|
|
|
|
return true, ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function UpdateFacet1Data( nProcId, tFData, nFacInd, dFacElev)
|
|
if not tFData then
|
|
tFData = {}
|
|
end
|
|
tFData.nFacInd = nFacInd
|
|
if dFacElev then
|
|
tFData.dFacElev = dFacElev
|
|
end
|
|
if tFData.nFacInd and tFData.nFacInd > -1 then
|
|
tFData.ptC, tFData.vtN = EgtSurfTmFacetCenter( nProcId, tFData.nFacInd, GDB_ID.ROOT)
|
|
tFData.rfFac, tFData.dH, tFData.dV = EgtSurfTmFacetMinAreaRectangle( nProcId, tFData.nFacInd, GDB_ID.ROOT)
|
|
end
|
|
return tFData
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function UpdateFacet2Data( nProcId, tFData, nFacInd2, dFacElev2)
|
|
if not tFData then
|
|
tFData = {}
|
|
end
|
|
tFData.nFacInd2 = nFacInd2
|
|
if dFacElev2 then
|
|
tFData.dFacElev2 = dFacElev2
|
|
end
|
|
if tFData.nFacInd2 and tFData.nFacInd2 ~= true and tFData.nFacInd2 > -1 then
|
|
tFData.ptC2, tFData.vtN2 = EgtSurfTmFacetCenter( nProcId, tFData.nFacInd2, GDB_ID.ROOT)
|
|
tFData.rfFac2, tFData.dH2, tFData.dV2 = EgtSurfTmFacetMinAreaRectangle( nProcId, tFData.nFacInd2, GDB_ID.ROOT)
|
|
end
|
|
return tFData
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetFacetsData( nProcId)
|
|
local tFData = {}
|
|
local nFacInd, dFacElev, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( nProcId, _nPartId)
|
|
if nFacInd then
|
|
tFData = UpdateFacet1Data( nProcId, tFData, nFacInd, dFacElev)
|
|
tFData = UpdateFacet2Data( nProcId, tFData, nFacInd2, dFacElev2)
|
|
if tFData.nFacInd == -1 and tFData.nFacInd2 and tFData.nFacInd2 == true then
|
|
tFData.isOrthoFaces = true
|
|
end
|
|
end
|
|
return tFData
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function SwapFacetsData( tFData)
|
|
if tFData then
|
|
tFData.nFacInd, tFData.nFacInd2 = tFData.nFacInd2, tFData.nFacInd
|
|
tFData.dFacElev, tFData.dFacElev2 = tFData.dFacElev2, tFData.dFacElev
|
|
tFData.ptC, tFData.ptC2 = tFData.ptC2, tFData.ptC
|
|
tFData.vtN, tFData.vtN2 = tFData.vtN2, tFData.vtN
|
|
tFData.rfFac, tFData.rfFac2 = tFData.rfFac2, tFData.rfFac
|
|
tFData.dH, tFData.dH2 = tFData.dH2, tFData.dH
|
|
tFData.dV, tFData.dV2 = tFData.dV2, tFData.dV
|
|
end
|
|
return tFData
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetToolInfoForMachining( sMachiningName)
|
|
if EgtMdbSetCurrMachining( sMachiningName) then
|
|
local toolInfo = {}
|
|
toolInfo.sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( toolInfo.sTuuid) or '') then
|
|
toolInfo.dLength = EgtTdbGetCurrToolParam( MCH_TP.LEN)
|
|
toolInfo.dDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
|
|
toolInfo.dThDiam = EgtTdbGetCurrToolThDiam()
|
|
toolInfo.dMaxMat = EgtTdbGetCurrToolParam( MCH_TP.MAXMAT)
|
|
toolInfo.dMaxDepth = EgtTdbGetCurrToolMaxDepth()
|
|
toolInfo.dSideDepth = EgtTdbGetCurrToolValInNotes( MCH_TP.USERNOTES, 'SIDEDEPTH', 'd')
|
|
toolInfo.dCornerRad = EgtTdbGetCurrToolParam( MCH_TP.CORNRAD)
|
|
toolInfo.dThick = EgtTdbGetCurrToolParam( MCH_TP.THICK)
|
|
return toolInfo
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function FormatWarning( sWarn, sWarn2)
|
|
if sWarn2 then
|
|
if not sWarn then sWarn = '' end
|
|
sWarn = EgtIf( #sWarn > 0, sWarn .. '\n' .. sWarn2, sWarn2)
|
|
end
|
|
return sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Restituisce solo gli indici delle facce adiacenti esistenti (no -1)
|
|
local function GetValidFacetAdjacencies( nSurfId, nFacet)
|
|
local vValidAdj
|
|
local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, nFacet)[1]
|
|
|
|
if vFacAdj then
|
|
vValidAdj = {}
|
|
for j = 1, #vFacAdj do
|
|
if vFacAdj[j] >= 0 then
|
|
table.insert( vValidAdj, vFacAdj[j])
|
|
end
|
|
end
|
|
end
|
|
|
|
return vValidAdj
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestElleShape3( Proc, bNotProc)
|
|
local nNumFacet
|
|
local nProcId
|
|
-- se non passato il Proc vero e proprio
|
|
if bNotProc then
|
|
nProcId = Proc
|
|
nNumFacet = EgtSurfTmFacetCount( nProcId)
|
|
else
|
|
nProcId = Proc.Id
|
|
nNumFacet = Proc.Fct
|
|
end
|
|
-- valida solo nel caso di tre facce
|
|
if nNumFacet ~= 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
|
|
-- conto le facce adiacenti (solo quelle valide)
|
|
local vFacAdj = GetValidFacetAdjacencies( nProcId, i - 1)
|
|
if #vFacAdj == 1 then
|
|
bIsL = false
|
|
break
|
|
end
|
|
end
|
|
return bIsL
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestElleShape4( Proc)
|
|
-- valida solo nel caso di quattro facce
|
|
if Proc.Fct ~= 4 then return false end
|
|
-- determino se L con due facce terminali o O
|
|
local nFac3Adj = 0
|
|
local dMinArea3 = GEO.INFINITO * GEO.INFINITO
|
|
local dMaxArea2 = 0
|
|
for i = 1, 4 do
|
|
-- conto le facce adiacenti (solo quelle valide)
|
|
local vFacAdj = GetValidFacetAdjacencies( Proc.Id, i - 1)
|
|
local _, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
local dArea = dH * dV
|
|
if #vFacAdj == 2 then
|
|
dMaxArea2 = max( dMaxArea2, dArea)
|
|
elseif #vFacAdj == 3 then
|
|
dMinArea3 = min( dMinArea3, dArea)
|
|
nFac3Adj = nFac3Adj + 1
|
|
end
|
|
end
|
|
if nFac3Adj ~= 2 then return false end
|
|
-- verifico se L profonda oppure lunga
|
|
if dMinArea3 < 2 * dMaxArea2 then
|
|
return 1
|
|
else
|
|
return 2
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
--- Test per facce a forma di U o a forma di L
|
|
local function TestUL( Proc)
|
|
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) or TestElleShape4( Proc) == 2)
|
|
|
|
return bIsU, bIsL
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetIdIniEndPoints( ptP1, ptP2, tFac)
|
|
local nIdIniPoint
|
|
local nIdEndPoint
|
|
if ptP1 and ptP2 then
|
|
if dist( ptP1, tFac[4]) < GEO.EPS_SMALL or dist( ptP2, tFac[4]) < GEO.EPS_SMALL then
|
|
nIdEndPoint = 4
|
|
nIdIniPoint = 5
|
|
elseif dist( ptP1, tFac[5]) < GEO.EPS_SMALL or dist( ptP2, tFac[5]) < GEO.EPS_SMALL then
|
|
nIdEndPoint = 5
|
|
nIdIniPoint = 4
|
|
end
|
|
end
|
|
return nIdIniPoint, nIdEndPoint
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetChainSawBlockedAxis( nInd)
|
|
if BD.GetChainSawBlockedAxis then
|
|
return BD.GetChainSawBlockedAxis( nInd)
|
|
else
|
|
if nInd == 1 then
|
|
return EgtIf( BD.C_SIMM, 'A=90', 'A=0')
|
|
else
|
|
return EgtIf( BD.C_SIMM, 'A=0', 'A=90')
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetChainSawInitAngs( vtN, vtO)
|
|
if BD.GetChainSawInitAngs then
|
|
return BD.GetChainSawInitAngs( vtN, vtO)
|
|
else
|
|
if BD.C_SIMM then
|
|
if vtN:getY() > 0 then
|
|
return 'C=180'
|
|
else
|
|
return 'C=-180'
|
|
end
|
|
else
|
|
return ''
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyChainSaw( dMinDim, dMaxDim)
|
|
local bUseChainSaw = false
|
|
local sMchFind = 'Sawing'
|
|
local sSawing = ML.FindSawing( sMchFind)
|
|
local dMaxMat = 0
|
|
local dSawCornerRad = 0
|
|
local dSawThick = 0
|
|
local dMaxDepth = 200
|
|
-- se non trova una lavorazione di sawing esco
|
|
if not sSawing then
|
|
return bUseChainSaw
|
|
else
|
|
-- recupero i dati dell'utensile
|
|
local dToolLength = 0
|
|
local dSawWidth = 75
|
|
local TI = GetToolInfoForMachining( sSawing)
|
|
if TI then
|
|
dToolLength = TI.dLength or dToolLength
|
|
dMaxMat = TI.dMaxMat or dMaxMat
|
|
dSawWidth = TI.dDiam or dSawWidth
|
|
dSawThick = TI.dThick or dSawThick
|
|
dSawCornerRad = TI.dCornerRad or dSawCornerRad
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
if dSawThick < ( dMinDim + 10 * GEO.EPS_SMALL) and dSawWidth < ( dMaxDim + 10 * GEO.EPS_SMALL) then
|
|
bUseChainSaw = true
|
|
end
|
|
end
|
|
end
|
|
return bUseChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick, dMaxDepth
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyPocket( dDiam, dDepth, dMaxTotLen, sMchFindMaster, bPocketUp, bPocketDown)
|
|
-- tipo di svuotatura
|
|
local sMchFind = EgtIf( sMchFindMaster and #sMchFindMaster > 0, sMchFindMaster, 'Pocket')
|
|
-- ricerca della svuotatura
|
|
local sPocketing
|
|
if dDepth then
|
|
sPocketing, _, _, bPocketDown = ML.FindPocketing( sMchFind, dDiam, dDepth, dMaxTotLen) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.8 * dDepth, dMaxTotLen) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.6 * dDepth, dMaxTotLen) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0.4 * dDepth, dMaxTotLen) or
|
|
ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen)
|
|
else
|
|
sPocketing, _, _, bPocketDown = ML.FindPocketing( sMchFind, dDiam, 0, dMaxTotLen)
|
|
end
|
|
if not sPocketing then
|
|
return false
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local bUsePocketing = false
|
|
local dMaxDepth = 0
|
|
local dToolDiam = 0
|
|
local TI = GetToolInfoForMachining( sPocketing)
|
|
if TI then
|
|
dToolDiam = TI.dDiam or dToolDiam
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
bUsePocketing = true
|
|
end
|
|
return bUsePocketing, sPocketing, dMaxDepth, dToolDiam, bPocketDown
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill)
|
|
|
|
local bUseBHSideMill = false
|
|
local bHead = true
|
|
local bHeadDir = true
|
|
local sMilling
|
|
local dThickTool = 0
|
|
local dToolDiam = 0
|
|
-- 22/09/2021 Su richiesta di Alessandro Sola, si toglie la richiesta di presenza del parametro Q per poter applicare
|
|
-- la lavorazione su più features (che non hanno questo parametro Q), quindi questa lavorazione viene verificata se è abilitato il parametro utensile
|
|
-- che ovviamente tramite la lavorazione è abbinata alla lista lavorazioni con BHSideMill.
|
|
-- Al fine di mantenere il funzionamento precedente (purtroppo non sono stati descritti i motivi del confrontare il parametro Q)
|
|
-- si elude il controllo del Q solo se la variabile del Beamdata BD.BH_MACHINE segnala che non è una macchina tipo BH (ha la fresa blockhaus al posto della lama)
|
|
|
|
-- se non feature BlockHausHalfLap o non abilitato parametro Q per lavorarlo di fianco esco
|
|
if Proc.Prc ~= 37 and Q_SIDE_ROUGH_TOOL == 0 and not BD.BH_MACHINE then
|
|
return false
|
|
end
|
|
-- verifico se U o L
|
|
local bIsU, bIsL = TestUL( Proc)
|
|
-- verifico se la funzione è lanciata da IsTailFeature o Classify
|
|
if bSinglePart == nil then
|
|
-- se lunghezza non richiede spezzatura setto la variabile bSinglePart per non fare con fresa BH
|
|
-- perchè deve avere almeno 2 facce
|
|
if not ( ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or
|
|
( Proc.Box:getDimX() > 0.8 * _b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN)) then
|
|
bSinglePart = true
|
|
end
|
|
end
|
|
-- ad oggi 22/09/2021 la lavorazione BH non va bene se le facce di chiusura non sono perpendicolari a X, quindi
|
|
-- se non sono perpendicolari non si applica la lavorazione BH
|
|
if bIsU or bIsL then
|
|
local bExit = false
|
|
for i = 1, Proc.Fct do
|
|
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, i - 1, GDB_ID.ROOT)
|
|
if abs( vtN:getX()) > 0.001 and abs( vtN:getX()) < 0.999962 then
|
|
bExit = true
|
|
break
|
|
end
|
|
end
|
|
if bExit then
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- se forma a U o L verifico che
|
|
-- se U e lunghezza non richiede spezzatura
|
|
if ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and Proc.Box:getDimX() <= BD.LONGCUT_MAXLEN then
|
|
-- se faccia singola di un passo multiplo e risultato precedente non applicato, riporto il risultato del passo precedente
|
|
if ( bIsU or bIsL or ( Proc.Fct == 1 and not bSinglePart)) and bPrevBhSideMill ~= nil and not bPrevBhSideMill then
|
|
return false
|
|
end
|
|
-- recupero la lavorazione
|
|
sMilling = ML.FindMilling( 'BHSideMill')
|
|
if sMilling then
|
|
-- recupero i dati dell'utensile
|
|
local dToolLength = 0
|
|
local dMaxDepth = 0
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dToolLength = TI.dLength or dToolLength
|
|
dToolDiam = TI.dDiam or dToolDiam
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
dThickTool = TI.dThick or dThickTool
|
|
end
|
|
-- verifico se la feature è abbastanza vicino a testa/coda da permettere la lavorazione con questo utensile
|
|
if _b3Solid then
|
|
local dMinXF = Proc.Box:getMin():getX()
|
|
local dMaxXF = Proc.Box:getMax():getX()
|
|
local dMinT = _b3Solid:getMin():getX()
|
|
local dMaxT = _b3Solid:getMax():getX()
|
|
-- determino se è più vicino alla testa o al bordo (con offset per evitare problemi a metà)
|
|
bHeadDir = ( dMaxT - dMinXF) < ( dMaxXF - dMinT) + 50
|
|
bHead = bHeadDir
|
|
-- determino se è compatibile con il massimo affondamento dell'utensile
|
|
-- nota F.M il 22/09/2021: non sarebbe meglio utilizzare lo spessore lama invece della massima lavorazione?
|
|
-- questo perchè Alessandro ha settato il parametro Max Material a 80 con spessore lama 42
|
|
-- se invece il Max material viene usato per definire fino a che affondamento (lungo l'asse utensile)
|
|
-- può arrivare prima di collidere con la testa allora si può utilizzare il dMaxDepth
|
|
bUseBHSideMill = EgtIf( bHead, ( dMaxT - dMinXF), ( dMaxXF - dMinT)) < dMaxDepth
|
|
-- se diametro maggiore della testa
|
|
if BD.HEAD_DIM_FOR_BH and dToolDiam > BD.HEAD_DIM_FOR_BH then
|
|
bHead = true
|
|
bUseBHSideMill = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return bUseBHSideMill, bHead, bHeadDir, sMilling, dThickTool, dToolDiam
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetTunnelDimension( Proc)
|
|
-- sono necessarie almeno due facce
|
|
if Proc.Fct < 2 then return 0, 0, 0 end
|
|
-- recupero centro e normale 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
|
|
-- calcolo l'orientamento del tunnel
|
|
local vtOrtho
|
|
local bAdj = EgtSurfTmFacetsContact( Proc.Id, 0, 1)
|
|
if bAdj then
|
|
vtOrtho = vtN[1] ^ vtN[2]
|
|
else
|
|
if Proc.Fct >= 3 then
|
|
vtOrtho = vtN[1] ^ vtN[3]
|
|
else
|
|
return 0, 0, 0
|
|
end
|
|
end
|
|
-- ottengo il boundingBox e prendo le dimensioni lungo la direzione (Z locale) che rappresenta la profondità della fessura
|
|
local frFc = Frame3d( ptC[1], vtOrtho)
|
|
local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc)
|
|
local dDepth = b3BoxLoc:getDimZ()
|
|
-- centro del bounding box locale
|
|
local ptCen = b3BoxLoc:getCenter()
|
|
ptCen:toGlob( frFc)
|
|
-- creo superficie intermedia
|
|
local nSurfInt = EgtSurfTmPlaneInBBox( _nAddGrpId, ptCen, vtOrtho, _b3Solid, GDB_ID.ROOT)
|
|
if not nSurfInt then return 0, 0, 0 end
|
|
-- ritaglio la superficie con le facce della fessura
|
|
for i = 1, Proc.Fct do
|
|
EgtCutSurfTmPlane( nSurfInt, ptC[i], -vtN[i], false, GDB_ID.ROOT)
|
|
end
|
|
local frSurfInt, dDimMax, dDimMin = EgtSurfTmFacetMinAreaRectangle( nSurfInt, 0, GDB_ID.ROOT)
|
|
-- cerco la faccia con larghezza pari a dimensione massima della fessura
|
|
local nLongFaceId = 0
|
|
for i = 1, Proc.Fct do
|
|
if abs( vtN[i] * frSurfInt:getVersX()) < 0.5 then
|
|
nLongFaceId = i - 1
|
|
break
|
|
end
|
|
end
|
|
return dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetFaceAdj( Proc, tFData)
|
|
-- Recupero le facce adiacenti alla principale (solo quelle esistenti)
|
|
local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd)
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
return -1, sErr
|
|
end
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 4)
|
|
-- Riordino le dimensioni per avere dH > dV
|
|
if tFData.dH < tFData.dV then
|
|
tFData.dH, tFData.dV = tFData.dV, tFData.dH
|
|
end
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj
|
|
for i = 1, #vAdj do
|
|
local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
if dLen > 0.5 * tFData.dH then
|
|
nFacAdj = vAdj[i]
|
|
EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 4)
|
|
break
|
|
end
|
|
end
|
|
if not nFacAdj then
|
|
local sErr = 'Error : main face without long adjacent face'
|
|
return -1, sErr
|
|
end
|
|
return nFacAdj
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CalcCollisionSafety( vtDir)
|
|
local dCollSic = 10 * BD.COLL_SIC
|
|
if abs( vtDir:getX()) > 0.999 or abs( vtDir:getY()) > 0.999 or abs( vtDir:getZ()) > 0.999 then
|
|
dCollSic = 0
|
|
elseif abs( vtDir:getX()) > 0.996 or abs( vtDir:getY()) > 0.996 or abs( vtDir:getZ()) > 0.996 then
|
|
dCollSic = 1 * BD.COLL_SIC
|
|
elseif abs( vtDir:getX()) > 0.89 or abs( vtDir:getY()) > 0.89 or abs( vtDir:getZ()) > 0.89 then
|
|
dCollSic = 2.5 * BD.COLL_SIC
|
|
elseif abs( vtDir:getX()) > 0.866 or abs( vtDir:getY()) > 0.866 or abs( vtDir:getZ()) > 0.866 then
|
|
dCollSic = 4 * BD.COLL_SIC
|
|
elseif abs( vtDir:getX()) > 0.707 or abs( vtDir:getY()) > 0.707 or abs( vtDir:getZ()) > 0.707 then
|
|
dCollSic = 5.5 * BD.COLL_SIC
|
|
end
|
|
return dCollSic
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Verifica se feature di testa
|
|
function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH)
|
|
if not InitGlob( Proc) then
|
|
return false
|
|
end
|
|
-- 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 e interessa veramente la testa, allora di testa
|
|
if Proc.Fct <= 2 then
|
|
if Proc.Box:getMax():getX() > _b3Solid:getMax():getX() - 1. then
|
|
return true
|
|
elseif Proc.Box:getMax():getX() < _b3Solid:getMax():getX() - 5. then
|
|
return false
|
|
end
|
|
end
|
|
local tFData = GetFacetsData( Proc.Id)
|
|
-- deve avere la normale principale diretta verso la testa
|
|
if tFData.vtN and tFData.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 ProcessLapJoint.IsTailFeature( Proc, b3Raw)
|
|
if not InitGlob( Proc) then
|
|
return false
|
|
end
|
|
-- 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
|
|
-- se può essere fatto con utensile tipo lama
|
|
local bUseBHSideMill, bHead, bHeadDir = VerifyBHSideMill( Proc)
|
|
if bUseBHSideMill then
|
|
Proc.HeadDir = bHeadDir
|
|
return not bHead
|
|
end
|
|
-- verifico se è in coda
|
|
local dEndDist = Proc.Box:getMin():getX() - _b3Solid:getMin():getX()
|
|
if dEndDist > 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 e interessa veramente la coda, allora di coda
|
|
if Proc.Fct <= 2 then
|
|
if Proc.Box:getMin():getX() < _b3Solid:getMin():getX() + 1. then
|
|
return true
|
|
elseif Proc.Box:getMin():getX() > _b3Solid:getMin():getX() + 5. then
|
|
return false
|
|
end
|
|
end
|
|
local tFData = GetFacetsData( Proc.Id)
|
|
-- deve avere la normale principale diretta verso la coda (oppure tunnel)
|
|
if tFData.vtN and tFData.vtN:getZ() < BD.NZ_MINA and tFData.nFacInd2 then
|
|
tFData = SwapFacetsData( tFData)
|
|
end
|
|
if not tFData.vtN or tFData.vtN:getX() > -0.001 or dEndDist + tFData.vtN:getX() * tFData.dFacElev > 0 then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Classificazione della feature
|
|
function ProcessLapJoint.Classify( Proc, b3Raw)
|
|
if not InitGlob( Proc) then
|
|
return false
|
|
end
|
|
-- se 1 faccia
|
|
if Proc.Fct == 1 then
|
|
-- dati della faccia
|
|
--local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- verifico se è lavorabile solo dal basso
|
|
--local bDown = ( vtN:getZ() < BD.NZ_MINA)
|
|
--return true, bDown
|
|
return true, false
|
|
-- se 2 facce
|
|
elseif Proc.Fct == 2 then
|
|
-- dati delle facce
|
|
local vtN = {}
|
|
_, vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
_, vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- verifico se è lavorabile solo dal basso
|
|
local bSmall = ( ( Proc.Head or Proc.Tail) and Proc.Box:getDimX() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ())) or
|
|
( not ( Proc.Head or Proc.Tail) and Proc.Box:getDimY() <= BD.GetMaxLenRidgeLapFromBottom( b3Raw:getDimZ()))
|
|
local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or
|
|
( vtN[1]:getZ() < BD.NZ_MINA and ( vtN[2]:getZ() < -0.1 or not bSmall)) or
|
|
( vtN[2]:getZ() < BD.NZ_MINA and ( vtN[1]:getZ() < -0.1 or not bSmall))
|
|
bDown = ( bDown and not BD.DOWN_HEAD)
|
|
return true, bDown
|
|
-- se più di 2 facce
|
|
else
|
|
local bClosedOrthoFaces
|
|
local nDeletedFace
|
|
local tFData = GetFacetsData( Proc.Id)
|
|
if not tFData.nFacInd or tFData.nFacInd < 0 then
|
|
if tFData.nFacInd == -1 then
|
|
bClosedOrthoFaces = tFData.isOrthoFaces
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
-- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche
|
|
if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then
|
|
-- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura
|
|
for i = 1, Proc.Fct do
|
|
local nNewProc = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL
|
|
-- elimino una faccia
|
|
nDeletedFace = i - 1
|
|
if EgtSurfTmRemoveFacet( nNewProc, nDeletedFace) then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
tFData = GetFacetsData( nNewProc)
|
|
if not tFData.nFacInd or tFData.nFacInd < 0 then
|
|
if tFData.nFacInd == -1 then
|
|
bClosedOrthoFaces = tFData.isOrthoFaces
|
|
EgtErase( nNewProc)
|
|
break
|
|
else
|
|
EgtErase( nNewProc)
|
|
return false
|
|
end
|
|
end
|
|
-- altrimenti esco
|
|
else
|
|
EgtErase( nNewProc)
|
|
break
|
|
end
|
|
end
|
|
-- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo
|
|
if bClosedOrthoFaces then
|
|
tFData = UpdateFacet1Data( Proc.Id, tFData, nDeletedFace)
|
|
-- rendo nulla la faccia opzionale perchè si tratta di una fessura
|
|
tFData = UpdateFacet2Data( Proc.Id, tFData, nil)
|
|
bClosedOrthoFaces = false -- non lo setto come tunnel
|
|
end
|
|
end
|
|
-- se facce formano un tunnel e sono ortogonali
|
|
if bClosedOrthoFaces then
|
|
-- ottengo le dimensioni del tunnel
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc)
|
|
EgtErase( nSurfInt)
|
|
-- verifico se può essere fatto con svuotatura
|
|
if VerifyPocket( dDimMin) then
|
|
return true, false
|
|
elseif VerifyChainSaw( dDimMin, dDimMax) then
|
|
return true, false
|
|
else
|
|
return false
|
|
end
|
|
else
|
|
-- se può essere fatto con utensile tipo lama
|
|
local bUseBHSideMill, _, _, dMaxMat = VerifyBHSideMill( Proc)
|
|
-- if bUseBHSideMill and ( dMaxMat <= tFData.dV + 15 * GEO.EPS_SMALL) then
|
|
if bUseBHSideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then
|
|
return true, false
|
|
-- altrimenti controllo se deve essere ruotato con le altre lavorazioni
|
|
else
|
|
-- dati della faccia
|
|
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, tFData.nFacInd, GDB_ID.ROOT)
|
|
-- cerco se c'è faccia adiacente sul lato più lungo
|
|
local nFaceAdj = GetFaceAdj( Proc, tFData) or -1
|
|
local _, bIsL = TestUL( Proc)
|
|
-- verifico se è lavorabile solo dal basso
|
|
local bDown = ( vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD)
|
|
-- se verso il basso, verifico se utilizzabile seconda faccia
|
|
if bDown then
|
|
if tFData.nFacInd2 and tFData.dFacElev2 < 2 * tFData.dFacElev then
|
|
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFData.nFacInd2, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
elseif not tFData.nFacInd2 and bIsL and nFaceAdj >= 0 then
|
|
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
end
|
|
-- verifico se la faccia principale è sottosquadra, ha forma L ed esiste la faccia adiacente
|
|
elseif vtN:getZ() < -0.2589 and bIsL and nFaceAdj >= 0 then
|
|
-- se il numero di facce > 2 o il box della feature supera una certa distanza dalle teste allora controllo la z della faccia ausiliaria
|
|
if Proc.Fct > 2 or ( Proc.Box:getMax():getX() < _b3Solid:getMin():getX() - 150) or ( Proc.Box:getMin():getX() > _b3Solid:getMax():getX() + 150) then
|
|
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, nFaceAdj, GDB_ID.ROOT)
|
|
bDown = ( vtN2:getZ() < BD.NZ_MINB)
|
|
end
|
|
end
|
|
return true, bDown
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Lavorazione con fresa
|
|
---------------------------------------------------------------------
|
|
local function MakeOneFaceByMill( Proc)
|
|
-- verifico il numero di facce della tacca
|
|
assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces')
|
|
-- dati della faccia
|
|
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
-- verifico se orientata verso l'alto
|
|
local bUp = ( vtN:getZ() >= BD.NZ_MINA)
|
|
-- scelta faccia da lavorare
|
|
local nFacInd = 0
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'BirdsMouth')
|
|
if not sMilling then
|
|
local sErr = 'Error : BirdsMouth not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia e lato correzione
|
|
if vtN:getX() > 0 then
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_LEFT, MCH_MILL_FU.PARAL_LEFT))
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bUp, MCH_MILL_FU.ORTHO_RIGHT, MCH_MILL_FU.PARAL_RIGHT))
|
|
end
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
if not bUp then EgtSetMachiningParam( MCH_MP.INVERT, true) end
|
|
-- imposto posizione braccio porta testa
|
|
if vtN:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- dichiaro non si generano sfridi per VMill
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;')
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * _b3Raw:getDimZ())
|
|
if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < _b3Raw:getMin():getZ() + dMinHIng then
|
|
if Proc.Head then
|
|
local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
BL.UpdateHCING( _nRawId, dOffs)
|
|
elseif Proc.Tail then
|
|
local dOffs = Proc.Box:getMax():getX() - _b3Solid:getMin():getX()
|
|
BL.UpdateTCING( _nRawId, dOffs)
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DoMill( Proc, sName, sMilling, offset, nFacInd, nFac2Ind, vtN)
|
|
-- 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
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}})
|
|
-- imposto uso faccia e lato correzione
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( vtN[nFac2Ind+1])
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto lato di correzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- tolgo l'inversione
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
-- aggiungo offset laterale
|
|
if offset then EgtSetMachiningParam( MCH_MP.OFFSR, offset) end
|
|
-- imposto posizione braccio porta testa
|
|
if vtN[nFacInd+1]:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- dichiaro non si generano sfridi per VMill
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, 'VMRS=0;')
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeTwoFacesByMill( Proc, bDownHead)
|
|
-- verifico il numero di facce della tacca
|
|
assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces')
|
|
-- recupero la lavorazione
|
|
local sMilling
|
|
sMilling = ML.FindMilling( EgtIf( Q_USE_MILL and Q_USE_MILL == 1, 'LongSmallCut', 'BirdsMouth'), nil , nil, nil, nil, not bDownHead, bDownHead)
|
|
if not sMilling then
|
|
local sErr = 'Error : LongSmallCut & BirdsMouth not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 0
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dTDiam = TI.dDiam or dTDiam
|
|
end
|
|
-- dati delle facce
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
-- dati medi
|
|
local ptM = ( ptC[1] + ptC[2]) / 2
|
|
-- verifico non siano orientate verso il basso
|
|
local bFaceOk = {}
|
|
bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB)
|
|
bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB)
|
|
if not bDownHead and not bFaceOk[1] and not bFaceOk[2] then
|
|
local sErr = 'Error : LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- scelta faccia da lavorare
|
|
local nFacInd
|
|
-- se entrambe possibili
|
|
if bFaceOk[1] and bFaceOk[2] then
|
|
-- se in testa, scelgo quella orientata verso la testa
|
|
if Proc.Head then
|
|
if vtN[1]:getX() > vtN[2]:getX() then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
-- se altrimenti in coda, scelgo quella orientata verso la coda
|
|
elseif Proc.Tail then
|
|
if vtN[1]:getX() < vtN[2]:getX() then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
-- altrimenti, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+)
|
|
else
|
|
if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then
|
|
if ptM:getX() > _b3Raw:getCenter():getX() then
|
|
nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1)
|
|
else
|
|
nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1)
|
|
end
|
|
else
|
|
nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1)
|
|
end
|
|
end
|
|
elseif bFaceOk[1] then
|
|
nFacInd = 0
|
|
else
|
|
nFacInd = 1
|
|
end
|
|
local nOthInd = 1 - nFacInd
|
|
local bOk, sErr, sName
|
|
-- se forzato uso fresa controllo se posso fare in una o più passate
|
|
if Q_USE_MILL and Q_USE_MILL == 1 then
|
|
sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_1'
|
|
bOk, sErr = DoMill( Proc, sName, sMilling, dTDiam / 2, nFacInd, nOthInd, vtN)
|
|
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
bOk, sErr = DoMill( Proc, sName, sMilling, 0, nFacInd, nOthInd, vtN)
|
|
if not bOk then return bOk, sErr end
|
|
-- eventuale segnalazione ingombro di testa o coda
|
|
local dMinHIng = min( 0.5 * BD.VICE_MINH, 0.5 * _b3Raw:getDimZ())
|
|
if Proc.Box:getDimZ() > dMinHIng and Proc.Box:getMin():getZ() < _b3Raw:getMin():getZ() + dMinHIng then
|
|
if Proc.Head then
|
|
local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
BL.UpdateHCING( _nRawId, dOffs)
|
|
elseif Proc.Tail then
|
|
local dOffs = Proc.Box:getMax():getX() - _b3Solid:getMin():getX()
|
|
BL.UpdateTCING( _nRawId, dOffs)
|
|
elseif Proc.Box:getCenter():getX() > _b3Solid:getCenter():getX() then
|
|
local dOffs = _b3Solid:getMax():getX() - Proc.Box:getMin():getX()
|
|
local dDist = _b3Solid:getMax():getX() - Proc.Box:getMax():getX()
|
|
-- sempre concavo aumento la distanza (rimane una punta...)
|
|
dDist = dDist + 10
|
|
BL.UpdateHCING( _nRawId, dOffs, dDist)
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePreCuts( Proc)
|
|
-- se interessa l'intera sezione della trave, necessaria sgrossatura
|
|
if _nChamfer < 2 and Proc.Box:getDimY() > 0.9 * _b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * _b3Raw:getDimZ() then
|
|
-- aggiungo sgrossatura e la lavoro
|
|
local AddId = EgtSurfTmConvexHullInBBox( _nAddGrpId, Proc.Id, _b3Raw, GDB_RT.GLOB)
|
|
if AddId then
|
|
EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id))
|
|
-- applico lavorazione
|
|
local CutProc = { Id = AddId, 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}
|
|
local nCutFacet = EgtSurfTmFacetCount( AddId)
|
|
if nCutFacet == 1 then
|
|
return Cut.Make( CutProc, _nPhase, _nRawId, _nPartId, _dOvmHead)
|
|
elseif nCutFacet == 2 then
|
|
return DoubleCut.Make( CutProc, _nPhase, _nRawId, _nPartId, _dOvmHead)
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMill( Proc, tFData, dCollSic, bSpecialApp, sMillMaster)
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj, sErr = GetFaceAdj( Proc, tFData)
|
|
if nFacAdj < 0 then
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Determino se estremi aperti o chiusi e faccia adiacente da aggiungere alla lavorazione
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
local _, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
-- Riordino le dimensioni per avere dH > dV
|
|
if dH2 < dV2 then
|
|
dH2, dV2 = dV2, dH2
|
|
end
|
|
local nFacAdj2
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == tFData.nFacInd then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == tFData.nFacInd do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == tFData.nFacInd do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
end
|
|
-- decommentare questa parte per concatenare due facce
|
|
--if bSpecialApp and vAdj2[j] >= 0 then
|
|
-- local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacAdj, vAdj2[j], GDB_ID.ROOT)
|
|
-- local dLen = dist( ptP1, ptP2)
|
|
-- if abs( dLen - dV2) < 10 * GEO.EPS_SMALL then
|
|
-- nFacAdj2 = vAdj2[j]
|
|
-- end
|
|
--end
|
|
end
|
|
-- Recupero la lavorazione di fresa
|
|
local sMilling
|
|
if bSpecialApp then
|
|
sMilling = sMillMaster
|
|
else
|
|
sMilling = ML.FindMilling( 'LongSmallCut')
|
|
if not sMilling then
|
|
sErr = 'Error : LongSmallCut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dMaxMat = 0
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dTDiam = TI.dDiam or dTDiam
|
|
dMaxMat = TI.dMaxMat or dMaxMat
|
|
end
|
|
-- Se massimo materiale utensile è molto inferiore dell'elevazione non faccio la lavorazione e do un warning
|
|
if dMaxMat > 0 and dMaxMat + 15 < tFData.dFacElev + dCollSic then
|
|
local sWarn = 'Warning : skipped milling; elevation bigger than max tool depth'
|
|
return true, sWarn, dMaxMat
|
|
end
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ())
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
if nFacAdj2 then
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}, { Proc.Id, nFacAdj2}})
|
|
else
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}})
|
|
end
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_YM
|
|
if tFData.rfFac:getVersZ():getY() > 100 * GEO.EPS_ZERO then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- lato di lavoro e direzione
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- tipo di attacco e uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR)
|
|
-- imposto accorciamento iniziale/finale per estremi aperti/chiusi
|
|
if bSpecialApp then
|
|
-- applico gli allungamenti o accorciamenti considerando che la lavorazione è invertita
|
|
if nFacAdj2 then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, dTDiam / 2, - dTDiam / 2))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, dTDiam / 2, - dTDiam / 2))
|
|
-- confronto la faccia applicata nella lavorazione (faccia adiacente) con la seconda faccia passata nella funzione
|
|
-- se corrispondono allora aggiungo una estensione nei lati chiusi pari all'elevazione della stessa faccia corrispondente
|
|
if nFacAdj == tFData.nFacInd2 then
|
|
if not bOpenStart then
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, tFData.dFacElev2)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
end
|
|
if not bOpenEnd then
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, tFData.dFacElev2)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
end
|
|
end
|
|
end
|
|
-- applico elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenEnd, 0, - dTDiam / 2))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenStart, 0, - dTDiam / 2))
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
_, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
return true, '', dTDiam
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ChooseCorner( Proc, nFacInd)
|
|
-- Recupero le adiacenze della faccia principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
-- Cerco i corner tra le facce adiacenti alla principale
|
|
local tFacAdj = {}
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
for j = i + 1, #vAdj do
|
|
if vAdj[j] >= 0 then
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, vAdj[i], vAdj[j], GDB_ID.ROOT)
|
|
if ptP1 and ptP2 and dAng < 0 then
|
|
local dLen = dist( ptP1, ptP2)
|
|
table.insert( tFacAdj, { vAdj[i], vAdj[j], dLen, ptP1, ptP2, dAng})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Tra le linee dei corner determino la più lunga
|
|
local dMaxLen = 0
|
|
local nIdLine
|
|
for i = 1, #tFacAdj do
|
|
if tFacAdj[i][3] > dMaxLen then
|
|
nIdLine = i
|
|
dMaxLen = tFacAdj[i][3]
|
|
end
|
|
end
|
|
|
|
return dMaxLen, nIdLine, tFacAdj
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ChooseContour( Proc, nFacInd, bVerifyCorner)
|
|
-- Recupero le adiacenze della faccia principale
|
|
local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1]
|
|
-- Se richiesto, verifico che ci siano facce adiacenti consecutive (sicuramente con angolo)
|
|
if bVerifyCorner then
|
|
local bCorner = false
|
|
for i = 1, #vAdj do
|
|
local j = EgtIf( i > 1, i - 1, #vAdj)
|
|
if vAdj[i] >= 0 and vAdj[j] >= 0 then
|
|
bCorner = true
|
|
break
|
|
end
|
|
end
|
|
if not bCorner then return {} end
|
|
end
|
|
-- Cerco le facce adiacenti con angolo convesso
|
|
local tFacAdjMain = {}
|
|
for i = 1, #vAdj do
|
|
if vAdj[i] >= 0 then
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
if ptP1 and ptP2 and dAng < 0 then
|
|
local dLen = dist( ptP1, ptP2)
|
|
table.insert( tFacAdjMain, { vAdj[i], dLen, ptP1, ptP2, dAng})
|
|
end
|
|
end
|
|
end
|
|
|
|
return tFacAdjMain
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function CheckToInvert( AuxId, bPositive)
|
|
-- recupero versore estrusione
|
|
local vtExtr = EgtCurveExtrusion( AuxId, GDB_ID.ROOT)
|
|
-- faccio una copia del percorso
|
|
local sParnt = EgtGetParent( AuxId)
|
|
local nNewEntId = EgtCopyGlob( AuxId, sParnt)
|
|
-- chiudo il percorso
|
|
if EgtCloseCurveCompo( nNewEntId) then
|
|
local vtMPlane, dDist, dArea = EgtCurveArea( nNewEntId)
|
|
-- cancello percorso copia
|
|
EgtErase( nNewEntId)
|
|
if dArea and abs(dArea) > 1 then
|
|
local frEnt = EgtGetGlobFrame( AuxId)
|
|
if vtMPlane then
|
|
vtMPlane:toGlob(frEnt)
|
|
if dArea and dArea * ( vtMPlane * vtExtr) < 0 then
|
|
if bPositive then
|
|
return true
|
|
end
|
|
elseif dArea and dArea * ( vtMPlane * vtExtr) > 0 then
|
|
if not bPositive then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else
|
|
-- cancello percorso copia
|
|
EgtErase(nNewEntId)
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestPoints( nPathInt, idx, dDiff, pP1, pP2, sAxis)
|
|
local pPini = EgtIf( sAxis == 'X', pP1:getX(), EgtIf( sAxis == 'Y', pP1:getY(), pP1:getZ()))
|
|
local pPend = EgtIf( sAxis == 'X', pP2:getX(), EgtIf( sAxis == 'Y', pP2:getY(), pP2:getZ()))
|
|
local b3SolidMin = EgtIf( sAxis == 'X', _b3Solid:getMin():getX(), EgtIf( sAxis == 'Y', _b3Solid:getMin():getY(), _b3Solid:getMin():getZ()))
|
|
local b3SolidMax = EgtIf( sAxis == 'X', _b3Solid:getMax():getX(), EgtIf( sAxis == 'Y', _b3Solid:getMax():getY(), _b3Solid:getMax():getZ()))
|
|
if ( abs( pPini - b3SolidMax) < dDiff and abs( pPend - b3SolidMax) < dDiff) or
|
|
( abs( pPini - b3SolidMin) < dDiff and abs( pPend - b3SolidMin) < dDiff) then
|
|
-- setto l'entità open
|
|
local sActInfo = EgtGetInfo( nPathInt, 'OPEN', 's') or ''
|
|
if #sActInfo > 0 then
|
|
EgtSetInfo( nPathInt, 'OPEN', sActInfo .. ',' .. idx)
|
|
else
|
|
EgtSetInfo( nPathInt, 'OPEN', idx)
|
|
end
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function SetOpenSide( nPathInt, vtOrtho, nStartPoint)
|
|
-- fondo tra loro le curve compatibili
|
|
EgtMergeCurvesInCurveCompo( nPathInt)
|
|
local nStartIdEnt, nNumEnt = EgtCurveDomain( nPathInt)
|
|
local pLastPIni, pLastPEnd
|
|
|
|
-- faccio una copia della curva e la esplodo
|
|
if nStartIdEnt then
|
|
-- prendo i punti
|
|
for i = 1, nNumEnt do
|
|
local pPini = EgtUP( nPathInt, (i - 1), GDB_RT.GLOB)
|
|
local pPend = EgtUP( nPathInt, EgtIf( i == nNumEnt, 0, i), GDB_RT.GLOB)
|
|
-- Se normale lungo la Z considero il box in X e Y
|
|
if abs( vtOrtho:getZ()) > 0.999 then
|
|
-- se corrisponde a X prendo i punti per eventuale modifica del punto di inizio percorso
|
|
if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'X') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
-- altrimenti se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso
|
|
elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
end
|
|
-- altrimenti se normale lungo la Y considero il box in X e Z
|
|
elseif abs( vtOrtho:getZ()) < 0.001 and abs( vtOrtho:getY()) > 0.999 then
|
|
-- se corrisponde a X prendo i punti per eventuale modifica del punto di inizio percorso
|
|
if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'X') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
-- altrimenti se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso
|
|
elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
end
|
|
-- caso che non dovrebbe mai capitare ma gestito per completezza
|
|
-- altrimenti se normale lungo la X considero il box in Y e Z
|
|
elseif abs( vtOrtho:getZ()) < 0.001 and abs( vtOrtho:getX()) > 0.999 then
|
|
-- se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso
|
|
if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
-- altrimenti se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso
|
|
elseif TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
end
|
|
-- se asse Z orizzontale verifico se si avvicina piú a Y
|
|
elseif abs( vtOrtho:getZ()) < 0.001 then
|
|
if abs( vtOrtho:getY()) > 0.75 then
|
|
-- se corrisponde a Z prendo i punti per eventuale modifica del punto di inizio percorso
|
|
if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Z') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
end
|
|
end
|
|
-- se asse Y a 0 (fresa ne davanti ne dietro) verifico se si avvicina piú a Z+
|
|
elseif abs( vtOrtho:getY()) < 0.001 then
|
|
if abs( vtOrtho:getZ()) > 0.75 then
|
|
-- se corrisponde a Y prendo i punti per eventuale modifica del punto di inizio percorso
|
|
if TestPoints( nPathInt, i - 1, 10 * GEO.EPS_SMALL, pPini, pPend, 'Y') then
|
|
pLastPIni = pPini
|
|
pLastPEnd = pPend
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- se devo cambiare il punto di partenza
|
|
if nStartPoint then
|
|
if pLastPIni and pLastPEnd then
|
|
-- calcolo il punto medio con gli ultimi punti utilizzati
|
|
local ptPs = ( pLastPIni + pLastPEnd) / 2
|
|
EgtChangeClosedCurveStartPoint( nPathInt, ptPs, GDB_RT.GLOB)
|
|
-- se devo eliminare la parte open
|
|
if nStartPoint == 2 then
|
|
EgtRemoveCurveCompoCurve( nPathInt, true)
|
|
EgtRemoveCurveCompoCurve( nPathInt, false)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DoClean( sName, sMilling, nIdPath, vtN, dMaxElev, dMachDepth, dExtraDepth, dNoLeadsAddLen, dLeadInPerp,
|
|
bLeftWorkside, bInvertTool, bInvertDir, bCheckToInvertPath, bSCCEvaluateOppositeVector, bEvaluateAddLeads)
|
|
local nMchId = EgtAddMachining( sName, sMilling)
|
|
local sMyWarn
|
|
if not nMchId then
|
|
sMyWarn = 'Warning : impossible add machining ' .. sName .. '-' .. sMilling
|
|
return false, sMyWarn
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nIdPath, -1}})
|
|
-- imposto lato di lavoro sinistro
|
|
if bLeftWorkside then
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
end
|
|
-- imposto direzione utensile opposta
|
|
if bInvertTool then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if EgtIf( bSCCEvaluateOppositeVector, AreSameOrOppositeVectorApprox( vtN, Z_AX()), AreSameVectorApprox( vtN, Z_AX())) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertDir, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertDir, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- gestione attacco e uscita
|
|
if bEvaluateAddLeads and EgtCurveIsClosed( nIdPath) then
|
|
-- attacco e uscita a quarto di cerchio senza allungamenti a inizio e fine
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.TANGENT)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dLeadInPerp)
|
|
EgtSetMachiningParam( MCH_MP.LIELEV, 0)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
|
|
else
|
|
-- nessun attacco e uscita, allungo inizio e fine di 3/4 del diametro utensile
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.NONE)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI)
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dNoLeadsAddLen)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dNoLeadsAddLen)
|
|
end
|
|
-- setto massimo affondamento possibile
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth + dExtraDepth)
|
|
-- setto se devo invertire il percorso
|
|
if bCheckToInvertPath then
|
|
local bInvert = CheckToInvert( nIdPath, true)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertDir, not bInvert, bInvert))
|
|
end
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione
|
|
local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if ML.ApplyMachining( true, false) then
|
|
_, sMyWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
-- altrimenti lavorazione non applicata
|
|
else
|
|
_, sMyWarn = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sMyWarn
|
|
end
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeRoundCleanCorner( Proc, nFacInd, dDiam, bMillDown, bDoubleSide)
|
|
-- recupero la lavorazione senza considerare l'elevazione
|
|
local sMilling = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide)
|
|
if not sMilling then
|
|
local sMyWarn = 'Warning : SmallToolContour not found in library'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dTMaxDepth = 0
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dTDiam = TI.dDiam or dTDiam
|
|
dTMaxDepth = TI.dMaxDepth or dTMaxDepth
|
|
end
|
|
|
|
-- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco
|
|
if dTDiam > ( 0.75 * dDiam) then
|
|
local sMyWarn = 'Warning : tool diameter not enough small'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- ottengo gli angoli dove applicare il percorso con fresa più piccola
|
|
local _, _, tFacAdj = ChooseCorner( Proc, nFacInd)
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdj == 0 then
|
|
return true
|
|
end
|
|
|
|
-- recupero la normale della faccia di fondo
|
|
local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then
|
|
local sErr = 'Error : milling from bottom '
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- ciclo su tutti gli angoli trovati
|
|
local sMyWarn = ''
|
|
for i = 1, #tFacAdj do
|
|
local pAuxId = {}
|
|
-- le 2 facce di contatto devono essere perpendicolari e non sottosquadra rispetto alla faccia di fondo
|
|
local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][1], GDB_ID.ROOT)
|
|
local _, ptP1x, ptP2x, dAngx = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[i][2], GDB_ID.ROOT)
|
|
if dAng >= 0 or dAng < -90 - 10 * GEO.EPS_SMALL or dAngx >= 0 or dAngx < -90 - 10 * GEO.EPS_SMALL then
|
|
goto continue
|
|
end
|
|
-- prendo la lunghezza di adiacenza delle due linee
|
|
local dLen1 = dist( ptP1, ptP2)
|
|
local dLen2 = dist( ptP1x, ptP2x)
|
|
-- cerco il punto tra le 3 facce: nIdEndPoint
|
|
local _, nIdEndPoint = GetIdIniEndPoints( ptP1, ptP2, tFacAdj[i])
|
|
-- devo avere un punto comune
|
|
if not nIdEndPoint then
|
|
goto continue
|
|
end
|
|
-- calcolo lunghezza minima in base all'angolo tra le due pareti
|
|
local dMinDist = ( ( dDiam / 2) / tan( ( 180 + tFacAdj[i][6]) / 2)) + 2
|
|
-- verifico che entrambe le linee siano maggiori delle lunghezza minima
|
|
if dLen1 <= dMinDist or dLen2 <= dMinDist then
|
|
sMyWarn = 'Warning : impossible make clean corner path'
|
|
goto continue
|
|
end
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
local ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1) < 10 * GEO.EPS_SMALL, ptP2, ptP1)
|
|
-- prima linea
|
|
local nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[i][nIdEndPoint], GDB_RT.GLOB)
|
|
-- calcolo arretramento
|
|
local dTrimDist = dLen1 - dMinDist
|
|
-- se arretramento valido
|
|
if dTrimDist > 100 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint, GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- se il punto finale corrisponde con il punto comune, uso l'altro
|
|
ptApPoint = EgtIf( dist( tFacAdj[i][nIdEndPoint], ptP1x) < 10 * GEO.EPS_SMALL, ptP2x, ptP1x)
|
|
-- seconda linea
|
|
nAuxId = EgtLine( _nAddGrpId, tFacAdj[i][nIdEndPoint], ptApPoint, GDB_RT.GLOB)
|
|
-- calcolo arretramento
|
|
dTrimDist = dLen2 - dMinDist
|
|
-- se arretramento valido
|
|
if dTrimDist > 100 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId , -dTrimDist, ptApPoint, GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- trasformo in percorso
|
|
local AuxId
|
|
if #pAuxId > 0 then
|
|
AuxId = EgtCurveCompo( _nAddGrpId, pAuxId, true)
|
|
end
|
|
-- deve esserci il percorso
|
|
if not AuxId then
|
|
sMyWarn = 'Warning : impossible make clean corner path'
|
|
goto continue
|
|
end
|
|
-- modifico versore direzione
|
|
EgtModifyCurveExtrusion( AuxId, vtN1, GDB_RT.GLOB)
|
|
-- inserisco la lavorazione
|
|
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local dDepth = 0
|
|
if tFacAdj[i][3] > dTMaxDepth then
|
|
dDepth = dTMaxDepth - tFacAdj[i][3]
|
|
end
|
|
_, sMyWarn = DoClean( sName, sMilling, AuxId, vtN1, tFacAdj[i][3], dDepth, 0, 0, 0, true, false, false, true, true, false)
|
|
::continue::
|
|
end
|
|
if #sMyWarn > 0 then
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeRoundCleanContour( Proc, nFacInd, dDiam, bMillDown,
|
|
bDoubleSide, vtOrtho, nPathInt, nSurfInt,
|
|
dDepth, bOneShot)
|
|
|
|
-- recupero la lavorazione senza considerare l'elevazione perché viene calcolata l'elevazione utile
|
|
local sMilling = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide)
|
|
if not sMilling then
|
|
local sMyWarn = 'Warning : SmallToolContour not found in library'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dTMaxDepth = 0
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dTDiam = TI.dDiam or dTDiam
|
|
dTMaxDepth = TI.dMaxDepth or dTMaxDepth
|
|
end
|
|
|
|
local sMillingDn = ML.FindMilling( 'SmallToolContour', nil, nil, nil, nil, not ( bMillDown and bDoubleSide), bMillDown and bDoubleSide)
|
|
if not sMillingDn then
|
|
local sMyWarn = 'Warning : Opposite SmallToolContour not found in library'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
-- recupero i dati dell'utensile testa da sotto
|
|
local dTDiamDn = 50
|
|
local dTMaxDepthDn = 0
|
|
local TI = GetToolInfoForMachining( sMillingDn)
|
|
if TI then
|
|
dTDiamDn = TI.dDiam or dTDiamDn
|
|
dTMaxDepthDn = TI.dMaxDepth or dTMaxDepthDn
|
|
end
|
|
|
|
-- se il diametro trovato non è minore dei 3/4 del diametro utilizzato in precedenza, esco
|
|
if dTDiam > ( 0.75 * dDiam) then
|
|
local sMyWarn = 'Warning : tool diameter not enough small'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
local vtN1
|
|
local nFirstId, nNumId
|
|
local dMaxElev
|
|
local dCollSic = 0
|
|
local dExtraDepth = 0
|
|
|
|
-- se non ho la faccia aggiunta
|
|
if not nPathInt then
|
|
-- cerco gli angoli dove applicare il percorso con fresa piú piccola e i lati in comune
|
|
local tFacAdjMain = ChooseContour( Proc, nFacInd, true)
|
|
-- se non trovato nessun angolo interno da pulire esco
|
|
if #tFacAdjMain == 0 then
|
|
return true
|
|
end
|
|
-- normale alla faccia di fondo
|
|
vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then
|
|
local sErr = 'Error : milling from bottom'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- distanza di sicurezza per evitare collisioni
|
|
dCollSic = CalcCollisionSafety( vtN1)
|
|
-- elevazione massima della faccia
|
|
dMaxElev = BL.GetFaceElevation( Proc.Id, nFacInd, _nPartId)
|
|
-- ciclo tutta la tabella
|
|
local tPaths = {}
|
|
local ptIniPath
|
|
local ptMidDist
|
|
local dMaxLen = 0
|
|
for i = 1, #tFacAdjMain do
|
|
-- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo
|
|
local ptP1, ptP2, dAng
|
|
ptP1 = tFacAdjMain[i][3]
|
|
ptP2 = tFacAdjMain[i][4]
|
|
dAng = tFacAdjMain[i][5]
|
|
if ( dAng < 0 and dAng >= -90 - 10 * GEO.EPS_SMALL) then
|
|
-- creo la linea da P1 a P2
|
|
local nAuxId = EgtLine( _nAddGrpId, ptP1, ptP2, GDB_RT.GLOB)
|
|
table.insert( tPaths, nAuxId)
|
|
-- prendo la lunghezza massima e il punto medio
|
|
if tFacAdjMain[i][2] > dMaxLen then
|
|
ptIniPath = ptP1
|
|
dMaxLen = tFacAdjMain[i][2]
|
|
ptMidDist = ( ptP1 + ptP2) / 2
|
|
end
|
|
end
|
|
end
|
|
-- costruisco il/i percorso/i
|
|
nFirstId, nNumId = EgtCurveCompoByReorder( _nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB)
|
|
if nFirstId then
|
|
-- se un solo percorso e chiuso cambio il punto di inizio nell'entitá piú lunga
|
|
if nNumId == 1 and EgtCurveIsClosed( nFirstId) then
|
|
EgtChangeClosedCurveStartPoint( nFirstId, ptMidDist, GDB_RT.GLOB)
|
|
end
|
|
-- modifico versore direzione
|
|
for i = 1, nNumId do
|
|
EgtModifyCurveExtrusion( nFirstId + i - 1, vtN1, GDB_RT.GLOB)
|
|
end
|
|
end
|
|
-- alrimenti ho la faccia aggiunta
|
|
else
|
|
-- assegno il percorso
|
|
nFirstId = EgtCopyGlob( nPathInt, _nAddGrpId)
|
|
nNumId = 1
|
|
-- distanza di sicurezza per evitare collisioni
|
|
dCollSic = CalcCollisionSafety( vtOrtho)
|
|
-- calcolo elevazione dalla faccia trasversale aggiunta
|
|
local dSurfIntElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
if bDoubleSide then
|
|
dMaxElev = dSurfIntElev
|
|
else
|
|
dMaxElev = dDepth
|
|
-- se la precedente svuotatura è stata fatta completamente in una sola volta
|
|
-- valuto di nuovo se devo fare due passate o una sola
|
|
if bOneShot then
|
|
-- se non è possibile svuotare completamente da una sola parte
|
|
if dTMaxDepth <= ( dMaxElev + BD.CUT_EXTRA + dCollSic) then
|
|
bDoubleSide = true
|
|
dMaxElev = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
else
|
|
dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
-- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie
|
|
else
|
|
dExtraDepth = dMaxElev - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
end
|
|
-- normale alla faccia aggiunta
|
|
vtN1 = Vector3d( vtOrtho)
|
|
-- imposto i lati aperti
|
|
SetOpenSide( nFirstId, vtOrtho, 2)
|
|
end
|
|
|
|
-- se non trovato il percorso, esco
|
|
if not nFirstId then
|
|
local sMyWarn = 'Warning : impossible make clean corner path'
|
|
EgtOutLog( sMyWarn)
|
|
return true, sMyWarn
|
|
end
|
|
|
|
-- assegno lavorazioni ad ogni percorso
|
|
local sMyWarn = ''
|
|
local bOk
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local bInvertMach
|
|
if nPathInt then
|
|
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
|
|
if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then
|
|
bInvertMach = true
|
|
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
|
|
elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then
|
|
bInvertMach = true
|
|
end
|
|
end
|
|
local dMachDepth = 0
|
|
if ( dMaxElev + dCollSic) > dTMaxDepth then
|
|
dMachDepth = dTMaxDepth - ( dMaxElev + dCollSic)
|
|
end
|
|
bOk, sMyWarn = DoClean( sName, sMilling, nIdPath, vtN1, dMaxElev, dMachDepth, dExtraDepth, 0.75 * dTDiam, 0.5 * dTDiam, true, bInvertMach, bInvertMach, true, true, true)
|
|
-- se devo applicare la contornatura anche sul lato opposto
|
|
if bOk and bDoubleSide then
|
|
if bMillDown then
|
|
sMilling = sMillingDn
|
|
dTDiam = dTDiamDn
|
|
dTMaxDepth = dTMaxDepthDn
|
|
end
|
|
sName = 'CleanOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
bOk, sMyWarn = DoClean( sName, sMilling, nIdPath, vtN1, dMaxElev, dMachDepth, 0, 0.75 * dTDiam, 0, true, true, true, true, false, false)
|
|
end
|
|
end
|
|
if #sMyWarn > 0 then
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeRoundCleanCornerOrContour( Proc, nFacInd, dDiam, bMillDown, bDoubleSide,
|
|
vtOrtho, nPathInt, nSurfInt, dDepth, bOneShot)
|
|
local nFunction = Q_CONTOUR_SMALL_TOOL
|
|
-- se modalitá pulitura spigoli e lavorazione di lato forzo a fare il contorno
|
|
if nFunction == 2 and nPathInt then
|
|
nFunction = 1
|
|
end
|
|
-- se richiesta pulitura del contorno
|
|
if nFunction == 1 then
|
|
return MakeRoundCleanContour( Proc, nFacInd, dDiam, bMillDown, bDoubleSide,
|
|
vtOrtho, nPathInt, nSurfInt, dDepth, bOneShot)
|
|
-- se richiesta pulitura dei soli corner
|
|
elseif nFunction == 2 then
|
|
return MakeRoundCleanCorner( Proc, nFacInd, dDiam, bMillDown, bDoubleSide)
|
|
-- altri casi non previsti
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeSharpCleanCorner( Proc, nFacInd, dDiam)
|
|
local sMyWarn = ''
|
|
local pAuxId = {}
|
|
local nAuxId
|
|
local AuxId
|
|
local ptApPoint
|
|
local dLenTrimExt
|
|
local sMilling
|
|
local dMaxDepth = 0
|
|
|
|
-- cerco l'angolo di riferimento dove applicare il percorso di pulitura, altrimenti esco
|
|
local _, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd)
|
|
if #tFacAdj == 0 then
|
|
return true
|
|
end
|
|
-- prendo i versori
|
|
local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local vtN3 = EgtSurfTmFacetNormVersor( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT)
|
|
-- trovo il punto sulla superfice di riferimento
|
|
local _, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local nIdIniPoint, nIdEndPoint = GetIdIniEndPoints( ptLocP1, ptLocP2, tFacAdj[nIdLine])
|
|
-- versore direzione
|
|
local vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint]
|
|
vtExtr:normalize()
|
|
-- inserisco le prime tre linee
|
|
if nIdIniPoint and nIdEndPoint then
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtExtr:getZ() < BD.DRILL_VZ_MIN then
|
|
local sErr = 'Error : clean corner milling from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- sommo i tre versori per avre una direzione media
|
|
vtExtr = vtN1 + vtN2 + vtN3
|
|
vtExtr:normalize()
|
|
-- recupero la lavorazione non calcolando l'elevazione
|
|
sMilling = ML.FindMilling( 'CleanCorner', ( 0.5 * dDiam))
|
|
if not sMilling then
|
|
local sErr = 'Error : CleanCorner not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile (temporaneo, per compensare errore nella lavorazione)
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dMaxDepth = TI.dMaxMat or dMaxDepth
|
|
end
|
|
-- l'altezza di taglio del tagliente corrisponde al raggio del raccordo che si riesce a coprire
|
|
-- quindi confronto l'elevazione con il raggio utensile utilizzato per la svuotatura
|
|
if dMaxDepth < ( dDiam * 0.5) - 100 * GEO.EPS_SMALL then
|
|
sMyWarn = 'Warning : skip clean corner (the cut heigth is too small to machine the corner radius)'
|
|
EgtOutLog( sMyWarn)
|
|
return false, sMyWarn
|
|
end
|
|
nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdIniPoint], tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB)
|
|
dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - ( ( dDiam / 2) + 2)
|
|
-- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta
|
|
if dLenTrimExt > 10 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId, -dLenTrimExt, ptApPoint, GDB_RT.GLOB)
|
|
-- prendo il nuovo punto finale
|
|
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- creo linea di ritorno
|
|
nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
-- inserisco le ultime tre linee + uscita discostata rispetto all'ingresso
|
|
-- trovo il secondo punto sulla superfice di riferimento
|
|
_, ptLocP1, ptLocP2 = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][2], GDB_ID.ROOT)
|
|
if ptLocP1 and ptLocP2 then
|
|
-- se il punto finale corrisponde con il punto utilizzato in precedenza, uso l'altro
|
|
if dist( tFacAdj[nIdLine][nIdEndPoint], ptLocP1) < 10 * GEO.EPS_SMALL then
|
|
ptApPoint = ptLocP2
|
|
else
|
|
ptApPoint = ptLocP1
|
|
end
|
|
nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], ptApPoint, GDB_RT.GLOB)
|
|
dLenTrimExt = dist( tFacAdj[nIdLine][nIdEndPoint], ptApPoint) - ( ( dDiam / 2) + 2)
|
|
-- se la distanza dei due punti della linea è maggiore dal raggio fresa + delta, trimmo al raggio fresa + delta
|
|
if dLenTrimExt > 10 * GEO.EPS_SMALL then
|
|
EgtTrimExtendCurveByLen( nAuxId, -dLenTrimExt, ptApPoint, GDB_RT.GLOB)
|
|
-- prendo il nuovo punto finale
|
|
ptApPoint = EgtEP( nAuxId, GDB_RT.GLOB)
|
|
end
|
|
table.insert( pAuxId, nAuxId)
|
|
-- creo linea di ritorno
|
|
nAuxId = EgtLine( _nAddGrpId, ptApPoint, tFacAdj[nIdLine][nIdEndPoint], GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- piccolo scostamento di 2mm dall'angolo
|
|
nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint], tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
-- ultima linea di risalita
|
|
nAuxId = EgtLine( _nAddGrpId, tFacAdj[nIdLine][nIdEndPoint] + ( 2 * vtExtr), tFacAdj[nIdLine][nIdIniPoint] + ( 2 * vtExtr), GDB_RT.GLOB)
|
|
table.insert( pAuxId, nAuxId)
|
|
end
|
|
-- trasformo in percorso
|
|
if #pAuxId > 0 then
|
|
AuxId = EgtCurveCompo( _nAddGrpId, pAuxId, true)
|
|
end
|
|
-- se non c'é il percorso do errore
|
|
if not AuxId then
|
|
local sErr = 'Error : impossible make clean corner path'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- modifico versore direzione
|
|
EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB)
|
|
-- inserisco la lavorazione
|
|
local sName = 'Clean_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local bOk
|
|
bOk, sMyWarn = DoClean( sName, sMilling, AuxId, vtN1, dMaxDepth, 0, 0, 10, 0, false, false, true, false, false, false)
|
|
if not bOk then
|
|
return false, sMyWarn
|
|
end
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeDrillOnCorner( Proc, nFacInd, dDiam, bSpecialMach)
|
|
local sMyWarn = ''
|
|
-- ottengo l'angolo dove applicare il foro
|
|
local dMaxLen, nIdLine, tFacAdj = ChooseCorner( Proc, nFacInd)
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdj == 0 then
|
|
return true, sMyWarn
|
|
end
|
|
-- trovo il punto sulla superfice di riferimento
|
|
local _, ptLocP1, ptLocP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local nIdIniPoint, nIdEndPoint = GetIdIniEndPoints(ptLocP1, ptLocP2, tFacAdj[nIdLine])
|
|
-- inserisco foro
|
|
if nIdIniPoint and nIdEndPoint then
|
|
local vtExtr
|
|
if bSpecialMach then
|
|
local _, vtN0 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
local _, vtN1 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][1], GDB_ID.ROOT)
|
|
local _, vtN2 = EgtSurfTmFacetCenter( Proc.Id, tFacAdj[nIdLine][2], GDB_ID.ROOT)
|
|
vtExtr = vtN0 + vtN1 + vtN2
|
|
else
|
|
-- versore direzione
|
|
vtExtr = tFacAdj[nIdLine][nIdIniPoint] - tFacAdj[nIdLine][nIdEndPoint]
|
|
end
|
|
vtExtr:normalize()
|
|
-- se foratura da sotto salto la lavorazione
|
|
if vtExtr:getZ() < BD.DRILL_VZ_MIN then
|
|
local sErr = 'Error : drilling from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero la lavorazione
|
|
local sDrilling, nType = ML.FindDrilling( dDiam)
|
|
if not sDrilling then
|
|
local sErr = 'Error : drilling not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dMaxDepth = 20
|
|
local dDiamTool = 20
|
|
local dDiamTh = 35
|
|
local bIsDrilling
|
|
local TI = GetToolInfoForMachining( sDrilling)
|
|
if TI then
|
|
bIsDrilling = ( EgtMdbGetCurrMachiningParam( MCH_MP.TYPE) == MCH_MY.DRILLING)
|
|
if bIsDrilling then
|
|
dMaxDepth = TI.dMaxMat or dMaxDepth
|
|
else
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
end
|
|
dDiamTool = TI.dDiam or dDiamTool
|
|
dDiamTh = TI.dThDiam or dDiamTh
|
|
end
|
|
-- se foro inclinato, limito il massimo affondamento
|
|
local CosB = abs( vtExtr:getX())
|
|
if CosB < BD.DRILL_VX_MAX then
|
|
local TgA = CosB / sqrt( 1 - CosB * CosB)
|
|
dMaxDepth = dMaxDepth - dDiamTh / 2 * TgA
|
|
else
|
|
dMaxDepth = 0
|
|
end
|
|
-- setto griglia
|
|
if bSpecialMach then
|
|
EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdEndPoint], vtExtr))
|
|
else
|
|
EgtSetGridFrame( Frame3d( tFacAdj[nIdLine][nIdIniPoint], vtExtr))
|
|
end
|
|
-- creo geometria
|
|
local AuxId = EgtCircle( _nAddGrpId, {0, 0, 0}, EgtIf( bIsDrilling, dDiamTool / 2, ( dDiamTool / 2) + 0.1), GDB_RT.GRID)
|
|
-- riporto la griglia a globale
|
|
EgtSetGridFrame()
|
|
-- calcolo spessore
|
|
local dDepthBore = dMaxLen
|
|
if bSpecialMach then
|
|
-- calcolo l'elevazione
|
|
local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, tFacAdj[nIdLine][nIdEndPoint], vtExtr)
|
|
if dLenIn > 0 then
|
|
dDepthBore = dLenIn
|
|
elseif dLedOut then
|
|
dDepthBore = dLedOut
|
|
end
|
|
EgtModifyCurveThickness( AuxId, dDepthBore)
|
|
else
|
|
EgtModifyCurveThickness( AuxId, -dMaxLen)
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'Drill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchId = EgtAddMachining( sName, sDrilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.ADIR_YM
|
|
if vtExtr:getY() > 100 * GEO.EPS_ZERO then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- aggiusto l'affondamento
|
|
local dDepth
|
|
if bSpecialMach then
|
|
dDepth = dDepthBore
|
|
else
|
|
dDepth = dMaxLen
|
|
if dDepth > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
sMyWarn = 'Warning in drill : depth (' .. EgtNumToString( dDepth, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
|
|
dDepth = dMaxDepth
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione (coincide con affondamento)
|
|
local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( dDepth, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
else
|
|
local _, sWarn = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sWarn
|
|
else
|
|
return true, ( sMyWarn or sWarn)
|
|
end
|
|
end
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ErasePathIfNecessary( nPathId, sDeleteByDir, dDiff)
|
|
local ptP1 = EgtSP( nPathId, GDB_RT.GLOB)
|
|
local ptP2 = EgtEP( nPathId, GDB_RT.GLOB)
|
|
if abs( EgtIf( sDeleteByDir == 'X', ( ptP1:getX() - ptP2:getX()), EgtIf( sDeleteByDir == 'Y', ( ptP1:getY() - ptP2:getY()), ( ptP1:getZ() - ptP2:getZ())))) > dDiff then
|
|
EgtErase( nPathId)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestPaths( sDeleteByDir, nStartId, nNumIds, dDiff)
|
|
local tPaths = {}
|
|
local dMaxVal, dMinVal
|
|
for i = 1, nNumIds do
|
|
local bInsTab
|
|
local nIdx = nStartId + i - 1
|
|
local ptP1 = EgtSP( nIdx, GDB_RT.GLOB)
|
|
if ptP1 then
|
|
for j = 1, #tPaths do
|
|
local dLocalVal = tPaths[j][2]
|
|
if abs( EgtIf( sDeleteByDir == 'X', ptP1:getX() - dLocalVal, EgtIf( sDeleteByDir == 'Y', ptP1:getY() - dLocalVal, ptP1:getZ() - dLocalVal))) < dDiff then
|
|
local tLocIds = tPaths[j][1]
|
|
table.insert( tLocIds, ( nIdx))
|
|
tPaths[j][1] = tLocIds
|
|
bInsTab = true
|
|
end
|
|
end
|
|
-- se non ho trovato da inserirlo aggiungo nuovo elemento in tabella
|
|
if not bInsTab then
|
|
table.insert( tPaths, {{ nIdx}, ptP1:getX()})
|
|
dMaxVal = EgtIf( sDeleteByDir == 'X', _b3Solid:getMax():getX(), EgtIf( sDeleteByDir == 'Y', _b3Solid:getMax():getY(), _b3Solid:getMax():getZ()))
|
|
dMinVal = EgtIf( sDeleteByDir == 'X', _b3Solid:getMin():getX(), EgtIf( sDeleteByDir == 'Y', _b3Solid:getMin():getY(), _b3Solid:getMin():getZ()))
|
|
end
|
|
end
|
|
end
|
|
|
|
return tPaths, dMaxVal, dMinVal
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ModifyPathExtrusion(tPath, sDeleteByDir, dMaxVal, dDiff)
|
|
local ptP1 = EgtSP( tPath, GDB_RT.GLOB)
|
|
if abs( EgtIf( sDeleteByDir == 'X', ptP1:getX(), EgtIf( sDeleteByDir == 'Y', ptP1:getY(), ptP1:getZ())) - dMaxVal) < dDiff then
|
|
EgtModifyCurveExtrusion( tPath, EgtIf( sDeleteByDir == 'X', X_AX(), EgtIf( sDeleteByDir == 'Y', Y_AX(), Z_AX())), GDB_RT.GLOB)
|
|
else
|
|
EgtModifyCurveExtrusion( tPath, EgtIf( sDeleteByDir == 'X', -X_AX(), EgtIf( sDeleteByDir == 'Y', -Y_AX(), -Z_AX())), GDB_RT.GLOB)
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ExtractExternalPaths( nPathInt, nNumIdAux, vtOrtho)
|
|
if nNumIdAux == 1 then
|
|
-- fondo tra loro le curve compatibili
|
|
EgtMergeCurvesInCurveCompo( nPathInt)
|
|
-- esplodo il percorso in modo da avere entià separate per poterle controllare
|
|
local nStartId, nNumIds = EgtExplodeCurveCompo( nPathInt)
|
|
if nStartId then
|
|
local sDeleteByDir
|
|
-- Se normale lungo la Z elimino le entità che hanno differenza in Z
|
|
if abs(vtOrtho:getZ()) > 0.7 then
|
|
sDeleteByDir = 'Z'
|
|
-- altrimenti se normale lungo la Y elimino le entità che hanno variazione in Y
|
|
-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getY()) > 0.7 then
|
|
elseif abs(vtOrtho:getY()) > 0.7 then
|
|
sDeleteByDir = 'Y'
|
|
-- caso che non dovrebbe mai capitare ma gestito per completezza
|
|
-- altrimenti se normale lungo la X elimino le entità che hanno variazione in X
|
|
-- elseif abs(vtOrtho:getZ()) < 0.001 and abs(vtOrtho:getX()) > 0.7 then
|
|
elseif abs(vtOrtho:getX()) > 0.7 then
|
|
sDeleteByDir = 'X'
|
|
end
|
|
if sDeleteByDir then
|
|
for i = 1, nNumIds do
|
|
ErasePathIfNecessary( nStartId + i - 1, sDeleteByDir, 10 * GEO.EPS_SMALL)
|
|
end
|
|
-- ricreo i vari percorsi
|
|
local tPaths, dMaxVal, dMinVal = TestPaths( sDeleteByDir, nStartId, nNumIds, 10 * GEO.EPS_SMALL)
|
|
|
|
if tPaths then
|
|
local tChamPath = {}
|
|
-- elimino quelle che non corrispondono agli estremi
|
|
for i = 1, #tPaths do
|
|
-- se non corrisponde ai limiti elimino l'elemento
|
|
if abs( tPaths[i][2] - dMaxVal) > 10 * GEO.EPS_SMALL and abs( tPaths[i][2] - dMinVal) > 10 * GEO.EPS_SMALL then
|
|
tPaths[i] = nil
|
|
else
|
|
local tNoMatch = {}
|
|
local tPathLoc = tPaths[i][1]
|
|
local pIniLoc = EgtSP( tPathLoc[1], GDB_RT.GLOB)
|
|
local pEndLoc = EgtEP( tPathLoc[1], GDB_RT.GLOB)
|
|
-- ciclo sui percorsi per trovare i punti non coincidenti (se percorso non chiuso)
|
|
for j = 2, #tPathLoc do
|
|
-- prendo i punti del percorso successivo
|
|
local pAddIni = EgtSP( tPathLoc[j], GDB_RT.GLOB)
|
|
local pAddEnd = EgtEP( tPathLoc[j], GDB_RT.GLOB)
|
|
-- se consecutivi
|
|
if AreSamePointApprox( pEndLoc, pAddIni) then
|
|
pEndLoc = pAddEnd
|
|
elseif AreSamePointApprox( pIniLoc, pAddEnd) then
|
|
pIniLoc = pAddIni
|
|
else
|
|
table.insert( tNoMatch, tPathLoc[j])
|
|
end
|
|
end
|
|
-- controllo eventuali percorsi scartati
|
|
for j = 1, #tNoMatch do
|
|
-- prendo i punti del percorso successivo
|
|
local pAddIni = EgtSP( tNoMatch[j], GDB_RT.GLOB)
|
|
local pAddEnd = EgtEP( tNoMatch[j], GDB_RT.GLOB)
|
|
-- se consecutivi
|
|
if AreSamePointApprox( pEndLoc, pAddIni) then
|
|
pEndLoc = pAddEnd
|
|
elseif AreSamePointApprox( pIniLoc, pAddEnd) then
|
|
pIniLoc = pAddIni
|
|
end
|
|
end
|
|
-- creo concatenamento partendo dal punto iniziale
|
|
local nIdLoc = EgtCurveCompoByReorder( _nAddGrpId, tPathLoc, pIniLoc, true)
|
|
if nIdLoc then
|
|
table.insert( tChamPath, nIdLoc)
|
|
end
|
|
end
|
|
end
|
|
for i = 1, #tChamPath do
|
|
-- modifico estrusione percorso
|
|
ModifyPathExtrusion( tChamPath[i], sDeleteByDir, dMaxVal, 10 * GEO.EPS_SMALL)
|
|
end
|
|
if #tChamPath == 1 then
|
|
return tChamPath[1], 1, nil
|
|
elseif #tChamPath == 2 then
|
|
return tChamPath[1], 2, tChamPath[2]
|
|
else
|
|
for i = 1, nNumIds do
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
for i = 1, #tChamPath do
|
|
EgtErase( tChamPath[i])
|
|
end
|
|
end
|
|
else
|
|
for i = 1, nNumIds do
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
end
|
|
-- altrimenti cancello tutte le emtità e restituisco nil
|
|
else
|
|
for i = 1, nNumIds do
|
|
EgtErase( nStartId + i - 1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return nil, 0, nil
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeChamfer( Proc, vtOrtho, nSurfInt)
|
|
-- Se variabile globale indica che lo smusso è già stato fatto, esco
|
|
if _bMadeChamfer then
|
|
return 0
|
|
end
|
|
_bMadeChamfer = true
|
|
local bIs3Faces = Proc.Fct == 3
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'Mark')
|
|
if not sMilling then
|
|
local sErr = 'Error : Mark not found in library'
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- ottengo le curve di contorno libero
|
|
local nAuxId1, nAuxId2, nNumIdAux
|
|
if bIs3Faces then
|
|
-- nAuxId1, _ = EgtExtractSurfTmLoops( nSurfInt, nAddGrpId)
|
|
-- EgtModifyCurveExtrusion( nAuxId1, vtOrtho, GDB_RT.GLOB)
|
|
-- SetOpenSide( nAuxId1, vtOrtho, b3Solid, nAddGrpId, 1)
|
|
-- nNumIdAux = 2
|
|
|
|
-- estraggo i percorsi
|
|
nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, _nAddGrpId)
|
|
-- se percorso creato estraggo solo i percorsi delle facce interessate, non di testa
|
|
if nAuxId1 then
|
|
nAuxId1, nNumIdAux, nAuxId2 = ExtractExternalPaths( nAuxId1, nNumIdAux, vtOrtho)
|
|
end
|
|
else
|
|
nAuxId1, nNumIdAux = EgtExtractSurfTmLoops( Proc.Id, _nAddGrpId)
|
|
if not nNumIdAux then nNumIdAux = 0 end
|
|
end
|
|
|
|
local dExtra = 2
|
|
for i = 1, nNumIdAux do
|
|
local AuxId
|
|
local vtExtr
|
|
if bIs3Faces then
|
|
if i == 1 then
|
|
AuxId = nAuxId1
|
|
else
|
|
-- faccio la copia del percorso
|
|
-- AuxId = EgtCopyGlob( nAuxId1, nAddGrpId)
|
|
AuxId = nAuxId2
|
|
end
|
|
if AuxId then
|
|
vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB)
|
|
end
|
|
else
|
|
AuxId = nAuxId1 + i - 1
|
|
vtExtr, _, _ = EgtCurveArea( AuxId)
|
|
end
|
|
if vtExtr then
|
|
if not bIs3Faces then
|
|
local fFrCurve = EgtGetGlobFrame( AuxId)
|
|
vtExtr:toGlob( fFrCurve)
|
|
end
|
|
-- if bIs3Faces and i == nNumIdAux then
|
|
-- vtExtr = -vtExtr
|
|
-- end
|
|
-- Se normale entro certi limiti
|
|
-- if vtExtr:getZ() > -0.707 and ( abs(vtOrtho:getX()) > 0.99 or abs(vtOrtho:getY()) > 0.99 or abs(vtOrtho:getZ()) > 0.99) then
|
|
if vtExtr:getZ() > -0.707 and ( abs(vtExtr:getX()) > 0.99 or abs(vtExtr:getY()) > 0.99 or abs(vtExtr:getZ()) > 0.99) then
|
|
-- inserisco la lavorazione
|
|
local sNameCh = 'Cham_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
local nMchId = EgtAddMachining( sNameCh, sMilling)
|
|
if not nMchId then
|
|
local sErr = 'Error adding machining ' .. sNameCh .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
-- modifico estrusione percorso
|
|
EgtModifyCurveExtrusion( AuxId, vtExtr, GDB_RT.GLOB)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ AuxId, -1}})
|
|
-- imposto posizione braccio porta testa
|
|
if vtExtr:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
-- assegno affondamento e offset radiale
|
|
-- EgtSetMachiningParam( MCH_MP.DEPTH, _dDepthCham + dExtra - EgtIf( bIs3Faces, (dDepth / 2), 0))
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, _dDepthCham + dExtra)
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dExtra)
|
|
-- se opero su 3 facce e sono al secondo e ultimo percorso inverto la lavorazione
|
|
-- if bIs3Faces and i == nNumIdAux then
|
|
-- EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return -1, sErr
|
|
end
|
|
-- se non perpendicolare emetto un warning
|
|
-- else
|
|
-- sWarn = 'Warning : chamfer skipped because not perpendicular to face or from bottom'
|
|
-- EgtOutLog( sWarn)
|
|
end
|
|
--emetto un warning
|
|
-- else
|
|
-- sWarn = 'Warning : chamfer skipped because not perpendicular to face'
|
|
-- EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
|
|
return 0
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByMillAsSaw( Proc, tFData, nBottomFace, sMillingOnSide, dSawDiam, dSawThick)
|
|
local sWarn
|
|
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = EgtGetInfo( _nRawId, 'BDST', 'd') or 5.
|
|
-- Recupero le facce adiacenti alla principale (solo quelle esistenti)
|
|
local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd)
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3)
|
|
-- Cerco una faccia adiacente alla principale sul lato più lungo
|
|
local nFacAdj
|
|
local dMaxLen = 0
|
|
for i = 1, #vAdj do
|
|
local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
if dLen > dMaxLen then
|
|
nFacAdj = vAdj[i]
|
|
dMaxLen = dLen
|
|
EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 3)
|
|
end
|
|
end
|
|
if not nFacAdj then
|
|
local sErr = 'Error : long adjacent face not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare
|
|
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
if abs( vtN * tFData.rfFac:getVersX()) > abs( vtN * tFData.rfFac:getVersY()) then
|
|
tFData.dH, tFData.dV = tFData.dV, tFData.dH
|
|
end
|
|
-- Determino se estremi aperti o chiusi
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
-- se non ho la faccia di fondo (che comporta essere una fessura) verifico se ho lati aperti
|
|
if not nBottomFace then
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == tFData.nFacInd then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == tFData.nFacInd do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == tFData.nFacInd do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
end
|
|
end
|
|
end
|
|
-- Se possibile, lavoro con la lama
|
|
if _bForceUseBlade then
|
|
-- Recupero la lavorazione di lama
|
|
local sCutting = sMillingOnSide
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( tFData.rfFac:getVersZ())
|
|
local dStartDist = -1
|
|
local dEndDist = -1
|
|
-- calcolo eventuali arretramenti lama
|
|
if not bOpenStart then
|
|
local dRadius = dSawDiam / 2
|
|
local dCat1 = dRadius - tFData.dFacElev
|
|
dStartDist = sqrt( ( dRadius * dRadius) - ( dCat1 * dCat1))
|
|
end
|
|
if not bOpenEnd then
|
|
if not bOpenStart then
|
|
dEndDist = dStartDist
|
|
else
|
|
local dRadius = dSawDiam / 2
|
|
local dCat1 = dRadius - tFData.dFacElev
|
|
dEndDist = sqrt( ( dRadius * dRadius) - ( dCat1 * dCat1))
|
|
end
|
|
end
|
|
-- Eseguo i tagli
|
|
local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( tFData.dV - dSawThick) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
local dOffs = ( i - 1) * dStep
|
|
--if vtN:getZ() < BD.NZ_MINA then dOffs = dOffs + dSawThick end
|
|
local bOk, sErr, nMchId = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, dStartDist, dEndDist, nil, _b3Raw)
|
|
if not bOk then return bOk, sErr end
|
|
-- setto l'elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( 0, 1) .. ';'
|
|
-- applico elevazione
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- tolgo eventuale step
|
|
EgtSetMachiningParam( MCH_MP.STEP, 0)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- in base all'elevazione calcolo l'impronta della lama
|
|
local dUsedBladeLen = sqrt( ( ( dSawDiam / 2) * ( dSawDiam / 2)) - ( ( ( dSawDiam / 2) - tFData.dFacElev) * ( ( dSawDiam / 2) - tFData.dFacElev)))
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then
|
|
-- do avviso che la lama può sbordare nel pezzo successivo
|
|
sWarn = 'Warning on mill side as blade : Cut machining can damage next piece'
|
|
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
|
|
end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DoHeadChainSaw( Proc, sName, sSawing, tFData, nFaceUse, nFacAdj, vtN, vtNE, vtNS, dSawWidth,
|
|
dOffs, dDistToNextPiece, dMaxDepth, bOpenStart, bOpenEnd)
|
|
local nMchFId = EgtAddMachining( sName, sSawing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL then
|
|
-- se ho lato partenza aperto e lato uscita chiuso e direzione lato chiuso è negativa, allora controllo uscita lama
|
|
if bOpenStart and not bOpenEnd and vtNE:getX() < -0.99 and dDistToNextPiece < ( dSawWidth / 2) then
|
|
-- imposto accorciamento iniziale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dDistToNextPiece - 1 - ( dSawWidth / 2))
|
|
else
|
|
-- imposto accorciamento iniziale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2))
|
|
end
|
|
-- se ho lato uscita aperto e lato partenza chiuso e direzione lato partenza è negativa, allora controllo uscita lama
|
|
if bOpenEnd and not bOpenStart and vtNS:getX() < -0.99 and dDistToNextPiece < ( dSawWidth / 2) then
|
|
-- imposto accorciamento finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dDistToNextPiece - 1 - ( dSawWidth / 2))
|
|
else
|
|
-- imposto accorciamento finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2))
|
|
end
|
|
else
|
|
-- imposto accorciamento iniziale/finale per estremi aperti/chiusi
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2))
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2))
|
|
end
|
|
-- imposto angolo 3° asse rot e eventuale angolo suggerito per inizio
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, tFData.rfFac:getVersZ()))
|
|
-- imposto offset radiale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
|
|
-- se necessario, limito l'affondamento
|
|
if tFData.dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
local sWarn = 'Warning in LapJoint : elevation (' .. EgtNumToString( tFData.dFacElev, 1) .. ') bigger than max tool depth (' .. EgtNumToString( dMaxDepth, 1) .. ')'
|
|
local dDepth = dMaxDepth - tFData.dFacElev
|
|
EgtOutLog( sWarn)
|
|
EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH ' .. EgtNumToString( dDepth, 1))
|
|
end
|
|
-- imposto elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev, 2) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- impostazione alternativa angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, tFData.rfFac:getVersZ()))
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if EgtIsMachiningEmpty() then
|
|
local _, sWarn = EgtGetMachMgrWarning( 0)
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sWarn
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DoSideChainSaw( Proc, sName, sSawing, tFData, vtN, vtOrtho, nLongFaceId,
|
|
dOffs, dMaxMat, dSawCornerRad, bOpenStart, bOpenEnd)
|
|
local nMchFId = EgtAddMachining( sName, sSawing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nLongFaceId}})
|
|
-- imposto uso del lato faccia
|
|
local nFaceUse
|
|
-- se non è un tunnel a 4 facce
|
|
if Proc.Fct < 4 then
|
|
nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ(), vtN)
|
|
-- altrimenti vero tunnel (solo sopra-sotto o davanti-dietro)
|
|
else
|
|
if abs( vtOrtho:getZ()) >= 0.707 then
|
|
nFaceUse = MCH_MILL_FU.PARAL_DOWN
|
|
else
|
|
nFaceUse = MCH_MILL_FU.PARAL_BACK
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho))
|
|
-- imposto offset radiale
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
|
|
-- se non è un tunnel a 4 facce
|
|
if Proc.Fct < 4 then
|
|
-- imposto sempre massimo affondamento
|
|
local dBoxDepth
|
|
if nFaceUse == MCH_MILL_FU.PARAL_LEFT or nFaceUse == MCH_MILL_FU.PARAL_RIGHT then
|
|
dBoxDepth = Proc.Box:getDimX()
|
|
elseif nFaceUse == MCH_MILL_FU.PARAL_FRONT or nFaceUse == MCH_MILL_FU.PARAL_BACK then
|
|
dBoxDepth = Proc.Box:getDimY()
|
|
else
|
|
dBoxDepth = Proc.Box:getDimZ()
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dBoxDepth)
|
|
if dBoxDepth > dMaxMat then
|
|
local sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- sistemo inizio e fine
|
|
if bOpenStart then EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0) end
|
|
if bOpenEnd then EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) end
|
|
-- altrimenti vero tunnel (solo sopra-sotto o davanti-dietro)
|
|
else
|
|
-- se possibile aumento l'affondamento pari al raggio corner + 1
|
|
if dMaxMat > ( dDepth + dSawCornerRad + 1) then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, ( dDepth + dSawCornerRad + 1))
|
|
-- se massimo affondamento supera altezza fessura, uso massimo affondamento
|
|
elseif dMaxMat > ( dDepth + 1) then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, ( dMaxMat - 1))
|
|
-- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning
|
|
elseif dMaxMat < dDepth then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat)
|
|
local sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
if Q_MAX_ELEVATION and Q_MAX_ELEVATION > 10 then
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( Q_MAX_ELEVATION, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- impostazione alternativa angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho))
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if EgtIsMachiningEmpty() then
|
|
local _, sWarn = EgtGetMachMgrWarning( 0)
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sWarn
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nLongFaceId,
|
|
bOrthoFacesMaster, nBottomFace, nSurfInt)
|
|
local bIs3Faces = Proc.Fct == 3
|
|
local bOrthoFaces
|
|
local sWarn
|
|
-- ottengo la distanza tra la fine del pezzo e il pezzo successivo
|
|
local dDistToNextPiece = EgtGetInfo( _nRawId, 'BDST', 'd') or 5.4
|
|
if bIs3Faces then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local nFacInd1, dFacElev1, nFacInd2, dFacElev2 = BL.GetFaceWithMostAdj( Proc.Id, _nPartId, bIs3Faces)
|
|
if not nFacInd1 or nFacInd1 < 0 then
|
|
if nFacInd1 == -1 then
|
|
bOrthoFaces = nFacInd2
|
|
else
|
|
local sErr = 'Error : MakeByChainOrSaw could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
else
|
|
bOrthoFaces = bOrthoFacesMaster
|
|
end
|
|
|
|
if bOrthoFaces then
|
|
-- ottengo le dimensioni del tunnel
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc)
|
|
-- verifico la direzione
|
|
-- se devo inserire il chamfer
|
|
if _nChamfer > 0 then
|
|
local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
end
|
|
-- Recupero le facce adiacenti alla principale (solo quelle esistenti)
|
|
local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd)
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3)
|
|
-- Cerco una faccia adiacente alla principale sul lato più lungo
|
|
local nFacAdj
|
|
local dMaxLen = 0
|
|
for i = 1, #vAdj do
|
|
local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
local dLen = dist( ptP1, ptP2)
|
|
if dLen > dMaxLen then
|
|
nFacAdj = vAdj[i]
|
|
dMaxLen = dLen
|
|
EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, tFData.dH, tFData.dV), 3)
|
|
end
|
|
end
|
|
if not nFacAdj then
|
|
local sErr = 'Error : long adjacent face not found'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Riordino le dimensioni per avere dH come lato lungo e dV come perpendicolare
|
|
local _, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
if abs( vtN * tFData.rfFac:getVersX()) > abs( vtN * tFData.rfFac:getVersY()) then
|
|
tFData.dH, tFData.dV = tFData.dV, tFData.dH
|
|
end
|
|
-- Determino se estremi aperti o chiusi
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
local vtNS, vtNE
|
|
-- se non ho la faccia di fondo (che comporta essere una fessura) verifico se ho lati aperti
|
|
if not nBottomFace then
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1]
|
|
EgtOutLog( 'Adj2=' .. table.concat( vAdj2, ' ,'), 3)
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == tFData.nFacInd then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == tFData.nFacInd do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- se è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenStart and vAdj2[i] >= 0 then
|
|
_, vtNS = EgtSurfTmFacetCenter( Proc.Id, vAdj2[i], GDB_ID.ROOT)
|
|
end
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == tFData.nFacInd do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
-- se è chiusa acquisisco vettore faccia tappo
|
|
if not bOpenEnd and vAdj2[k] >= 0 then
|
|
_, vtNE = EgtSurfTmFacetCenter( Proc.Id, vAdj2[k], GDB_ID.ROOT)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- Recupero il massimo affondamento possibile con la lama
|
|
local dSawMaxDepth = 0
|
|
local sCutting = ML.FindCutting( 'HeadSide')
|
|
if sCutting then
|
|
local TI = GetToolInfoForMachining( sCutting)
|
|
if TI then
|
|
dSawMaxDepth = TI.dMaxDepth or dSawMaxDepth
|
|
end
|
|
end
|
|
-- se lavorazione sulle teste e altezza trave supera il limite (che causa collisione con la forcella) e direzione taglio lungo la Z
|
|
-- e limite profondità BeamData è maggiore del taglio massimo lama, assegno il massimo affondamento pari al limite profondità del BeamData
|
|
if bOpenStart and bOpenEnd and _bForceUseBlade and ( Proc.Head or Proc.Tail) and abs( tFData.rfFac:getVersY():getY()) > 0.866 and
|
|
_b3Solid:getDimZ() > BD.MIN_DIM_HBEAM and dSawMaxDepth > BD.MAX_DIM_HTCUT_HBEAM then
|
|
dSawMaxDepth = BD.MAX_DIM_HTCUT_HBEAM
|
|
end
|
|
-- Se entrambi gli estremi sono aperti e possibile, lavoro con la lama
|
|
if bOpenStart and bOpenEnd and _bForceUseBlade and tFData.dFacElev < dSawMaxDepth + 10 * GEO.EPS_SMALL then
|
|
-- Recupero la lavorazione di lama
|
|
local sCutting = ML.FindCutting( 'HeadSide')
|
|
if not sCutting then
|
|
local sErr = 'Error : HeadSide (cutting) not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr, 'MNF'
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 4
|
|
local TI = GetToolInfoForMachining( sCutting)
|
|
if TI then
|
|
dSawDiam = TI.dDiam or dSawDiam
|
|
dSawThick = TI.dThick
|
|
end
|
|
if dSawThick > tFData.dV + 10 * GEO.EPS_SMALL then
|
|
local sErr = 'Error : sawblade too thick'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( tFData.rfFac:getVersZ())
|
|
-- Eseguo i tagli
|
|
local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( tFData.dV - dSawThick) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
local dOffs = ( i - 1) * dStep
|
|
local bOk, sErr = Fbs.MakeOne( Proc.Id, nFacAdj, sCutting, dSawDiam, nFaceUse, -0.01, 0, BD.CUT_SIC, dOffs, 0, 0, nil, _b3Raw)
|
|
if not bOk then return bOk, sErr end
|
|
end
|
|
-- in base all'elevazione calcolo l'impronta della lama
|
|
local dUsedBladeLen = sqrt( ( ( dSawDiam / 2) * ( dSawDiam / 2)) - ( ( ( dSawDiam / 2) - tFData.dFacElev) * ( ( dSawDiam / 2) - tFData.dFacElev)))
|
|
-- controllo direzione taglio e se il minimo della feature sborda in coda
|
|
if not Proc.Tail and abs( vtN:getX()) < GEO.EPS_SMALL and abs( _b3Solid:getMin():getX() - Proc.Box:getMin():getX()) < 100 * GEO.EPS_SMALL and dDistToNextPiece < dUsedBladeLen then
|
|
-- do avviso che la lama può sbordare nel pezzo successivo
|
|
sWarn = 'Warning on saw cut : Cut machining can damage next piece'
|
|
EgtOutLog( sWarn .. ' (process ' .. tostring( Proc.Id) .. ')')
|
|
end
|
|
-- altrimenti con sega a catena
|
|
else
|
|
-- Recupero la lavorazione
|
|
local sSawing = ML.FindSawing( 'Sawing')
|
|
if not sSawing then
|
|
local sErr = 'Error : Sawing not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr, 'MNF'
|
|
end
|
|
-- Recupero i dati dell'utensile
|
|
local dSawWidth = 75
|
|
local dSawThick = 8
|
|
local dMaxDepth = 200
|
|
local TI = GetToolInfoForMachining( sSawing)
|
|
if TI then
|
|
dSawWidth = TI.dDiam or dSawWidth
|
|
dSawThick = TI.dThick or dSawThick
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
end
|
|
if dSawThick > tFData.dV + 10 * GEO.EPS_SMALL then
|
|
local sErr = 'Error : chainsaw too thick'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local bGoFromHead = true
|
|
-- se la lunghezza utensile non riesce ad arrivare sul fondo assegno la possibilità di lavorare di testa o di fianco
|
|
if tFData.dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
-- lavora di testa se è un tunnel, lavora di fianco se non è un tunnel
|
|
bGoFromHead = not bOrthoFaces
|
|
end
|
|
-- se continuo a lavorare di testa
|
|
if bGoFromHead then
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestParalOpposite( tFData.rfFac:getVersZ())
|
|
-- Calcolo normale faccia adiacente
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT)
|
|
-- Verifico se necessarie più passate
|
|
local nStep = ceil( ( tFData.dV - 10 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( tFData.dV - dSawThick) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
-- Applico la lavorazione con sega a catena a questa faccia
|
|
local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
local dOffs = ( i - 1) * dStep
|
|
local bOk, sErr = DoHeadChainSaw( Proc, sName, sSawing, tFData, nFaceUse, nFacAdj, vtN, vtNE, vtNS, dSawWidth, dOffs, dDistToNextPiece, dMaxDepth, bOpenStart, bOpenEnd)
|
|
if not bOk then
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- altrimenti segacatena di fianco
|
|
else
|
|
-- verifico se posso farlo con la sega-catena
|
|
local bMakeChainSaw, sSawing2, dMaxMat2, dSawCornerRad2, dSawThick2 = VerifyChainSaw( dDimMin, dDimMax)
|
|
if bMakeChainSaw then
|
|
-- Verifico se necessarie più passate
|
|
local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick2)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( dDimMin - dSawThick2) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
-- inserisco la lavorazione di sawing
|
|
local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
local dOffs = ( i - 1) * dStep
|
|
local bOk, sErr = DoSideChainSaw( Proc, sName, sSawing2, tFData, vtN, vtOrtho, nLongFaceId, dOffs, dMaxMat2, dSawCornerRad2, bOpenStart, bOpenEnd)
|
|
if not bOk then
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeAntiSplintBySaw( Proc, nFacet, vtN, nFacInd, bReduceDepth, bMillDown)
|
|
-- Recupero la lavorazione di lama
|
|
local sCutting = ML.FindCutting( 'HeadSide', not bMillDown, bMillDown)
|
|
if not sCutting then
|
|
local sErr = 'Error : HeadSide (cutting) not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- valuto l'angolo tra le due facce
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, nFacet, GDB_ID.ROOT)
|
|
local ptPm = (ptP1 + ptP2) / 2
|
|
-- ottengo il boundingBox e prendo le dimensioni lungo la normale (Z locale) che rappresenta l'elevazione della faccia
|
|
-- laterale sul punto medio della linea in comune
|
|
local frFc = Frame3d( ptPm, vtN)
|
|
local b3BoxLoc = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frFc)
|
|
local dDepth = b3BoxLoc:getDimZ() or 0
|
|
-- recupero i dati dell'utensile
|
|
local dSawDiam = 400
|
|
local dSawThick = 0
|
|
local dMaxDepth = 0
|
|
local TI = GetToolInfoForMachining( sCutting)
|
|
if TI then
|
|
dSawDiam = TI.dDiam or dSawDiam
|
|
dSawThick = TI.dThick or dSawThick
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
end
|
|
local dExtraOffs = 0
|
|
-- se profondità superiore al massimo lama modifico elevazione
|
|
if dDepth > dMaxDepth then
|
|
dExtraOffs = dMaxDepth - dDepth
|
|
end
|
|
-- se devo ridurre l'affondamento
|
|
if bReduceDepth then
|
|
local dLimitDepth = 100
|
|
-- se ho ridotto l'affondamento ne riduco ulteriormente l'affondamento (50mm)
|
|
if abs( dExtraOffs) > 0 then
|
|
if dMaxDepth > dLimitDepth then
|
|
dExtraOffs = dLimitDepth - dDepth
|
|
end
|
|
else
|
|
if dDepth > dLimitDepth then
|
|
dExtraOffs = dLimitDepth - dDepth
|
|
else
|
|
dExtraOffs = -( dDepth / 2)
|
|
end
|
|
end
|
|
end
|
|
-- eseguo il taglio
|
|
local bMadeASbyBld, sWarn, nIdMach = Fbs.MakeOne( Proc.Id, nFacet, sCutting, dSawDiam, vtN, nil, ( -0.5 + dExtraOffs), BD.CUT_SIC, 0, 0, 0, nil, _b3Raw)
|
|
if bMadeASbyBld then
|
|
sWarn = nil
|
|
if abs( dExtraOffs) > 0 then
|
|
sWarn = 'Warning : antisplint elevation is bigger than max tool depth'
|
|
end
|
|
end
|
|
return bMadeASbyBld, sWarn, nIdMach, dSawThick, dMaxDepth, dAng
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DoPocketing( sName, sPocketing, sMchFind, vtN, nPathInt, nFaceIdx, nUseRoughTool, dMachDepth, dMaxElev, bInvertTool, bInvertPath, bFaceOrtho, bSCCEvaluateOppositeVector, bSCCYSpecialStrategy)
|
|
-- inserisco la lavorazione di svuotatura
|
|
local nMchFId = EgtAddMachining( sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nPathInt, nFaceIdx}})
|
|
if bInvertTool then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
end
|
|
if bFaceOrtho then
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT)
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if EgtIf( bSCCEvaluateOppositeVector, AreSameOrOppositeVectorApprox( vtN, Z_AX()), AreSameVectorApprox( vtN, Z_AX())) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif bSCCYSpecialStrategy then
|
|
if vtN:getY() > 0.1 then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
else
|
|
if vtN:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertTool, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertTool, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- se tasca aperta, imposto opportuno attacco
|
|
if (sMchFind == 'OpenPocket' and nUseRoughTool == 0) or sMchFind == 'OpenPocket_H2' then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
end
|
|
if bInvertPath then
|
|
-- inverto il percorso di lavorazione se necessario lavorare sinistro
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvertPath)
|
|
end
|
|
if dMachDepth ~= 0 then
|
|
-- imposto affondamento
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
end
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'VMRS=0;'
|
|
if dMaxElev > 0 then
|
|
sNotes = sNotes .. 'MaxElev=' .. EgtNumToString( dMaxElev, 1) .. ';'
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local bOk, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
return true, '', nMchFId
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePocket( Proc, ptPs, tvtN, nFaceRef, sMchFind, nUseRoughTool,
|
|
sMasterPocket, dPrevFaceElev, tDimAndRef, dAng)
|
|
-- calcolo l'elevazione dal punto medio
|
|
local dElev
|
|
local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, ptPs, tvtN[2])
|
|
if dLenIn > 0 then
|
|
dElev = dLenIn
|
|
elseif dLedOut then
|
|
dElev = dLedOut
|
|
end
|
|
local dCollSic = 2 * BD.COLL_SIC
|
|
-- calcolo il diametro utensile
|
|
local dDiamTool
|
|
local dFaceDiamTool
|
|
if tDimAndRef then
|
|
-- prendo il valore dalle dimensioni minime delle facce
|
|
dFaceDiamTool = min( tDimAndRef[2][1], tDimAndRef[2][2])
|
|
end
|
|
-- se ho lavorazione precedente ricalcolo grossolanamente l'elevazione
|
|
if dPrevFaceElev and dPrevFaceElev > 0 and dAng then
|
|
dElev = dElev + ( sqrt( ( dElev * dElev) - ( dPrevFaceElev * dPrevFaceElev)) * sin( dAng))
|
|
elseif dPrevFaceElev and dPrevFaceElev > dElev then
|
|
dElev = dPrevFaceElev
|
|
end
|
|
local sPocketing
|
|
if sMasterPocket then
|
|
sPocketing = sMasterPocket
|
|
else
|
|
sPocketing = ML.FindPocketing( sMchFind, dFaceDiamTool, dElev + dCollSic)
|
|
end
|
|
if not sPocketing then
|
|
local sErr = 'Error : ' .. sMchFind .. ' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
dDiamTool = 20
|
|
local dMaxDepth = 0
|
|
local sTuuidPk
|
|
if EgtMdbSetCurrMachining( sPocketing) then
|
|
sTuuidPk = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
|
|
if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuidPk) or '') then
|
|
dMaxDepth = ( EgtTdbGetCurrToolMaxDepth() or dMaxDepth)
|
|
dDiamTool = EgtTdbGetCurrToolParam( MCH_TP.DIAM)
|
|
end
|
|
end
|
|
-- se nome svuotatura non è stato ricalcolato, confronto il diametro utensile utilizzato con il minimo faccia e se non sono compatibili esco
|
|
if sMasterPocket and dFaceDiamTool and dDiamTool >= dFaceDiamTool then
|
|
return false, '', sTuuidPk, dDiamTool, dElev
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. 'F' .. tostring( nFaceRef)
|
|
local dMachDepth = 0
|
|
if dElev > dMaxDepth + 10 * GEO.EPS_SMALL then
|
|
dMachDepth = dMaxDepth - dElev
|
|
dElev = dMaxDepth
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
local bOk, sWarn, nMchFId = DoPocketing( sName, sPocketing, sMchFind, tvtN[2], Proc.Id, nFaceRef, nUseRoughTool, dMachDepth, dElev, false, false, true, false, true)
|
|
if not bOk then
|
|
return bOk, sWarn
|
|
end
|
|
return true, sWarn, sTuuidPk, dDiamTool
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DoHeadCut( Proc, sName, sMilling, nMchFId, dElev, nSideFace, tvtN)
|
|
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, nSideFace}})
|
|
-- imposto uso faccia
|
|
local nFaceUse = BL.GetNearestOrthoOpposite( tvtN[1])
|
|
-- aggiusto i parametri
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH')
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, 0)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, false)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, 1)
|
|
-- imposto posizione braccio porta testa
|
|
if tvtN[2]:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dElev, 1) .. ';VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MachineByMill( Proc, tvtN, nBaseFace, nSideFace, ptPs, tDimAndRef,
|
|
nDiffWidth, nUseRoughTool, dAng, sPocketing, sTuuidPk, dPrevFaceElev)
|
|
-- se angolo tra le facce maggiore di 90, inserisco la contornatura o svuotatura del lato più corto
|
|
if ( 180 + dAng) > 90.1 then
|
|
local sMchFind = 'Pocket'
|
|
local dAngLimit = 40
|
|
|
|
-- se feature é larga come trave imposto openpocket
|
|
if nDiffWidth == 0 then
|
|
sMchFind = 'OpenPocket'
|
|
-- altrimenti non è passante disabilito il truciolatore
|
|
else
|
|
nUseRoughTool = 0
|
|
end
|
|
-- calcolo l'angolo dalla verticale dall'angolo tra le due facce, perchè la feature potrebbe essere ruotata sulla Z locale della
|
|
-- faccia principale e quindi la componente X del versore della faccia potrebbe dare un valore non coerente
|
|
local dDiffFromSqAng = dAng + 90
|
|
-- se l'angolo dalla verticale si discosta di più dell'angolo limite impostato, utilizzo la svuotatura
|
|
if cos( dDiffFromSqAng) < cos( dAngLimit) then
|
|
-- applico la svuotatura
|
|
local bOk, sWarn, sTuuidPk, dDiamTool, dElev = MakePocket( Proc, ptPs, tvtN, nSideFace, sMchFind, nUseRoughTool, sPocketing, dPrevFaceElev, tDimAndRef, dAng)
|
|
if not bOk then
|
|
if sTuuidPk then
|
|
-- recupero la lavorazione
|
|
local sMilling = ML.FindMilling( 'Long2Cut', dElev, sTuuidPk)
|
|
if not sMilling then
|
|
local sErr = 'Error : Long2Cut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inserisco la lavorazione
|
|
local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
bOk, sWarn = DoHeadCut( Proc, sName, sMilling, nMchFId, dElev, nSideFace, tvtN)
|
|
if not bOk then
|
|
return false, sWarn
|
|
end
|
|
end
|
|
else
|
|
return bOk, sWarn
|
|
end
|
|
-- altrimenti contornatura di fianco
|
|
else
|
|
local bOpenStart = false
|
|
local bOpenEnd = false
|
|
if nDiffWidth == 0 then
|
|
bOpenStart = true
|
|
bOpenEnd = true
|
|
else
|
|
local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, (nBaseFace))[1]
|
|
for j = 1, #vAdj2 do
|
|
if vAdj2[j] == nSideFace then
|
|
-- Se non esiste faccia adiacente a lato precedente -> inizio aperto
|
|
local i = EgtIf( j > 1, j - 1, #vAdj2)
|
|
while vAdj2[i] == nSideFace do
|
|
i = EgtIf( i > 1, i - 1, #vAdj2)
|
|
end
|
|
bOpenStart = ( vAdj2[i] < 0)
|
|
-- Se non esiste faccia adiacente a lato successivo -> fine aperto
|
|
local k = EgtIf( j < #vAdj2, j + 1, 1)
|
|
while vAdj2[k] == nSideFace do
|
|
k = EgtIf( k < #vAdj2, k + 1, 1)
|
|
end
|
|
bOpenEnd = ( vAdj2[k] < 0)
|
|
end
|
|
end
|
|
end
|
|
local sMilling
|
|
if nUseRoughTool > 0 then
|
|
sMilling = ML.FindMilling( 'Long2Cut', nil, sTuuidPk)
|
|
else
|
|
sMilling = ML.FindMilling( 'LongSmallCut', nil, sTuuidPk)
|
|
end
|
|
if not sMilling then
|
|
local sErr = 'Error : Long2Cut & LongSmallCut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dTDiam = TI.dDiam or dTDiam
|
|
end
|
|
-- Calcolo uso faccia
|
|
local nFaceUse = BL.GetNearestParalOpposite( tDimAndRef[1][3]:getVersZ())
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, (nSideFace)}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse)
|
|
-- setto inversione del percorso
|
|
EgtSetMachiningParam( MCH_MP.INVERT, true)
|
|
-- setto a 0 eventuali offset
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, 0)
|
|
-- calcolo elevazione per allungamenti attacchi con fianchi chiusi
|
|
local dElev
|
|
local dLenIn, dLedOut = BL.GetPointDirDepth( _nPartId, ptPs, tvtN[2])
|
|
if dLenIn > 0 then
|
|
dElev = dLenIn
|
|
elseif dLedOut then
|
|
dElev = dLedOut
|
|
end
|
|
-- applico gli allungamenti o accorciamenti
|
|
if bOpenStart then
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dTDiam / 2)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dTDiam / 2)
|
|
if dElev > 0 then
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, dElev)
|
|
end
|
|
end
|
|
if bOpenEnd then
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dTDiam / 2)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dTDiam / 2)
|
|
if dElev > 0 then
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, dElev)
|
|
end
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function GetUShapeWidth( Proc, nFacInd)
|
|
-- Recupero le facce adiacenti alla principale (solo quelle esistenti)
|
|
local vAdj = GetValidFacetAdjacencies( Proc.Id, nFacInd)
|
|
-- se non ho facce adiacenti esco subito
|
|
if not vAdj or #vAdj == 0 then return nil end
|
|
-- Normale della faccia
|
|
local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
-- Cerco le facce adiacenti alla principale con angolo concavo >= 90
|
|
local dWidth = 0
|
|
for i = 1, #vAdj do
|
|
-- verifico l'angolo tra le facce ( esco se angolo compreso < 90)
|
|
local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
if bAdj and dAng < -90 - 20 * GEO.EPS_ANG_SMALL then return nil end
|
|
-- larghezza della faccia ortogonalmente alla adiacente
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
local vtX = vtN2 ^ vtN
|
|
local frRef = Frame3d( ptC, ptC + 100 * vtX, ptC + 100 * vtN2)
|
|
local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, nFacInd, GDB_BB.STANDARD, frRef)
|
|
if b3Ref then
|
|
dWidth = max( dWidth, b3Ref:getDimY())
|
|
end
|
|
end
|
|
return dWidth
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByPockets( Proc, bOrthoFacesMaster, bMillDown)
|
|
local nFirstMachId
|
|
local bOrthoFaces
|
|
local sWarn
|
|
local sMchFind = 'Pocket'
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt
|
|
local bBadMach = false
|
|
local bIs3Faces = Proc.Fct == 3
|
|
|
|
if bIs3Faces then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local nFacInd, _, nFacInd2, _ = BL.GetFaceWithMostAdj( Proc.Id, _nPartId, bIs3Faces)
|
|
if not nFacInd or nFacInd < 0 then
|
|
if nFacInd == -1 then
|
|
bOrthoFaces = nFacInd2
|
|
else
|
|
local sErr = 'Error : MakeByPockets could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return -1, sErr
|
|
end
|
|
end
|
|
else
|
|
bOrthoFaces = bOrthoFacesMaster
|
|
end
|
|
-- se è un tunnel verifico se è possibile usare la svuotatura
|
|
if bOrthoFaces then
|
|
-- ottengo le dimensioni del tunnel
|
|
dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc)
|
|
local nPathInt
|
|
-- se devo inserire il chamfer
|
|
if _nChamfer > 0 then
|
|
local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt)
|
|
if nOk < 0 then return -1, sErr end
|
|
end
|
|
-- se smusso non è esclusivo
|
|
if _nChamfer < 2 then
|
|
-- ricalcolo se è lavorabile da sotto
|
|
bMillDown = ( BD.DOWN_HEAD == true)
|
|
-- verifico se può essere fatto con svuotatura
|
|
local bMakePocket, sPocketing, dMaxDepth, dDiamTool = VerifyPocket( dDimMin, dDepth / 2, nil, sMchFind)
|
|
local bMakePocketDn, sPocketingDn, dMaxDepthDn
|
|
if bMillDown then
|
|
bMakePocketDn, sPocketingDn, dMaxDepthDn = VerifyPocket( dDimMin, dDepth / 2, nil, sMchFind .. '_H2', false, true)
|
|
-- se è negativo inverto il versore e la faccia
|
|
if vtOrtho:getZ() < 0 then
|
|
vtOrtho = -vtOrtho
|
|
EgtInvertSurf( nSurfInt)
|
|
end
|
|
end
|
|
if bMakePocket then
|
|
-- gestione svuotatura da un solo lato o anche dal lato opposto (se non verticale)
|
|
-- estraggo il contorno dalla superfice per evitare i problemi con la svuotatura
|
|
-- e assegno l'estrusione
|
|
nPathInt = EgtExtractSurfTmLoops( nSurfInt, _nAddGrpId)
|
|
EgtModifyCurveExtrusion( nPathInt, vtOrtho, GDB_RT.GLOB)
|
|
-- se ho 3 facce, ciclo sulle entità del percorso per segnare quelle che sono aperte
|
|
if bIs3Faces then
|
|
SetOpenSide( nPathInt, vtOrtho)
|
|
end
|
|
-- variabili per parametri lavorazione
|
|
local dMachDepth
|
|
local dElev = 0
|
|
local bDoubleSide
|
|
local bOneShot
|
|
local bComplete = true
|
|
-- imposto altezza aggiuntiva di elevazione
|
|
local dCollSic = CalcCollisionSafety( vtOrtho)
|
|
-- se possibile svuotare completamente da una sola parte
|
|
if dMaxDepth > ( dDepth + BD.CUT_EXTRA + dCollSic) then
|
|
dMachDepth = ( dDepth / 2) + BD.CUT_EXTRA
|
|
dElev = dDepth + BD.CUT_EXTRA
|
|
bOneShot = true
|
|
else
|
|
-- se direzione verso la verticale setto max affondamento possibile ed
|
|
-- emetto messaggio di warning perché non lavorabile interamente
|
|
if abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then
|
|
dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
bComplete = false
|
|
-- altrimenti setto il flag per fare la svuotatura da due parti
|
|
else
|
|
-- se l'altezza utensile riesce a lavorare completamente da due parti
|
|
if dMaxDepth > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then
|
|
dMachDepth = BD.CUT_EXTRA_MIN
|
|
dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN
|
|
-- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione
|
|
else
|
|
dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
-- se molto inclinato rispetto alla normale della faccia di riferimento, lavorazione non idonea per probabili collisioni
|
|
local vtRef = Y_AX()
|
|
if abs( vtOrtho:getX()) > abs( vtOrtho:getY()) and abs( vtOrtho:getX()) > abs( vtOrtho:getZ()) then
|
|
vtRef = X_AX()
|
|
elseif abs( vtOrtho:getZ()) > abs( vtOrtho:getX()) and abs( vtOrtho:getZ()) > abs( vtOrtho:getY()) then
|
|
vtRef = Z_AX()
|
|
end
|
|
if abs( vtOrtho * vtRef) < 0.5 then
|
|
bBadMach = true
|
|
end
|
|
end
|
|
bDoubleSide = true
|
|
end
|
|
end
|
|
-- se lavorazione non idonea esco
|
|
if bIs3Faces and bBadMach then
|
|
local sErr = 'Impossible apply perpendicular pocketing: ' .. sPocketing
|
|
return -2, sErr
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local bToolInvert = false
|
|
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
|
|
if vtOrtho:getZ() < BD.NZ_MINA and abs( vtOrtho:getZ()) >= 0.707 and not BD.DOWN_HEAD then
|
|
bToolInvert = true
|
|
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
|
|
elseif not bDoubleSide and vtOrtho:getY() > GEO.EPS_SMALL and not ( -(vtOrtho:getZ()) < BD.NZ_MINA) then
|
|
bToolInvert = true
|
|
end
|
|
-- eseguo svuotatura
|
|
local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtOrtho, nPathInt, -1, 0, dMachDepth, dElev, bToolInvert, true, false, true)
|
|
if not bOk then
|
|
return -1, sErr
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
-- se posso applicare la svuotatura sul lato opposto
|
|
if bDoubleSide then
|
|
-- se ho la lavorazione da sotto ricalcolo in base a questa lavorazione
|
|
if bMakePocketDn then
|
|
-- sPocketing = sPocketingDn
|
|
-- dMaxDepth = dMaxDepthDn
|
|
-- dDiamTool = dDiamToolDn
|
|
-- se l'altezza utensile riesce a lavorare completamente da due parti
|
|
if dMaxDepthDn > ( dDepth / 2) + dCollSic + BD.CUT_EXTRA_MIN then
|
|
dMachDepth = BD.CUT_EXTRA_MIN
|
|
dElev = ( dDepth / 2) + BD.CUT_EXTRA_MIN
|
|
-- altrimenti non si riesce in due passate, limito la profondità e setto l'elevazione
|
|
else
|
|
dMachDepth = dMaxDepthDn - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepthDn
|
|
bComplete = false
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
else
|
|
-- se anche lavorando dal lato opposto non riesco a svuotare completamente la fessura
|
|
-- setto i parametri affondamento ed emetto warning
|
|
if dMaxDepth < ( dDepth / 2) + BD.CUT_EXTRA + dCollSic then
|
|
dMachDepth = dMaxDepth - ( dDepth / 2) - dCollSic
|
|
dElev = dMaxDepth
|
|
bComplete = false
|
|
sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'PockOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
-- eseguo svuotatura in direzione invertita
|
|
local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtOrtho, nPathInt, -1, 0, dMachDepth, dElev, true, true, false, false)
|
|
if not bOk then
|
|
return -1, sErr
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
end
|
|
-- se non completo e U, cerco di lavorare anche la faccia di fondo (con il massimo affondamento possibile)
|
|
if not bComplete and bIs3Faces then
|
|
-- recupero la faccia da lavorare
|
|
local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id, _nPartId)
|
|
local vtN
|
|
local bPock3rd = false
|
|
if nFacInd then
|
|
vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
bPock3rd = ( vtN and ( vtN:getZ() >= BD.NZ_MINA or bMakePocketDn))
|
|
end
|
|
if bPock3rd then
|
|
-- recupero la distanza di sicurezza aggiuntiva
|
|
local dFacCollSic = CalcCollisionSafety( vtN)
|
|
-- scelgo se lavorare da sotto
|
|
local bFacPocketDn = ( bMakePocketDn and vtN:getZ() < -0.174)
|
|
-- calcolo affondamento
|
|
local dDepth = 0
|
|
local dActMaxDepth = EgtIf( bFacPocketDn, dMaxDepthDn, dMaxDepth)
|
|
if dActMaxDepth < dFacElev + dFacCollSic then
|
|
dDepth = dActMaxDepth - dFacElev + dFacCollSic
|
|
end
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = EgtIf( bDoubleSide, 'Pock3rd_', 'Pock2nd_') .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
-- eseguo svuotatura
|
|
local bOk, sErr, nMchFId = DoPocketing( sName, sPocketing, sMchFind, vtN, Proc.Id, nFacInd, 0, dDepth, 0, false, true, false, true)
|
|
if not bOk then
|
|
return -1, sErr
|
|
end
|
|
-- prendo l'id della prima lavorazione inserita
|
|
if not nFirstMachId then
|
|
nFirstMachId = nMchFId
|
|
end
|
|
end
|
|
end
|
|
return 1, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId
|
|
end
|
|
end
|
|
end
|
|
|
|
return 0, sWarn, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool, bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ManageAntiSplintBySaw( Proc, bIsU, vtN, nFacInd, sWarn, bMillDown, bReduceDepth)
|
|
local bMadeASbyBld = false
|
|
local nNumFac = EgtIf( bIsU, 2, 1)
|
|
local nPrefSide = 1 -- di preferenza il motore è meglio tenerlo sinistra
|
|
-- se a U cerco di ottimizzare il lato di lavoro della lama
|
|
if bIsU then
|
|
if abs( vtN:getY()) > 0.996 then
|
|
nPrefSide = 0
|
|
elseif abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then
|
|
-- se X è negativa allora devo tenere il motore a destra
|
|
if vtN:getX() < -(10 * GEO.EPS_SMALL) then
|
|
nPrefSide = 2
|
|
end
|
|
end
|
|
end
|
|
-- va eseguito sulle facce diverse dalla principale
|
|
local nPrevSCC = nil
|
|
for nFacet = 0, nNumFac do
|
|
if nFacet ~= nFacInd then
|
|
-- lavoro
|
|
local dSawThick = 0
|
|
local dAng, sWarn2, nIdMach
|
|
bMadeASbyBld, sWarn2, nIdMach, dSawThick, dMaxDepth, dAng = MakeAntiSplintBySaw( Proc, nFacet, vtN, nFacInd, bReduceDepth, bMillDown)
|
|
if not bMadeASbyBld then return bMadeASbyBld, false, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
-- se antischeggia veramente inserito perchè necessario
|
|
if nIdMach then
|
|
-- verifico se da invertire
|
|
local bInvertMach = false
|
|
if bIsU then
|
|
if abs( vtN:getZ()) > 0.63 or abs( vtN:getY()) > 0.63 then
|
|
-- if abs( vtN:getZ()) > 0.7 or abs( vtN:getY()) > 0.7 then
|
|
-- prendo il vettore normale alla faccia
|
|
local ptC, vtNFc = EgtSurfTmFacetCenter( Proc.Id, nFacet, GDB_ID.ROOT)
|
|
-- se superficie principale parallela al piano XZ
|
|
if nPrefSide == 0 then
|
|
-- se facce inclinate \\ allora mandrino a destra (per essere verso l'alto)
|
|
if vtNFc:getX() * vtNFc:getZ() > 0 then
|
|
nPrefSide = 2
|
|
-- altrimenti facce inclinate // quindi mandrino a sinistra (per essere ancora verso l'alto)
|
|
else
|
|
nPrefSide = 1
|
|
end
|
|
end
|
|
-- se faccia verso X+ e mandrino verso sinistra
|
|
if vtNFc:getX() > 0 and nPrefSide == 1 then
|
|
-- se angolo interno e circa -90
|
|
if abs( dAng + 90) < 5 then
|
|
bInvertMach = true
|
|
end
|
|
-- se faccia verso X- e mandrino verso destra
|
|
elseif vtNFc:getX() < 0 and nPrefSide == 2 then
|
|
-- se angolo interno e circa -90
|
|
if abs( dAng + 90) < 5 then
|
|
bInvertMach = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- eseguo inversione
|
|
if bInvertMach then
|
|
local bToolInvert = EgtGetMachiningParam( MCH_MP.TOOLINVERT)
|
|
local nWS = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
local nInvWS = EgtIf( nWS == MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT)
|
|
local nFaceUse = EgtGetMachiningParam( MCH_MP.FACEUSE)
|
|
local bOrtUp = ( nFaceUse >= MCH_MILL_FU.ORTUP_DOWN and nFaceUse <= MCH_MILL_FU.ORTUP_RIGHT)
|
|
if not bOrtUp then
|
|
-- assegno i parametri invertiti
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, nInvWS)
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, not bToolInvert)
|
|
-- setto l'offset pari allo spessore lama
|
|
EgtSetMachiningParam( MCH_MP.OFFSL, -dSawThick)
|
|
end
|
|
end
|
|
-- posizione del braccio : se primo taglio la recupero, altrimenti la imposto
|
|
if not nPrevSCC then
|
|
nPrevSCC = EgtGetMachiningParam( MCH_MP.SCC)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, nPrevSCC)
|
|
end
|
|
-- rieseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nIdMach, false)
|
|
return false, false, sErr
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return bMadeASbyBld, true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePathsOnExtremePoints( nIdPath, pPaths, dTDiam)
|
|
|
|
local dLength = 2
|
|
if not nIdPath then return pPaths end
|
|
|
|
-- prendo i punti iniziali e finali del percorso e i versori direzione
|
|
local ptIni = EgtSP( nIdPath, GDB_RT.GLOB)
|
|
local ptEnd = EgtEP( nIdPath, GDB_RT.GLOB)
|
|
|
|
-- se distanza tra i punti è <= del diametro utensile esco
|
|
if dist( ptIni, ptEnd) <= dTDiam then return pPaths end
|
|
|
|
-- prendo i versori iniziali e finali
|
|
local vtIni = EgtSV( nIdPath, GDB_RT.GLOB)
|
|
local vtEnd = EgtEV( nIdPath, GDB_RT.GLOB)
|
|
|
|
local ptIniP = ptIni
|
|
local ptEndP = ptIniP + (vtIni * dLength)
|
|
local nAuxId = EgtLine( _nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB)
|
|
table.insert( pPaths, { nAuxId, 1, ptIniP})
|
|
|
|
ptIniP = ptEnd
|
|
ptEndP = ptEnd - ( vtEnd * dLength)
|
|
nAuxId = EgtLine( _nAddGrpId, ptIniP, ptEndP, GDB_RT.GLOB)
|
|
table.insert( pPaths, { nAuxId, 2, ptIniP})
|
|
|
|
return pPaths
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1,
|
|
bDoubleSide, bOppoSide, sMilling, sMyWarn,
|
|
dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId)
|
|
|
|
local sMyWarn2
|
|
|
|
-- assegno lavorazioni ad ogni percorso
|
|
for i = 1, #pPaths do
|
|
local nIdPath = pPaths[i][1]
|
|
local nSide = pPaths[i][2]
|
|
-- modifico versore direzione
|
|
EgtModifyCurveExtrusion( nIdPath, vtN1, GDB_RT.GLOB)
|
|
local sName
|
|
if bOppoSide then
|
|
sName = 'AntiSplintOppo_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
else
|
|
sName = 'AntiSplint_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
end
|
|
local nMchId = EgtAddMachining( sName, sMilling)
|
|
if nMchId then
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ nIdPath, -1}})
|
|
if ( bOppoSide and nSide == 1) or ( not bOppoSide and nSide == 2) then
|
|
-- imposto lato di lavoro destro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT)
|
|
else
|
|
-- imposto lato di lavoro sinistro
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT)
|
|
end
|
|
local nSCC
|
|
if bOppoSide then
|
|
-- imposto direzione utensile opposta
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
-- imposto posizione braccio porta testa
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
if not BD.C_SIMM then
|
|
if AreSameVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
else
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
end
|
|
end
|
|
else
|
|
local bInvertMach = false
|
|
if not nPathInt then
|
|
-- imposto posizione braccio porta testa
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
if vtN1:getY() > 100 * GEO.EPS_ZERO then
|
|
nSCC = MCH_SCC.ADIR_YP
|
|
end
|
|
else
|
|
-- verifico se devo invertire direzione utensile (in caso di direzione verso la verticale)
|
|
if vtN1:getZ() < BD.NZ_MINA and abs(vtN1:getZ()) >= 0.707 then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
-- altrimenti se da fare in una sola volta e direzionato verso Y+ lo inverto per lavorarlo davanti
|
|
elseif not bDoubleSide and vtN1:getY() > GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.TOOLINVERT, true)
|
|
bInvertMach = true
|
|
end
|
|
-- imposto posizione braccio porta testa
|
|
nSCC = MCH_SCC.NONE
|
|
if not BD.C_SIMM then
|
|
if AreSameOrOppositeVectorApprox( vtN1, Z_AX()) then
|
|
nSCC = MCH_SCC.ADIR_YM
|
|
elseif abs( vtN1:getX()) < 0.1 then
|
|
nSCC = EgtIf( BL.IsPartFinalPhase( _nPhase), MCH_SCC.ADIR_XM, MCH_SCC.ADIR_XP)
|
|
elseif vtN1:getY() < GEO.EPS_SMALL then
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
else
|
|
nSCC = EgtIf( bInvertMach, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- parametri attacco
|
|
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 1)
|
|
-- allungo inizio
|
|
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 2)
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 10)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, -5)
|
|
-- parametri uscita
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, 0)
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
|
|
local dMachDepth = 0
|
|
local dExtraElev = 0
|
|
if bDoubleSide then
|
|
dExtraElev = BL.GetFaceElevationFromPointDir( Proc.Id, _nPartId, pPaths[i][3], EgtIf( bOppoSide, -vtN1, vtN1)) - dMaxElevMaster
|
|
end
|
|
local dMaxElev = dMaxElevMaster + dExtraElev
|
|
if ( dMaxElev + BD.CUT_EXTRA + dCollSic) > dMaxDepth then
|
|
dMachDepth = dMaxDepth - ( dMaxElev + dCollSic)
|
|
end
|
|
-- setto se devo invertire il percorso
|
|
local bInvert = CheckToInvert( nIdPath, true)
|
|
if bOppoSide then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMachDepth)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, (dMachDepth + dExtraDepth))
|
|
EgtSetMachiningParam( MCH_MP.INVERT, EgtIf( bInvertMach, not bInvert, bInvert))
|
|
end
|
|
-- Note utente con dichiarazione nessuna generazione sfridi per Vmill e massima elevazione
|
|
local sUserNotes = 'VMRS=0;MaxElev=' .. EgtNumToString( ( dMaxElev + dMachDepth), 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
|
|
-- eseguo
|
|
if ML.ApplyMachining( true, false) then
|
|
_, sMyWarn2 = EgtGetMachMgrWarning( 0)
|
|
if EgtIsMachiningEmpty() then
|
|
EgtSetOperationMode( nMchId, false)
|
|
else
|
|
-- se ho la lavorazione di svuotatura riloco la lavorazione antischeggia prima di questa
|
|
if nFirstMachId then
|
|
EgtRelocateGlob( nMchId, nFirstMachId, GDB_IN.BEFORE)
|
|
end
|
|
end
|
|
-- altrimenti lavorazione non applicata
|
|
else
|
|
_, sMyWarn2 = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchId, false)
|
|
end
|
|
-- altrimenti non è stata inserita lavorazione
|
|
else
|
|
sMyWarn2 = 'warning adding machining ' .. sName .. '-' .. sMilling
|
|
end
|
|
end
|
|
|
|
if sMyWarn2 and #sMyWarn2 > 0 then
|
|
sMyWarn = sMyWarn .. '\n' .. sMyWarn2
|
|
end
|
|
return sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function ManageAntiSplintByMill( Proc, nFacInd, bMillDown, bDoubleSide,
|
|
vtOrtho, nPathInt, nSurfInt, dDepth,
|
|
bOneShot, nFirstMachId)
|
|
local sMyWarn = ''
|
|
local pPaths = {}
|
|
local nAuxId
|
|
local sMilling
|
|
|
|
-- recupero la lavorazione tenendo conto dell'elevazione
|
|
local dCheckDepth
|
|
if bDoubleSide then
|
|
dCheckDepth = 0.5 * dDepth
|
|
else
|
|
if not nPathInt then
|
|
dCheckDepth = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
else
|
|
dCheckDepth = dDepth
|
|
end
|
|
end
|
|
sMilling = ML.FindMilling( 'AntiSplintMillCut', dCheckDepth, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) or
|
|
ML.FindMilling( 'AntiSplintMillCut', 2/3 * dCheckDepth, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide) or
|
|
ML.FindMilling( 'AntiSplintMillCut', nil, nil, nil, nil, not ( bMillDown and not bDoubleSide), bMillDown and not bDoubleSide)
|
|
|
|
if sMilling then
|
|
|
|
local vtN1
|
|
local nFirstId, nNumId
|
|
local dMaxElevMaster
|
|
local dExtraDepth = 0
|
|
local dCollSic
|
|
-- recupero i dati dell'utensile
|
|
local dTDiam = 50
|
|
local dMaxDepth = 0
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dTDiam = TI.dDiam or dTDiam
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
end
|
|
|
|
-- se non ho la faccia aggiunta
|
|
if not nPathInt then
|
|
-- ottengo i percorsi da cui estrapolare il percorso di antischeggia
|
|
local tFacAdjMain = ChooseContour( Proc, nFacInd, false)
|
|
local tPaths = {}
|
|
-- se non trovato nessun angolo interno valido esco
|
|
if #tFacAdjMain == 0 then
|
|
return true, sMyWarn
|
|
end
|
|
-- prendo il primo versore
|
|
_, vtN1 = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT)
|
|
dCollSic = CalcCollisionSafety( vtN1) or 0
|
|
-- se direzione tende verso una delle alle 3 direzioni azzero l'altezza extra
|
|
if abs( vtN1:getX()) > 0.7 or abs( vtN1:getY()) > 0.7 or abs( vtN1:getZ()) > 0.7 then dCollSic = 0 end
|
|
|
|
-- se fresatura da sotto salto la lavorazione
|
|
if vtN1:getZ() < BD.DRILL_VZ_MIN and not bMillDown then
|
|
local sErr = 'Error : milling from bottom'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
local ptIniPath
|
|
local nMaxLen = 0
|
|
dMaxElevMaster = BL.GetFaceElevation( Proc.Id, nFacInd)
|
|
-- ciclo tutta la tabella
|
|
for i = 1, #tFacAdjMain do
|
|
-- le 2 facce di contatto devono essere perpendicolari o non sottosquadra rispetto alla faccia di fondo
|
|
local ptP1, ptP2, dAng
|
|
ptP1 = tFacAdjMain[i][3]
|
|
ptP2 = tFacAdjMain[i][4]
|
|
dAng = tFacAdjMain[i][5]
|
|
if ( dAng < 0 and 180 + dAng >= 90 - 10 * GEO.EPS_SMALL) then
|
|
-- creo la linea da P1 a P2
|
|
nAuxId = EgtLine( _nAddGrpId, ptP1, ptP2, GDB_RT.GLOB)
|
|
table.insert( tPaths, nAuxId)
|
|
-- prendo la lunghezza massima e il punto iniziale
|
|
if tFacAdjMain[i][2] > nMaxLen then
|
|
ptIniPath = ptP1
|
|
nMaxLen = tFacAdjMain[i][2]
|
|
end
|
|
end
|
|
end
|
|
-- costruisco il/i percorso/i
|
|
nFirstId, nNumId = EgtCurveCompoByReorder( _nAddGrpId, tPaths, ptIniPath, true, GDB_RT.GLOB)
|
|
local bOkPath = true
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
if EgtCurveIsClosed( nIdPath) then
|
|
bOkPath = false
|
|
end
|
|
end
|
|
-- se ho un percorso chiuso cancello tutto
|
|
if not bOkPath then
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
EgtErase(nIdPath)
|
|
end
|
|
else
|
|
-- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati
|
|
for i = 1, nNumId do
|
|
local nIdPath = nFirstId + i - 1
|
|
pPaths = MakePathsOnExtremePoints( nIdPath, pPaths, dTDiam)
|
|
end
|
|
end
|
|
-- alrimenti ho la faccia aggiunta
|
|
else
|
|
dCollSic = CalcCollisionSafety( vtOrtho)
|
|
nFirstId = EgtCopyGlob( nPathInt, _nAddGrpId)
|
|
nNumId = 1
|
|
-- calcolo elevazione dalla faccia trasversale aggiunta
|
|
if bDoubleSide then
|
|
dMaxElevMaster = 0.5 * dDepth
|
|
else
|
|
dMaxElevMaster = dDepth
|
|
-- se la precedente svuotatura è stata fatta completamente in una sola volta
|
|
-- valuto di nuovo se devo fare due passate o una sola
|
|
if bOneShot then
|
|
-- se non è possibile svuotare completamente da una sola parte
|
|
if dMaxDepth <= ( dMaxElevMaster + BD.CUT_EXTRA + dCollSic) then
|
|
bDoubleSide = true
|
|
dMaxElevMaster = BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
else
|
|
dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
-- altrimenti non è stata fatta completamente calcolo la distanza tra faccia aggiunta e profondità superficie
|
|
else
|
|
dExtraDepth = dMaxElevMaster - BL.GetOtherFaceElevation( Proc.Id, nSurfInt, 0)
|
|
end
|
|
end
|
|
vtN1 = Vector3d(vtOrtho)
|
|
local bOkPath = SetOpenSide( nFirstId, vtOrtho, 2)
|
|
-- se non ho un percorso chiuso estraggo i percorsi
|
|
if bOkPath then
|
|
-- creo percorsi antisplint dagli estremi dei percorsi di contorno trovati
|
|
pPaths = MakePathsOnExtremePoints( nFirstId, pPaths, dTDiam)
|
|
end
|
|
EgtErase(nFirstId)
|
|
end
|
|
|
|
if #pPaths > 0 then
|
|
sMyWarn = MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1,
|
|
bDoubleSide, false, sMilling, sMyWarn,
|
|
dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId)
|
|
if bDoubleSide then
|
|
if bMillDown then
|
|
local sMillingDn = ML.FindMilling( 'AntiSplintMillCut_H2', dCheckDepth) or
|
|
ML.FindMilling( 'AntiSplintMillCut_H2', 2/3 * dCheckDepth) or
|
|
ML.FindMilling( 'AntiSplintMillCut_H2')
|
|
sMilling = sMillingDn
|
|
-- controllo dati lavorazione
|
|
local TI = GetToolInfoForMachining( sMilling)
|
|
if TI then
|
|
dTDiam = TI.dDiam or dTDiam
|
|
dMaxDepth = TI.dMaxDepth or dMaxDepth
|
|
end
|
|
end
|
|
-- se lavorazione valida
|
|
if sMilling then
|
|
sMyWarn = MakeAntiSplintByMill( Proc, pPaths, nPathInt, vtN1,
|
|
bDoubleSide, true, sMilling, sMyWarn,
|
|
dMaxElevMaster, dExtraDepth, dCollSic, dMaxDepth, nFirstMachId)
|
|
else
|
|
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library'
|
|
end
|
|
end
|
|
-- altrimenti non c'è il percorso
|
|
else
|
|
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' impossible make clean corner path'
|
|
end
|
|
-- altrimenti non è stata trovata lavorazione
|
|
else
|
|
sMyWarn = 'warning in process ' .. tostring( Proc.Id) .. ' clean corner milling/tool not found in library'
|
|
end
|
|
if #sMyWarn > 0 then
|
|
EgtOutLog( sMyWarn)
|
|
end
|
|
|
|
return true, sMyWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function DoSideMill( Proc, sName, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir, bHalf, dV)
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
sName = EgtGetName( nMchFId)
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, tFData.nFacInd}})
|
|
-- imposto uso del lato faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, EgtIf( bHeadDir, MCH_MILL_FU.PARAL_LEFT, MCH_MILL_FU.PARAL_RIGHT))
|
|
-- calcolo step effettivo ed elevazione
|
|
local dVcalc = dV - dMaxMat
|
|
local dStep = EgtMdbGetCurrMachiningParam( MCH_MP.STEP) or dMaxMat
|
|
local nStep = ceil( dVcalc / dStep)
|
|
if tFData.vtN:getZ() < - 0.5 and ( nStep % 2) == 0 then
|
|
nStep = nStep + 1
|
|
end
|
|
dStep = dVcalc / nStep + 0.1
|
|
EgtSetMachiningParam( MCH_MP.STEP, dStep)
|
|
-- imposto elevazione e dichiaro non si generano sfridi per VMill
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( dVcalc + dStep, 2) .. ';'
|
|
sNotes = sNotes .. 'VMRS=0;'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- attacchi e uscite
|
|
if tFData.vtN:getZ() > -0.5 then
|
|
EgtSetMachiningParam( MCH_MP.LITANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, tFData.dFacElev + BD.CUT_SIC)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + BD.CUT_SIC)
|
|
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
|
|
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.LINEAR)
|
|
EgtSetMachiningParam( MCH_MP.LOTANG, 0)
|
|
EgtSetMachiningParam( MCH_MP.LOPERP, tFData.dFacElev + BD.COLL_SIC)
|
|
if bHalf then
|
|
EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dH / 2)
|
|
end
|
|
end
|
|
-- tipo passate multiple
|
|
local nStepType = EgtIf( ( Proc.HeadDir and tFData.vtN:getY() < -0.5) or ( not Proc.HeadDir and tFData.vtN:getY() > 0.5), MCH_MILL_ST.ONEWAY, MCH_MILL_ST.ZIGZAG)
|
|
EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType)
|
|
-- imposto posizione braccio porta testa
|
|
local nSCC = EgtIf( ( tFData.vtN:getY() > 0.5 or ( bHeadDir and tFData.vtN:getZ() > 0.5 ) or ( not bHeadDir and tFData.vtN:getZ() < -0.5)), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM)
|
|
EgtSetMachiningParam( MCH_MP.SCC, nSCC)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
-- se divisa in due metà
|
|
if bHalf then
|
|
local nMchFNId = EgtCopyMachining( sName .. '_2', sName)
|
|
if not nMchFNId then
|
|
local sErr = 'Error copying machining ' .. sName
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- inverto direzione e lato di lavoro e direzione ausiliaria
|
|
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
|
|
EgtSetMachiningParam( MCH_MP.INVERT, not bInvert)
|
|
local nWorkSide = EgtGetMachiningParam( MCH_MP.WORKSIDE)
|
|
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( nWorkSide == MCH_MILL_WS.LEFT, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT))
|
|
EgtSetMachiningParam( MCH_MP.SCC, EgtIf( nSCC == MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM, MCH_SCC.ADIR_YP))
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFNId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
|
|
return true, ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir)
|
|
local dH, dV
|
|
-- recupero la larghezza della faccia perpendicolarmente alle altre 2
|
|
local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, EgtIf( tFData.nFacInd == 0, 1, 0), GDB_ID.ROOT)
|
|
local vtX = vtN2 ^ tFData.vtN
|
|
local frRef = Frame3d( tFData.ptC, tFData.ptC + 100 * vtX, tFData.ptC + 100 * vtN2)
|
|
local b3Ref = EgtSurfTmGetFacetBBoxRef( Proc.Id, tFData.nFacInd, GDB_BB.STANDARD, frRef)
|
|
if b3Ref then
|
|
dV = b3Ref:getDimY()
|
|
dH = b3Ref:getDimX()
|
|
end
|
|
-- se lavorazione da sotto e lunga, va divisa in due metà
|
|
local bHalf = ( tFData.vtN:getZ() < -0.5 and dH > ( BD.MAX_LEN_BH_FROM_BOTTOM or 200))
|
|
-- inserisco la lavorazione di fresatura
|
|
local sName = 'BHMill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sMilling)
|
|
local bOk, sErr = DoSideMill( Proc, sName, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir, bHalf, dV)
|
|
return bOk, sErr
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeSpecialThreeFaces( Proc, tFData)
|
|
-- se orientata verso il basso, verifico l'alternativa
|
|
if tFData.vtN:getZ() < BD.NZ_MINA and tFData.vtN2:getZ() < BD.NZ_MINA then
|
|
local sErr = 'Error : special LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- eventuali tagli preliminari
|
|
do
|
|
local bOk, sErr = MakePreCuts( Proc)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
-- Recupero la lavorazione di fresa
|
|
local sMilling = ML.FindMilling( 'LongSmallCut')
|
|
if not sMilling then
|
|
local sErr = 'Error : LongSmallCut not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Recupero la lavorazione di svuotatura
|
|
local sMchFind = 'Pocket'
|
|
-- se forzato uso truciolatore
|
|
if Q_USE_ROUGH_TOOL == 1 then
|
|
sMchFind = 'OpenPocket'
|
|
end
|
|
local dDiam = min( tFData.dH, tFData.dV)
|
|
local dDiam2 = min( tFData.dH2, tFData.dV2)
|
|
local dCollSic = 2 * BD.COLL_SIC
|
|
local dCollSic2 = 2 * BD.COLL_SIC
|
|
if abs( tFData.vtN:getX()) > 0.7 or abs( tFData.vtN:getY()) > 0.7 or abs( tFData.vtN:getZ()) > 0.7 then dCollSic = 0 end
|
|
if abs( tFData.vtN2:getX()) > 0.7 or abs( tFData.vtN2:getY()) > 0.7 or abs( tFData.vtN2:getZ()) > 0.7 then dCollSic2 = 0 end
|
|
local sPocketing = ML.FindPocketing( sMchFind, dDiam2, tFData.dFacElev2 + dCollSic2)
|
|
local nPockFace = tFData.nFacInd2
|
|
-- se non trova una svuotatura adatta provo ad assegnarla all'altra faccia
|
|
if not sPocketing then
|
|
dDiam, dDiam2 = dDiam2, dDiam
|
|
dCollSic, dCollSic2 = dCollSic2, dCollSic
|
|
tFData = SwapFacetsData( tFData)
|
|
|
|
-- prendo a riferimento la seconda faccia per la svuotatura
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam2, tFData.dFacElev2 + dCollSic2)
|
|
|
|
if not sPocketing then
|
|
local sErr = 'Error : ' .. sMchFind .. ' not found in library'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
|
|
-- provo con contornatura
|
|
local dDiamTool = 20
|
|
-- verifico se forma ad L
|
|
local bIsU, bIsL = TestUL( Proc)
|
|
if bIsL then
|
|
local bOk, sWarn
|
|
bOk, sWarn, _ = MakeByMill( Proc, tFData, dCollSic, true, sMilling)
|
|
if not bOk then return bOk, sWarn end
|
|
else
|
|
local sErr = 'Error : Impossible mill special LapJoint'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- inserisco la lavorazione di svuotatura
|
|
local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id))
|
|
local nMchFId = EgtAddMachining( sName, sPocketing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nPockFace}})
|
|
-- imposto uso faccia
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT)
|
|
-- imposto posizione braccio porta testa
|
|
if tFData.vtN:getY() < GEO.EPS_SMALL then
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP)
|
|
end
|
|
-- se tasca aperta, imposto opportuno attacco
|
|
if sMchFind == 'OpenPocket' then
|
|
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.SPIRALIN)
|
|
end
|
|
-- imposto elevazione
|
|
local sNotes = 'MaxElev=' .. EgtNumToString( tFData.dFacElev2, 1) .. ';'
|
|
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
-- provo ad allargare leggermente la tasca
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, -0.1)
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
|
|
-- se abilitato dal parametro Q inserisco foro sullo spigolo
|
|
if Q_BORE_ON_CORNER == 1 then
|
|
local bOk, sWarn = MakeDrillOnCorner( Proc, 0, dDiamTool, true)
|
|
if not bOk then return false, sWarn end
|
|
-- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura
|
|
elseif Q_BORE_ON_CORNER == 2 then
|
|
local bOk, sWarn = MakeSharpCleanCorner( Proc, 0, dDiamTool)
|
|
if not bOk then return false, sWarn end
|
|
end
|
|
|
|
return true, ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeByChainsaw( Proc, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId)
|
|
-- verifico se posso farlo con la sega-catena
|
|
local bMakeChainSaw, sSawing, dMaxMat, dSawCornerRad, dSawThick = VerifyChainSaw( dDimMin, dDimMax)
|
|
|
|
if bMakeChainSaw then
|
|
-- Verifico se necessarie più passate
|
|
local nStep = ceil( ( dDimMin - 10 * GEO.EPS_SMALL) / dSawThick)
|
|
local dStep = 0
|
|
if nStep > 1 then
|
|
dStep = ( dDimMin - dSawThick) / ( nStep - 1)
|
|
end
|
|
for i = 1, nStep do
|
|
-- inserisco la lavorazione di sawing
|
|
local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i)
|
|
local nMchFId = EgtAddMachining( sName, sSawing)
|
|
if not nMchFId then
|
|
local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- aggiungo geometria
|
|
EgtSetMachiningGeometry( {{ Proc.Id, nLongFaceId}})
|
|
-- imposto uso del lato faccia
|
|
-- al momento, dato che la fessura è passante da parte a parte, gestisco solo la lavorazione
|
|
-- dall'alto e di fronte (da dietro è disabilitata perchè ho exracorsa con la FAST).
|
|
-- Questa feature non è applicata su facce di testa e quindi non controllo l'entrata in X
|
|
if abs(vtOrtho:getZ()) >= 0.707 then
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN)
|
|
else
|
|
EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK)
|
|
end
|
|
local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nLongFaceId, GDB_ID.ROOT)
|
|
-- imposto angolo 3° asse rot
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 1))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho))
|
|
-- imposto offset radiale
|
|
local dOffs = ( i - 1) * dStep
|
|
EgtSetMachiningParam( MCH_MP.OFFSR, dOffs)
|
|
-- se possibile aumento l'affondamento pari al raggio corner + 1
|
|
if dMaxMat > (dDepth + dSawCornerRad + 1) then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, (dDepth + dSawCornerRad + 1))
|
|
-- se massimo affondamento utensile inferiore fessura, setto affondamento ed emetto warning
|
|
elseif dMaxMat < dDepth then
|
|
EgtSetMachiningParam( MCH_MP.DEPTH, dMaxMat)
|
|
local sWarn = 'Warning : elevation bigger than max tool depth'
|
|
EgtOutLog( sWarn)
|
|
end
|
|
-- eseguo
|
|
if not ML.ApplyMachining( true, false) then
|
|
if EgtGetOutstrokeInfo() then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, GetChainSawBlockedAxis( 2))
|
|
EgtSetMachiningParam( MCH_MP.INITANGS, GetChainSawInitAngs( vtN, vtOrtho))
|
|
if not ML.ApplyMachining( true, false) then
|
|
local _, sErr = EgtGetLastMachMgrError()
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sErr
|
|
end
|
|
end
|
|
if EgtIsMachiningEmpty() then
|
|
local _, sWarn = EgtGetMachMgrWarning( 0)
|
|
EgtSetOperationMode( nMchFId, false)
|
|
return false, sWarn
|
|
end
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeSidePocketings( Proc, tFData, dCollSic, bSpecialMillOnSide,
|
|
nBottomFace, sMillingOnSide, dToolDiamOnSide, dThickMillOnSide,
|
|
bSinglePart, bIsU, bIsL, dDiam, bMillDown, bMillUp, sMchFind, sMchFindBackUp)
|
|
local bTryWithBlades = true
|
|
local nOk, bOk, sWarn, sStat, sErr, dDimMin, dDimMax, dDepth, vtOrtho, bOrthoFaces, nSurfInt, sPocketing, nLongFaceId
|
|
if bSpecialMillOnSide then
|
|
-- eseguo
|
|
bOk, sWarn = MakeByMillAsSaw( Proc, tFData, nBottomFace, sMillingOnSide, dToolDiamOnSide, dThickMillOnSide)
|
|
if bOk then
|
|
return 1, true, sWarn
|
|
end
|
|
end
|
|
-- se feature 16 o 17 e se forzata lama provo prima con questa e poi con la fresa
|
|
if ( Proc.Prc == 16 or Proc.Prc == 17) and _bForceUseBlade then
|
|
-- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame
|
|
if bTryWithBlades and _nChamfer < 2 then
|
|
-- anche su macchine con testa da sotto, la sega a catena è solo da sopra
|
|
if tFData.vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and tFData.nFacInd2 then
|
|
tFData = SwapFacetsData( tFData)
|
|
end
|
|
-- eseguo
|
|
bOk, sWarn, sStat = MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nil, bOrthoFaces, nBottomFace, nSurfInt)
|
|
if not bOk then
|
|
-- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e
|
|
-- se non è possibile allora provo in seguito con lama o segacatena
|
|
-- o passare subito dalla lavorazione con lama/sega catena
|
|
if Proc.Fct == 3 and bIsU then
|
|
-- lavoro con svuotature (singola o doppia contrapposta)
|
|
nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, _, _, _, _, _, _, _, _, bOrthoFaces = MakeByPockets( Proc, nil, bMillDown)
|
|
-- se lavorazione non idonea (asse della feature troppo inclinato e impossibile lavorare completamente da due parti)
|
|
if nOk == -2 then
|
|
if not sMchFind then
|
|
sMchFind = sMchFindBackUp
|
|
end
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr = 'Error : ' .. sMchFind .. ' not found in library'
|
|
EgtOutLog( sErr)
|
|
return 1, false, sErr
|
|
end
|
|
elseif nOk < 0 then
|
|
return 1, false, sErr
|
|
elseif nOk == 0 then
|
|
if sStat == 'MNF' then
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr = 'Error : ' .. sMchFind .. ' not found in library'
|
|
EgtOutLog( sErr)
|
|
return 1, false, sErr
|
|
end
|
|
else
|
|
return 1, bOk, sWarn
|
|
end
|
|
else
|
|
bOk = true
|
|
return 1, bOk, sErr
|
|
end
|
|
else
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr = 'Error : ' .. sMchFind .. ' not found in library'
|
|
EgtOutLog( sErr)
|
|
return 1, false, sErr
|
|
end
|
|
end
|
|
else
|
|
return 1, bOk, sWarn
|
|
end
|
|
else
|
|
-- se devo inserire il chamfer
|
|
if ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL)) and _nChamfer > 0 then
|
|
-- ottengo le dimensioni dello pseudotunnel
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc)
|
|
local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt)
|
|
if nOk < 0 then return 1, false, sErr end
|
|
end
|
|
bOk = true
|
|
return 1, bOk, sWarn
|
|
end
|
|
else
|
|
-- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo
|
|
-- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa
|
|
-- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z
|
|
-- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia
|
|
-- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in:
|
|
-- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a furma U e con 3 facce oppore a forma a L e con 2 facce
|
|
local bPassThrou = ( Proc.Box:getDimY() > _b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > _b3Raw:getDimZ() - 1)
|
|
local bPassEdge = ( ( ( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * _b3Raw:getDimX())
|
|
if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 1 and ( ( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then
|
|
local bOk
|
|
local bSawDown = ( bMillDown and not bMillUp)
|
|
_, bOk, sWarn = ManageAntiSplintBySaw( Proc, bIsU, tFData.vtN, tFData.nFacInd, sWarn, bSawDown, true)
|
|
if not bOk then return 1, false, sWarn end
|
|
end
|
|
-- in base al flag interno e al numero di facce e se ha forma ad U: provo prima la svuotatura sul fianco e
|
|
-- se non è possibile allora provo in seguito con lama o segacatena
|
|
-- o passare subito dalla lavorazione con lama/sega catena
|
|
if _bTrySidePocketAtFirst and Proc.Fct == 3 and bIsU then
|
|
-- lavoro con svuotature (singola o doppia contrapposta)
|
|
local dDiamTool = 100
|
|
local nPathInt, nSurfInt, bOneShot, nFirstMachId, bDoubleSide
|
|
nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, dDiamTool,
|
|
bDoubleSide, nPathInt, nSurfInt, bOneShot, bMillDown, nFirstMachId, bOrthoFaces = MakeByPockets( Proc, nil, bMillDown)
|
|
if nOk == -2 then
|
|
if not sMchFind then
|
|
sMchFind = sMchFindBackUp
|
|
end
|
|
sPocketing = ML.FindPocketing( sMchFind, dDiam)
|
|
if not sPocketing then
|
|
local sErr2 = 'Error : ' .. sMchFind .. ' not found in library'
|
|
EgtOutLog( sErr2)
|
|
return 1, false, sErr2
|
|
end
|
|
bTryWithBlades = false
|
|
sWarn = sErr
|
|
elseif nOk < 0 then
|
|
return 1, false, sErr
|
|
elseif nOk > 0 then
|
|
bTryWithBlades = false
|
|
sWarn = sErr
|
|
-- se ho antischeggia con fresa le inserisco
|
|
if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 2 then
|
|
local bOk, sWarn2 = ManageAntiSplintByMill( Proc, tFData.nFacInd, bMillDown, bDoubleSide, vtOrtho,
|
|
nPathInt, nSurfInt, dDepth, bOneShot, nFirstMachId)
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
end
|
|
-- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola
|
|
if Q_CONTOUR_SMALL_TOOL > 0 then
|
|
local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, dDiamTool, bMillDown,
|
|
bDoubleSide, vtOrtho, nPathInt, nSurfInt, dDepth, bOneShotm)
|
|
if not bOk then return 1, false, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
end
|
|
end
|
|
bOk = true
|
|
end
|
|
-- 03/09/2020 da conferma di Fabio Squaratti: Per ora solo sulla feature 016:
|
|
-- se ha fallito la fresatura (qua sopra) allora di default (anche se il flag Q della lama è disattivato) prima provo la lama
|
|
if Proc.Prc == 16 then
|
|
_bForceUseBlade = true
|
|
end
|
|
-- Se la svuotatura precedente non è stata fatta e smusso non è esclusivo, provo con le lame
|
|
if bTryWithBlades and _nChamfer < 2 then
|
|
-- anche su macchine con testa da sotto, la sega a catena è solo da sopra
|
|
if tFData.vtN:getZ() < BD.NZ_MINA and BD.DOWN_HEAD and tFData.nFacInd2 then
|
|
tFData = SwapFacetsData( tFData)
|
|
end
|
|
-- eseguo
|
|
bOk, sWarn, sStat = MakeByChainOrSaw( Proc, tFData, dDimMin, dDimMax, vtOrtho, nLongFaceId, bOrthoFaces, nBottomFace, nSurfInt)
|
|
if not bOk and sStat == 'MNF' then
|
|
_, sPocketing = VerifyPocket( dDiam, tFData.dFacElev + dCollSic, nil, sMchFind, bMillUp, bMillDown)
|
|
if sPocketing then
|
|
sWarn = ''
|
|
else
|
|
local sErr2 = 'Error : ' .. sMchFind .. ' not found in library'
|
|
EgtOutLog( sErr2)
|
|
return 1, false, sErr2
|
|
end
|
|
else
|
|
-- se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola
|
|
if Q_CONTOUR_SMALL_TOOL > 0 then
|
|
local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, 100, bMillDown)
|
|
if not bOk then return 1, false, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
end
|
|
return 1, bOk, sWarn
|
|
end
|
|
-- altrimenti verifico se ho già svuotato dal fianco, se si esco
|
|
else
|
|
-- se non ho annullato la/le svuotatura/e dal fianco
|
|
if nOk ~= -2 then
|
|
return 1, bOk, sWarn
|
|
end
|
|
end
|
|
end
|
|
|
|
return 0, true, ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakePocketingOrMilling( Proc, tFData, bSinglePart)
|
|
-- verifico se forma ad U o L
|
|
local bIsU, bIsL = TestUL( Proc)
|
|
local bUseOtherFace
|
|
-- se orientata verso il basso e non c'è testa da sotto, verifico l'alternativa
|
|
if tFData.vtN:getZ() < BD.NZ_MINA and not BD.DOWN_HEAD and tFData.nFacInd2 then
|
|
tFData = SwapFacetsData( tFData)
|
|
bUseOtherFace = true
|
|
end
|
|
-- verifico non sia orientata verso il basso o ci sia una testa dal basso
|
|
local bFaceDown = ( tFData.vtN:getZ() < BD.NZ_MINA)
|
|
if bFaceDown and not BD.DOWN_HEAD then
|
|
local sErr = 'Error : LapJoint from bottom impossible'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- se forma a L e la componente in X è maggiore di 60° e non in testa allora verifico se posso utilizzare la faccia secondaria
|
|
if bIsL and abs( tFData.vtN:getX()) > 0.866 and
|
|
( Proc.Box:getMax():getX() < _b3Solid:getMax():getX() - 10 or tFData.vtN:getX() < 0) and
|
|
( not Proc.Tail or tFData.vtN:getX() > 0) then
|
|
-- se non ho scambiato la faccia
|
|
if not bUseOtherFace then
|
|
if tFData.nFacInd2 then
|
|
tFData = SwapFacetsData( tFData)
|
|
-- altrimenti cerco la faccia secondaria per adiacenza alla principale
|
|
else
|
|
-- Cerco una faccia adiacente alla principale sul lato lungo
|
|
local nFacAdj, sErr = GetFaceAdj( Proc, tFData)
|
|
if nFacAdj < 0 then
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
tFData = UpdateFacet1Data( Proc.Id, tFData, nFacAdj)
|
|
end
|
|
-- altrimenti se ho già cambiato faccia do errore per impossibilità di lavorazione
|
|
else
|
|
local sErr = 'Error : impossible to machine by side angle too big that cause collision'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- eventuali tagli preliminari
|
|
do
|
|
local bOk, sErr = MakePreCuts( Proc)
|
|
if not bOk then return false, sErr end
|
|
end
|
|
-- imposto altezza aggiuntiva di elevazione
|
|
local dCollSic = CalcCollisionSafety( tFData.vtN)
|
|
-- abilitazione lavorazione da sotto
|
|
local bMillUp = ( BD.DOWN_HEAD and tFData.vtN:getZ() > -0.259)
|
|
local bMillDown = ( BD.DOWN_HEAD and tFData.vtN:getZ() < 0.342)
|
|
-- settaggio voluto da Alessandro/Fabio (per fare angoli con fresa piccola)
|
|
local sMchFind = 'Pocket'
|
|
local dDiam = min( tFData.dH, tFData.dV)
|
|
local bTailOnSide = ( Proc.Box:getMin():getX() - _b3Solid:getMin():getX() < 0.1 and not Proc.Tail)
|
|
if ( Proc.Fct == 1) or ( ( Proc.Fct == 2 or Proc.Fct == 3) and bIsL) or ( ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 4 and not bTailOnSide)) and bSinglePart) then
|
|
sMchFind = 'OpenPocket'
|
|
if bIsU then
|
|
dDiam = GetUShapeWidth( Proc, tFData.nFacInd) or dDiam
|
|
elseif Proc.Fct == 4 then
|
|
-- per rifinire gli angoli premio utensile diam 25 o da BD
|
|
dDiam = min( dDiam, BD.MAXDIAM_POCK_CORNER or 30)
|
|
elseif Proc.Fct == 3 and bIsL then
|
|
-- per rifinire gli angoli premio utensile diam 25 o da BD
|
|
dDiam = min( 2 * dDiam, BD.MAXDIAM_POCK_CORNER or 30)
|
|
else
|
|
dDiam = 2 * dDiam
|
|
end
|
|
end
|
|
sMchFindBackUp = sMchFind
|
|
local nUseRoughTool = EgtIf( bSinglePart, 0, 1)
|
|
-- 04/08/2020 Se settato parametro uso truciolatore (parametro Q), non si devono prendere altre frese, si da errore (Fabio)
|
|
-- Questa opzione si scontra facilmente con altre interpretazioni dello stasso parametro Q (per tornare indietro bNewCheck = false)
|
|
local bNewCheck = true
|
|
-- se processo 20 e non sto usando il truciolatore
|
|
if bNewCheck and Proc.Prc == 20 and nUseRoughTool == 0 then
|
|
-- verifico se forzato uso truciolatore
|
|
if Q_USE_ROUGH_TOOL and Q_USE_ROUGH_TOOL ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- 03/12/2020 aggiunto controllo su feature 30 senza uso truciolatore
|
|
if bNewCheck and Proc.Prc == 30 and nUseRoughTool == 0 then
|
|
-- verifico se forzato uso truciolatore
|
|
if Q_SIDE_ROUGH_TOOL and Q_SIDE_ROUGH_TOOL ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- se processo 20 e non sto usando il truciolatore
|
|
if Proc.Prc == 20 and nUseRoughTool == 0 then
|
|
if Q_USE_ROUGH_TOOL and Q_USE_ROUGH_TOOL ~= 0 then
|
|
sMchFind = 'OpenPocket'
|
|
nUseRoughTool = 1
|
|
end
|
|
end
|
|
-- se da sotto, imposto massima lunghezza secondo la direzione
|
|
local dMaxTotLen
|
|
if bMillDown and BD.GetBottomToolMaxTotLen then
|
|
dMaxTotLen = BD.GetBottomToolMaxTotLen( tFData.vtN)
|
|
end
|
|
-- ricerca lavorazione
|
|
local sPocketing, sMyPocketing, dMyTMaxDepth
|
|
_, sMyPocketing, dMyTMaxDepth, _, bMillDown = VerifyPocket( dDiam, tFData.dFacElev + dCollSic, dMaxTotLen, sMchFind .. EgtIf( bMillDown, '_H2', ''), bMillUp, bMillDown)
|
|
--local sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, dFacElev + dCollSic, dMaxTotLen)
|
|
--if not sMyPocketing then
|
|
-- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind .. EgtIf( bMillDown, '_H2', ''), dDiam, nil, dMaxTotLen)
|
|
--end
|
|
--if not sMyPocketing and bMillUp then
|
|
-- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam, dFacElev + dCollSic)
|
|
-- if not sMyPocketing then
|
|
-- sMyPocketing, dMyTDiam, dMyTMaxDepth = ML.FindPocketing( sMchFind, dDiam)
|
|
-- end
|
|
-- bMillDown = false
|
|
--end
|
|
if sMyPocketing and
|
|
( dMyTMaxDepth > tFData.dFacElev + dCollSic - 10 * GEO.EPS_SMALL or ( dMyTMaxDepth > 0.8 * tFData.dFacElev + dCollSic and not bIsU) or ( bIsL and nUseRoughTool == 0)) then
|
|
sPocketing = sMyPocketing
|
|
end
|
|
if bMillDown then
|
|
sMchFind = sMchFind .. '_H2'
|
|
end
|
|
-- 2021.09.16 Richiesta di Fabio Squaratti per lavorazione "Lamello":
|
|
-- se ho attiva questo tipo di lavorazione (delle fresature) e una di queste feature: L016, L030, L032, L039
|
|
-- verifico se sono compatibili con questa lavorazione forma a U e larga più dell'altezza tagliente e profondità compatibile con
|
|
local bSpecialMillOnSide
|
|
local dThickMillOnSide = 0
|
|
local sMillingOnSide
|
|
local dToolDiamOnSide = 0
|
|
local dMaxDepthOnSide = 0
|
|
if ( Proc.Prc == 16 or Proc.Prc == 30 or Proc.Prc == 32 or Proc.Prc == 39) then
|
|
-- verifico se ho una gola con 3 facce ed eventualmente delle facce terminali:
|
|
-- faccio una copia della superfice ed elimino le facce che hanno dimensione X < 1 e le facce risultanti devono essere una U
|
|
local nTestId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL
|
|
if nTestId then
|
|
local bNewIsU
|
|
local bExit
|
|
local nFaces = EgtSurfTmFacetCount( nTestId)
|
|
while not bExit and nFaces >= 3 do
|
|
local bDeleteFace
|
|
local nInt = 0
|
|
while not bDeleteFace and nInt < nFaces do
|
|
nInt = nInt + 1
|
|
local b3Facet = EgtSurfTmGetFacetBBoxGlob( nTestId, nInt - 1, GDB_BB.STANDARD)
|
|
local vtNi = EgtSurfTmFacetNormVersor( nTestId, nInt - 1, GDB_ID.ROOT)
|
|
-- se dimensione faccia sulla X
|
|
if b3Facet:getDimX() < 1 or abs( vtNi:getX()) > 0.1 then
|
|
EgtSurfTmRemoveFacet( nTestId, nInt - 1)
|
|
bDeleteFace = true
|
|
end
|
|
end
|
|
nFaces = EgtSurfTmFacetCount( nTestId)
|
|
-- se non ho cancellato una faccia faccio il test per forma ad U
|
|
if not bDeleteFace then
|
|
-- ottengo il numero di facce rimanenti
|
|
bNewIsU = ( nFaces == 3 and not TestElleShape3( nTestId, true))
|
|
bExit = true
|
|
end
|
|
end
|
|
-- verifico che la componente x della faccia 0 deve essere nulla
|
|
local vtN1 = EgtSurfTmFacetNormVersor( nTestId, 0, GDB_ID.ROOT)
|
|
if bNewIsU and abs( vtN1:getX()) > 0.01 then
|
|
bNewIsU = false
|
|
end
|
|
-- cancello la copia del percorso
|
|
EgtErase( nTestId)
|
|
|
|
if bNewIsU and ( not BD.MIN_LEN_LAMELLO or
|
|
( Proc.TotBox and Proc.TotBox:getDimX() > BD.MIN_LEN_LAMELLO) or
|
|
( not Proc.TotBox and Proc.Box:getDimX() > BD.MIN_LEN_LAMELLO)) then
|
|
-- recupero la lavorazione
|
|
local bDownhead = BD.DOWN_HEAD and tFData.vtN:getZ() < BD.NZ_MINA
|
|
sMillingOnSide = ML.FindMilling( 'SideMillAsBlade_H2', nil, nil, nil, nil, not bDownhead, bDownhead)
|
|
|
|
if sMillingOnSide then
|
|
-- recupero i dati dell'utensile
|
|
local dToolLength = 0
|
|
local TI = GetToolInfoForMachining( sMillingOnSide)
|
|
if TI then
|
|
dToolLength = TI.dLength or dToolLength
|
|
dToolDiamOnSide = TI.dDiam or dToolDiamOnSide
|
|
dThickMillOnSide = TI.dMaxMat or dThickMillOnSide
|
|
dMaxDepthOnSide = TI.dSideDepth or dMaxDepthOnSide
|
|
end
|
|
-- 2021.09.17 Su conferma di Fabio Squaratti, se la gola è più stretta dell'utensile o la profondità della gole è maggiore
|
|
-- del valore parametro SIDEDEPTH (preso dalle note utente dell'utensile) allora si prosegue come se non fosse abilitata
|
|
-- questo tipo di lavorazione SideMillAsBlade
|
|
if dDiam > dThickMillOnSide - 10 * GEO.EPS_SMALL and tFData.dFacElev < dMaxDepthOnSide + 10 * GEO.EPS_SMALL then
|
|
bSpecialMillOnSide = true
|
|
-- disabilito eventuale svuotatura
|
|
sPocketing = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
-- se feature 16 e forzata lama e forma ad U, annulla la svuotatura
|
|
if Proc.Prc == 16 and _bForceUseBlade and Proc.Fct == 3 and bIsU then
|
|
sPocketing = nil
|
|
end
|
|
-- se lavorazione fresa come lama disabilito eventuale antischegggia
|
|
if bSpecialMillOnSide then Q_ANTISPLINT_TYPE = 0 end
|
|
-- se non trova una svuotatura adatta
|
|
if not sPocketing then
|
|
-- se forma a L provo con contornatura
|
|
if bIsL and not bSpecialMillOnSide then
|
|
-- se smusso non è esclusivo
|
|
if _nChamfer < 2 then
|
|
return MakeByMill( Proc, tFData, dCollSic)
|
|
end
|
|
-- altrimenti, in base alla forma, provo con svuotature di fianco o con la sega a catena o lama
|
|
else
|
|
local stat, bOk, sWarn = MakeSidePocketings( Proc, tFData, dCollSic, bSpecialMillOnSide, nBottomFace,
|
|
sMillingOnSide, dToolDiamOnSide, dThickMillOnSide, bSinglePart,
|
|
bIsU, bIsL, dDiam, bMillDown, bMillUp, sMchFind, sMchFindBackUp)
|
|
if stat == 1 then
|
|
return bOk, sWarn
|
|
end
|
|
end
|
|
else
|
|
-- se devo inserire il chamfer
|
|
if ( ( Proc.Fct == 3 and bIsU) or ( Proc.Fct == 2 and bIsL)) and _nChamfer > 0 then
|
|
-- ottengo le dimensioni dello pseudotunnel
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc)
|
|
local nOk, sErr = MakeChamfer( Proc, vtOrtho, nSurfInt)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
end
|
|
-- se richiesti antischeggia con lama su U trasversale e smusso non esclusivo
|
|
-- rimane da gestire: se da eseguire con fresa o se richiesto lama ma impossibile utilizzarla, si utilizza fresa
|
|
-- 2021.04.27 esegue antischeggia di lama se forma U o L con feature passante in Y o Z
|
|
-- 2021.07.16 Per poter eseguire antischeggia di lama su feature che non sono passanti da faccia a faccia
|
|
-- ma che sono su un angolo (coinvolgono 2 facce contigue) è stato modificato il confronto in:
|
|
-- esegue antischeggia di lama se forma U o L con feature passante in Y o Z, oppure se feature a forma U e con 3 facce oppore a forma a L e con 2 facce
|
|
local bMadeASbyBld = false
|
|
local bPassThrou = ( Proc.Box:getDimY() > _b3Raw:getDimY() - 1 or Proc.Box:getDimZ() > _b3Raw:getDimZ() - 1)
|
|
local bPassEdge = ( ( ( bIsU and Proc.Fct == 3) or ( bIsL and Proc.Fct == 2)) and bSinglePart and Proc.Box:getDimX() < 0.9 * _b3Raw:getDimX())
|
|
if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 1 and ( ( bIsU or bIsL) and ( bPassThrou or bPassEdge)) then
|
|
local bOk
|
|
local bSawDown = ( bMillDown and not bMillUp)
|
|
bMadeASbyBld, bOk, sWarn = ManageAntiSplintBySaw( Proc, bIsU, tFData.vtN, tFData.nFacInd, sWarn, bSawDown)
|
|
if not bOk then return false, sWarn end
|
|
end
|
|
if _nChamfer < 2 and Q_ANTISPLINT_TYPE == 2 then
|
|
local bOk, sWarn2
|
|
bOk, sWarn2 = ManageAntiSplintByMill( Proc, tFData.nFacInd, bMillDown)
|
|
if not bOk then return false, sWarn2 end
|
|
end
|
|
-- se smusso non esclusivo
|
|
if _nChamfer < 2 then
|
|
-- eseguo la svuotatura della faccia principale, mi restituisce id utensile, il diametro utensile per il foro opzionale
|
|
local tvtNx = {}
|
|
tvtNx[2] = tFData.vtN
|
|
local bOk, sWarn2, sTuuidPk, dDiamTool
|
|
bOk, sWarn2, sTuuidPk, dDiamTool = MakePocket( Proc, tFData.ptC, tvtNx, tFData.nFacInd, sMchFind, nUseRoughTool, sPocketing, tFData.dFacElev + dCollSic)
|
|
if not bOk then return false, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
-- se ho più di 3 facce e non di forma ad U oppure ho 3 facce e di forma ad U
|
|
-- e non sono stati inseriti antischeggia di lama
|
|
-- controllo se c'è una faccia non ortogonale alla principale e la lavoro con una contornatura o svuotatura
|
|
if ( ( Proc.Fct > 3 and not bIsU) or ( Proc.Fct == 3 and bIsU)) and not bMadeASbyBld then
|
|
-- Recupero le facce adiacenti alla principale (solo quelle esistenti)
|
|
local vAdj = GetValidFacetAdjacencies( Proc.Id, tFData.nFacInd)
|
|
if not vAdj or #vAdj == 0 then
|
|
local sErr = 'Error : main face without adjacencies'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
-- Cerco una faccia adiacente alla principale con angolo > 90
|
|
local tDimAndRef = {}
|
|
tvtNx = {}
|
|
tvtNx[1] = tFData.vtN
|
|
tDimAndRef[1] = { tFData.dH, tFData.dV, tFData.rfFac}
|
|
for i = 1, #vAdj do
|
|
local bAdj, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, tFData.nFacInd, vAdj[i], GDB_ID.ROOT)
|
|
if bAdj and dAng < 0 and 180 + dAng > 90.1 then
|
|
local rfFac2, dH2, dV2 = EgtSurfTmFacetMinAreaRectangle( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
_, tvtNx[2] = EgtSurfTmFacetCenter( Proc.Id, vAdj[i], GDB_ID.ROOT)
|
|
tDimAndRef[2] = { dH2, dV2, rfFac2}
|
|
local ptPs = ( ptP1 + ptP2) / 2
|
|
local bOk, sWarn2 = MachineByMill( Proc, tvtNx, tFData.nFacInd, vAdj[i], ptPs, tDimAndRef,
|
|
EgtIf( Proc.Fct == 3 and bIsU, 0, 2), nUseRoughTool, dAng, sPocketing, sTuuidPk, tFData.dFacElev)
|
|
if not bOk then return bOk, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
end
|
|
end
|
|
end
|
|
-- se abilitato dal parametro Q inserisco foro sullo spigolo
|
|
if Q_BORE_ON_CORNER == 1 then
|
|
local bOk, sWarn2 = MakeDrillOnCorner( Proc, tFData.nFacInd, dDiamTool)
|
|
if not bOk then return false, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
-- altrimenti se abilitato dal parametro Q inserisco percorso di pulitura
|
|
elseif Q_BORE_ON_CORNER == 2 then
|
|
local bOk, sWarn2 = MakeSharpCleanCorner( Proc, tFData.nFacInd, dDiamTool)
|
|
if not bOk then return false, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
-- altrimenti se abilitato dal parametro Q inserisco pulitura spigoli o contorno con fresa più piccola
|
|
elseif Q_CONTOUR_SMALL_TOOL > 0 then
|
|
local bOk, sWarn2 = MakeRoundCleanCornerOrContour( Proc, tFData.nFacInd, dDiamTool, bMillDown)
|
|
if not bOk then return false, sWarn2 end
|
|
sWarn = FormatWarning( sWarn, sWarn2)
|
|
end
|
|
end
|
|
|
|
return true, ''
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeTwoFaces( Proc, bSinglePart, bPrevBhSideMill)
|
|
-- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer
|
|
-- genero errore e non faccio nulla
|
|
if _nChamfer < 0 then
|
|
return false, _sErrCham
|
|
end
|
|
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local tFData = GetFacetsData( Proc.Id)
|
|
if not tFData.nFacInd or tFData.nFacInd < 0 then
|
|
local sErr = 'Error : MakeTwoFaces could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia
|
|
local bMakeBySideMill, _, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill)
|
|
if bPrevBhSideMill == nil then
|
|
bPrevBhSideMill = bMakeBySideMill
|
|
end
|
|
if bMakeBySideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then
|
|
-- se smusso non è esclusivo
|
|
if _nChamfer < 2 then
|
|
local bOk, sErr = MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir)
|
|
return bOk, sErr
|
|
end
|
|
-- altrimenti lavoro con svuotatura
|
|
else
|
|
local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart)
|
|
return bOk, sErr
|
|
end
|
|
|
|
return true, '', bPrevBhSideMill
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeThreeFaces( Proc, bSinglePart, bPrevBhSideMill)
|
|
-- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer
|
|
-- genero errore e non faccio nulla
|
|
if _nChamfer < 0 then
|
|
return false, _sErrCham
|
|
end
|
|
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local tFData = GetFacetsData( Proc.Id)
|
|
if not tFData.nFacInd or tFData.nFacInd < 0 then
|
|
local sErr = 'Error : MakeThreeFaces could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
|
|
-- se fattibile con fresa BH di fianco e spessore utensile inferiore alla larghezza faccia
|
|
local bMakeBySideMill, _, bHeadDir, sMilling, dMaxMat, dToolDiam = VerifyBHSideMill( Proc, bSinglePart, bPrevBhSideMill)
|
|
if bPrevBhSideMill == nil then
|
|
bPrevBhSideMill = bMakeBySideMill
|
|
end
|
|
--if bMakeBySideMill and ( dMaxMat <= tFData.dV + 15 * GEO.EPS_SMALL) then
|
|
if bMakeBySideMill and ( dMaxMat <= tFData.dH + 15 * GEO.EPS_SMALL) then
|
|
-- se smusso non è esclusivo
|
|
if _nChamfer < 2 then
|
|
local bOk, sErr = MakeSideMill( Proc, sMilling, tFData, dMaxMat, dToolDiam, bHeadDir)
|
|
return bOk, sErr
|
|
end
|
|
-- altrimenti lavoro con svuotatura
|
|
else
|
|
local bSpecial3faces = false
|
|
local bBoxF = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, tFData.rfFac)
|
|
|
|
if tFData.dH * tFData.dV < 0.9 * ( bBoxF:getDimX() * bBoxF:getDimY()) then
|
|
bSpecial3faces = true
|
|
end
|
|
|
|
-- se riconosciuta gestione special (limitata per ora alla feature 20)
|
|
if bSpecial3faces and Proc.Prc == 20 and tFData.nFacInd2 then
|
|
-- se smusso non è esclusivo
|
|
if _nChamfer < 2 then
|
|
local bOk, sErr = MakeSpecialThreeFaces( Proc, tFData)
|
|
return bOk, sErr
|
|
end
|
|
-- altrimenti lavorazione di svuotatura o contornatura
|
|
else
|
|
local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart)
|
|
return bOk, sErr
|
|
end
|
|
end
|
|
|
|
return true, '', bPrevBhSideMill
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeMoreFaces( Proc, bSinglePart, bPrevBhSideMill)
|
|
local bClosedOrthoFaces
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
local tFData = GetFacetsData( Proc.Id)
|
|
if not tFData.nFacInd or tFData.nFacInd < 0 then
|
|
if tFData.nFacInd == -1 then
|
|
bClosedOrthoFaces = tFData.isOrthoFaces
|
|
else
|
|
local sErr = 'Error : MakeMoreFaces could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- se è una feature scanalatura (con 5 facce) e non è stata riconosciuta come fessura, eseguo altre verifiche
|
|
if Proc.Prc == 16 and Proc.Fct == 5 and not bClosedOrthoFaces then
|
|
local nBottomFace
|
|
-- dalla copia della superfice, ciclo eliminando una faccia per volta per verificare se trova fessura
|
|
for i = 1, Proc.Fct do
|
|
local nNewProcId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL
|
|
-- elimino una faccia
|
|
nBottomFace = i - 1
|
|
if EgtSurfTmRemoveFacet( nNewProcId, nBottomFace) then
|
|
-- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa
|
|
tFData = GetFacetsData( nNewProcId)
|
|
if not tFData.nFacInd or tFData.nFacInd < 0 then
|
|
if tFData.nFacInd == -1 then
|
|
bClosedOrthoFaces = tFData.isOrthoFaces
|
|
EgtErase( nNewProcId)
|
|
break
|
|
else
|
|
EgtErase( nNewProcId)
|
|
local sErr = 'Error : MakeMoreFaces could not find reference face'
|
|
EgtOutLog( sErr)
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- altrimenti esco
|
|
else
|
|
EgtErase( nNewProcId)
|
|
break
|
|
end
|
|
end
|
|
-- se riconosciuta fessura ricalcolo l'elevazione dalla faccia di fondo
|
|
if bClosedOrthoFaces then
|
|
local dFacElev = BL.GetFaceElevation( Proc.Id, nBottomFace)
|
|
tFData = UpdateFacet1Data( Proc.Id, tFData, nBottomFace, dFacElev)
|
|
-- rendo nulla la faccia opzionale perchè si tratta di una fessura
|
|
tFData = UpdateFacet2Data( Proc.Id, tFData, nil)
|
|
-- non setto come tunnel
|
|
bClosedOrthoFaces = false
|
|
end
|
|
end
|
|
-- se non posso lavorare la feature perché condizionata dall'esecuzione del solo chamfer
|
|
-- genero errore e non faccio nulla
|
|
if _nChamfer < 0 then
|
|
return false, _sErrCham
|
|
end
|
|
-- se è un tunnel provo a vedere se è possibile lavorarlo con la svuotatura o con la sega catena
|
|
if bClosedOrthoFaces then
|
|
local bTryWithBlades = true
|
|
-- lavoro fessura con svuotature (singola o doppia contrapposta)
|
|
local nOk, sErr, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId = MakeByPockets( Proc, bClosedOrthoFaces)
|
|
if nOk < 0 then
|
|
return false, sErr
|
|
elseif nOk > 0 then
|
|
bTryWithBlades = false
|
|
end
|
|
-- Se la svuotatura precedente non è stata fatta e chamfer non è mutuamente esclusivo provo con la sega-catena
|
|
if bTryWithBlades and _nChamfer < 2 then
|
|
-- verifico se posso farlo con la sega-catena
|
|
local bOk, sErr = MakeByChainsaw( Proc, dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId)
|
|
if not bOk then
|
|
return false, sErr
|
|
end
|
|
end
|
|
-- altrimenti non è una fessura
|
|
else
|
|
local bOk, sErr = MakePocketingOrMilling( Proc, tFData, bSinglePart)
|
|
return bOk, sErr, bPrevBhSideMill
|
|
end
|
|
|
|
return true, '', bPrevBhSideMill
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function MakeLongFaces( Proc, Func)
|
|
-- divido in parti lungo X
|
|
local vAddId = {}
|
|
local nPart = max( ceil( Proc.Box:getDimX() / BD.LONGCUT_MAXLEN), 2)
|
|
local dPartLen = Proc.Box:getDimX() / nPart
|
|
local Xmin = Proc.Box:getMin():getX()
|
|
for i = 1, nPart do
|
|
-- eseguo divisione
|
|
local AddId = EgtCopyGlob( Proc.Id, _nAddGrpId) or GDB_ID.NULL
|
|
EgtSetName( AddId, 'AddPart_' .. tostring( Proc.Id) .. '_' .. tostring( i))
|
|
if i > 1 then
|
|
local ptOn = Point3d( Xmin + ( i - 1) * dPartLen, 0, 0)
|
|
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
|
|
end
|
|
if i < nPart then
|
|
local ptOn = Point3d( Xmin + i * dPartLen, 0, 0)
|
|
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
|
|
end
|
|
-- eseguo inserimento in modo da ordinare da X+ a X-
|
|
table.insert( vAddId, 1, AddId)
|
|
end
|
|
-- applico le lavorazioni sulle diverse parti
|
|
local sWarn
|
|
local bPrevBhSideMill
|
|
for i = 1, #vAddId do
|
|
local b3Box = EgtGetBBoxGlob( vAddId[i], GDB_BB.STANDARD)
|
|
local nFct = EgtSurfTmFacetCount( vAddId[i])
|
|
local AddProc = { Id = vAddId[i], Grp = Proc.Grp, Prc = Proc.Prc, Box = b3Box, TotBox = Proc.Box, Fct = nFct, Flg = Proc.Flg}
|
|
local bOk, sMyWarn
|
|
-- richiamo la funzione necessaria (passata come parametro)
|
|
bOk, sMyWarn, bPrevBhSideMill = Func( AddProc, false, bPrevBhSideMill)
|
|
if not sWarn then sWarn = sMyWarn end
|
|
if not bOk then return bOk, sWarn end
|
|
end
|
|
return true, sWarn
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
local function TestTwoFacesDownHead( Proc)
|
|
-- verifico ci siano due facce
|
|
if Proc.Fct ~= 2 then return false end
|
|
-- verifico se da lavorare con testa da sotto
|
|
local bDownHead = false
|
|
if BD.DOWN_HEAD then
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize()
|
|
bDownHead = ( vtNm:getZ() < -0.5)
|
|
end
|
|
return bDownHead
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
-- Applicazione della lavorazione
|
|
---------------------------------------------------------------------
|
|
function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
-- inizializzo variabili globali al modulo
|
|
local bOk, sErr = InitGlob( Proc, nPhase, nRawId, nPartId, dOvmHead)
|
|
if not bOk then
|
|
return bOk, sErr
|
|
end
|
|
-- limiti di fresatura semplice
|
|
local MAX_MILL_LIN = 80
|
|
-- se non forzate frese, uso la lama
|
|
local bUseBlade = Q_USE_ROUGH_TOOL ~= 1 and Q_USE_MILL ~= 1
|
|
local nForceUseBladeOnNotContinueFace
|
|
-- se ho attiva la lama e ho la feature 30, verifico i parametri Q propri della feature
|
|
if bUseBlade then
|
|
if Proc.Prc == 30 then
|
|
nForceUseBladeOnNotContinueFace = Q_BLADE_ON_ALONG_FACE
|
|
-- se antischeggia di fresa o abilitato sgrossatore di fianco
|
|
if Q_ANTISPLINT_TYPE == 2 or Q_SIDE_ROUGH_TOOL == 1 then
|
|
bUseBlade = false
|
|
end
|
|
-- se ho attiva la lama e ho la feature 32, verifico i parametri Q propri della feature
|
|
elseif Proc.Prc == 32 then
|
|
-- se antischeggia di fresa o abilitato sgrossatore di fianco
|
|
if Q_ANTISPLINT_TYPE == 2 or Q_SIDE_ROUGH_TOOL == 1 then
|
|
bUseBlade = false
|
|
end
|
|
-- se ho attiva la lama e ho la feature 34, verifico i parametri Q propri della feature
|
|
elseif Proc.Prc == 34 then
|
|
-- se antischeggia di fresa o abilitato sgrossatore di fianco
|
|
if Q_ANTISPLINT_TYPE == 2 then
|
|
bUseBlade = false
|
|
end
|
|
end
|
|
end
|
|
-- se lunghezza richiede spezzatura
|
|
if ( Proc.Box:getDimX() > BD.LONGCUT_MAXLEN) or
|
|
( Proc.Box:getDimX() > 0.7 * _b3Solid:getDimX() and Proc.Box:getDimX() > BD.LONGCUT_ENDLEN) then
|
|
-- una faccia
|
|
if Proc.Fct == 1 then
|
|
if bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then
|
|
return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace)
|
|
else
|
|
return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId)
|
|
end
|
|
-- due facce
|
|
elseif Proc.Fct == 2 then
|
|
-- verifico se da lavorare con testa da sotto
|
|
local bDownHead = TestTwoFacesDownHead( Proc)
|
|
-- determino se due facce lunghe oppure una lunga e l'altra terminale
|
|
local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD)
|
|
local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD)
|
|
if abs( b3Fac1:getDimX() - b3Fac2:getDimX()) < 50 then
|
|
-- leggo i parametri Q per utilizzare la fresa di fianco e/o lama
|
|
return Long2Cut.Make( Proc, _nPhase, _nRawId, _nPartId, Q_ANTISPLINT_TYPE == 1, Q_SIDE_ROUGH_TOOL)
|
|
elseif b3Fac1:getDimX() < 1 or b3Fac2:getDimX() < 1 then
|
|
-- la faccia 0 deve essere quella lunga
|
|
if b3Fac1:getDimX() < 1 then EgtSurfTmSwapFacets( Proc.Id, 0, 1) end
|
|
if bUseBlade then
|
|
if nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then
|
|
return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace)
|
|
else
|
|
return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead)
|
|
end
|
|
else
|
|
return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId)
|
|
end
|
|
else
|
|
if bUseBlade then
|
|
return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead)
|
|
else
|
|
return MakeLongFaces( Proc, MakeTwoFaces)
|
|
end
|
|
end
|
|
-- tre facce
|
|
elseif Proc.Fct == 3 then
|
|
-- determino se due facce lunghe oppure una lunga e l'altra terminale
|
|
local b3Fac1 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 0, GDB_BB.STANDARD)
|
|
local b3Fac2 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 1, GDB_BB.STANDARD)
|
|
local b3Fac3 = EgtSurfTmGetFacetBBoxGlob( Proc.Id, 2, GDB_BB.STANDARD)
|
|
local bApplyBladeOnLongNotContinueFace
|
|
|
|
if b3Fac1:getDimX() < 1 and b3Fac3:getDimX() < 1 then
|
|
-- la faccia 0 deve essere quella lunga
|
|
EgtSurfTmSwapFacets( Proc.Id, 0, 1)
|
|
bApplyBladeOnLongNotContinueFace = true
|
|
elseif b3Fac1:getDimX() < 1 and b3Fac2:getDimX() < 1 then
|
|
-- la faccia 0 deve essere quella lunga
|
|
EgtSurfTmSwapFacets( Proc.Id, 0, 2)
|
|
bApplyBladeOnLongNotContinueFace = true
|
|
elseif b3Fac2:getDimX() < 1 and b3Fac3:getDimX() < 1 then
|
|
bApplyBladeOnLongNotContinueFace = true
|
|
end
|
|
|
|
if bApplyBladeOnLongNotContinueFace and bUseBlade and nForceUseBladeOnNotContinueFace and nForceUseBladeOnNotContinueFace > 0 then
|
|
return LongCut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, nForceUseBladeOnNotContinueFace)
|
|
else
|
|
return MakeLongFaces( Proc, MakeThreeFaces)
|
|
end
|
|
-- 4 o 5 facce
|
|
else
|
|
return MakeLongFaces( Proc, MakeMoreFaces)
|
|
end
|
|
-- altrimenti lavorazione unica
|
|
else
|
|
-- una faccia
|
|
if Proc.Fct == 1 then
|
|
-- se piccola, con fresa
|
|
if not bUseBlade and ( Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN)) then
|
|
return MakeOneFaceByMill( Proc)
|
|
-- altrimenti, con lama
|
|
else
|
|
return Cut.Make( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead)
|
|
end
|
|
-- due facce
|
|
elseif Proc.Fct == 2 then
|
|
-- se praticamente è lunga come la trave
|
|
if Proc.Box:getDimX() > 0.8 * _b3Solid:getDimX() then
|
|
return Long2Cut.Make( Proc, _nPhase, _nRawId, _nPartId, bUseBlade, Q_SIDE_ROUGH_TOOL)
|
|
-- altrimenti
|
|
else
|
|
-- verifico se da lavorare con testa da sotto
|
|
local bDownHead = TestTwoFacesDownHead( Proc)
|
|
if BD.DOWN_HEAD then
|
|
local ptC = {}
|
|
local vtN = {}
|
|
ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT)
|
|
ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT)
|
|
local vtNm = ( vtN[1] + vtN[2])
|
|
vtNm:normalize()
|
|
bDownHead = ( vtNm:getZ() < -0.5)
|
|
end
|
|
-- determino l'angolo tra le facce
|
|
local bAdj, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT)
|
|
-- se ortogonali e non forzata lama oppure con testa da sotto, con fresa
|
|
if ( not bUseBlade or bDownHead) and bAdj and abs( dAng + 90) < 1 then
|
|
-- se piccole
|
|
if Proc.Box:getDimX() < MAX_MILL_LIN and ( Proc.Box:getDimZ() < MAX_MILL_LIN or Proc.Box:getDimY() < MAX_MILL_LIN) then
|
|
return MakeTwoFacesByMill( Proc, bDownHead)
|
|
else
|
|
return MakeTwoFaces( Proc, true)
|
|
end
|
|
-- altrimenti, con lama
|
|
else
|
|
-- verifico se due facce o L con una o due facce di terminazione
|
|
local _, bIsL = TestUL( Proc)
|
|
if bIsL and _nChamfer > 0 then
|
|
local dDimMin, dDimMax, dDepth, vtOrtho, nLongFaceId, nSurfInt = GetTunnelDimension( Proc)
|
|
local nOk, sErr = MakeChamfer( Proc, vtOrtho, _b3Solid, nSurfInt)
|
|
if nOk < 0 then return false, sErr end
|
|
end
|
|
return Fbs.MakeTwo( Proc, _nPhase, _nRawId, _nPartId, _dOvmHead, 'HeadSide' .. EgtIf( bDownHead, '_H2', ''), true, bDownHead)
|
|
end
|
|
end
|
|
-- tre facce
|
|
elseif Proc.Fct == 3 then
|
|
return MakeThreeFaces( Proc, true)
|
|
-- 4 o 5 facce
|
|
else
|
|
return MakeMoreFaces( Proc, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return ProcessLapJoint |