Files
Dario Sassi 499d06227c CamAuto 3.1d3 :
- correzioni in calcolo preview per UpdateSawing.
2026-04-30 17:47:20 +02:00

5729 lines
253 KiB
Lua

-- 2026/04/29 19:00:00
-- Programma per Cam automatico in OmagCut
-- Legenda codici errore (CAM.ERR) :
-- 0 = tutto bene
-- 10 = manca il grezzo
-- 20 = pezzo indicato mancante
-- 30 = errore nell'inserimento della lavorazione
-- 4x = errore nel calcolo del preview della lavorazione
-- 5x = errore nel calcolo della lavorazione
-- 60 = errore nel recupero dell'entità in lavorazione (in SORT)
-- 70 = errore nel calcolo della disposizione
-- -10 = modificati parametri di lavorazione
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Versione
local CAMAUTO_VER = 'ver 3.1d3'
-- Determino il tipo di macchina
local bIsMultiCut = ( EgtGetHeadId( 'H101') ~= nil)
local bIsTableRot = false
if bIsMultiCut then
local nTabId = EgtGetTableId( 'MainTab') or GDB_ID.NULL
local sParName = EgtGetName( EgtGetParent( nTabId) or GDB_ID.NULL) or ''
bIsTableRot = ( EgtGetAxisType( sParName) == false)
end
-- Determinazioni da Ini di OmagCUT
local bSizeAlwaysOnTop = ( EgtGetStringFromIni( 'Sides', 'SizeAlwaysOnTop', '0', EgtGetIniFile()) == '1')
-- Determinazioni da Ini di macchina
local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini'
-- Se fresa e foretto devono lavorare con C=90deg (tavola 1 C90, tavola 2 C-90),
local nDrillMillC90 = tonumber( EgtGetStringFromIni( 'Nest', 'DrillMillC90', '0', sMachIni))
-- Se i tagli lungo X (longitudinali) devono andare da dx a sn o viceversa
local bCutLongDxSx = ( EgtGetStringFromIni( 'Nest', 'CutLongDxSx', '1', sMachIni) == '1')
-- Abilitazione rotazione automatica o manuale della tavola (nil = automatico, valore = angolo tavola (0 o +/-90))
local dSetTab = tonumber( EgtGetStringFromIni( 'Table', 'SetTab', '', sMachIni))
-- Abilitazione due teste per MultiCut
local bUse2Heads = ( EgtGetStringFromIni( 'Nest', 'Use2HeadsMultiCut', '1', sMachIni) == '1')
-- Angolo di rotazione tavola per MultiCut
local dAngRotMultiCut = tonumber( EgtGetStringFromIni( 'Nest', 'AngRotMultiCut', '90', sMachIni))
-- Minima distanza tra teste per MultiCut (quando si fronteggiano)
local dMinDistHeadsMultiCut = tonumber( EgtGetStringFromIni( 'Nest', 'MinDistHeadsMultiCut', '245', sMachIni))
-- Minima distanza tra teste per MultiCut (quando sono inclinate)
local dMinDistSlantHeadsMultiCut = tonumber( EgtGetStringFromIni( 'Nest', 'MinDistSlantHeadsMultiCut', '1000', sMachIni))
-- Minima distanza tra teste per MultiCut (quando sono opposte)
local dMinDistOppoHeadsMultiCut = tonumber( EgtGetStringFromIni( 'Nest', 'MinDistOppoHeadsMultiCut', '1800', sMachIni))
-- Minima quota dei tagli di lama rispetto al sotto della lastra
local dMinSawRbHeight = tonumber( EgtGetStringFromIni( 'Nest', 'MinSawRbHeight', '', sMachIni))
-- Feed ridotta all'inizio/fine dei tagli
local bCutFsevEnable = ( EgtGetStringFromIni( 'Nest', 'CutFsevEnable', '0', sMachIni) == '1')
local dCutFsevLen = tonumber( EgtGetStringFromIni( 'Nest', 'CutFsevLen', '0', sMachIni))
local dCutFsevPerc = tonumber( EgtGetStringFromIni( 'Nest', 'CutFsevPerc', '0', sMachIni))
-- Distanza massima taglio da sotto da centro pezzo per lavorare in Y-
local dDripCutYmMaxDist = tonumber( EgtGetStringFromIni( 'Nest', 'DripCutYmMaxDist', '2000', sMachIni))
-- Uso fresa per incisioni
local bEngravingWithMill = ( EgtGetStringFromIni( 'Nest', 'EngravingWithMill', '0', sMachIni) == '1')
-- Affondamento e larghezza standard per incisioni
local dEngravingDepth = tonumber( EgtGetStringFromIni( 'Nest', 'EngravingDepth', '5', sMachIni))
local dEngravingWidth = tonumber( EgtGetStringFromIni( 'Nest', 'EngravingWidth', '0', sMachIni))
-- Pretaglio uscite (per materiali ceramici)
local bExitPreCut = ( EgtGetStringFromIni( 'Nest', 'PreCutExit', '0', sMachIni) == '1')
-- Angolo iniziale suggerito asse C per WaterJet
local dWjStartC = tonumber( EgtGetStringFromIni( 'Nest', 'WjStartC', '', sMachIni))
-- Larghezza bridge per WaterJet
local dBridgeW = tonumber( EgtGetStringFromIni( 'Nest', 'WjBridgeW', '5', sMachIni))
-- parametri **Spianatura**: se 3 allora accorcio della lunghezza dei baffi, se 4 no
local nWhiskerLen = tonumber( EgtGetStringFromIni( 'Nest', 'WhiskerLen', '4', sMachIni)) or 3
-- parametri **Taglio**: se angolo interno e taglio piccolo (**NON DISPONIBILE IN INTERFACCIA**)
local nManageLeadInOnIntCorner = tonumber( EgtGetStringFromIni( 'Nest', 'ManageLeadInOnIntCorner', '0', sMachIni) or 0)
-- parametro per forzare la creazione dei tagli sulle feature interne
local bStartEndModifyOnIntCorner = ( EgtGetStringFromIni( 'Nest', 'StartEndModifyOnIntCorner', '0', sMachIni) == '1')
-- parametro di altezza massima per abilitare **tagli speciali** per girare attorno al pezzo
local HighPieceZ = tonumber( EgtGetStringFromIni( 'RawMove', 'MaxHeightPiece', '800', sMachIni))
-- parametri **Taglio Finale**: un taglio di lama viene suddiviso in due parti fasi
local bFinalCut = ( EgtGetStringFromIni( 'Mach', 'EnableFinalSawCut', '0', sMachIni) == '1')
local FlagDirectCut = {ManualMove = 1, SingleCut = 2, GridCut = 3, SinleDrill = 4,
Flattening = 5, Squaring = 6, SawTest = 7, Polishing = 8, CopyTemplate = 9}
-- visualizzazione colore di lavorazione: se è attiva la modalità TOOLCHANGERWITHSAW(4)
local nMTC = EgtGetNumberFromIni( 'Tools', 'MountedToolConfig', 0, sMachIni)
local bGetColorPv = ( nMTC == 4)
-- Recupero il grezzo
local nRawId = EgtGetFirstRawPart()
if not nRawId then
CAM.ERR = 10
return
end
local b3Raw = EgtGetRawPartBBox( nRawId)
-- Pezzo/i cui applicare la lavorazione
if not CAM.PARTID then
CAM.PARTID = GDB_ID.NULL
elseif CAM.PARTID ~= GDB_ID.NULL then
if not EgtExistsObj(CAM.PARTID) then
CAM.ERR = 20
return
end
end
-- Materiale
local sMaterial = CAM.MATERIAL
-- Nomi e dati delle lavorazioni per Add
local sSaw = CAM.SAWMCH
-- ver. 2.7d1
local sSawTilted = CAM.SAWTILTEDMCH
local sMill = CAM.MILLMCH
local sDrill = CAM.DRILLMCH
local sPocket = CAM.POCKETMCH
local sWaterJet = CAM.WATERJETMCH
local sWjQuality = CAM.WATERJETQLTY
local sOnSaw = CAM.SAWMCH
local sOnMill = CAM.MILLMCH
local sDripSaw = CAM.DRIPSAWMCH
local sDripDrill = CAM.DRIPDRILLMCH
local dReducedDepth = CAM.REDUCEDDEPTH
local dOffsetHoles = CAM.HOLESOFFSET
local dOverlapHoles = CAM.HOLESOVERLAP
local dDeltaLenHoles = 4.0
local bOneHoleIntCorner = CAM.ONEHOLEINTCORNER
local dDeltaCutSafety = CAM.CUTSAFETY or 2.0
local dDeltaIntCorner = CAM.CORNERSAFETY
local bMillingOnCorners = CAM.MILLINGONCORNERS
local bMillingOnSinks = CAM.MILLINGONSINKS
local dDeltaLenPartMilling = - ( CAM.MILLINGSHORT or 0.0)
local bWaterJetOptimize = CAM.WATERJETOPTIMIZE
local bWaterJetOnSinks = CAM.WATERJETONSINKS
local dRawHeight = CAM.RAWHEIGHT
local dOffsAxisBlock = - ( CAM.REGROT or 0.0)
local colOnCut = Color3d( 255, 165, 0)
local colOnExt = Color3d( 192, 128, 0)
local colDripCut = Color3d( 255, 0, 165)
local colDripExt = Color3d( 192, 0, 128)
-- Recupero lato testa previsto nella lavorazione di taglio con lama
local nStdHside = MCH_SAW_HS.RIGHT
if sSaw and sSaw ~= '' then
if not EgtMdbSetCurrMachining( sSaw) then
CAM.ERR = 31
return
end
nStdHside = EgtMdbGetCurrMachiningParam( MCH_MP.HEADSIDE)
end
local nOthHside = EgtIf( nStdHside == MCH_SAW_HS.RIGHT, MCH_SAW_HS.LEFT, MCH_SAW_HS.RIGHT)
-- Reset stato di errore
CAM.ERR = 0
-- Tavole per entità da lavorare
local TabOutCut = {}
local TabOutCrv = {}
local TabOutPartial = {}
local TabInCut = {}
local TabInCrv = {}
local TabInHole = {}
local TabInPartial = {}
local TabOnCut = {}
local TabDripCut = {}
local TabDripHole = {}
local TabFiloTopLay = {}
local TabPocketLay = {}
-- Eventuale valore asse bloccato
local AxisBlock = 0
local function SquaringWJ( MyTabRtf, TabOutCrv, TabInCrv)
--[[ Funzione che calcola le due curve per le due lavorazioni associate al tallone.
Recupero le informazioni del secondo taglio ( misura OnTop):
______ ______
/ | H| |
/ |T | |T
H| a>0 | \ a<0 |
| ______ | \____|
dOrigSideAng>0: SideAng1=0, Offset1=(Th-H)*tan(a) | SideAng2=a, Offset2=0, Depth2=Th-H
dOrigSideAng<0: SideAng1=a, Offset1=H*tan(a) | SideAng2=0, Offset2=0, Depth=H
]]--
local TabTrimCrvs = {}
for i = 1, #MyTabRtf do
local nEntId = MyTabRtf[i][1]
local _, dSideAng = CAM.GetSideAng( nEntId)
local _, dSideAng2 = CAM.GetSideAng( nEntId, 2)
local _, dPrevAng = CAM.GetPrevAngle( nEntId)
local _, dNextAng = CAM.GetNextAngle( nEntId)
-- verifico se è vero tallone che necessita di due lavorazioni
if abs( dSideAng) > GEO.EPS_ANG_SMALL or abs( dSideAng2) > GEO.EPS_ANG_SMALL then
-- recupero il primo layer del pezzo con nome 'WjRectification', altrimenti lo creo
local nPartId = EgtGetParent( EgtGetParent( nEntId))
local nRtfLayId = EgtGetFirstNameInGroup( nPartId, 'WjRectification')
if not nRtfLayId then
nRtfLayId = EgtGroup( nPartId, GDB_RT.GLOB)
EgtSetName( nRtfLayId, 'WjRectification')
end
-- costruisco l'entità per lavorazione inclinata
local nNewId = EgtCopyGlob( nEntId, nRtfLayId)
EgtSetInfo( nNewId, 'CopyEnt', nEntId)
if dSideAng2 > 0 then
-- riporto l'informazione su SideAng perchè è l'unica info letta nel calcolare la lavorazione
EgtSetInfo( nNewId, 'SideAng', dSideAng2)
end
-- costruisco l'entità per lavorazione non inclinata
local nRtfId = EgtCopyGlob( nEntId, nRtfLayId)
EgtSetInfo( nRtfId, 'CopyEnt', nEntId)
EgtSetInfo( nRtfId, 'SideAng', 0)
-- offset: se sovrasquadra devo offsettare il tratto non inclinato, se sottosquadra quello inclinato
local _, dOffset = CAM.GetOffset( nEntId)
local nOffsEntId = EgtIf( dSideAng2 > 0, nRtfId, nNewId)
EgtOffsetCurve( nOffsEntId, dOffset, GDB_OT.FILLET)
EgtSetInfo( nNewId, 'Offset', 0)
EgtSetInfo( nRtfId, 'Offset', 0)
-- estensione: se sovrasquadra gli angoli esterni devono essere uniti, quindi allungo opportunamente le curve non inclinate per trovarle con estremi coincidenti
-- durante l'analisi dei concatenamenti del waterjet
if dSideAng2 > 0 then
if dPrevAng > GEO.EPS_ANG_SMALL then
local dSWE = EgtGetInfo( nEntId, 'SWE', 'd') or 0
EgtExtendCurveStartByLen( nRtfId, dSWE)
EgtRemoveInfo( nRtfId, 'SWE')
end
if dNextAng > GEO.EPS_ANG_SMALL then
local dEWE = EgtGetInfo( nEntId, 'EWE', 'd') or 0
EgtExtendCurveEndByLen( nRtfId, dEWE)
EgtRemoveInfo( nRtfId, 'EWE')
end
end
-- inserisco le nuove entità tra quelle da lavorare nell'ordine corretto. La prima sostituisce la curva di partenza, la seconda viene aggiunta in fondo al vettore
-- Nel caso di sovrasquadra viene fatta prima la lavorazione non inclinata e poi quella inclinata, nel caso di sottosquadra il contrario
local TabCrvRef = EgtIf( MyTabRtf[i][2] == 0, TabOutCrv, TabInCrv)
local nFirstEnt = EgtIf( dSideAng2 > 0, nRtfId, nNewId)
local nSecondEnt = EgtIf( dSideAng2 > 0, nNewId, nRtfId)
for j = 1, #TabCrvRef do
if MyTabRtf[i][1] == TabCrvRef[j] then
TabCrvRef[j] = nFirstEnt
table.insert( TabCrvRef, nSecondEnt)
break
end
end
-- se sottosquadra e angolo interno salvo la curva inclinata tra quelle da trimmare
if dSideAng2 == 0 and ( dPrevAng < GEO.EPS_ANG_SMALL or dNextAng < GEO.EPS_ANG_SMALL) then
table.insert( TabTrimCrvs, { nId = nNewId, nOrigId = nEntId, dSideAng = dSideAng, bStart = ( dPrevAng < GEO.EPS_ANG_SMALL), bEnd = ( dNextAng < GEO.EPS_ANG_SMALL)})
end
end
end
-- le curve di angoli interni in sottosquadra devono essere concatenate per garantire lavorazione completa, quindi ne faccio trim per trovarle con estremi coincidenti
-- durante l'analisi dei concatenamenti del waterjet
for i = 1, #TabTrimCrvs do
if TabTrimCrvs[i].bStart then
for j = 1, #TabTrimCrvs do
if i ~= j and TabTrimCrvs[j].bEnd then
-- verifico se le curve originali sono concatenabili
if abs( TabTrimCrvs[i].dSideAng - TabTrimCrvs[j].dSideAng) < GEO.EPS_ANG_SMALL and
AreSamePointApprox( EgtSP( TabTrimCrvs[i].nOrigId, GDB_ID.ROOT), EgtEP( TabTrimCrvs[j].nOrigId, GDB_ID.ROOT), 10 * GEO.EPS_SMALL) then
-- trim delle curve nel loro punto di intersezione
local ptInt = EgtIP( TabTrimCrvs[i].nId, TabTrimCrvs[j].nId, EgtSP( TabTrimCrvs[i].nId, GDB_ID.ROOT), GDB_ID.ROOT)
local dPar = EgtCurveParamAtPoint( TabTrimCrvs[i].nId, ptInt, 10 * GEO.EPS_SMALL, GDB_RT.GLOB)
EgtTrimCurveStartAtParam( TabTrimCrvs[i].nId, dPar)
local dParPrev = EgtCurveParamAtPoint( TabTrimCrvs[j].nId, ptInt, 10 * GEO.EPS_SMALL, GDB_RT.GLOB)
EgtTrimCurveEndAtParam( TabTrimCrvs[j].nId, dParPrev)
break
end
end
end
end
end
end
-- Funzione che raccoglie gli identificativi delle entità di un pezzo da lavorare
function CAM.AnalyzePart( nPartId)
-- |OUTLOOP|
local MyTabRtf = {}
-- Ciclo sui layer di contorno esterno del pezzo
local nOutLayId = EgtGetFirstNameInGroup( nPartId, 'OutLoop')
while nOutLayId do
-- Ciclo sulle entità del layer
local nEntId = EgtGetFirstInGroup( nOutLayId)
while nEntId do
local nType = EgtGetType(nEntId)
-- Se waterjet attivo ed entità con tallone
if sWaterJet ~= '' and CAM.GetHeelNotNull( nEntId) then
table.insert( TabOutCrv, nEntId)
table.insert( MyTabRtf, {nEntId, 0})
else
-- Se **RETTA**
if nType == GDB_TY.CRV_LINE then
table.insert( TabOutCut, nEntId)
-- Se **ARCO** o **CURVA** composita
elseif nType == GDB_TY.CRV_ARC or nType == GDB_TY.CRV_COMPO then
table.insert( TabOutCut, nEntId)
end
end
-- Passo all'entità successiva
nEntId = EgtGetNext( nEntId)
end
-- Passo al layer successivo
nOutLayId = EgtGetNextName( nOutLayId, 'OutLoop')
end
-- Ciclo sui layer di contorno interno del pezzo
local bAllCrv = (( bMillingOnSinks and sMill ~= "") or ( bWaterJetOnSinks and sWaterJet ~= "") or sSaw == "")
local dDrillDiam = CAM.GetToolDiameterFromMdb( sDrill)
local dMillDiam = CAM.GetToolDiameterFromMdb( sMill)
local dDripDrillDiam = CAM.GetToolDiameterFromMdb( sDripDrill)
local dDiamToler = EgtMdbGetGeneralParam( MCH_GP.HOLEDIAMTOLER)
-- |INLOOP|
local nInLayId = EgtGetFirstNameInGroup( nPartId, 'InLoop')
-- lista delle entità da analizzare per veririfcare se generare un foro (lavorazione WJ)
local MyTabInLoop = {}
while nInLayId do
-- Ciclo sulle entità del layer
local nEntId = EgtGetFirstInGroup( nInLayId)
while nEntId do
local nType = EgtGetType(nEntId)
-- Se waterjet attivo ed entità con tallone
if sWaterJet ~= '' and CAM.GetHeelNotNull( nEntId) then
table.insert( TabInCrv, nEntId)
table.insert( MyTabInLoop, nEntId)
table.insert( MyTabRtf, {nEntId, 1})
else
-- Se retta
if nType == GDB_TY.CRV_LINE then
if not bAllCrv then
table.insert( TabInCut, nEntId)
else
table.insert( TabInCrv, nEntId)
end
table.insert( MyTabInLoop, nEntId)
-- se arco
elseif nType == GDB_TY.CRV_ARC then
local dDiam = 2 * EgtArcRadius( nEntId)
if abs( EgtArcAngCenter( nEntId)) > 350.0 then
if sDrill ~= "" and dDrillDiam > 1 and
(( dDiamToler > 0 and abs( dDrillDiam - dDiam) < dDiamToler) or
( dDiamToler < 0 and dDrillDiam < dDiam + 10 * GEO.EPS_SMALL and dDrillDiam > dDiam + dDiamToler - GEO.EPS_SMALL)) then
table.insert( TabInHole, nEntId)
elseif dDiam > dMillDiam + 10 * GEO.EPS_SMALL then
if not bAllCrv then
table.insert( TabInCut, nEntId)
else
table.insert( TabInCrv, nEntId)
end
else
EgtOutLog( 'Drill skipped : too small')
end
else
if not bAllCrv then
table.insert( TabInCut, nEntId)
else
table.insert( TabInCrv, nEntId)
end
end
-- se curva composita
elseif nType == GDB_TY.CRV_COMPO then
if not bAllCrv then
table.insert( TabInCut, nEntId)
else
table.insert( TabInCrv, nEntId)
end
end
end
-- Passo all'entità successiva
nEntId = EgtGetNext( nEntId)
end
-- Passo al layer successivo
nInLayId = EgtGetNextName( nInLayId, 'InLoop')
end
-- verifico se necessario ricalcolo delle curve di lavorazione per talloni
if sWaterJet ~= '' then
SquaringWJ( MyTabRtf, TabOutCrv, TabInCrv)
end
-- |FILOTOP|
local nFTLayId = EgtGetFirstNameInGroup( nPartId, 'FiloTop')
while nFTLayId do
-- Se richiede FiloTop
table.insert( TabFiloTopLay, nFTLayId)
nFTLayId = EgtGetNextName( nFTLayId, 'FiloTop')
end
-- |ONPATH|
-- Ciclo sui layer sopra
local nOnLayId = EgtGetFirstNameInGroup( nPartId, 'OnPath')
while nOnLayId do
-- Ciclo sulle entità del layer
local nEntId = EgtGetFirstInGroup( nOnLayId)
while nEntId do
local nType = EgtGetType(nEntId)
-- Se retta o curva composita
if nType == GDB_TY.CRV_LINE or nType == GDB_TY.CRV_COMPO then
table.insert( TabOnCut, nEntId)
end
-- Passo all'entità successiva
nEntId = EgtGetNext( nEntId)
end
-- Passo al layer successivo
nOnLayId = EgtGetNextName( nOnLayId, 'OnPath')
end
-- |POCKET|
-- Ciclo sui layer svuotature
local nPockLayId = EgtGetFirstNameInGroup( nPartId, 'Pocket')
while nPockLayId do
table.insert( TabPocketLay, nPockLayId)
-- Passo al layer successivo
nPockLayId = EgtGetNextName( nPockLayId, 'Pocket')
end
-- |DRIP|
-- Ciclo sui layer per tagli da sotto
local nDripLayId = EgtGetFirstNameInGroup( nPartId, 'Drip')
while nDripLayId do
-- Ciclo sulle entità del layer
local nEntId = EgtGetFirstInGroup( nDripLayId)
while nEntId do
local nType = EgtGetType(nEntId)
-- Se retta o curva composita
if nType == GDB_TY.CRV_LINE or nType == GDB_TY.CRV_COMPO then
table.insert( TabDripCut, nEntId)
end
-- Passo all'entità successiva
nEntId = EgtGetNext( nEntId)
end
-- Passo al layer successivo
nDripLayId = EgtGetNextName( nDripLayId, 'Drip')
end
-- |UNDERDRILL|
-- Ciclo sui layer per fori da sotto
local nUdrillLayId = EgtGetFirstNameInGroup( nPartId, 'UnderDrill')
while nUdrillLayId do
-- Ciclo sulle entità del layer
local nEntId = EgtGetFirstInGroup( nUdrillLayId)
while nEntId do
local nType = EgtGetType(nEntId)
-- Se arco
if nType == GDB_TY.CRV_ARC then
local dDiam = 2 * EgtArcRadius( nEntId)
if abs( EgtArcAngCenter( nEntId)) > 350.0 then
if ( ( dDiamToler > 0 and abs( dDripDrillDiam - dDiam) < dDiamToler) or
( dDiamToler < 0 and dDripDrillDiam < dDiam + 10 * GEO.EPS_SMALL and
dDripDrillDiam > dDiam + dDiamToler - GEO.EPS_SMALL)) then
table.insert( TabDripHole, nEntId)
else
EgtOutLog( 'UnderDrill skipped : different diameter')
end
end
end
-- Passo all'entità successiva
nEntId = EgtGetNext( nEntId)
end
-- Passo al layer successivo
nUdrillLayId = EgtGetNextName( nUdrillLayId, 'UnderDrill')
end
end
-- Funzione che applica i tagli |LAMA|
function CAM.ApplyCuts( TabEnt, sLay, TabCrv, TabPartial, Index_j)
-- nome lama corrente
local sCurrSaw = sSaw
-- altezza grezzo
local nRawId = EgtGetFirstRawPart() or EgtGetFirstNameInGroup( EgtGetTableId( 'MainTab'), 'RawPart')
local dRawH = EgtGetRawPartBBox( nRawId):getDimZ()
local dAddTab = tonumber( EgtGetStringFromIni( 'Table', 'AdditionalTable', '0', sMachIni))
local bOverHeightCut = ( dRawH + dAddTab > HighPieceZ + 0.1)
-- diametro della lama
local SawDiam = 0
-- Ciclo sulle entità
for i = 1, #TabEnt do
sCurrSaw = sSaw
local nEntId = TabEnt[i]
local nStartInd = 1
local nEndInd = 2
-- forzo la generazione di una sola lavorazione
if Index_j then
nStartInd = Index_j
nEndInd = Index_j
end
-- Ad ogni entità possono essere associate due lavorazioni: inclinato + tallonamento
-- per questo motivo sulla stessa entità è eseguito un ciclo for da 1 a 2
for j = nStartInd, nEndInd do
if j == 2 and not CAM.GetSideAng( nEntId, j) then
break
end
-- **Info entita'**
local bDepth, Depth = CAM.GetDepth( nEntId, j)
local _, PrevAng = CAM.GetPrevAngle( nEntId)
local _, NextAng = CAM.GetNextAngle( nEntId)
local _, SideAng = CAM.GetSideAng( nEntId, j)
local _, StFreeLen = CAM.GetStartFreeLength( nEntId)
local _, EdFreeLen = CAM.GetEndFreeLength( nEntId)
local _, StWhiExt = CAM.GetStartWhiskersExtend( nEntId)
local _, EdWhiExt = CAM.GetEndWhiskersExtend( nEntId)
local _, Offset = CAM.GetOffset( nEntId, j)
local _, EnInv = CAM.GetEnableInvert( nEntId)
local _, RetDir = CAM.GetReturnDir( nEntId)
local bInvert = false
-- |LAVORAZIONE|
local sNewSaw = EgtGetInfo( nEntId, 'Def_Machining', 's')
if abs( SideAng) > GEO.EPS_ANG_SMALL then
sNewSaw = EgtGetInfo( nEntId, 'Def_Machining_Tilted', 's')
end
if sNewSaw then
sCurrSaw = sNewSaw
EgtOutLog('Applico nuova lavorazione '..sCurrSaw..' a EntId:'..tostring(nEntId))
end
SawDiam = CAM.GetToolDiameterFromMdb( sCurrSaw)
--EgtOutLog( 'Test : nEntId='..tostring( nEntId) .. ' SideAng='..tostring( SideAng) .. ' EnInv='..tostring( EnInv))
-- |-->CREAZIONE LAVORAZIONE| inserimento lavorazione
local nSaw = EgtAddMachining( 'Saw'..tostring( nEntId), sCurrSaw)
-- assegno una nuova info che specifica se è la prima o la seconda lavorazione associata all'entità
EgtSetInfo( nSaw, 'Index_j', j)
CAM.NEW_OPERATION = nSaw
if nSaw then
if abs( SideAng) < GEO.EPS_ANG_SMALL then
if EnInv then
local P1 = EgtSP( nEntId, GDB_ID.ROOT)
local P2 = EgtEP( nEntId, GDB_ID.ROOT)
bInvert = CAM.GetInvertVerticalCut( P1, P2)
end
else
local nHSide = EgtGetMachiningParam( MCH_MP.HEADSIDE)
bInvert = ( SideAng < 0 and nHSide == MCH_SAW_HS.RIGHT) or ( SideAng > 0 and nHSide == MCH_SAW_HS.LEFT)
-- lavorazione invertibile **SOLO** se non oltre le dimensioni del grezzo
if bOverHeightCut then bInvert = false end
end
-- **Inserisco la geometria del percorso**
EgtSetMachiningGeometry( {nEntId})
if bDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, Depth)
end
-- |-->-->SETTING PARAMETRI LAVORAZIONE|)
EgtSetMachiningParam( MCH_MP.SIDEANGLE, SideAng)
EgtSetMachiningParam( MCH_MP.OFFSL, Offset)
local nIntCorner = 0
if bInvert then
EgtSetMachiningParam( MCH_MP.INVERT, true)
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_SAW_WS.LEFT)
if PrevAng < - GEO.EPS_ANG_SMALL then
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dDeltaIntCorner)
nIntCorner = nIntCorner + 1
end
if NextAng < - GEO.EPS_ANG_SMALL then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dDeltaIntCorner)
nIntCorner = nIntCorner + 1
end
StFreeLen, EdFreeLen = EdFreeLen, StFreeLen
StWhiExt, EdWhiExt = EdWhiExt, StWhiExt
else
EgtSetMachiningParam( MCH_MP.INVERT, false)
EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_SAW_WS.RIGHT)
if PrevAng < - GEO.EPS_ANG_SMALL then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dDeltaIntCorner)
nIntCorner = nIntCorner + 1
end
if NextAng < - GEO.EPS_ANG_SMALL then
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dDeltaIntCorner)
nIntCorner = nIntCorner + 1
end
end
-- **BAFFI**
CAM.SetWhiskExtends( StWhiExt, EdWhiExt)
if RetDir == 2 then -- solo per spianature
EgtSetMachiningParam( MCH_MP.INVERT, not bInvert)
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.RIGHT, MCH_SAW_WS.LEFT))
EgtSetMachiningParam( MCH_MP.HEADSIDE, nOthHside)
end
-- **OVERHEIGHTCUT**
if bOverHeightCut then
EgtSetMachiningParam( MCH_MP.USERNOTES, "DownSE=1")
-- Outer Extended: 4
EgtSetMachiningParam( MCH_MP.LEADINTYPE, 4)
-- Back and forth
EgtSetMachiningParam( MCH_MP.STEPTYPE, 2)
-- avviso il cambio di parametri di taglio
CAM.ERR = -10
end
local bInTabCrv = false
local dDeltaT = 0
local dDeltaTI = 0
-- |-->-->GENERO PREVIEW|
if EgtPreviewMachining() then
-- se previsto, limito quota minima lama
if dMinSawRbHeight then
local dRbH = CAM.GetRawBottomHeight( nSaw)
if dRbH < dMinSawRbHeight - GEO.EPS_SMALL then
local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR)
sDepth = sDepth .. '-' .. EgtNumToString( dMinSawRbHeight - dRbH, 3)
EgtSetMachiningParam( MCH_MP.DEPTH_STR, sDepth)
EgtPreviewMachining()
end
end
-- controllo di non superare la eventuale lunghezza libera prima e dopo con i baffi
if not EgtIsMachiningEmpty() and not bOverHeightCut then
dDeltaT = CAM.GetDeltaT( nSaw)
dDeltaTI = CAM.GetDeltaTI( nSaw) or dDeltaT
if bInvert then
dDeltaT, dDeltaTI = dDeltaTI, dDeltaT
end
if dDeltaTI + dDeltaIntCorner > StFreeLen or dDeltaT > EdFreeLen then
if dDeltaTI > StFreeLen then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dDeltaIntCorner)
nIntCorner = nIntCorner + 1
end
if dDeltaT + dDeltaIntCorner > EdFreeLen then
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dDeltaIntCorner)
nIntCorner = nIntCorner + 1
end
EgtPreviewMachining()
end
end
-- se la generazione è andata a buon fine allora procedo a copiarla nel pezzo
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent(EgtGetParent( nEntId))
CAM.CopyPreviewToPiece( nSaw, nPartId)
CAM.ApplyPvColor( sCurrSaw, nSaw)
-- |TAGLIO FINALE|
-- recupero il valore di affondamento del taglio
local dRbH = CAM.GetRawBottomHeight( nSaw)
-- taglio VERTICALE e PASSANTE, lavorazione con richiesta di lavorazione Sovrameteriale finale
if bFinalCut and abs( SideAng) < GEO.EPS_ANG_SMALL and dRbH < GEO.EPS_SMALL then
local nSawFINAL = EgtCopyMachining( 'Saw_FINAL'..tostring( nEntId), 'Saw'..tostring( nEntId))
if EgtSetCurrMachining( nSawFINAL) then
-- One way:1, Back and forth:2, Zig Zag:0
EgtSetMachiningParam( MCH_MP.STEPTYPE, 1)
-- Un solo step di affondamento
EgtSetMachiningParam( MCH_MP.STEP, dRawHeight + 0.1)
-- identifico la lavorazione come ultima
EgtSetInfo( nSawFINAL, 'FinalCut', true)
-- imposto come feed quella dell'ultimo taglio di ritorno
local dBackFeed = EgtGetMachiningParam( MCH_MP.BACKFEED)
EgtSetMachiningParam( MCH_MP.FEED, dBackFeed)
-- assegno il nome del layer a cui fa riferimento (se assente non è estensibile da terfaccia!)
EgtSetInfo( nSawFINAL, 'Lay', sLay)
EgtPreviewMachining()
CAM.CopyPreviewToPiece( nSawFINAL, nPartId)
CAM.ApplyPvColor( sCurrSaw, nSawFINAL)
-- alle operazioni assegno i riferimenti incrociati
EgtSetInfo( nSawFINAL, 'IdTwinCut', nSaw)
EgtSetInfo( nSaw, 'IdTwinCut', nSawFINAL)
end
-- Reimposto la lavorazione creata durante questo ciclo
if EgtSetCurrMachining( nSaw) then
-- ridefinisco l'affondamento corretto (più in alto dall'ultimo taglio)
local dLastStep = EgtGetMachiningParam( MCH_MP.STEPLAST)
if dLastStep < 0.1 then dLastStep = 10 end
local sNewDepth = 'Rb-'..EgtNumToString( dLastStep)
EgtSetMachiningParam( MCH_MP.DEPTH_STR, sNewDepth)
-- aggiusto la feed dell'ultima passata di questa lav. (che ora non è più l'ultima del taglio)
local dFeed = EgtGetMachiningParam( MCH_MP.FEED)
EgtSetMachiningParam( MCH_MP.BACKFEED, dFeed)
EgtPreviewMachining()
CAM.ApplyPvColor( sCurrSaw, nSaw)
-- ...
end
end
elseif j == 1 and not bStartEndModifyOnIntCorner and not bOverHeightCut then
-- **inserisco in elenco di entità da fare con fori/fresa**
table.insert( TabCrv, nEntId)
bInTabCrv = true
-- modifico il taglio per non rovinare il pezzo
local dLen = EgtCurveLength( nEntId)
if nIntCorner > 0 and dLen and dLen < SawDiam then
-- Versione **2.6f4**: allungo i tagli il più possibile
if nManageLeadInOnIntCorner == 1 then
local dExtraLen = -dLen + 5.5
local dExtraLen_2 = 0
if PrevAng < 0 and NextAng > 0 then
if bInvert then
EgtSetMachiningParam( MCH_MP.LEADINTYPE ,MCH_SAW_LI.OUT)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen_2)
EgtSetInfo( EgtGetCurrMachining(), 'Usal', dExtraLen)
else
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE ,MCH_SAW_LO.OUT)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen_2)
EgtSetInfo( EgtGetCurrMachining(), 'Ueal', dExtraLen)
end
EgtSetInfo( EgtGetCurrMachining(), 'ManageLeadInOnIntCorner', true)
elseif PrevAng > 0 and NextAng < 0 then
if bInvert then
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE ,MCH_SAW_LO.OUT)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen_2)
EgtSetInfo( EgtGetCurrMachining(), 'Ueal', dExtraLen)
else
EgtSetMachiningParam( MCH_MP.LEADINTYPE ,MCH_SAW_LI.OUT)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen_2)
EgtSetInfo( EgtGetCurrMachining(), 'Usal', dExtraLen)
end
EgtSetInfo( EgtGetCurrMachining(), 'ManageLeadInOnIntCorner', true)
end
if EgtIsMachiningEmpty() then
EgtOutLog( 'Cut '..tostring( nSaw)..' on internal angle: new management')
end
else
-- provo a ridurre l'affondamento
local dWhiskerLen = ( dLen - nIntCorner * dDeltaIntCorner - 5) / nIntCorner
local dNewDepth = 0.5 * ( SawDiam - sqrt( SawDiam * SawDiam - 4 * dWhiskerLen * dWhiskerLen))
if dNewDepth >= dReducedDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, min( dNewDepth, dRawHeight))
end
end
else
EgtSetMachiningParam( MCH_MP.DEPTH, min( dReducedDepth, dRawHeight))
EgtOutLog( 'Cut ' .. tostring( nSaw) .. ' reduced: interference with other parts')
end
EgtPreviewMachining()
--CAM.ChangePvColor( nSaw, colOnCut, colOnExt)
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent(EgtGetParent( nEntId))
CAM.CopyPreviewToPiece( nSaw, nPartId)
CAM.ApplyPvColor( sCurrSaw, nSaw)
else
EgtRemoveOperation( nSaw)
nSaw = nil
end
elseif j == 1 and bStartEndModifyOnIntCorner and not bOverHeightCut then
-- Forzo il taglio all'interno del pezzo buono
bInTabCrv = true
-- allungo la lavorazione
local dLen = EgtCurveLength( nEntId)
-- dRawHeight + Affondamento
local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR)
-- sostituisco ad RB lo spessore del pezzo
sDepth = string.gsub( sDepth, "RB", tostring(dRawHeight))
-- converto il dato stringa in numero
local dRbH = EgtEvalNumExpr( sDepth)
local dExtraLen = sqrt( (SawDiam /2)*(SawDiam /2) - (SawDiam/2 - dRbH)*(SawDiam/2 - dRbH))
if SideAng then
dExtraLen = sqrt( (SawDiam /2)*(SawDiam /2) - (SawDiam/2 - dRbH / cos(SideAng))*(SawDiam/2 - dRbH / cos(SideAng)))
end
--local dWhiskerLen = ( dLen - nIntCorner * dDeltaIntCorner - 5) / nIntCorner
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen)
EgtSetInfo( EgtGetCurrMachining(), 'Usal', dExtraLen)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen)
EgtSetInfo( EgtGetCurrMachining(), 'Ueal', dExtraLen)
EgtSetInfo( EgtGetCurrMachining(), 'StartEndModifyOnIntCorner', true)
EgtPreviewMachining()
-- verfico che la lavorazione sia stata inserita
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent(EgtGetParent( nEntId))
CAM.CopyPreviewToPiece( nSaw, nPartId)
CAM.ApplyPvColor( sCurrSaw, nSaw)
else
EgtRemoveOperation( nSaw)
nSaw = nil
end
end
else
CAM.ERR = 40
end
-- non è stata creata la lavorazione di lama
if nSaw then
if not bInTabCrv and j == 1 and
( PrevAng < - GEO.EPS_ANG_SMALL or NextAng < - GEO.EPS_ANG_SMALL or
dDeltaTI + dDeltaIntCorner > StFreeLen or dDeltaT + dDeltaIntCorner > EdFreeLen) then
EgtOutLog( 'Cut ' .. tostring( nSaw) .. ' to refine with mill')
table.insert( TabPartial, nSaw)
end
EgtSetOperationStatus( nSaw, false)
EgtSetInfo( nSaw, 'Lay', sLay)
end
else
-- **Lavorazione non creata**
CAM.ERR = 30
end
end
end
end
-- Funzione che applica le fresature per completare i tagli
function CAM.ApplyMillings( TabEnt, TabPartMch, sLay)
-- recupero lo spessore lama di una lavorazione incompleta
local SawThickness = 0
if #TabPartMch > 0 then
SawThickness = CAM.GetSawThickness( TabPartMch[1])
end
local TabMPartC = {}
-- Preparo tabella info tagli completi
for i = 1, #TabEnt do
local nEntId = TabEnt[i]
if EgtExistsObj( nEntId) then
local dEntLen = EgtCurveLength( nEntId)
local _, PrevAng = CAM.GetPrevAngle( nEntId)
local _, NextAng = CAM.GetNextAngle( nEntId)
local _, SideAng = CAM.GetSideAng(nEntId)
-- inserisco i dati nella tabella
local RecMPartC = {}
RecMPartC.OperId = 0
RecMPartC.StartStrict = false
RecMPartC.EndStrict = false
RecMPartC.DeltaT = 0
RecMPartC.DeltaTI = 0
RecMPartC.EntId = nEntId
RecMPartC.EntLen = dEntLen
RecMPartC.PrevAng = PrevAng
RecMPartC.NextAng = NextAng
RecMPartC.SideAng = SideAng
RecMPartC.PrevInd = 0
RecMPartC.NextInd = 0
RecMPartC.StartDone = false
RecMPartC.EndDone = false
table.insert( TabMPartC, RecMPartC)
end
end
-- Preparo tabella info tagli parziali
for i = 1, #TabPartMch do
local nOperId = TabPartMch[i]
-- verifico sia un taglio di lama
if EgtGetOperationType(nOperId) == MCH_OY.SAWING then
EgtSetCurrMachining(nOperId)
-- recupero i dati
local Geo = EgtGetMachiningGeometry()
local bInvert = EgtGetMachiningParam(MCH_MP.INVERT)
local bStartStrict = ( EgtGetMachiningParam(MCH_MP.LEADINTYPE) == MCH_SAW_LI.STRICT)
local bEndStrict = ( EgtGetMachiningParam(MCH_MP.LEADOUTTYPE) == MCH_SAW_LO.STRICT)
local dDeltaT = CAM.GetDeltaT( nOperId)
local dDeltaTI = CAM.GetDeltaTI( nOperId) or dDeltaT
if bInvert then
bStartStrict, bEndStrict = bEndStrict, bStartStrict
dDeltaT, dDeltaTI = dDeltaTI, dDeltaT
end
if type(Geo) == 'table' and type(Geo[1]) == 'table' and type(Geo[1][1]) == 'number' then
local nEntId = Geo[1][1]
local dEntLen = EgtCurveLength( nEntId)
local _, PrevAng = CAM.GetPrevAngle( nEntId)
local _, NextAng = CAM.GetNextAngle( nEntId)
local _, SideAng = CAM.GetSideAng(nEntId)
-- inserisco i dati nella tabella
local RecMPartC = {}
RecMPartC.OperId = nOperId
RecMPartC.StartStrict = bStartStrict
RecMPartC.EndStrict = bEndStrict
RecMPartC.DeltaT = dDeltaT -- lunghezza baffo
RecMPartC.DeltaTI = dDeltaTI -- lunghezza baffo
RecMPartC.EntId = nEntId
RecMPartC.EntLen = dEntLen
RecMPartC.PrevAng = PrevAng
RecMPartC.NextAng = NextAng
RecMPartC.SideAng = SideAng
RecMPartC.PrevInd = 0
RecMPartC.NextInd = 0
RecMPartC.StartDone = false
RecMPartC.EndDone = false
table.insert( TabMPartC, RecMPartC)
end
end
end
-- Cerco le congiunzioni
for i = 1, #TabMPartC do
local RecMPartC = TabMPartC[i]
if RecMPartC.OperId == 0 or RecMPartC.StartStrict then
local ptStart = EgtSP( RecMPartC.EntId, GDB_ID.ROOT)
for j = 1, #TabMPartC do
if j ~= i then
local RecMPartC2 = TabMPartC[j]
if RecMPartC2.OperId == 0 or RecMPartC2.EndStrict then
local ptEnd = EgtEP( RecMPartC2.EntId, GDB_ID.ROOT)
-- verifico se l'inizio e la fine delle lavorazioni delle entità coincidono
if AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL) and
( abs( RecMPartC.SideAng - RecMPartC2.SideAng) < 10 * GEO.EPS_ANG_SMALL or
(RecMPartC.SideAng < GEO.EPS_ANG_SMALL and RecMPartC2.SideAng < GEO.EPS_ANG_SMALL)) then
RecMPartC.PrevInd = j
RecMPartC2.NextInd = i
end
end
end
end
end
end
-- Stampe di debug
--[[for i = 1, #TabMPartC do
local RecMPartC = TabMPartC[i]
EgtOutLog( 'OperId='..tostring(RecMPartC.OperId)..
', StartStrict='..tostring(RecMPartC.StartStrict)..', EndStrict='..tostring(RecMPartC.EndStrict)..
', DeltaT='..EgtNumToString(RecMPartC.DeltaT,2)..', DeltaTI='..EgtNumToString(RecMPartC.DeltaTI,2)..
', EntId='..tostring(RecMPartC.EntId)..', EntLen='..EgtNumToString(RecMPartC.EntLen,2)..
', PrevAng='..EgtNumToString(RecMPartC.PrevAng,2)..', NextAng='..EgtNumToString(RecMPartC.NextAng,2)..
', SideAng='..EgtNumToString(RecMPartC.SideAng,2)..
', PrevInd='..tostring(RecMPartC.PrevInd)..', NextInd='..tostring(RecMPartC.NextInd)..
', StartDone='..tostring(RecMPartC.StartDone)..', EndDone='..tostring(RecMPartC.EndDone))
end]]--
-- Ciclo sui tratti concatenabili
for i = 1, #TabMPartC do
local RecMPartCs = TabMPartC[i]
-- se tratto completo ed esiste precedente non lavorato passo a questo
local j = i
local Count = 0
while RecMPartCs.OperId == 0 and not RecMPartCs.StartDone and RecMPartCs.PrevInd ~= 0 do
j = RecMPartCs.PrevInd
RecMPartCs = TabMPartC[j]
Count = Count + 1
-- se sono ritornato all'inizio, esco
if j == i then break end
-- se ho esaminato tutte le entità, esco
if Count > #TabMPartC then break end
end
-- se concatenato con successivo
if not RecMPartCs.EndDone and RecMPartCs.NextInd ~= 0 then
local tabEnt = {}
local tabMid = {}
table.insert( tabEnt, RecMPartCs.EntId)
local RecMPartCe = TabMPartC[RecMPartCs.NextInd]
table.insert( tabEnt, RecMPartCe.EntId)
while RecMPartCe.OperId == 0 and not RecMPartCe.StartDone and RecMPartCe.NextInd ~= 0 and RecMPartCe.NextInd ~= j do
RecMPartCe = TabMPartC[RecMPartCe.NextInd]
table.insert( tabEnt, RecMPartCe.EntId)
table.insert( tabMid, RecMPartCe.PrevInd)
end
local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartCs.EntId)..'S', sMill)
if nMill then
-- eventuale suggerimento angolo asse C a 90 deg
CAM.HintDrillMillAngC()
-- eventuale offset
local dRad = 0.5 * CAM.GetToolDiameter()
if RecMPartCs.SideAng > GEO.EPS_ANG_SMALL then
local dTotOffs = dRawHeight * tan( RecMPartCs.SideAng)
EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs)
end
-- verifico se percorso chiuso
local ptStart = EgtSP( RecMPartCs.EntId, GDB_ID.ROOT)
local ptEnd = EgtEP( RecMPartCe.EntId, GDB_ID.ROOT)
local bClosed = not RecMPartCs.StartStrict and not RecMPartCe.EndStrict and AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL)
-- se non chiuso, sistemazioni inizio e fine
if not bClosed then
-- aggiusto inizio
local dStartAddLen = 0
if RecMPartCs.OperId == 0 then
if RecMPartCs.PrevAng > - 175 and RecMPartCs.PrevAng < - 5 then
dStartAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartCs.PrevAng) + 1) / sin( 180 + RecMPartCs.PrevAng)
elseif RecMPartCs.PrevAng < 175 and RecMPartCs.PrevAng > 5 then
-- Verifico se devo allungare il taglio
local PrevEnt = EgtGetPrev( RecMPartCs.EntId)
if not PrevEnt then EgtGetFirstInGroup( EgtGetParent(RecMPartCs.EntId)) end
if PrevEnt then
local _, PrevSideAng = CAM.GetSideAng( PrevEnt, 1)
if PrevSideAng then
-- valore di riduzione lunghezza a causa del taglio in sottosquadra/soprasquadra
local dExtraLen = dRawHeight * tan( abs( PrevSideAng))
-- Impronta lama : SawThickness/cos( abs( NextSideAng))
-- **SOPRA SQUADRA**
if PrevSideAng > 0 and bSizeAlwaysOnTop then
dStartAddLen = -dExtraLen
EgtOutLog( 'Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOPRA SQUDRA)')
-- **SOTTO SQUADRA**
elseif PrevSideAng < 0 and bSizeAlwaysOnTop then
if RecMPartCs.EntLen * ( 1 + cos( RecMPartCs.PrevAng)) - dExtraLen <= 10 * GEO.EPS_SMALL then
dStartAddLen = 0
else
dStartAddLen = -dExtraLen / sin( abs( PrevSideAng))
end
EgtOutLog( 'Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOTTO SQUDRA)')
-- ALTRO
elseif ( PrevSideAng < 0 or PrevSideAng > 0) and not bSizeAlwaysOnTop then
dStartAddLen = -dExtraLen
EgtOutLog( 'Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=0)')
end
end
end
else
-- se retta molto corta con angolo interno dopo, la allungo del raggio utensile
if RecMPartCs.EntLen < dRad and EgtGetType( RecMPartCs.EntId) == GDB_TY.CRV_LINE and RecMPartCs.NextAng > - 175 and RecMPartCs.NextAng < - 5 then
dStartAddLen = RecMPartCs.EntLen - dRad - 1.0
else
dStartAddLen = 0
end
end
else
dStartAddLen = RecMPartCs.EntLen - RecMPartCs.DeltaT - dDeltaIntCorner - dDeltaLenPartMilling
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dStartAddLen)
-- aggiusto fine
local dEndAddLen = 0
if RecMPartCe.OperId == 0 then
if RecMPartCe.NextAng > - 175 and RecMPartCe.NextAng < - 5 then
dEndAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartCe.NextAng) + 1) / sin( 180 + RecMPartCe.NextAng)
elseif RecMPartCe.NextAng < 175 and RecMPartCe.NextAng > 5 then
-- Verifico se devo allungare il taglio
local NextEnt = EgtGetNext( RecMPartCe.EntId)
if not NextEnt then EgtGetFirstInGroup( EgtGetParent( RecMPartCe.EntId)) end
if NextEnt then
local _, NextSideAng = CAM.GetSideAng( NextEnt, 1)
if NextSideAng then
-- valore di riduzione lunghezza a causa del taglio in sottosquadra/soprasquadra
local dExtraLen = dRawHeight * tan( abs( NextSideAng))
-- Impronta lama : SawThickness / cos( abs( NextSideAng))
-- **SOPRA SQUADRA**
if NextSideAng > 0 and bSizeAlwaysOnTop then
dEndAddLen = -dExtraLen
EgtOutLog( 'Allungo USCITA fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOPRA SQUDRA)')
-- **SOTTO SQUADRA**
elseif NextSideAng < 0 and bSizeAlwaysOnTop then
if RecMPartCe.EntLen *( 1 + cos( RecMPartCs.PrevAng)) - dExtraLen <= 10 * GEO.EPS_SMALL then
dEndAddLen = 0
else
dEndAddLen = -dExtraLen / sin( abs( NextSideAng))
end
EgtOutLog( 'Allungo USCITA fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOTTO SQUDRA)')
-- ALTRO
elseif ( NextSideAng < 0 or NextSideAng > 0) and not bSizeAlwaysOnTop then
dEndAddLen = -dRawHeight / tan( abs( NextSideAng))- dRad
EgtOutLog( 'Allungo USCITA fresa '..tostring( dEndAddLen)..' per compensare il taglio inclinato (SizeAlwaysOnTop=0)')
end
end
end
else
-- se retta molto corta con angolo interno prima, la allungo del raggio utensile
if RecMPartCe.EntLen < dRad and EgtGetType( RecMPartCe.EntId) == GDB_TY.CRV_LINE and RecMPartCe.PrevAng > - 175 and RecMPartCe.PrevAng < - 5 then
dEndAddLen = RecMPartCe.EntLen - dRad - 1.0
else
dEndAddLen = 0
end
end
else
dEndAddLen = RecMPartCe.EntLen - RecMPartCe.DeltaTI - dDeltaIntCorner - dDeltaLenPartMilling
end
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen)
end
-- altri aggiustamenti
EgtSetMachiningParam(MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL)
EgtSetMachiningParam(MCH_MP.LIELEV, 2.0)
-- assegno geometria
if EgtSetMachiningGeometry( tabEnt) then
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( RecMPartCs.EntId))
CAM.CopyPreviewToPiece( nMill, nPartId)
else
CAM.ERR = 41
end
EgtSetOperationStatus( nMill, false)
EgtSetInfo( nMill, 'Lay', sLay)
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
-- segnalazione lavorazioni applicate
RecMPartCs.EndDone = true
if RecMPartCs.OperId == 0 then
RecMPartCs.StartDone = true
end
RecMPartCe.StartDone = true
if RecMPartCe.OperId == 0 then
RecMPartCe.EndDone = true
end
for k = 1, #tabMid do
TabMPartC[tabMid[k]].StartDone = true
TabMPartC[tabMid[k]].EndDone = true
end
end
end
-- Ciclo sui tratti singoli rimasti
for i = 1, #TabMPartC do
local RecMPartC = TabMPartC[i]
-- completo singolo
if not RecMPartC.StartDone and RecMPartC.OperId == 0 then
local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartC.EntId)..'S', sMill)
if nMill then
-- eventuale suggerimento angolo asse C a 90 deg
CAM.HintDrillMillAngC()
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
if RecMPartC.SideAng > GEO.EPS_ANG_SMALL then
local dTotOffs = dRawHeight * tan( RecMPartC.SideAng)
EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs)
end
local dStartAddLen = 0
if RecMPartC.PrevAng < - 5 and RecMPartC.PrevAng > - 175 then
dStartAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.PrevAng) + 1) / sin( 180 + RecMPartC.PrevAng)
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen)
local dEndAddLen = 0
if RecMPartC.NextAng < - 5 and RecMPartC.NextAng > - 175 then
dEndAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.NextAng) + 1) / sin( 180 + RecMPartC.NextAng)
end
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen)
EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL)
--EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_MILL_LI.GLIDE)
EgtSetMachiningParam( MCH_MP.LIELEV, 2.0)
if EgtSetMachiningGeometry( {RecMPartC.EntId}) then
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId))
CAM.CopyPreviewToPiece(nMill, nPartId)
else
CAM.ERR = 42
end
EgtSetOperationStatus(nMill,false)
EgtSetInfo(nMill,'Lay',sLay)
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
RecMPartC.StartDone = true
RecMPartC.EndDone = true
end
-- parziale singolo su inizio
if not RecMPartC.StartDone and RecMPartC.StartStrict then
local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartC.EntId)..'S', sMill)
if nMill then
-- eventuale suggerimento angolo asse C a 90 deg
CAM.HintDrillMillAngC()
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
if RecMPartC.SideAng > GEO.EPS_ANG_SMALL then
local dTotOffs = dRawHeight * tan( RecMPartC.SideAng)
EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs)
end
local dStartAddLen = 0
if RecMPartC.PrevAng < - 5 and RecMPartC.PrevAng > - 175 then
dStartAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.PrevAng) + 1) / sin( 180 + RecMPartC.PrevAng)
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen)
local dEndAddLen = RecMPartC.EntLen - RecMPartC.DeltaTI - dDeltaIntCorner - dDeltaLenPartMilling
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen)
EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL)
--EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_MILL_LI.GLIDE)
EgtSetMachiningParam( MCH_MP.LIELEV, 2.0)
if EgtSetMachiningGeometry( {RecMPartC.EntId}) then
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId))
CAM.CopyPreviewToPiece(nMill, nPartId)
else
CAM.ERR = 43
end
EgtSetOperationStatus(nMill,false)
EgtSetInfo(nMill,'Lay',sLay)
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
RecMPartC.StartDone = true
end
-- parziale singolo su fine
if not RecMPartC.EndDone and RecMPartC.EndStrict then
local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartC.EntId)..'E', sMill)
if nMill then
-- eventuale suggerimento angolo asse C a 90 deg
CAM.HintDrillMillAngC()
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
if RecMPartC.SideAng > GEO.EPS_ANG_SMALL then
local dTotOffs = dRawHeight * tan( RecMPartC.SideAng)
EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs)
end
local dStartAddLen = RecMPartC.EntLen - RecMPartC.DeltaT - dDeltaIntCorner - dDeltaLenPartMilling
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dStartAddLen)
local dEndAddLen = 0
if RecMPartC.NextAng < - 5 and RecMPartC.NextAng > - 175 then
dEndAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.NextAng) + 1) / sin( 180 + RecMPartC.NextAng)
end
EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dEndAddLen)
EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL)
--EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_MILL_LI.GLIDE)
EgtSetMachiningParam( MCH_MP.LIELEV, 2.0)
if EgtSetMachiningGeometry( {RecMPartC.EntId}) then
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId))
CAM.CopyPreviewToPiece(nMill, nPartId)
else
CAM.ERR = 44
end
EgtSetOperationStatus(nMill,false)
EgtSetInfo(nMill,'Lay',sLay)
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
RecMPartC.EndDone = true
end
end
end
-- Funzione che applica waterjet per completare i tagli:
-- **TabEnt**: tabella delle entità che devono essere lavorate
function CAM.ApplyWaterJettings( TabEnt, TabPartMch, sLay)
-- determino tabella spessore-feed da utilizzare: **vThickFeed**
local vThickFeed = nil
if sMaterial and sWjQuality and dRawHeight then
vThickFeed = {}
local sWjDbPath = EgtGetCurrMachineDir() .. '\\Machinings\\WaterjetDB.data'
for i = 1, 20 do
local sLine = EgtGetStringFromIni( sMaterial, tostring( i), '', sWjDbPath)
if #sLine == 0 then break end
local vVal = EgtSplitString( sLine, ',')
local dThick = tonumber( vVal[1] or '')
local dFeed
if sWjQuality == 'Q1' then
dFeed = tonumber( vVal[2] or '')
elseif sWjQuality == 'Q2' then
dFeed = tonumber( vVal[3] or '')
elseif sWjQuality == 'Q3' then
dFeed = tonumber( vVal[4] or '')
elseif sWjQuality == 'Q4' then
dFeed = tonumber( vVal[5] or '')
elseif sWjQuality == 'Q5' then
dFeed = tonumber( vVal[6] or '')
else
dFeed = tonumber( vVal[7] or '')
end
local dTaperAng = tonumber( vVal[8] or '') or 0
local dFlux = tonumber( vVal[9] or '') or 250
if dThick and dFeed then
table.insert( vThickFeed, { Th=dThick, F=dFeed, Ta=dTaperAng, Fl=dFlux})
end
end
end
-- funzione locale per tabella spessore-feed
local function GetWjSpeed( dDepth)
for i = 1, #( vThickFeed or {}) do
if dDepth < vThickFeed[i].Th + 0.1 then
if i == 1 or ( vThickFeed[i].Th - vThickFeed[i-1].Th) < 0.1 then
return vThickFeed[i].F, 0
else
local dCoeff = ( dDepth - vThickFeed[i-1].Th) / ( vThickFeed[i].Th - vThickFeed[i-1].Th)
return ( 1 - dCoeff) * vThickFeed[i-1].F + dCoeff * vThickFeed[i].F, 0
end
end
end
if #( vThickFeed or {}) > 0 then
return vThickFeed[#vThickFeed].F, vThickFeed[#vThickFeed].Th
end
end
-- funzione locale per tabella spessore-conicità
local function GetWjTaperAng( dDepth)
for i = 1, #( vThickFeed or {}) do
if dDepth < vThickFeed[i].Th + 0.1 then
if i == 1 or ( vThickFeed[i].Th - vThickFeed[i-1].Th) < 0.1 then
return vThickFeed[i].Ta
else
local dCoeff = ( dDepth - vThickFeed[i-1].Th) / ( vThickFeed[i].Th - vThickFeed[i-1].Th)
return ( 1 - dCoeff) * vThickFeed[i-1].Ta + dCoeff * vThickFeed[i].Ta
end
end
end
if #( vThickFeed or {}) > 0 then
return vThickFeed[#vThickFeed].Ta
end
return 0
end
-- funzione locale per tabella spessore-flusso sabbia
local function GetWjFlux( dDepth)
for i = 1, #( vThickFeed or {}) do
if dDepth < vThickFeed[i].Th + 0.1 then
return vThickFeed[i].Fl
end
end
if #( vThickFeed or {}) > 0 then
return vThickFeed[#vThickFeed].Fl
end
return 250
end
-- Inizio elaborazioni --
local nIntAngLiType = MCH_WJET_LI.LINEAR
local dIntAngLiTang = -1
local dIntAngLiPerp = 3
local nIntAngLoType = MCH_WJET_LO.LINEAR
local dIntAngLoTang = 0
local dIntAngLoPerp = 2
local TabMPartC = {}
-- Preparo tabella info tagli completi: **TabMPartC** partendo dall'identificativo dell'entità
for i = 1, #TabEnt do
local nEntId = TabEnt[i]
if EgtExistsObj( nEntId) and not bRtfPath then
local dEntLen = EgtCurveLength( nEntId)
local _, PrevAng = CAM.GetPrevAngle( nEntId)
local _, NextAng = CAM.GetNextAngle( nEntId)
local _, SideAng = CAM.GetSideAng( nEntId)
local _, Offset = CAM.GetOffset( nEntId)
local _, StWhiExt = CAM.GetStartWhiskersExtend( nEntId)
local _, EdWhiExt = CAM.GetEndWhiskersExtend( nEntId)
local _, Join = CAM.GetJoinEntity( nEntId)
-- inserisco i dati nella tabella: creo record per la tabella
local RecMPartC = {}
RecMPartC.OperId = 0
RecMPartC.StartStrict = false
RecMPartC.EndStrict = false
RecMPartC.Sal = 0
RecMPartC.Eal = 0
RecMPartC.DeltaT = 0
RecMPartC.DeltaTI = 0
RecMPartC.EntId = nEntId
RecMPartC.EntLen = dEntLen
RecMPartC.PrevAng = PrevAng
RecMPartC.NextAng = NextAng
RecMPartC.SideAng = SideAng
RecMPartC.Offset = Offset
RecMPartC.StWhiExt = StWhiExt
RecMPartC.EdWhiExt = EdWhiExt
RecMPartC.PrevInd = 0
RecMPartC.NextInd = 0
RecMPartC.StartDone = false
RecMPartC.EndDone = false
RecMPartC.Join = ( Join ~= 0)
table.insert( TabMPartC, RecMPartC)
end
end
-- Preparo tabella info tagli parziali, solo se tipo operazione **MCH_OY.SAWING**
for i = 1, #TabPartMch do
local nOperId = TabPartMch[i]
-- verifico sia un taglio di lama
if EgtGetOperationType( nOperId) == MCH_OY.SAWING then
EgtSetCurrMachining( nOperId)
-- recupero i dati
local Geo = EgtGetMachiningGeometry()
local bInvert = EgtGetMachiningParam(MCH_MP.INVERT)
local bStartStrict = ( EgtGetMachiningParam(MCH_MP.LEADINTYPE) == MCH_SAW_LI.STRICT)
local bEndStrict = ( EgtGetMachiningParam(MCH_MP.LEADOUTTYPE) == MCH_SAW_LO.STRICT)
local dSal = EgtGetMachiningParam( MCH_MP.STARTADDLEN)
local dEal = EgtGetMachiningParam( MCH_MP.ENDADDLEN)
local dDeltaT = CAM.GetDeltaT( nOperId)
local dDeltaTI = CAM.GetDeltaTI( nOperId) or dDeltaT
local dWidth = CAM.GetSawThickness()
-- Affondamento lavorazione
local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR)
sDepth = string.gsub( sDepth, "RB", tostring(dRawHeight))
local dRbH = EgtEvalNumExpr( sDepth)
if bInvert then
bStartStrict, bEndStrict = bEndStrict, bStartStrict
dDeltaT, dDeltaTI = dDeltaTI, dDeltaT
dSal, dEal = dEal, dSal
end
local bDouble = false
local sOthMIds = EgtGetInfo( nOperId, 'OthMIds')
if sOthMIds then
-- divido la lista separata da virgole nelle sue parti
for sId in string.gmatch(sOthMIds, '([^,]+)') do
local nId = tonumber(sId)
if nId then
local nOthPvId = EgtGetInfo( EgtGetFirstNameInGroup( nId, 'PV') or GDB_ID.NULL, 'PvId')
if not nOthPvId or EgtGetGroupObjs( nOthPvId) == 0 then
bDouble = true
break
end
end
end
end
if type( Geo) == 'table' and type( Geo[1]) == 'table' and type( Geo[1][1]) == 'number' then
local nEntId = Geo[1][1]
local dEntLen = EgtCurveLength( nEntId)
local _, PrevAng = CAM.GetPrevAngle( nEntId)
local _, NextAng = CAM.GetNextAngle( nEntId)
local _, SideAng = CAM.GetSideAng( nEntId)
local _, Offset = CAM.GetOffset( nEntId)
local _, StWhiExt = CAM.GetStartWhiskersExtend( nEntId)
local _, EdWhiExt = CAM.GetEndWhiskersExtend( nEntId)
local _, Join = CAM.GetJoinEntity( nEntId)
-- inserisco i dati nella tabella
local RecMPartC = {}
RecMPartC.OperId = nOperId
RecMPartC.StartStrict = bStartStrict
RecMPartC.EndStrict = bEndStrict
RecMPartC.Sal = dSal
RecMPartC.Eal = dEal
RecMPartC.DeltaT = dDeltaT
RecMPartC.DeltaTI = dDeltaTI
RecMPartC.EntId = nEntId
RecMPartC.EntLen = dEntLen
RecMPartC.PrevAng = PrevAng
RecMPartC.NextAng = NextAng
RecMPartC.SideAng = SideAng
RecMPartC.Offset = Offset
RecMPartC.StWhiExt = StWhiExt
RecMPartC.EdWhiExt = EdWhiExt
RecMPartC.PrevInd = 0
RecMPartC.NextInd = 0
RecMPartC.StartDone = false
RecMPartC.EndDone = false
RecMPartC.Double = bDouble
RecMPartC.Width = dWidth
RecMPartC.Join = ( Join ~= 0)
RecMPartC.Depth = dRbH
table.insert( TabMPartC, RecMPartC)
end
end
end
-- FINE: Preparo tabella info tagli parziali, solo se tipo operazione **MCH_OY.SAWING**
-- Se richiesta ottimizzazione, escludo i tagli verticali sovrapposti
if bWaterJetOptimize then
local dMaxDist = 1.4
for i = 1, #TabMPartC do
local CurrMPC = TabMPartC[i]
local ptStart = EgtSP( CurrMPC.EntId, GDB_ID.ROOT)
local ptEnd = EgtEP( CurrMPC.EntId, GDB_ID.ROOT)
local ptMid = EgtMP( CurrMPC.EntId, GDB_ID.ROOT)
if abs( CurrMPC.SideAng) < GEO.EPS_ANG_SMALL then
for j = 1, #TabMPartC do
if j ~= i then
local OtherMPC = TabMPartC[j]
if not OtherMPC.Skip and abs( OtherMPC.SideAng) < GEO.EPS_ANG_SMALL and
EgtPointCurveDist( ptStart, OtherMPC.EntId, GDB_RT.GLOB) < dMaxDist and
EgtPointCurveDist( ptEnd, OtherMPC.EntId, GDB_RT.GLOB) < dMaxDist and
EgtPointCurveDist( ptMid, OtherMPC.EntId, GDB_RT.GLOB) < dMaxDist then
CurrMPC.Skip = true
CurrMPC.Join = false
break
end
end
end
end
end
end
-- |CONGIUNZIONI TAGLI|
-- Cerco le congiunzioni -> aggiorno i campi della tabella **RecMPartC.PrevInd** e **RecMPartC2.NextInd** !ATTENZIONE! sono gli indici della tabella (NON dell'entità)
for i = 1, #TabMPartC do
local RecMPartC = TabMPartC[i]
if RecMPartC.OperId == 0 or RecMPartC.StartStrict then
local ptStart = EgtSP( RecMPartC.EntId, GDB_ID.ROOT)
-- se il taglio WaterJet è solo parziale allora #TabEnt=0, quindi non deve essere separato
if RecMPartC.Join or #TabEnt == 0 then
for j = 1, #TabMPartC do
if j ~= i then
local RecMPartC2 = TabMPartC[j]
if ( RecMPartC2.OperId == 0 or RecMPartC2.EndStrict) and ( RecMPartC2.Join or #TabEnt == 0) then
local ptEnd = EgtEP( RecMPartC2.EntId, GDB_ID.ROOT)
-- se estremi e angoli coincidono
if AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL) and
abs( RecMPartC.SideAng - RecMPartC2.SideAng) < 10 * GEO.EPS_ANG_SMALL then
RecMPartC.PrevInd = j
RecMPartC2.NextInd = i
break
end
-- se angoli interni in sovrasquadra le curve di lavorazione non hanno estremi coincidenti ma le lavorazioni devono essere unite per essere complete
-- quindi confronto le curve del loop originale
if RecMPartC.PrevAng < - GEO.EPS_ANG_SMALL and RecMPartC.SideAng > GEO.EPS_ANG_SMALL and
abs( RecMPartC.SideAng - RecMPartC2.SideAng) < 10 * GEO.EPS_ANG_SMALL then
-- recupero tratto di riferimento ( se entità per tallone è in una info altrimenti è l'entità stessa)
local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId
-- recupero la curva originale
local nLoopLayer = EgtGetParent( nRefEntId)
local nPart = EgtGetParent( nLoopLayer)
local nOrigLoopLayer = EgtGetFirstNameInGroup( nPart, EgtGetName( nLoopLayer) .. '.orig')
local nOrig = EgtGetFirstNameInGroup( nOrigLoopLayer, EgtGetName( nRefEntId))
local nRefEntId2 = EgtGetInfo( RecMPartC2.EntId, 'CopyEnt', 'i') or RecMPartC2.EntId
local nLoopLayer2 = EgtGetParent( nRefEntId2)
local nPart2 = EgtGetParent( nLoopLayer2)
local nOrigLoopLayer2 = EgtGetFirstNameInGroup( nPart2, EgtGetName( nLoopLayer2) .. '.orig')
local nOrig2 = EgtGetFirstNameInGroup( nOrigLoopLayer2, EgtGetName( nRefEntId2))
if AreSamePointEpsilon( EgtSP( nOrig, GDB_ID.ROOT), EgtEP( nOrig2, GDB_ID.ROOT), 10 * GEO.EPS_SMALL) then
-- estendo le curve in modo che vengano trovate come consecutive e salvo l'info di accorciamento per tornare alla dimensione originale ( per separazione)
local dLenOld = EgtCurveLength( RecMPartC.EntId)
EgtModifyCurveStartPoint( RecMPartC.EntId, EgtSP( nOrig, GDB_ID.ROOT), GDB_RT.GLOB)
EgtSetInfo( RecMPartC.EntId, 'SWE', dLenOld - EgtCurveLength( RecMPartC.EntId))
local dLenOld2 = EgtCurveLength( RecMPartC2.EntId)
EgtModifyCurveEndPoint( RecMPartC2.EntId, EgtEP( nOrig2, GDB_ID.ROOT), GDB_RT.GLOB)
EgtSetInfo( RecMPartC2.EntId, 'EWE', dLenOld2 - EgtCurveLength( RecMPartC2.EntId))
RecMPartC.PrevInd = j
RecMPartC2.NextInd = i
break
end
end
end
end
end
end
end
end
-- FINE: Cerco le congiunzioni
--Stampe di debug
--for i = 1, #TabMPartC do
-- local RecMPartC = TabMPartC[i]
-- EgtOutLog( 'OperId='..tostring( RecMPartC.OperId)..
-- ', Sstc='..tostring( RecMPartC.StartStrict)..', Estc='..tostring( RecMPartC.EndStrict)..
-- ', Sal='..EgtNumToString( RecMPartC.Sal, 2)..', Eal='..EgtNumToString( RecMPartC.Eal, 2)..
-- ', DeltaT='..EgtNumToString( RecMPartC.DeltaT, 2)..', DeltaTI='..EgtNumToString( RecMPartC.DeltaTI, 2)..
-- ', EntId='..tostring( RecMPartC.EntId)..', EntLen='..EgtNumToString( RecMPartC.EntLen, 2)..
-- ', PrevAng='..EgtNumToString( RecMPartC.PrevAng, 2)..', NextAng='..EgtNumToString( RecMPartC.NextAng, 2)..
-- ', SideAng='..EgtNumToString( RecMPartC.SideAng, 2)..', Join='..tostring( RecMPartC.Join)..', Skip='..tostring( RecMPartC.Skip or false)..
-- ', PrevInd='..tostring( RecMPartC.PrevInd)..', NextInd='..tostring( RecMPartC.NextInd)..
-- ', Sdone='..tostring( RecMPartC.StartDone)..', Edone='..tostring( RecMPartC.EndDone)..
-- ', Double='..tostring( RecMPartC.Double or false)..', Width='..EgtNumToString( RecMPartC.Width or 0, 2))
--end
-- Ciclo sui tratti concatenabili
for i = 1, #TabMPartC do
local RecMPartCs = TabMPartC[i]
-- se tratto completo ed esiste precedente non lavorato passo a questo
local j = i
local Count = 0
-- **conto il numero di lati concatenati che PRECEDONO il lato attuale** [i-esimo] e restituisco l'indice **j** dell'ultimo lato trovato
while RecMPartCs.OperId == 0 and not RecMPartCs.StartDone and RecMPartCs.PrevInd ~= 0 do
j = RecMPartCs.PrevInd
RecMPartCs = TabMPartC[j]
Count = Count + 1
-- se sono ritornato all'inizio, esco
if j == i then break end
-- se ho esaminato tutte le entità, esco
if Count > #TabMPartC then break end
end
-- se concatenato con successivo: il lato **i-esimo** non è l'ultimo e ha un lato concatenato dopo
if not RecMPartCs.EndDone and RecMPartCs.NextInd ~= 0 then
-- Creo la tabella **tabEnt** che contiene l'Id del lato corrente **i-esimo** e dei suo concatenati successivo
local tabEnt = {}
local tabMid = {}
table.insert( tabEnt, RecMPartCs.EntId)
local RecMPartCe = TabMPartC[RecMPartCs.NextInd]
table.insert( tabEnt, RecMPartCe.EntId)
-- Creo la tabella **tabMid** che contiene l'indice dei lati compresi tra il primo e l'ultimo esclusi
while RecMPartCe.OperId == 0 and not RecMPartCe.StartDone and RecMPartCe.NextInd ~= 0 and RecMPartCe.NextInd ~= j do
RecMPartCe = TabMPartC[RecMPartCe.NextInd]
table.insert( tabEnt, RecMPartCe.EntId)
table.insert( tabMid, RecMPartCe.PrevInd)
end
-- |LAVORAZIONE| costruisco la lavorazione dell'entità **i-esima**
local nRefEntId = EgtGetInfo( RecMPartCs.EntId, 'CopyEnt', 'i') or RecMPartCs.EntId
local nMill = EgtAddMachining( 'Waterjet' .. tostring( nRefEntId) .. 'S', sWaterJet)
if nMill then
local sName = EgtGetName( nMill)
-- assegno il valore di flusso (da ver. 2.7f1)
if vThickFeed then
local dDepth = dRawHeight / cos( RecMPartCs.SideAng)
local dFlux = GetWjFlux( dDepth)
if dFlux then EgtSetInfo( nMill, 'Flux', dFlux) end
end
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter() -- diametro utensile
local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR) -- offset radiale
-- verifico se percorso chiuso: tra punto **i-esimo** e **j-esimo**
local ptStart = EgtSP( RecMPartCs.EntId, GDB_ID.ROOT)
local ptEnd = EgtEP( RecMPartCe.EntId, GDB_ID.ROOT)
local bClosed = AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL)
-- se aperto, sistemazioni inizio e fine
if not bClosed then
-- aggiusto inizio
local dStartAddLen = 0
if RecMPartCs.OperId == 0 then
if bWaterJetOptimize and RecMPartCs.Join and abs( RecMPartCs.SideAng) < GEO.EPS_ANG_SMALL then
dStartAddLen = 0
EgtSetMachiningParam( MCH_MP.LIHOLE, false)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nIntAngLiType)
EgtSetMachiningParam( MCH_MP.LITANG, dRad)
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
elseif RecMPartCs.PrevAng > - 175 and RecMPartCs.PrevAng < - 5 then
dStartAddLen = dRad * ( cos( 180 + RecMPartCs.PrevAng) + 1) / sin( 180 + RecMPartCs.PrevAng)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nIntAngLiType)
EgtSetMachiningParam( MCH_MP.LITANG, dIntAngLiTang)
EgtSetMachiningParam( MCH_MP.LIPERP, dIntAngLiPerp)
else
-- se entità molto corta con angolo interno dopo, la allungo del raggio utensile
if RecMPartCs.EntLen < dRad and RecMPartCs.NextAng > - 175 and RecMPartCs.NextAng < - 5 then
dStartAddLen = RecMPartCs.EntLen - dRad - 1.0
else
dStartAddLen = 0
end
end
else
dStartAddLen = RecMPartCs.EntLen - RecMPartCs.DeltaT - dDeltaIntCorner - dDeltaLenPartMilling
end
dStartAddLen = dStartAddLen - RecMPartCs.StWhiExt
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dStartAddLen)
-- aggiusto fine
local dEndAddLen = 0
if RecMPartCe.OperId == 0 then
if bWaterJetOptimize and RecMPartCs.Join and abs( RecMPartCs.SideAng) < GEO.EPS_ANG_SMALL then
dEndAddLen = 0
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nIntAngLoType)
EgtSetMachiningParam( MCH_MP.LOTANG, dRad)
EgtSetMachiningParam( MCH_MP.LOPERP, 0)
elseif RecMPartCe.NextAng > - 175 and RecMPartCe.NextAng < - 5 then
dEndAddLen = dRad * ( cos( 180 + RecMPartCe.NextAng) + 1) / sin( 180 + RecMPartCe.NextAng)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nIntAngLoType)
EgtSetMachiningParam( MCH_MP.LOTANG, dIntAngLoTang)
EgtSetMachiningParam( MCH_MP.LOPERP, dIntAngLoPerp)
else
-- se entità molto corta con angolo interno prima, la allungo del raggio utensile
if RecMPartCe.EntLen < dRad and RecMPartCe.PrevAng > - 175 and RecMPartCe.PrevAng < - 5 then
dEndAddLen = RecMPartCe.EntLen - dRad - 1.0
else
dEndAddLen = 0
end
end
else
dEndAddLen = RecMPartCe.EntLen - RecMPartCe.DeltaTI - dDeltaIntCorner - dDeltaLenPartMilling
end
dEndAddLen = dEndAddLen - RecMPartCe.EdWhiExt
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen)
end
-- se previsto, imposto feed e conicità da Q*
local dTaperAng = 0
if vThickFeed then
local dDepth = dRawHeight / cos( RecMPartCs.SideAng)
local dFeed, dThRef = GetWjSpeed( dDepth)
if dFeed and dThRef then
EgtSetMachiningParam( MCH_MP.FEED, dFeed)
EgtSetMachiningParam( MCH_MP.THICKREF, dThRef)
end
dTaperAng = GetWjTaperAng( dDepth)
end
-- eventuale angolo di lato e offset associato
EgtSetMachiningParam( MCH_MP.SIDEANGLE, RecMPartCs.SideAng + dTaperAng)
EgtSetMachiningParam( MCH_MP.OFFSR, dUserOffsR + RecMPartCs.Offset)
-- suggerisco angoli iniziali
CAM.HintWaterJetAngC( RecMPartCs.SideAng + dTaperAng, ( sLay == 'OutLoop'), nRefEntId)
-- assegno geometria
if EgtSetMachiningGeometry( tabEnt) then
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( RecMPartCs.EntId))
CAM.CopyPreviewToPiece( nMill, nPartId)
-- se inclinata e non sta nelle corse
if abs( RecMPartCs.SideAng + dTaperAng) > GEO.EPS_ANG_SMALL and not EgtApplyMachining( true) and EgtGetOutstrokeInfo() then
-- se aperto, cambio gli angoli iniziali
if not bClosed then
CAM.HintWaterJetAngC( RecMPartCs.SideAng + dTaperAng, ( sLay ~= 'OutLoop'), nRefEntId)
-- altrimenti chiuso, spezzo a metà
else
-- lunghezza della geometria
local dPathLen = 0
for k = 1, #tabEnt do
dPathLen = dPathLen + EgtCurveLength( tabEnt[k])
end
-- accorcio la lavorazione alla metà
EgtSetMachiningParam( MCH_MP.OVERL, 0)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dPathLen/2)
if EgtPreviewMachining() then
CAM.CopyPreviewToPiece( nMill, nPartId)
end
-- copio la lavorazione per lavorare l'altra metà
local nMill2 = EgtCopyMachining( sName .. '2', sName)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dPathLen/2)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
if EgtPreviewMachining() then
CAM.CopyPreviewToPiece( nMill2, nPartId)
end
EgtSetOperationStatus( nMill2, false)
EgtSetInfo( nMill2, 'Lay', sLay)
end
end
else
CAM.ERR = 41
end
EgtSetOperationStatus( nMill, false)
EgtSetInfo( nMill, 'Lay', sLay)
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
-- segnalazione lavorazioni applicate
RecMPartCs.EndDone = true
if RecMPartCs.OperId == 0 then
RecMPartCs.StartDone = true
end
RecMPartCe.StartDone = true
if RecMPartCe.OperId == 0 then
RecMPartCe.EndDone = true
end
for k = 1, #tabMid do
TabMPartC[tabMid[k]].StartDone = true
TabMPartC[tabMid[k]].EndDone = true
end
end
end
-- FINE: Ciclo sui tratti concatenabili
-- Se necessario riduco ingresso/uscita per occupare il solco del taglio di lama (dWidth)
local function VerifyInterference( nMill, dWidth)
local dRad = 0.5 * CAM.GetToolDiameter()
EgtPreviewMachining()
local nRet = EgtVerifyMachining( nMill)
if nRet == NST_FMI.RM then
-- Recupero i parametri di uscita
local Tang = EgtGetMachiningParam( MCH_MP.LOTANG)
local Perp = EgtGetMachiningParam( MCH_MP.LOPERP)
if Perp and dWith and Perp > dWidth then
EgtSetMachiningParam( MCH_MP.LOTANG, dWidth - dRad)
EgtSetMachiningParam( MCH_MP.LOPERP, dWidth - 2*dRad)
EgtPreviewMachining()
end
end
nRet = EgtVerifyMachining( nMill)
if nRet == NST_FMI.RM then
-- Recupero i parametri di ingresso
local Tang = EgtGetMachiningParam( MCH_MP.LITANG)
local Perp = EgtGetMachiningParam( MCH_MP.LIPERP)
if Perp and dWith and Perp > dWidth then
EgtSetMachiningParam( MCH_MP.LITANG, dWidth - dRad)
EgtSetMachiningParam( MCH_MP.LIPERP, dWidth - 2*dRad)
EgtSetMachiningParam( MCH_MP.LIHOLE, false)
end
end
end
-- Ciclo sui tratti singoli rimasti
for i = 1, #TabMPartC do
local RecMPartC = TabMPartC[i]
-- completo singolo
if not RecMPartC.StartDone and RecMPartC.OperId == 0 then
-- |LAVORAZIONE|
local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId
local nMill = EgtAddMachining( 'Waterjet'..tostring( nRefEntId)..'S', sWaterJet)
if nMill then
local sName = EgtGetName( nMill)
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR)
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
-- verifico se percorso chiuso
local bClosed = EgtCurveIsClosed( RecMPartC.EntId)
-- se aperto, sistemazioni inizio e fine
if not bClosed then
-- dati inizio-fine dipendono da inverti lavorazione
local dPrevAng = RecMPartC.PrevAng
local dNextAng = RecMPartC.NextAng
if bInvert then dPrevAng, dNextAng = dNextAng, dPrevAng end
local dStWhiExt = RecMPartC.StWhiExt
local dEdWhiExt = RecMPartC.EdWhiExt
if bInvert then dStWhiExt, dEdWhiExt = dEdWhiExt, dStWhiExt end
-- aggiusto inizio
local dStartAddLen = 0
if bWaterJetOptimize and RecMPartC.Join and abs( RecMPartC.SideAng) < GEO.EPS_ANG_SMALL then
dStartAddLen = 0
EgtSetMachiningParam( MCH_MP.LIHOLE, false)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nIntAngLiType)
EgtSetMachiningParam( MCH_MP.LITANG, dRad)
EgtSetMachiningParam( MCH_MP.LIPERP, 0)
elseif dPrevAng < - 5 and dPrevAng > - 175 then
dStartAddLen = dRad * ( cos( 180 + dPrevAng) + 1) / sin( 180 + dPrevAng)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nIntAngLiType)
EgtSetMachiningParam( MCH_MP.LITANG, dIntAngLiTang)
EgtSetMachiningParam( MCH_MP.LIPERP, dIntAngLiPerp)
end
dStartAddLen = dStartAddLen - dStWhiExt
EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen)
-- aggiusto fine
local dEndAddLen = 0
if bWaterJetOptimize and RecMPartC.Join and abs( RecMPartC.SideAng) < GEO.EPS_ANG_SMALL then
dEndAddLen = 0
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nIntAngLoType)
EgtSetMachiningParam( MCH_MP.LOTANG, dRad)
EgtSetMachiningParam( MCH_MP.LOPERP, 0)
elseif dNextAng < - 5 and dNextAng > - 175 then
dEndAddLen = dRad * ( cos( 180 + dNextAng) + 1) / sin( 180 + dNextAng)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nIntAngLoType)
EgtSetMachiningParam( MCH_MP.LOTANG, dIntAngLoTang)
EgtSetMachiningParam( MCH_MP.LOPERP, dIntAngLoPerp)
end
dEndAddLen = dEndAddLen - dEdWhiExt
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen)
end
-- se previsto, imposto feed e conicità da Q*
local dTaperAng = 0
if vThickFeed then
local dDepth = dRawHeight / cos( RecMPartC.SideAng)
local dFeed, dThRef = GetWjSpeed( dDepth)
if dFeed and dThRef then
EgtSetMachiningParam( MCH_MP.FEED, dFeed)
EgtSetMachiningParam( MCH_MP.THICKREF, dThRef)
end
dTaperAng = GetWjTaperAng( dDepth)
end
-- eventuale angolo di lato e offset associato
EgtSetMachiningParam( MCH_MP.SIDEANGLE, RecMPartC.SideAng + dTaperAng)
EgtSetMachiningParam( MCH_MP.OFFSR, RecMPartC.Offset + dUserOffsR)
-- suggerisco angoli iniziali
CAM.HintWaterJetAngC( RecMPartC.SideAng + dTaperAng, ( sLay == 'OutLoop'), nRefEntId)
-- aggiungo la geometria
if EgtSetMachiningGeometry( {RecMPartC.EntId}) then
-- verifico che la lavorazione parziale non interferisca con altri pezzi
VerifyInterference( nMill, RecMPartC.Width)
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId))
CAM.CopyPreviewToPiece( nMill, nPartId)
-- se inclinata e non sta nelle corse
if abs( RecMPartC.SideAng + dTaperAng) > GEO.EPS_ANG_SMALL and not EgtApplyMachining( true) and EgtGetOutstrokeInfo() then
-- se aperto, cambio gli angoli iniziali
if not bClosed then
CAM.HintWaterJetAngC( RecMPartC.SideAng + dTaperAng, ( sLay ~= 'OutLoop'), nRefEntId)
-- altrimenti chiuso, spezzo a metà
else
-- lunghezza della geometria
local dPathLen = EgtCurveLength( RecMPartC.EntId)
-- accorcio la lavorazione alla metà
EgtSetMachiningParam( MCH_MP.OVERL, 0)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dPathLen/2)
if EgtPreviewMachining() then
CAM.CopyPreviewToPiece( nMill, nPartId)
end
-- copio la lavorazione per lavorare l'altra metà
local nMill2 = EgtCopyMachining( sName .. '2', sName)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dPathLen/2)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
if EgtPreviewMachining() then
CAM.CopyPreviewToPiece( nMill2, nPartId)
end
EgtSetOperationStatus( nMill2, false)
EgtSetInfo( nMill2, 'Lay', sLay)
end
end
-- se aperta e necessaria lavorazione doppia
if not bClosed and RecMPartC.Double then
-- copio la lavorazione per fare il doppio
local nMill2 = EgtCopyMachining( sName .. '2', sName)
CAM.InvertWorkside()
EgtSetMachiningParam( MCH_MP.OFFSR, -RecMPartC.Width)
if EgtPreviewMachining() then
CAM.CopyPreviewToPiece( nMill2, nPartId)
end
EgtSetOperationStatus( nMill2, false)
EgtSetInfo( nMill2, 'Lay', sLay)
end
else
CAM.ERR = 42
end
EgtSetOperationStatus( nMill, false)
EgtSetInfo( nMill, 'Lay', sLay)
if RecMPartC.Skip then
local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId))
CAM.ErasePreview( nMill)
EgtRemoveOperation( nMill)
end
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
RecMPartC.StartDone = true
RecMPartC.EndDone = true
end
-- parziale singolo su **inizio**
if not RecMPartC.StartDone and RecMPartC.StartStrict and RecMPartC.PrevAng >= - 5 then
local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId
local nMill = EgtAddMachining( 'Waterjet'..tostring( nRefEntId)..'S', sWaterJet)
if nMill then
local sName = EgtGetName( nMill)
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR)
local dEndAddLen = RecMPartC.EntLen - RecMPartC.DeltaTI - dDeltaLenPartMilling - RecMPartC.EdWhiExt + RecMPartC.Sal
-- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!!
if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then
dEndAddLen = 0
end
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen)
local dStartAddLen = 0
if RecMPartC.PrevAng < - 5 and RecMPartC.PrevAng > - 175 then
dStartAddLen = dRad * ( cos( 180 + RecMPartC.PrevAng) + 1) / sin( 180 + RecMPartC.PrevAng)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nIntAngLiType)
EgtSetMachiningParam( MCH_MP.LITANG, dIntAngLiTang)
EgtSetMachiningParam( MCH_MP.LIPERP, dIntAngLiPerp)
end
dStartAddLen = dStartAddLen - RecMPartC.StWhiExt - RecMPartC.Sal - dDeltaCutSafety
-- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!!
if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then
dStartAddLen = 0
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen)
-- se previsto, imposto feed e conicità da Q*
local dTaperAng = 0
if vThickFeed then
local dDepth = dRawHeight / cos( RecMPartC.SideAng)
local dFeed, dThRef = GetWjSpeed( dDepth)
if dFeed and dThRef then
EgtSetMachiningParam( MCH_MP.FEED, dFeed)
EgtSetMachiningParam( MCH_MP.THICKREF, dThRef)
end
dTaperAng = GetWjTaperAng( dDepth)
end
-- eventuale angolo di lato e offset associato
EgtSetMachiningParam( MCH_MP.SIDEANGLE, RecMPartC.SideAng + dTaperAng)
EgtSetMachiningParam( MCH_MP.OFFSR, RecMPartC.Offset + dUserOffsR)
-- suggerisco angoli iniziali
CAM.HintWaterJetAngC( RecMPartC.SideAng + dTaperAng, ( sLay == 'OutLoop'), nRefEntId)
-- disattivo foro di ingresso
EgtSetMachiningParam( MCH_MP.LIHOLE, false)
-- riduco le lavorazioni per rimanere nel solco della lama
dRad = 0.5 * CAM.GetToolDiameter()
local Perp = EgtGetMachiningParam( MCH_MP.LIPERP)
if Perp > RecMPartC.Width then
EgtSetMachiningParam( MCH_MP.LITANG, RecMPartC.Width/2)
EgtSetMachiningParam( MCH_MP.LIPERP, RecMPartC.Width/2 - dRad)
end
-- Recupero i parametri di uscita
Perp = EgtGetMachiningParam( MCH_MP.LOPERP)
if Perp > RecMPartC.Width then
EgtSetMachiningParam( MCH_MP.LOTANG, RecMPartC.Width/2)
EgtSetMachiningParam( MCH_MP.LOPERP, RecMPartC.Width/2 - dRad)
end
if EgtSetMachiningGeometry( {RecMPartC.EntId}) then
-- verifico che la lavorazione parziale non interferisca con altri pezzi
-- VerifyInterference( nMill, RecMPartC.Width)
if EgtPreviewMachining() then
local nPartId = EgtGetParent( EgtGetParent( RecMPartC.EntId))
CAM.CopyPreviewToPiece( nMill, nPartId)
if RecMPartC.Double then
-- copio la lavorazione per fare il doppio
local nMill2 = EgtCopyMachining( sName .. '2', sName)
CAM.InvertWorkside()
EgtSetMachiningParam( MCH_MP.OFFSR, -RecMPartC.Width - RecMPartC.Offset - dUserOffsR)
if EgtPreviewMachining() then
CAM.CopyPreviewToPiece( nMill2, nPartId)
end
EgtSetOperationStatus( nMill2, false)
EgtSetInfo( nMill2, 'Lay', sLay)
end
else
CAM.ERR = 43
end
EgtSetOperationStatus(nMill,false)
EgtSetInfo(nMill,'Lay',sLay)
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
RecMPartC.StartDone = true
end
-- parziale singolo su **fine**
if not RecMPartC.EndDone and RecMPartC.EndStrict and RecMPartC.NextAng >= - 5 then
local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId
local nMill = EgtAddMachining( 'Waterjet'..tostring( nRefEntId)..'E', sWaterJet)
if nMill then
local sName = EgtGetName( nMill)
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR)
local dStartAddLen = RecMPartC.EntLen - RecMPartC.DeltaT - dDeltaLenPartMilling - RecMPartC.StWhiExt + RecMPartC.Eal
-- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!!
if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then
dStartAddLen = 0
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dStartAddLen)
local dEndAddLen = 0
if RecMPartC.NextAng < - 5 and RecMPartC.NextAng > - 175 then
dEndAddLen = dRad * ( cos( 180 + RecMPartC.NextAng) + 1) / sin( 180 + RecMPartC.NextAng)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nIntAngLoType)
EgtSetMachiningParam( MCH_MP.LOTANG, dIntAngLoTang)
EgtSetMachiningParam( MCH_MP.LOPERP, dIntAngLoPerp)
end
dEndAddLen = dEndAddLen - RecMPartC.EdWhiExt - RecMPartC.Eal - dDeltaCutSafety
-- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!!
if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then
dEndAddLen = 0
end
EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dEndAddLen)
-- se previsto, imposto feed e conicità da Q*
local dTaperAng = 0
if vThickFeed then
local dDepth = dRawHeight / cos( RecMPartC.SideAng)
local dFeed, dThRef = GetWjSpeed( dDepth)
if dFeed and dThRef then
EgtSetMachiningParam( MCH_MP.FEED, dFeed)
EgtSetMachiningParam( MCH_MP.THICKREF, dThRef)
end
dTaperAng = GetWjTaperAng( dDepth)
end
-- eventuale angolo di lato e offset associato
EgtSetMachiningParam( MCH_MP.SIDEANGLE, RecMPartC.SideAng + dTaperAng)
EgtSetMachiningParam( MCH_MP.OFFSR, RecMPartC.Offset + dUserOffsR)
-- suggerisco angoli iniziali
CAM.HintWaterJetAngC( RecMPartC.SideAng + dTaperAng, ( sLay == 'OutLoop'), nRefEntId)
-- disattivo foro di ingresso
EgtSetMachiningParam( MCH_MP.LIHOLE, false)
-- riduco le lavorazioni per rimanere nel solco della lama
dRad = 0.5 * CAM.GetToolDiameter()
local Perp = EgtGetMachiningParam( MCH_MP.LIPERP)
if Perp > RecMPartC.Width then
EgtSetMachiningParam( MCH_MP.LITANG, RecMPartC.Width/2)
EgtSetMachiningParam( MCH_MP.LIPERP, RecMPartC.Width/2 - dRad)
end
-- Recupero i parametri di uscita
Perp = EgtGetMachiningParam( MCH_MP.LOPERP)
if Perp > RecMPartC.Width then
EgtSetMachiningParam( MCH_MP.LOTANG, RecMPartC.Width/2)
EgtSetMachiningParam( MCH_MP.LOPERP, RecMPartC.Width/2 - dRad)
end
-- aggiungo la geometria
if EgtSetMachiningGeometry( {RecMPartC.EntId}) then
-- verifico che la lavorazione parziale non interferisca con altri pezzi
-- VerifyInterference( nMill, RecMPartC.Width)
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId))
CAM.CopyPreviewToPiece(nMill, nPartId)
if RecMPartC.Double then
-- copio la lavorazione per fare il doppio
local nMill2 = EgtCopyMachining( sName .. '2', sName)
CAM.InvertWorkside()
EgtSetMachiningParam( MCH_MP.OFFSR, -RecMPartC.Width - RecMPartC.Offset - dUserOffsR)
if EgtPreviewMachining() then
CAM.CopyPreviewToPiece( nMill2, nPartId)
end
EgtSetOperationStatus( nMill2, false)
EgtSetInfo( nMill2, 'Lay', sLay)
end
else
CAM.ERR = 44
end
EgtSetOperationStatus(nMill,false)
EgtSetInfo(nMill,'Lay',sLay)
else
EgtRemoveOperation( nMill)
end
else
CAM.ERR = 30
end
RecMPartC.EndDone = true
end
end
-- FINE: Ciclo sui tratti singoli rimasti
-- Preparo tabella collegamenti : **TabBridges** (per contorni esterni e interni)
local TabBridges = {}
if sLay == 'OutLoop' or sLay == 'InLoop' then
local BriGrpId = EgtGetFirstNameInGroup( EgtGetCurrMachGroup(), 'Bridges')
local BriId = EgtGetFirstNameInGroup( BriGrpId or GDB_ID.NULL, 'BridgeLine')
while BriId do
local nPart1 = EgtGetInfo( BriId, 'PartStart', 'i')
local nEnt1 = EgtGetInfo( BriId, 'EntStart', 'i')
local ptP1 = EgtSP( BriId, GDB_ID.ROOT)
local nPart2 = EgtGetInfo( BriId, 'PartEnd', 'i')
local nEnt2 = EgtGetInfo( BriId, 'EntEnd', 'i')
local ptP2 = EgtEP( BriId, GDB_ID.ROOT)
local nPhase = EgtGetInfo( BriId, 'Ph', 'i')
table.insert( TabBridges, { Part1 = nPart1, Ent1 = nEnt1, P1 = ptP1, Part2 = nPart2, Ent2 = nEnt2, P2 = ptP2, Phase = nPhase})
EgtSetInfo( BriId, 'BridgeW', dBridgeW)
BriId = EgtGetNextName( BriId, 'BridgeLine')
end
end
-- Stampe di debug
--for i = 1, #TabBridges do
-- local RecBri = TabBridges[i]
-- EgtOutLog( 'Part1='..tostring( RecBri.Part1)..' Ent1='..tostring( RecBri.Ent1)..' P1='..tostring( RecBri.P1)..
-- ' Part2='..tostring( RecBri.Part2)..' Ent2='..tostring( RecBri.Ent2)..' P2='..tostring( RecBri.P2))
--end
-- Recupero le lavorazioni WaterJet inserite
local TabWjOper = {}
local OperId = EgtGetFirstActiveOperation()
while OperId do
if EgtGetOperationType( OperId) == MCH_OY.WATERJETTING then
table.insert( TabWjOper, OperId)
end
OperId = EgtGetNextActiveOperation( OperId)
end
-- Funzione per ricerca geometrie in tabella geometrie da lavorazione
local function FindGeometryInTab( nEnt, vTab)
for i = 1, #vTab do
if vTab[i][1] == nEnt then
return true
end
end
return false
end
-- Se ci sono lavorazioni e collegamenti unisco le lavorazioni collegate
if #TabWjOper > 0 and #TabBridges > 0 then
local i = 1
while i <= #TabWjOper do
local bJoined = false
-- imposto una lavorazione e verifico se è interessata da collegamenti
if EgtSetCurrMachining( TabWjOper[i]) then
local TabEntI = EgtGetMachiningGeometry()
local BriInd, sOtherPart, sOtherEnt
for k = 1, #TabBridges do
if not TabBridges[k].Used then
if FindGeometryInTab( TabBridges[k].Ent1, TabEntI) then
BriInd = k
sOtherPart = 'Part2'
sOtherEnt = 'Ent2'
break
elseif FindGeometryInTab( TabBridges[k].Ent2, TabEntI) then
BriInd = k
sOtherPart = 'Part1'
sOtherEnt = 'Ent1'
break
end
end
end
-- se ci sono collegamenti, cerca l'altra lavorazione a cui è associata
if BriInd then
local WjOtherId
local TabEntJ
for j = 1, #TabWjOper do
if j ~= i and EgtSetCurrMachining( TabWjOper[j]) then
TabEntJ = EgtGetMachiningGeometry()
if FindGeometryInTab( TabBridges[BriInd][sOtherEnt], TabEntJ) then
TabBridges[BriInd].Used = true
WjOtherId = TabWjOper[j]
break
end
end
end
-- se trovata, unisco le due lavorazioni nella prima
if WjOtherId then
-- elimino lavorazione collegata
CAM.ErasePreview( WjOtherId)
EgtRemoveOperation( WjOtherId)
-- sistemo la lavorazione principale
EgtSetCurrMachining( TabWjOper[i])
table.move( TabEntJ, 1, #TabEntJ, #TabEntI + 1, TabEntI)
EgtSetMachiningGeometry( TabEntI)
EgtPreviewMachining( true)
local PartId = EgtGetParent( EgtGetParent( TabEntI[1][1]))
CAM.CopyPreviewToPiece( TabWjOper[i], PartId)
-- dichiaro lavorazioni unite
bJoined = true
end
end
end
if not bJoined then i = i + 1 end
end
end
-- Se inserita almeno una lavorazione WJ, ne salvo alcuni parametri in intestazione
local LastId = EgtGetLastActiveOperation()
if EgtGetOperationType( LastId) == MCH_OY.WATERJETTING then
-- recupero i dati
EgtSetCurrMachining( LastId)
local sTuuid = EgtGetMachiningParam( MCH_MP.TUUID)
EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '')
local dTLen = EgtTdbGetCurrToolParam( MCH_TP.LEN)
local dLiHoleRad = EgtGetMachiningParam( MCH_MP.LIHOLERAD)
local dFeedT = EgtGetMachiningParam( MCH_MP.TIPFEED)
local nLPTurns = EgtGetMachiningParam( MCH_MP.LPTURNS)
local nHPTurns = EgtGetMachiningParam( MCH_MP.HPTURNS)
-- scrivo i dati nel gruppo di lavoro
EgtSetInfo( EgtGetCurrMachGroup(), 'WJ_TL', dTLen)
EgtSetInfo( EgtGetCurrMachGroup(), 'WJ_HR', dLiHoleRad)
EgtSetInfo( EgtGetCurrMachGroup(), 'WJ_FT', dFeedT)
EgtSetInfo( EgtGetCurrMachGroup(), 'WJ_LP', nLPTurns)
EgtSetInfo( EgtGetCurrMachGroup(), 'WJ_HP', nHPTurns)
end
end
-- Funzione che applica le forature
function CAM.ApplyDrillings( TabEnt, sLay)
-- Ciclo sulle entità curva
for i = 1, #TabEnt do
local nEntId = TabEnt[i]
local nDrill = EgtAddMachining( 'Drill' .. tostring( nEntId), sDrill)
if nDrill then
-- eventuale suggerimento angolo asse C a 90 deg
CAM.HintDrillMillAngC()
-- foro standard
local bSetOk = EgtSetMachiningGeometry( {nEntId})
-- sequenza di fori su percorso
if not bSetOk then
local dEntLen = EgtCurveLength( nEntId)
local _, PrevAng = CAM.GetPrevAngle( nEntId)
local _, NextAng = CAM.GetNextAngle( nEntId)
local _, SideAng = CAM.GetSideAng( nEntId)
local dRad = 0.5 * CAM.GetToolDiameter()
EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_DRI_SUB.ALONG_CURVE)
local dTotOffs = dRad + dOffsetHoles
if SideAng > GEO.EPS_ANG_SMALL then
dTotOffs = dTotOffs + dRawHeight * tan( SideAng)
end
EgtSetMachiningParam( MCH_MP.OFFSET, dTotOffs)
local dStartAddLen = - dDeltaLenHoles
if PrevAng < - 5 and PrevAng > - 175 then
dStartAddLen = ( dRad + dOffsetHoles) * ( cos( 180 + PrevAng) + 1) / sin( 180 + PrevAng) - dRad
elseif PrevAng > 120 then
dStartAddLen = - 0.5 * dRad
end
local dEndAddLen = - dDeltaLenHoles
if NextAng < - 5 and NextAng > - 175 then
dEndAddLen = ( dRad + dOffsetHoles) * ( cos( 180 + NextAng) + 1) / sin( 180 + NextAng) + dRad - dOverlapHoles
elseif NextAng > 120 then
dEndAddLen = - 0.5 * dRad
end
if bOneHoleIntCorner and ( PrevAng < -5 or NextAng < -5) then
if PrevAng < -5 then
--dEndAddLen = dEndAddLen + 2 * dRad
--if NextAng > 2 then
dEndAddLen = dEntLen - dStartAddLen - 2 * dRad
--end
elseif NextAng < -5 then
dStartAddLen = dEntLen
end
elseif dEntLen - dStartAddLen - dEndAddLen < 2 * dRad then
if PrevAng > 2 then
if dEndAddLen > 2 * dRad - dOverlapHoles - GEO.EPS_SMALL then
dEndAddLen = dEndAddLen - dRad
end
if dEntLen - dStartAddLen - dEndAddLen < 2 * dRad then
dStartAddLen = dEntLen - dEndAddLen - 2 * dRad
end
elseif NextAng > 2 then
dEndAddLen = dEntLen - dStartAddLen - 2 * dRad
end
end
EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dEndAddLen)
EgtSetMachiningParam( MCH_MP.OVERLAP, dOverlapHoles)
bSetOk = EgtSetMachiningGeometry( {nEntId})
end
if bSetOk then
if EgtPreviewMachining() then
local nPartId = EgtGetParent( EgtGetParent( nEntId))
CAM.CopyPreviewToPiece( nDrill, nPartId)
else
CAM.ERR = 45
end
EgtSetOperationStatus( nDrill, false)
EgtSetInfo( nDrill, 'Lay', sLay)
else
EgtRemoveOperation( nDrill)
end
else
CAM.ERR = 30
end
end
end
-- Funzione che applica le forature per completare i tagli parziali
function CAM.ApplyDrillingsOnPartialCuts( TabPartMch, sLay)
-- Ciclo sui tagli di lama parziali
for i = 1, #TabPartMch do
local nOperId = TabPartMch[i]
-- verifico sia un taglio di lama
if EgtGetOperationType(nOperId) == MCH_OY.SAWING then
EgtSetCurrMachining(nOperId)
-- recupero i dati
local Geo = EgtGetMachiningGeometry()
local bInvert = EgtGetMachiningParam(MCH_MP.INVERT)
local bStartStrict = ( EgtGetMachiningParam(MCH_MP.LEADINTYPE) == MCH_SAW_LI.STRICT)
local bEndStrict = ( EgtGetMachiningParam(MCH_MP.LEADOUTTYPE) == MCH_SAW_LO.STRICT)
local dDeltaT = CAM.GetDeltaT( nOperId)
local dDeltaTI = CAM.GetDeltaTI( nOperId) or dDeltaT
if bInvert then
bStartStrict, bEndStrict = bEndStrict, bStartStrict
dDeltaT, dDeltaTI = dDeltaTI, dDeltaT
end
if type(Geo) == 'table' and type(Geo[1]) == 'table' and type(Geo[1][1]) == 'number' then
local nEntId = Geo[1][1]
local dEntLen = EgtCurveLength( nEntId)
local _, PrevAng = CAM.GetPrevAngle( nEntId)
local _, NextAng = CAM.GetNextAngle( nEntId)
local _, SideAng = CAM.GetSideAng(nEntId)
if bStartStrict then
local nDrill = EgtAddMachining( 'Drill'..tostring(nEntId)..'S', sDrill)
if nDrill then
-- eventuale suggerimento angolo asse C a 90 deg
CAM.HintDrillMillAngC()
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
local dTotOffs = dRad + dOffsetHoles
if SideAng > GEO.EPS_ANG_SMALL then
dTotOffs = dTotOffs + dRawHeight * tan( SideAng)
end
EgtSetMachiningParam(MCH_MP.SUBTYPE,MCH_DRI_SUB.ALONG_CURVE)
EgtSetMachiningParam(MCH_MP.OFFSET, dTotOffs)
local dStartAddLen = 0
if PrevAng < - 5 and PrevAng > - 175 then
dStartAddLen = ( dRad + dOffsetHoles) * ( cos( 180 + PrevAng) + 1) / sin( 180 + PrevAng) - dRad
end
EgtSetMachiningParam(MCH_MP.STARTADDLEN, - dStartAddLen)
if not ( bOneHoleIntCorner and ( PrevAng < -5 or NextAng < -5)) then
EgtSetMachiningParam( MCH_MP.ENDADDLEN,-( dEntLen - dDeltaTI - dDeltaIntCorner - dRad))
else
EgtSetMachiningParam( MCH_MP.ENDADDLEN,-( dEntLen - dStartAddLen - 2 * dRad))
end
EgtSetMachiningParam( MCH_MP.OVERLAP, dOverlapHoles)
if EgtSetMachiningGeometry({nEntId}) then
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( nEntId))
CAM.CopyPreviewToPiece(nDrill, nPartId)
else
CAM.ERR = 46
end
EgtSetOperationStatus(nDrill,false)
EgtSetInfo(nDrill,'Lay',sLay)
else
EgtRemoveOperation( nDrill)
end
else
CAM.ERR = 30
end
end
if bEndStrict and not ( bOneHoleIntCorner and ( PrevAng < -5 or NextAng < -5)) then
local nDrill = EgtAddMachining( 'Drill'..tostring(nEntId)..'E', sDrill)
if nDrill then
-- eventuale suggerimento angolo asse C a 90 deg
CAM.HintDrillMillAngC()
-- aggiustamenti vari
local dRad = 0.5 * CAM.GetToolDiameter()
local dTotOffs = dRad + dOffsetHoles
if SideAng > GEO.EPS_ANG_SMALL then
dTotOffs = dTotOffs + dRawHeight * tan( SideAng)
end
EgtSetMachiningParam(MCH_MP.SUBTYPE,MCH_DRI_SUB.ALONG_CURVE)
EgtSetMachiningParam(MCH_MP.OFFSET, dTotOffs)
EgtSetMachiningParam(MCH_MP.STARTADDLEN, - ( dEntLen - dDeltaT - dDeltaIntCorner - dRad))
local dEndAddLen = 0
if NextAng < - 5 and NextAng > - 175 then
dEndAddLen = ( dRad + dOffsetHoles) * ( cos( 180 + NextAng) + 1) / sin( 180 + NextAng) + dRad - dOverlapHoles
end
EgtSetMachiningParam(MCH_MP.ENDADDLEN,- dEndAddLen)
EgtSetMachiningParam(MCH_MP.OVERLAP, dOverlapHoles)
if EgtSetMachiningGeometry({nEntId}) then
if EgtPreviewMachining() then
local nPartId = EgtGetParent(EgtGetParent( nEntId))
CAM.CopyPreviewToPiece(nDrill, nPartId)
else
CAM.ERR = 47
end
EgtSetOperationStatus(nDrill,false)
EgtSetInfo(nDrill,'Lay',sLay)
else
EgtRemoveOperation( nDrill)
end
else
CAM.ERR = 30
end
end
end
end
end
end
-- Funzione che applica i tagli da sopra
function CAM.ApplyOnCuts( TabOnCut, sLay)
-- Diametro e spessore della lama
local SawDiam = CAM.GetToolDiameterFromMdb( sOnSaw)
local SawTh = CAM.GetSawThicknessFromMdb( sOnSaw)
if SawDiam < GEO.EPS_SMALL or SawTh < GEO.EPS_SMALL then
CAM.ERR = 30
return
end
local function PreVerifyMachining( TabOnCut)
local EntId = TabOnCut[1]
local bDirectCut, nFlag = CAM.GetDirectCut( EntId)
-- se non è tipo FLATTENING allora esco
if nFlag ~= FlagDirectCut.Flattening then return end
if bDirectCut then
EgtOutLog(' → OnCuts da taglio diretto NUOVO GESTIONE STEP')
-- tipologia di step
local _, nStepType = CAM.GetStepType( EntId)
-- se taglio a ZigZag
if nStepType == 0 then
-- determino lo spessore da lavorare
local _, Depth = CAM.GetDepth( EntId)
-- determino l'affondamento da applicare
EgtMdbSetCurrMachining( sOnSaw)
local dStep = tonumber( EgtMdbGetCurrMachiningParam( MCH_MP.STEP))
if dStep < 1 then dStep = 4.2 end
local nStep = floor( Depth / dStep) + 1
dStep = Depth / nStep
-- assegno un nuovo affondamento alla prima lavorazione
local nCountEnt = #TabOnCut
for i = 1 , nCountEnt, 1 do
EgtSetInfo( TabOnCut[i], 'Depth', dStep)
EgtSetInfo( TabOnCut[i], 'StepType', 1)
end
-- recupero l'ultima direzione di taglio
local _, LastDir = CAM.GetReturnDir( TabOnCut[nCountEnt])
-- aggiungo tutte le altre entità per gestire l'affondamento di taglio
for j = 2, nStep, 1 do
for i = #TabOnCut, #TabOnCut - nCountEnt + 1, -1 do
table.insert( TabOnCut, EgtCopyGlob( TabOnCut[i], EgtGetParent(TabOnCut[i])))
end
for i = #TabOnCut - nCountEnt + 1, #TabOnCut, 1 do
EgtSetInfo( TabOnCut[i], 'Depth', j * dStep)
EgtSetInfo( TabOnCut[i], 'StepType', 1)
if LastDir == 1 then
LastDir = 2
else
LastDir = 1
end
EgtSetInfo( TabOnCut[i], 'Dir', LastDir)
end
end
end
end
end
PreVerifyMachining( TabOnCut)
-- Ciclo sulle entità
for i = 1, #TabOnCut do
local nOnCutId = TabOnCut[i]
-- leggo la direzione di taglio
local _, RetDir = CAM.GetReturnDir( nOnCutId)
local bDepth, Depth = CAM.GetDepth( nOnCutId)
if not bDepth then Depth = dEngravingDepth end
local bWidth, Width = CAM.GetWidth( nOnCutId)
if not bWidth then Width = dEngravingWidth end
local _, EnInv = CAM.GetEnableInvert( nOnCutId)
-- **gestione incisioni inclinate**
local _, SideAng = CAM.GetSideAng( nOnCutId, 1)
local Offset = 0
local bInvert = false
--
if Width < GEO.EPS_SMALL then Width = SawTh end
local nStrict = EgtGetInfo( nOnCutId, 'Strict', 'i') or nWhiskerLen
-- verifico se entità composta quante parti lavorare
local _, nParts = EgtCurveDomain( nOnCutId)
-- eseguo uno o più tagli
if Width > SawTh - 0.3 then
local nCuts = ceil( Width / ( SawTh + 10 * GEO.EPS_SMALL))
if abs( SideAng) > GEO.EPS_ANG_SMALL then nCuts = 1 end
local dSideStep = EgtIf( nCuts <= 1, 0, ( Width - SawTh) / ( nCuts - 1))
-- EgtOutLog(" → # Cuts ← "..nCuts)
-- EgtOutLog(" → SideStep ← "..dSideStep)
for j = 1, nParts do
for k = 1, nCuts do
-- EgtOutLog(" → # current Cuts ← "..i)
-- inserimento lavorazione
local nSaw = EgtAddMachining( 'OnSaw'..tostring( nOnCutId), sOnSaw)
if nSaw then
if abs( SideAng) < GEO.EPS_ANG_SMALL then
if EnInv then
local P1 = EgtSP( nOnCutId, GDB_ID.ROOT)
local P2 = EgtEP( nOnCutId, GDB_ID.ROOT)
bInvert = CAM.GetInvertVerticalCut(P1,P2)
end
else
local nHSide = EgtGetMachiningParam( MCH_MP.HEADSIDE)
bInvert = ( SideAng < 0 and nHSide == MCH_SAW_HS.RIGHT) or ( SideAng > 0 and nHSide == MCH_SAW_HS.LEFT)
end
EgtSetMachiningGeometry( EgtIf( nParts == 1, { nOnCutId}, {{ nOnCutId, j - 1}}))
EgtSetMachiningParam( MCH_MP.DEPTH, min( Depth, dRawHeight))
if nStrict == 1 or nStrict == 3 then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
end
if nStrict == 2 or nStrict == 3 then
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
end
-- |WARNING| :
EgtSetMachiningParam( MCH_MP.OFFSL, -Width / 2 + ( k - 1) * dSideStep)
-- Verifico di essere nei tagli diretti **Ver_2.6f2**
local bDirectCut, _ = CAM.GetDirectCut( nOnCutId)
if bDirectCut then
EgtOutLog(' → OnCuts da taglio diretto')
-- tipologia di step
local _, nStepType = CAM.GetStepType( nOnCutId)
EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType)
else
EgtOutLog(' → OnCuts da taglio CAD')
end
-- inizio settattaggio parametri per **incisione inclinata**
if abs( SideAng) > GEO.EPS_ANG_SMALL then
Offset = - SawTh/2
EgtSetMachiningParam( MCH_MP.OFFSL, Offset)
EgtSetMachiningParam( MCH_MP.SIDEANGLE, SideAng)
end
if RetDir ~= 2 then
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT))
else -- solo per spianature
EgtSetMachiningParam( MCH_MP.INVERT, not bInvert)
EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.RIGHT, MCH_SAW_WS.LEFT))
EgtSetMachiningParam( MCH_MP.HEADSIDE, nOthHside)
end
-- fine settaggio
if EgtPreviewMachining() then
-- se lavorazione non applicata, provo a ridurre l'affondamento
if EgtIsMachiningEmpty() then
local dLen = EgtCurveLength( nOnCutId)
if dLen and dLen < SawDiam then
local dRedLen = dLen - 5
local dNewDepth = 0.5 * ( SawDiam - sqrt( SawDiam * SawDiam - dRedLen * dRedLen))
if dNewDepth > 1.0 then
EgtSetMachiningParam( MCH_MP.DEPTH, min( dNewDepth, dRawHeight))
EgtPreviewMachining()
end
end
end
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent( EgtGetParent( nOnCutId))
CAM.ChangePvColor( nSaw, colOnCut, colOnExt)
CAM.CopyPreviewToPiece( nSaw, nPartId)
end
else
CAM.ERR = 46
end
EgtSetOperationStatus( nSaw, false)
EgtSetInfo( nSaw, 'Lay', sLay)
else
CAM.ERR = 30
end
end
end
end
end
end
-- Funzione che applica le fresature da sopra
function CAM.ApplyOnMillings( TabOnCut, sLay)
-- Diametro della fresa
local MillDiam = CAM.GetToolDiameterFromMdb( sOnMill)
if MillDiam < GEO.EPS_SMALL then
CAM.ERR = 30
return
end
-- Ciclo sulle entità
for i = 1, #TabOnCut do
local nOnCutId = TabOnCut[i]
local bDepth, Depth = CAM.GetDepth( nOnCutId)
if not bDepth then Depth = dEngravingDepth end
if Depth > dRawHeight then Depth = dRawHeight end
local bWidth, Width = CAM.GetWidth( nOnCutId)
if not bWidth then Width = dEngravingWidth end
if Width < GEO.EPS_SMALL then Width = MillDiam end
local nStrict = EgtGetInfo( nOnCutId, 'Strict', 'i') or 3
-- eseguo uno o più tagli
if Width > MillDiam - 0.3 then
local nMills = ceil( Width / ( MillDiam + 10 * GEO.EPS_SMALL))
local dSideStep = EgtIf( nMills <= 1, 0, ( Width - MillDiam) / ( nMills - 1))
for i = 1, nMills do
-- inserimento lavorazione
local nMill = EgtAddMachining( 'OnMill'..tostring( nOnCutId), sOnMill)
if nMill then
CAM.HintDrillMillAngC()
EgtSetMachiningGeometry( { nOnCutId})
EgtSetMachiningParam( MCH_MP.DEPTH, Depth)
-- Verifico di essere nei tagli diretti **Ver_2.6f2**
local bDirectCut, _ = CAM.GetDirectCut( nOnCutId)
if bDirectCut then
EgtOutLog(' → OnMilling da taglio diretto')
-- tipologia di step
local _, nStepType = CAM.GetStepType( nOnCutId)
EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType)
-- tipo di ingresso
local sLeadInType = EgtGetMachiningParam( MCH_MP.LEADINTYPE)
EgtSetMachiningParam( MCH_MP.LEADINTYPE, sLeadInType or MCH_MILL_ST.GLIDE)
-- affondameto di step
local dStep = EgtGetMachiningParam( MCH_MP.STEP)
EgtSetMachiningParam( MCH_MP.STEP, dStep)
else
EgtOutLog(' → OnMilling da taglio CAD')
local dStep = EgtGetMachiningParam( MCH_MP.STEP)
dStep = min( dStep, Depth - 0.1)
EgtSetMachiningParam( MCH_MP.STEP, dStep)
end
EgtSetMachiningParam( MCH_MP.LIELEV, 2.0)
if nStrict == 1 or nStrict == 3 then
EgtSetMachiningParam( MCH_MP.STARTADDLEN, -MillDiam/2)
end
if nStrict == 2 or nStrict == 3 then
EgtSetMachiningParam( MCH_MP.ENDADDLEN, -MillDiam/2)
end
EgtSetMachiningParam( MCH_MP.OFFSR, -Width / 2 + ( i - 1) * dSideStep)
if EgtPreviewMachining() then
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent( EgtGetParent( nOnCutId))
CAM.ChangePvColor( nMill, colOnCut, colOnExt)
CAM.CopyPreviewToPiece( nMill, nPartId)
end
else
CAM.ERR = 46
end
EgtSetOperationStatus( nMill, false)
EgtSetInfo( nMill, 'Lay', sLay)
else
CAM.ERR = 30
end
end
end
end
end
-- Funzione che applica le fresature Filo Top **riceve direttamente il percorso utensile**
function CAM.ApplyFiloTopMillings( TabFiloTopLay)
-- Ciclo sui layer
for i = 1, #TabFiloTopLay do
local LayId = TabFiloTopLay[i]
local dDepth = EgtGetInfo( LayId, 'Depth', 'd')
-- applico la lavorazione
local nMill = EgtAddMachining( 'FiloTop'..tostring( LayId), sMill)
if nMill then
CAM.HintDrillMillAngC()
local vGeom = {}
local EntId = EgtGetFirstInGroup( LayId)
while EntId do
table.insert( vGeom, EntId)
EntId = EgtGetNext( EntId)
end
EgtSetMachiningGeometry( vGeom)
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL)
local dStep = EgtGetMachiningParam( MCH_MP.STEP)
dStep = min( dStep, dDepth - 0.1)
EgtSetMachiningParam( MCH_MP.STEP, dStep)
EgtSetMachiningParam( MCH_MP.LIELEV, 2.0)
if EgtPreviewMachining() then
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent( LayId)
CAM.ChangePvColor( nMill, colOnCut, colOnExt)
CAM.CopyPreviewToPiece( nMill, nPartId)
end
else
CAM.ERR = 46
end
EgtSetOperationStatus( nMill, false)
EgtSetInfo( nMill, 'Lay', 'InLoop')
EgtSetInfo( nMill, 'FiloTop', 1)
else
CAM.ERR = 30
end
end
end
-- Funzione che applica le Svuotature
function CAM.ApplyPocketings( TabPocketLay)
-- Ciclo sui layer
for i = 1, #TabPocketLay do
local LayId = TabPocketLay[i]
local dDepth = EgtGetInfo( LayId, 'Depth', 'd')
-- applico la lavorazione
local nPock = EgtAddMachining( 'Pocket'..tostring( LayId), sPocket)
if nPock then
CAM.HintDrillMillAngC()
local vGeom = {}
local EntId = EgtGetFirstInGroup( LayId)
while EntId do
if EgtGetType( EntId) == GDB_TY.CRV_COMPO then
table.insert( vGeom, EntId)
end
EntId = EgtGetNext( EntId)
end
EgtSetMachiningGeometry( vGeom)
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
EgtSetMachiningParam( MCH_MP.LIELEV, 2.0)
if EgtPreviewMachining() then
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent( LayId)
CAM.ChangePvColor( nPock, colOnCut, colOnExt)
CAM.CopyPreviewToPiece( nPock, nPartId)
end
else
CAM.ERR = 46
end
EgtSetOperationStatus( nPock, false)
EgtSetInfo( nPock, 'Lay', 'Pocket')
EgtSetInfo( nPock, 'Pocket', 1)
else
CAM.ERR = 30
end
end
end
-- Funzione che applica i tagli da sotto
function CAM.ApplyUnderCuts( TabDripCut, sLay)
-- Ciclo sulle entità
for i = 1, #TabDripCut do
local nDripId = TabDripCut[i]
local bDepth, dDepth = CAM.GetDepth( nDripId)
local bStrict = ( EgtGetInfo( nDripId, 'Strict') ~= nil)
local nPartId = EgtGetParent( EgtGetParent( nDripId))
-- inserimento lavorazione
local nSaw = EgtAddMachining( 'DripSaw'..tostring(nDripId), sDripSaw)
if nSaw then
EgtSetMachiningGeometry( {nDripId})
if bDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
end
if bStrict then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
end
-- calcolo il centro del pezzo
local ptPartCen = CAM.GetPartCenter( nPartId)
-- distanza della linea da lavorare dal centro
local ptSt = EgtSP( nDripId, GDB_ID.ROOT)
local vtNrm = EgtSV( nDripId, GDB_ID.ROOT)
vtNrm:rotate( Z_AX(), 90)
local dDist = abs( ( ptPartCen - ptSt) * vtNrm)
--EgtOutLog( 'DripDist=' .. EgtNumToString( dDist, 1))
-- se la distanza supera il limite e il lato mandrino è a sinistra
if dDist > dDripCutYmMaxDist and EgtGetMachiningParam( MCH_MP.HEADSIDE) == MCH_SAW_HS.LEFT then
-- inverto la direzione di lavoro (per portare il taglio a Ymax)
EgtSetMachiningParam( MCH_MP.INVERT, true)
-- conseguentemente devo invertire anche il lato di lavoro
CAM.InvertWorkside()
end
if EgtPreviewMachining() then
if not EgtIsMachiningEmpty() then
CAM.ChangePvColor( nSaw, colDripCut, colDripExt)
CAM.CopyPreviewToPiece( nSaw, nPartId)
end
else
CAM.ERR = 46
end
EgtSetOperationStatus( nSaw, false)
EgtSetInfo( nSaw, 'Lay', sLay)
else
CAM.ERR = 30
end
end
end
-- Funzione che applica le forature da sotto
function CAM.ApplyUnderDrillings( TabDripHole, sLay)
-- Ciclo sulle entità curva
for i = 1, #TabDripHole do
local nEntId = TabDripHole[i]
local bDepth, dDepth = CAM.GetDepth( nEntId)
local nPartId = EgtGetParent( EgtGetParent( nEntId))
local nDrill = EgtAddMachining( 'UnderDrill'..tostring( nEntId), sDripDrill)
if nDrill then
-- foro standard
local bSetOk = EgtSetMachiningGeometry( {nEntId})
if bSetOk then
-- calcolo il centro del pezzo
local ptPartCen = CAM.GetPartCenter( nPartId)
-- calcolo il centro del foro
local ptCen = EgtCP( nEntId, GDB_ID.ROOT)
-- porto il foro sempre a Y max
if ptCen:getY() < ptPartCen:getY() - 10 then
EgtSetMachiningParam( MCH_MP.INITANGS, "V=180")
else
EgtSetMachiningParam( MCH_MP.INITANGS, "V=0")
end
if bDepth then
EgtSetMachiningParam( MCH_MP.DEPTH, dDepth)
end
if EgtPreviewMachining() then
CAM.ChangePvColor( nDrill, colDripCut, colDripExt)
CAM.CopyPreviewToPiece( nDrill, nPartId)
else
CAM.ERR = 45
end
EgtSetOperationStatus( nDrill, false)
EgtSetInfo( nDrill, 'Lay', sLay)
else
EgtRemoveOperation( nDrill)
end
else
CAM.ERR = 30
end
end
end
-- Funzione che applica le lavorazioni
function CAM.ApplyMachinings()
-- calcolo flag fresature sugli angoli
local bCalcMoC = ( ( sMill ~= '' and bMillingOnCorners) or sDrill == '')
-- |OUTLOOP| lavorazioni esterne
if sSaw ~= '' then
CAM.ApplyCuts( TabOutCut, 'OutLoop', TabOutCrv, TabOutPartial)
elseif sSawTilted ~= '' then
local TabIndex = {}
for i = 1, #TabOutCut, 1 do
local bExists, dAng = CAM.GetSideAng( TabOutCut[i])
if not bExists then
table.insert( TabOutCrv, TabOutCut[i])
table.insert( TabIndex, i)
end
end
for i = #TabIndex, 1, -1 do
table.remove( TabOutCut, TabIndex[i])
end
CAM.ApplyCuts( TabOutCut, 'OutLoop', TabOutCrv, TabOutPartial)
else
TabOutCrv = EgtJoinTables( TabOutCut, TabOutCrv)
end
if sMill ~= '' then
local TabPart = EgtIf( bCalcMoC, TabOutPartial, {})
CAM.ApplyMillings( TabOutCrv, TabPart, 'OutLoop')
elseif sDrill ~= '' then
CAM.ApplyDrillings( TabOutCrv, 'OutLoop')
end
if sDrill ~= '' then
if not bCalcMoC then
CAM.ApplyDrillingsOnPartialCuts( TabOutPartial, 'OutLoop')
end
end
-- **APPLY WATERJETTING**
if sWaterJet ~= '' then
CAM.ApplyWaterJettings( TabOutCrv, TabOutPartial, 'OutLoop')
end
-- |INLOOP| lavorazioni interne
if sSaw ~= '' then
CAM.ApplyCuts( TabInCut, 'InLoop', TabInCrv, TabInPartial)
else
TabInCrv = EgtJoinTables( TabInCut, TabInCrv)
end
if sMill ~= '' then
local TabPart = EgtIf( bCalcMoC, TabInPartial, {})
CAM.ApplyMillings( TabInCrv, TabPart, 'InLoop')
elseif sDrill ~= '' then
CAM.ApplyDrillings( TabInCrv, 'InLoop')
end
if sDrill ~= '' then
CAM.ApplyDrillings( TabInHole, 'InLoop')
if not bCalcMoC then
CAM.ApplyDrillingsOnPartialCuts( TabInPartial, 'InLoop')
end
end
if sWaterJet ~= '' then
CAM.ApplyWaterJettings( TabInCrv, TabInPartial, 'InLoop')
end
-- |ONPATH| lavorazioni di incisione
if #TabOnCut > 0 then
-- dalla versione **2.6f2** cerco nelle info dell'entità il tipo di utensile da usare
local _, ToolInFLattening = CAM.GetFlattenigTool( TabOnCut[1])
--if bEngravingWithMill and sOnMill then
if ToolInFLattening==1 and sOnMill then
CAM.ApplyOnMillings( TabOnCut, 'OnPath')
elseif sOnSaw ~= '' then
CAM.ApplyOnCuts( TabOnCut, 'OnPath')
end
end
-- **APPLY FILOTOP**
if sMill ~= '' and #TabFiloTopLay > 0 then
CAM.ApplyFiloTopMillings( TabFiloTopLay)
end
-- lavorazioni di Svuotatura
if sPocket ~= '' and #TabPocketLay > 0 then
CAM.ApplyPocketings( TabPocketLay)
end
-- lavorazioni di taglio da sotto
if sDripSaw ~= '' and #TabDripCut > 0 then
CAM.ApplyUnderCuts( TabDripCut, 'Drip')
end
-- lavorazioni di foratura da sotto
if sDripDrill ~= '' and #TabDripHole then
CAM.ApplyUnderDrillings( TabDripHole, 'UnderDrill')
end
end
--
-- Funzione che raccoglie gli identificativi delle lavorazioni di un pezzo
function CAM.FindPartMachinings( nPartId, TabData)
-- cerco il gruppo di preview
local nPrevId = EgtGetFirstNameInGroup( nPartId, 'PV')
-- analizzo i gruppi del preview
local nId = EgtGetFirstGroupInGroup( nPrevId or GDB_ID.NULL)
while nId do
local nMchId = EgtGetInfo( nId, 'MId', 'i')
if nMchId then
local nEntId = CAM.GetEntIdFromMachining( nMchId)
table.insert( TabData, {Mch= nMchId, Part=nPartId, Ent=nEntId})
end
nId = EgtGetNextGroup( nId)
end
return TabData
end
-- Funzione che aggiorna le lavorazioni
function CAM.UpdateOperations( TabData, bPreview, bClPath)
-- Reset flag presenza tagli inclinati
EgtRemoveInfo( EgtGetCurrMachGroup(), 'SIDECUTS')
local bSideCuts = false
-- Imposto come fase corrente la prima
local nCurrPhase = 1
EgtSetCurrPhase( nCurrPhase)
-- Ciclo sulle lavorazioni da aggiornare
for i = 1, #TabData do
local nOperId = TabData[i].Mch
local nPartId = TabData[i].Part
-- verifico se cambiata la fase
local nPhase = EgtGetOperationPhase( nOperId)
if nPhase ~= nCurrPhase then
nCurrPhase = nPhase
EgtSetCurrPhase( nCurrPhase)
end
-- se disposizione
if EgtGetOperationType( nOperId) == MCH_OY.DISP then
CAM.MultiCutDispositionSettings( nOperId)
if not EgtSpecialApplyDisposition( nOperId, true) then
if EgtEmptyGroup( nOperId) then
EgtOutLog("The phase "..tostring(nCurrPhase).." is empty: see *.mlse to understand the problem!" )
end
CAM.ERR = 70
end
-- altrimenti lavorazione
else
-- imposto la lavorazione come corrente
EgtSetCurrMachining( nOperId)
-- verifico se tagli standard, da sopra o da sotto
local bCut = CAM.MachiningIsStdCut( nOperId)
local bOn = CAM.MachiningIsOnCut( nOperId)
local bDrip = CAM.MachiningIsDripCut( nOperId)
-- aggiorno anteprima se richiesto
if bPreview and nPartId then
if EgtPreviewMachining( true) then
if bOn then
CAM.ChangePvColor( nOperId, colOnCut, colOnExt)
elseif bDrip then
CAM.ChangePvColor( nOperId, colDripCut, colDripExt)
elseif bCut then
local sCurrSaw = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or '')
if sCurrSaw and EgtTdbSetCurrTool( sCurrSaw) then
CAM.ApplyPvColor( sCurrSaw, nOperId)
end
end
CAM.CopyPreviewToPiece( nOperId, nPartId)
else
CAM.ERR = 48
end
end
-- aggiorno percorso di lavoro se richiesto e lavorazione attiva
if bClPath and EgtGetOperationMode( nOperId) then
-- verifico se taglio inclinato
local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
local bSideAng = ( dSideAng and abs( dSideAng) > GEO.EPS_ANG_SMALL)
if bSideAng then bSideCuts = true end
CAM.MultiCutMachiningSettings()
-- verifico waterjet
-- setto la feed letta da operation
------------------------------------------------------------------------------
local sWjQuality = EgtGetInfo( nOperId, 'Quality')
if EgtGetOperationType( nOperId) == MCH_OY.WATERJETTING and sWjQuality then
-- determino tabella spessore-feed da utilizzare: **vThickFeed**
local vThickFeed = nil
if sMaterial and sWjQuality and dRawHeight then
vThickFeed = {}
local sWjDbPath = EgtGetCurrMachineDir() .. '\\Machinings\\WaterjetDB.data'
for i = 1, 20 do
local sLine = EgtGetStringFromIni( sMaterial, tostring( i), '', sWjDbPath)
if #sLine == 0 then break end
local vVal = EgtSplitString( sLine, ',')
local dThick = tonumber( vVal[1] or '')
local dFeed
if sWjQuality == 'Q1' then
dFeed = tonumber( vVal[2] or '')
elseif sWjQuality == 'Q2' then
dFeed = tonumber( vVal[3] or '')
elseif sWjQuality == 'Q3' then
dFeed = tonumber( vVal[4] or '')
elseif sWjQuality == 'Q4' then
dFeed = tonumber( vVal[5] or '')
elseif sWjQuality == 'Q5' then
dFeed = tonumber( vVal[6] or '')
else
dFeed = tonumber( vVal[7] or '')
end
local dFlux = tonumber( vVal[9] or '') or 250
if dThick and dFeed then
table.insert( vThickFeed, { Th=dThick, F=dFeed, Fl=dFlux})
end
end
end
-- funzione locale per tabella spessore-feed
local function GetWjSpeed( dDepth)
for i = 1, #( vThickFeed or {}) do
if dDepth < vThickFeed[i].Th + 0.1 then
if i == 1 or ( vThickFeed[i].Th - vThickFeed[i-1].Th) < 0.1 then
return vThickFeed[i].F, 0
else
local dCoeff = ( dDepth - vThickFeed[i-1].Th) / ( vThickFeed[i].Th - vThickFeed[i-1].Th)
return ( 1 - dCoeff) * vThickFeed[i-1].F + dCoeff * vThickFeed[i].F, 0
end
end
end
if #( vThickFeed or {}) > 0 then
return vThickFeed[#vThickFeed].F, vThickFeed[#vThickFeed].Th
end
end
-- funzione locale per tabella spessore-flusso sabbia
local function GetWjFlux( dDepth)
for i = 1, #( vThickFeed or {}) do
if dDepth < vThickFeed[i].Th + 0.1 then
return vThickFeed[i].Fl
end
end
if #( vThickFeed or {}) > 0 then
return vThickFeed[#vThickFeed].Fl
end
return 250
end
-- assegno valore di flusso e imposto feed da Q*
if vThickFeed then
local dDepth = dRawHeight / cos( dSideAng)
local dFlux = GetWjFlux( dDepth)
if dFlux then
EgtSetInfo( nOperId, 'Flux', dFlux)
end
local dFeed, dThRef = GetWjSpeed( dDepth)
if dFeed and dThRef then
EgtSetMachiningParam( MCH_MP.FEED, dFeed)
EgtSetMachiningParam( MCH_MP.THICKREF, dThRef)
end
end
end
------------------------------------------------------------------------------
local bMchOk = EgtApplyMachining( true)
if ( bCut or bOn) and ( not bMchOk or ( bIsMultiCut and bUse2Heads and EgtIsOperationEmpty( nOperId))) then
-- se multi cut provo con la testa 2 senza invertire
local bHead2Ok = false
if bIsMultiCut and bUse2Heads then
-- imposto utensile della seconda testa
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
EgtSetMachiningParam( MCH_MP.TOOL, sTool..'-2')
-- se taglio inclinato, inverto direzione taglio e angolo di sbandamento
if bSideAng then
CAM.InvertSideAngCut()
-- altrimenti, imposto lato testa opposto a quello standard
else
EgtSetMachiningParam( MCH_MP.HEADSIDE, nOthHside)
end
-- ricalcolo
CAM.MultiCutMachiningSettings()
bHead2Ok = EgtApplyMachining() and not EgtIsOperationEmpty( nOperId)
if not bHead2Ok then
-- ripristino per testa 1
EgtSetMachiningParam( MCH_MP.TOOL, sTool)
if bSideAng then
CAM.InvertSideAngCut()
else
EgtSetMachiningParam( MCH_MP.HEADSIDE, nStdHside)
end
end
end
-- se possibile invertire e non risolto
local nEntId = CAM.GetEntIdFromMachining( nOperId)
local _, EnInv = CAM.GetEnableInvert( nEntId)
if EnInv and not bHead2Ok and not bDrip then
if not CAM.InvertVerticalCutOnExtraStroke() then
if bIsMultiCut and bUse2Heads then
-- imposto utensile della seconda testa
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
sTool = sTool .. '-2'
EgtSetMachiningParam( MCH_MP.TOOL, sTool)
-- imposto lato testa opposto
EgtSetMachiningParam( MCH_MP.HEADSIDE, nOthHside)
-- ricalcolo
CAM.MultiCutMachiningSettings()
if not EgtApplyMachining( true) then
CAM.ERR = 54
end
else
CAM.ERR = 55
end
end
elseif not bHead2Ok then
CAM.ERR = 56
end
elseif not bMchOk then
CAM.ERR = 57
end
end
end
EgtSetOperationStatus( nOperId, false)
end
-- Aggiorno flag presenza tagli inclinati
if bSideCuts then
EgtSetInfo( EgtGetCurrMachGroup(), 'SIDECUTS', '1')
end
end
--
-- Funzione che cancella una lavorazione
function CAM.EraseMachining( nMchId, nPartId)
-- elimino eventuale preview dal pezzo
local sName = EgtGetName( nMchId)
-- cerco il gruppo di preview
local nPrevId = EgtGetFirstNameInGroup( nPartId, 'PV')
local nId = EgtGetFirstNameInGroup( nPrevId, sName)
if nId then
EgtErase( nId)
end
-- cancello la lavorazione
EgtRemoveOperation( nMchId)
end
-- Funzione che cancella le lavorazioni
function CAM.EraseAllMachinings( TabData)
-- Ciclo sulle lavorazioni da cancellare
for i = 1, #TabData do
CAM.EraseMachining( TabData[i].Mch, TabData[i].Part)
CAM.SetEnableInvert( TabData[i].Ent)
end
end
--
-- Funzione che determina se invertire un taglio verticale
function CAM.GetInvertVerticalCut(P1,P2)
local DeltaX = P2:getX() - P1:getX()
local DeltaY = P2:getY() - P1:getY()
if abs(DeltaX) > 2 * abs(DeltaY) then
if ( DeltaX > 0 and bCutLongDxSx) or ( DeltaX < 0 and not bCutLongDxSx) then
return true
else
return false
end
else
if DeltaY > 0 then
return true
else
return false
end
end
end
-- Funzione che copia il preview nel pezzo
function CAM.CopyPreviewToPiece( nSaw, nPartId)
-- verifico e se necessario creo gruppo preview nel pezzo (con livello System)
local nPrevId = EgtGetFirstNameInGroup( nPartId, 'PV')
if not nPrevId then
nPrevId = EgtGroup( nPartId)
EgtSetName( nPrevId, 'PV')
end
if not nPrevId then
return false
end
EgtSetLevel( nPrevId, GDB_LV.SYSTEM)
-- se esiste sottogruppo con nome della lavorazione, lo svuoto
local nDestId = EgtGetFirstNameInGroup( nPrevId, EgtGetName( nSaw))
if nDestId then
EgtEmptyGroup( nDestId)
-- altrimenti lo creo
else
nDestId = EgtGroup( nPrevId)
EgtSetName( nDestId, EgtGetName(nSaw))
end
-- assegno Info con Id della lavorazione
EgtSetInfo( nDestId, 'MId', nSaw)
-- sposto tutti gli oggetti preview dalla lavorazione al pezzo
local nSouId = EgtGetFirstNameInGroup( nSaw, 'PV')
local nId = EgtGetFirstInGroup( nSouId)
while nId do
EgtRelocateGlob( nId, nDestId)
local nEntId = EgtGetFirstInGroup( nId)
while nEntId do
if EgtGetType( nEntId) == GDB_TY.SRF_FRGN and not AreSameVectorApprox( EgtSurfFrNormVersor( nEntId, GDB_ID.ROOT), Z_AX()) then
local frScale = Frame3d( EgtCP( nEntId, GDB_ID.ROOT))
EgtScale( nEntId, frScale, 1, 1, 0, GDB_RT.GLOB)
end
nEntId = EgtGetNext( nEntId)
end
nId = EgtGetFirstInGroup( nSouId)
end
-- assegno Info con Id del preview
EgtSetInfo( nSouId, 'PvId', nDestId)
return true
end
-- Funzione che cancella la preview (ovunque sia)
function CAM.ErasePreview( nMachId)
-- gruppo preview nella lavorazione
local nPvId = EgtGetFirstNameInGroup( nMachId, "PV")
if not nPvId then return end
-- eventuale reindirizzamento
local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i')
if nPv2Id then
EgtRemoveInfo( nPvId, 'PvId')
nPvId = nPv2Id
end
-- cancello
EgtErase( nPvId)
end
-- Funzione che recupera il colore da sCurrTool e lo applica alla lavorazione nSaw
function CAM.ApplyPvColor( sCurrTool, nSaw)
if not bGetColorPv then return end
local sColor = EgtTdbGetCurrToolValInNotes( MCH_TP.SYSNOTES, "COLOR", 's')
local tbRGB = EgtSplitString( sColor)
if tbRGB then
CAM.ChangePvColor( nSaw, Color3d( tonumber(tbRGB[1]), tonumber(tbRGB[2]), tonumber(tbRGB[3])))
else
EgtOutLog( '-- WARNING: in tool '..sCurrTool..' color does not exist or is not valid!')
end
end
-- Funzione che cambia colore al preview ancora nella lavorazione
function CAM.ChangePvColor( nSaw, colCut, colExt)
local nPvId = EgtGetFirstNameInGroup( nSaw, 'PV')
-- local nPvGrpId = EgtGetFirstGroupInGroup( nPvId)
local nPvGrpId = EgtGetInfo( nPvId, "PvId", 'i')
while nPvGrpId do
--local nCutId = EgtGetFirstNameInGroup( nPvGrpId, 'CUT')
local nCutId = EgtGetFirstNameInGroup( EgtGetFirstInGroup(nPvGrpId), 'CUT')
if colCut then
while nCutId do
EgtSetColor( nCutId, colCut)
nCutId = EgtGetNextName( nCutId, 'CUT')
end
nCutId = EgtGetFirstNameInGroup( EgtGetFirstInGroup(nPvGrpId), 'DCUT')
while nCutId do
EgtSetColor( nCutId, colCut)
nCutId = EgtGetNextName( nCutId, 'DCUT')
end
end
if colExt then
EgtSetColor( EgtGetFirstNameInGroup( nPvGrpId, 'PRC') or GDB_ID.NULL, colExt)
EgtSetColor( EgtGetFirstNameInGroup( nPvGrpId, 'POC') or GDB_ID.NULL, colExt)
end
nPvGrpId = EgtGetNextGroup( nPvGrpId)
end
end
-- Funzione che restituisce identificativo entità in lavorazione
function CAM.GetEntIdFromMachining(nOperId)
if not EgtSetCurrMachining( nOperId) then
return GDB_ID.NULL
end
return CAM.GetEntIdFromCurrMachining()
end
-- Funzione che restituisce entità in lavorazione corrente
function CAM.GetEntIdFromCurrMachining()
local Geo = EgtGetMachiningGeometry()
if not Geo then return GDB_ID.NULL end
if type( Geo) == 'table' and
type( Geo[1]) == 'table' and type( Geo[1][1]) == 'number' and
type( Geo[#Geo]) == 'table' and type( Geo[#Geo][1]) == 'number' then
return Geo[1][1], Geo[#Geo][1]
else
return GDB_ID.NULL
end
end
-- Funzione che calcola il centro del pezzo
function CAM.GetPartCenter( nPartId)
local RegGrpId = EgtGetFirstNameInGroup( nPartId, 'Region')
local RegId = EgtGetFirstInGroup( RegGrpId)
while RegId do
if EgtGetType( RegId) == GDB_TY.SRF_FRGN then break end
RegId = EgtGetNext( RegId)
end
local ptCen = EgtGP( RegId or GDB_ID.NULL, GDB_ID.ROOT)
return ptCen
end
-- Funzione che determina se la lavorazione è un taglio di lama di contorno
function CAM.MachiningIsStdCut( nOperId)
return EgtGetOperationType( nOperId) == MCH_OY.SAWING and
( EgtGetInfo( nOperId, 'Lay') == 'OutLoop' or EgtGetInfo( nOperId, 'Lay') == 'InLoop')
end
-- Funzione che determina se la lavorazione è un taglio di lama da sopra
function CAM.MachiningIsOnCut( nOperId)
return EgtGetOperationType( nOperId) == MCH_OY.SAWING and EgtGetInfo( nOperId, 'Lay') == 'OnPath'
end
-- Funzione che determina se la lavorazione è un taglio di lama da sotto
function CAM.MachiningIsDripCut( nOperId)
return EgtGetOperationType( nOperId) == MCH_OY.SAWING and EgtGetInfo( nOperId, 'Lay') == 'Drip'
end
-- Funzione che determina se la lavorazione è una foratura da sotto
function CAM.MachiningIsUnderDrilling( nOperId)
return EgtGetOperationType( nOperId) == MCH_OY.DRILLING and EgtGetInfo( nOperId, 'Lay') == 'UnderDrill'
end
-- Funzione per la lettura dell'angolo di fianco
function CAM.GetSideAng( nEntId, nInd)
local dSideAng = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'SideAng', 'SideAng2'), 'd')
if dSideAng then
return true, dSideAng
else
return false, 0
end
end
-- Funzione per la lettura dell'angolo di fianco con verifica non sia nullo
function CAM.GetSideAngNotNull( nEntId, nInd)
local bFound, dSideAng = CAM.GetSideAng( nEntId, nInd)
return ( bFound and abs( dSideAng) > GEO.EPS_ANG_SMALL), dSideAng
end
-- Funzione per la lettura dell'offset
function CAM.GetOffset( nEntId, nInd)
local dOffset = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'Offset', 'Offset2'), 'd')
if dOffset then
return true, dOffset
else
return false, 0
end
end
-- Funzione per la lettura dell'affondamento
function CAM.GetDepth( nEntId, nInd)
local dDepth = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'Depth', 'Depth2'), 'd')
if dDepth then
return true, dDepth
else
return false, 0
end
end
-- Funzione per la lettura del tallone
function CAM.GetHeel( nEntId)
local dHeel = EgtGetInfo( nEntId, 'Heel', 'd')
if dHeel then
return true, dHeel
else
return false, 0
end
end
-- Funzione per la lettura del tallone con verifica non sia nullo
function CAM.GetHeelNotNull( nEntId, nInd)
local bFound, dHeel = CAM.GetHeel( nEntId, nInd)
return ( bFound and abs( dHeel) > GEO.EPS_SMALL), dHeel
end
-- Funzione per la lettura della larghezza dell'incisione
function CAM.GetWidth( nEntId)
local dWidth = EgtGetInfo( nEntId, 'Width', 'd')
if dWidth then
return true, dWidth
else
return false, 0
end
end
-- Funzione per la lettura del tipo di taglio (Diretto oppure CAD)
function CAM.GetDirectCut( nEntId)
local nDirectCut = EgtGetInfo( nEntId, 'DirectCut', 'i')
if nDirectCut then
return true, nDirectCut
else
return false, 0
end
end
function CAM.GetStepType( nEntId)
local nStepType = EgtGetInfo( nEntId, 'StepType', 'i')
if nStepType then
return true, nStepType
else
return false, MCH_MILL_ST.SPIRAL
end
end
function CAM.GetFlattenigTool( nEntId)
local sTool = EgtGetInfo( nEntId, 'EngravingWithMill')
-- sTool=1 -> Mill, sTool=0 -> Saw
if sTool then
return true, tonumber( sTool) or EgtIf( bEngravingWithMill, 1, 0)
else
return false, EgtIf( bEngravingWithMill, 1, 0)
end
end
-- Funzione per lettura abilitazione possibilità di inversione su tagli verticali
function CAM.GetEnableInvert( nEntId)
local nEnInv = EgtGetInfo( nEntId, 'EnInv', 'i')
if nEnInv then
return true, ( nEnInv == 1)
else
return false, true
end
end
-- Funzione per abilitare possibilità di inversione su tagli verticali (default)
function CAM.SetEnableInvert( nEntId)
EgtRemoveInfo( nEntId, 'EnInv')
end
-- Funzione per lettura se lato concatenato in lavorazione waterjet (1=true, 0=false, nil=true)
function CAM.GetJoinEntity( nEntId)
local nJoinEntity = EgtGetInfo( nEntId, 'JoinEntity', 'i')
if nJoinEntity then
return ( nJoinEntity ~= 0), nJoinEntity or 1
else
return true, 1
end
end
-- Funzione per lettura angolo in piano XY con entità precedente
function CAM.GetPrevAngle( nEntId)
local dPreAng = EgtGetInfo( nEntId, 'PrevAng', 'd')
if dPreAng then
return true, dPreAng
else
return false, 0
end
end
-- Funzione per lettura angolo in piano XY con entità successiva
function CAM.GetNextAngle( nEntId)
local dNextAng = EgtGetInfo( nEntId, 'NextAng', 'd')
if dNextAng then
return true, dNextAng
else
return false, 0
end
end
-- Funzione per lettura distanza libera all'inizio
function CAM.GetStartFreeLength( nEntId)
local dSFL = EgtGetInfo( nEntId, 'SFL', 'd')
if dSFL then
return true, dSFL
else
return false, 10000
end
end
-- Funzione per lettura distanza libera alla fine
function CAM.GetEndFreeLength( nEntId)
local dEFL = EgtGetInfo( nEntId, 'EFL', 'd')
if dEFL then
return true, dEFL
else
return false, 10000
end
end
-- Funzione per lettura allungamento baffo all'inizio
function CAM.GetStartWhiskersExtend( nEntId)
local dSWE = EgtGetInfo( nEntId, 'SWE', 'd')
if dSWE then
return true, dSWE
else
return false, 0
end
end
-- Funzione per lettura allungamento baffo alla fine
function CAM.GetEndWhiskersExtend( nEntId)
local dEWE = EgtGetInfo( nEntId, 'EWE', 'd')
if dEWE then
return true, dEWE
else
return false, 0
end
end
-- Funzione per la lettura direzione di ritorno
function CAM.GetReturnDir( nEntId)
local nDir = EgtGetInfo( nEntId, 'Dir', 'i')
if nDir then
return true, nDir
else
return false, 1
end
end
-- Funzione per recuperare spessore lama da nome lavorazione in DB
function CAM.GetSawThicknessFromMdb( sMchName)
if not EgtMdbSetCurrMachining( sMchName) then return 0 end
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if not EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then return 0 end
return EgtTdbGetCurrToolParam( MCH_TP.THICK) or 0
end
-- Funzione per recuperare diametro utensile da nome lavorazione in DB
function CAM.GetToolDiameterFromMdb( sMchName)
if not EgtMdbSetCurrMachining( sMchName) then return 0 end
local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID)
if not EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then return 0 end
return EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0
end
-- Funzione per recuperare spessore lama
function CAM.GetSawThickness( nOperId)
if nOperId then EgtSetCurrMachining( nOperId) end
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
if not EgtTdbSetCurrTool( sTool or '') then return 0 end
return EgtTdbGetCurrToolParam( MCH_TP.THICK) or 0
end
-- Funzione per recuperare lunghezza lama
function CAM.GetSawLength( nOperId)
if nOperId then EgtSetCurrMachining( nOperId) end
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
if not EgtTdbSetCurrTool( sTool or '') then return 0 end
return EgtTdbGetCurrToolParam( MCH_TP.LEN) or 0
end
-- Funzione per recuperare diametro utensile
function CAM.GetToolDiameter( nOperId)
if nOperId then EgtSetCurrMachining( nOperId) end
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
if not EgtTdbSetCurrTool( sTool or '') then return 0 end
return EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0
end
-- Funzione per recuperare DeltaT
function CAM.GetDeltaT( nOperId)
local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV')
local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i')
if nPv2Id then nPvId = nPv2Id end
if nPvId then
local nGrpId = EgtGetFirstGroupInGroup( nPvId)
if nGrpId then
return EgtGetInfo( nGrpId, 'DT', 'd') or 0
end
end
return 0
end
-- Funzione per recuperare DeltaTI (ritorna nil se non trovato)
function CAM.GetDeltaTI( nOperId)
local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV')
local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i')
if nPv2Id then nPvId = nPv2Id end
if nPvId then
local nGrpId = EgtGetFirstGroupInGroup( nPvId)
if nGrpId then
return EgtGetInfo( nGrpId, 'DTI', 'd')
end
end
end
-- Funzione per recuperare ExtraCut
function CAM.GetExtraCut( nOperId)
local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV')
local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i')
if nPv2Id then nPvId = nPv2Id end
if nPvId then
local nGrpId = EgtGetFirstGroupInGroup( nPvId)
if nGrpId then
return EgtGetInfo( nGrpId, 'EC', 'd') or 0
end
end
return 0
end
-- Funzione per recuperare RawBottomHeight
function CAM.GetRawBottomHeight( nOperId)
local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV')
local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i')
if nPv2Id then nPvId = nPv2Id end
if nPvId then
local nGrpId = EgtGetFirstGroupInGroup( nPvId)
if nGrpId then
return EgtGetInfo( nGrpId, 'RBH', 'd') or 0
end
end
return 0
end
-- Funzione per salvare tipo attacco originale
function CAM.SaveOriLeadIn( nOperId, nLeadIn)
if not EgtExistsInfo( nOperId, 'OriLI') then
EgtSetInfo( nOperId, 'OriLI', nLeadIn)
end
end
-- Funzione per salvare tipo uscita originale
function CAM.SaveOriLeadOut( nOperId, nLeadOut)
if not EgtExistsInfo( nOperId, 'OriLO') then
EgtSetInfo( nOperId, 'OriLO', nLeadOut)
end
end
-- Funzione per recuperare tipo attacco originale
function CAM.GetOriLeadIn( nOperId)
local nOriLeadIn = EgtGetInfo( nOperId, 'OriLI', 'i')
if nOriLeadIn then
return true, nOriLeadIn
else
return false, MCH_SAW_LI.CENT
end
end
-- Funzione per recuperare tipo uscita originale
function CAM.GetOriLeadOut( nOperId)
local nOriLeadOut = EgtGetInfo( nOperId, 'OriLO', 'i')
if nOriLeadOut then
return true, nOriLeadOut
else
return false, MCH_SAW_LO.CENT
end
end
-- Funzione per disattivare una lavorazione e toglierla dalle tabelle
function CAM.DeactivateMachining( TabSort, j)
EgtSetOperationMode( TabSort[j].Mch, false)
EgtRemoveInfo( TabSort[j].Mch, 'UserOff')
table.remove( TabSort, j)
end
-- Funzione per impostare lunghezze aggiuntive per baffi
function CAM.SetWhiskExtends( dSWE, dEWE)
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) or ''
if abs( dSWE) > GEO.EPS_SMALL then
sNotes = EgtAdjustNotes( sNotes, 'SWE', EgtNumToString( dSWE, 3))
else
sNotes = EgtAdjustNotes( sNotes, 'SWE', nil)
end
if abs( dEWE) > GEO.EPS_SMALL then
sNotes = EgtAdjustNotes( sNotes, 'EWE', EgtNumToString( dEWE, 3))
else
sNotes = EgtAdjustNotes( sNotes, 'EWE', nil)
end
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
end
-- Funzione per scambiare gli allungamenti dei baffi dei tagli
function CAM.SwapWhiskExtends()
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
if not sNotes then return end
sNotes = string.gsub( sNotes, 'SWE=', 'FWE=')
sNotes = string.gsub( sNotes, 'EWE=', 'SWE=')
sNotes = string.gsub( sNotes, 'FWE=', 'EWE=')
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
end
-- Funzione che restituisce gli allungamenti dei baffi dei tagli
function CAM.GetWhiskExtends()
local dSWE, dEWE = 0, 0
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
if not sNotes then return dSWE, dEWE end
local vItem = EgtSplitString( sNotes, ';') or {}
for i = 1, #vItem do
local sItem = EgtTrim( vItem[i])
if sItem and #sItem > 0 then
if sItem:find( 'SWE=', 1, true) then
dSWE = tonumber( sItem:sub( 5))
elseif sItem:find( 'EWE=', 1, true) then
dEWE = tonumber( sItem:sub( 5))
end
end
end
return dSWE, dEWE
end
-- Funzione per invertire il lato di lavoro della lavorazione corrente
function CAM.InvertWorkside()
local nWorkside = EgtGetMachiningParam( MCH_MP.WORKSIDE)
if nWorkside == MCH_SAW_WS.LEFT then
nWorkside = MCH_SAW_WS.RIGHT
elseif nWorkside == MCH_SAW_WS.RIGHT then
nWorkside = MCH_SAW_WS.LEFT
end
EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkside)
end
-- Funzione per invertire il lato mandrino della lavorazione corrente
function CAM.InvertHeadside()
local nHeadside = EgtGetMachiningParam( MCH_MP.HEADSIDE)
if nHeadside == MCH_SAW_HS.RIGHT then
nHeadside = MCH_SAW_HS.LEFT
else
nHeadside = MCH_SAW_HS.RIGHT
end
EgtSetMachiningParam( MCH_MP.HEADSIDE, nHeadside)
end
-- Funzione per invertire tagli di lama verticali in caso di fuori corsa
function CAM.InvertVerticalCutOnExtraStroke()
-- se non è taglio di lama, esco subito
if EgtGetMachiningParam( MCH_MP.TYPE) ~= MCH_MY.SAWING then
return false
end
-- se angolo di fianco non nullo, esco subito
local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
if abs(dSideAng) > GEO.EPS_ANG_SMALL then
return false
end
-- inverto direzione per cercare di evitare eventuale extracorsa
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
bInvert = (not bInvert)
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
-- conseguentemente devo invertire anche il lato di lavoro
CAM.InvertWorkside()
-- devo scambiare tra loro i parametri di attacco e uscita
CAM.SwapCutLeadInOut()
-- e anche gli allungamenti iniziale e finale
CAM.SwapCutAllStartEnd()
-- e anche gli allungamenti dei baffi
CAM.SwapWhiskExtends()
-- ricalcolo
CAM.MultiCutMachiningSettings()
if EgtApplyMachining() then
return true
end
return false
end
-- Funzione per invertire tagli di lama con angolo di fianco
function CAM.InvertSideAngCut()
-- se non è taglio di lama, esco subito
if EgtGetMachiningParam( MCH_MP.TYPE) ~= MCH_MY.SAWING then
return false
end
-- se angolo di fianco nullo, esco subito
local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
if abs( dSideAng) < GEO.EPS_ANG_SMALL then
return false
end
-- inverto direzione
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
bInvert = ( not bInvert)
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
-- conseguentemente devo invertire anche il lato di lavoro
CAM.InvertWorkside()
-- e il lato mandrino
local nHeadside = EgtGetMachiningParam( MCH_MP.HEADSIDE)
if nHeadside == MCH_SAW_HS.RIGHT then
nHeadside = MCH_SAW_HS.LEFT
else
nHeadside = MCH_SAW_HS.RIGHT
end
EgtSetMachiningParam( MCH_MP.HEADSIDE, nHeadside)
-- devo scambiare tra loro i parametri di attacco e uscita
CAM.SwapCutLeadInOut()
-- e anche gli allungamenti iniziale e finale
CAM.SwapCutAllStartEnd()
-- ricalcolo
CAM.MultiCutMachiningSettings()
return EgtApplyMachining()
end
-- Funzione per scambiare i parametri di ingresso e uscita dei tagli di lama
function CAM.SwapCutLeadInOut()
local LeadIn = EgtGetMachiningParam( MCH_MP.LEADINTYPE)
local LeadOut = EgtGetMachiningParam( MCH_MP.LEADOUTTYPE)
local NewLeadOut = MCH_SAW_LO.STRICT
if LeadIn == MCH_SAW_LI.CENT then
NewLeadOut = MCH_SAW_LO.CENT
elseif LeadIn == MCH_SAW_LI.OUT then
NewLeadOut = MCH_SAW_LO.OUT
elseif LeadIn == MCH_SAW_LI.EXT_CENT then
NewLeadOut = MCH_SAW_LO.EXT_CENT
elseif LeadIn == MCH_SAW_LI.EXT_OUT then
NewLeadOut = MCH_SAW_LO.EXT_OUT
end
local NewLeadIn = MCH_SAW_LI.STRICT
if LeadOut == MCH_SAW_LO.CENT then
NewLeadIn = MCH_SAW_LI.CENT
elseif LeadOut == MCH_SAW_LO.OUT then
NewLeadIn = MCH_SAW_LI.OUT
elseif LeadOut == MCH_SAW_LO.EXT_CENT then
NewLeadIn = MCH_SAW_LI.EXT_CENT
elseif LeadOut == MCH_SAW_LO.EXT_OUT then
NewLeadIn = MCH_SAW_LI.EXT_OUT
end
EgtSetMachiningParam( MCH_MP.LEADINTYPE, NewLeadIn)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, NewLeadOut)
end
-- Funzione per scambiare gli allungamenti iniziale e finale dei tagli di lama
function CAM.SwapCutAllStartEnd()
local AllStart = EgtGetMachiningParam( MCH_MP.STARTADDLEN)
local AllEnd = EgtGetMachiningParam( MCH_MP.ENDADDLEN)
AllStart, AllEnd = AllEnd, AllStart
EgtSetMachiningParam( MCH_MP.STARTADDLEN, AllStart)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, AllEnd)
end
--
function CAM.HintDrillMillAngC()
-- se richiesto bloccaggio standard
if nDrillMillC90 < 2 then
if not ( bIsMultiCut and bIsTableRot) then
EgtSetMachiningParam( MCH_MP.INITANGS, 'C=' .. EgtNumToString( nDrillMillC90 * 90, 0))
else
EgtSetMachiningParam( MCH_MP.INITANGS, 'C=90,'..CAM.MultiCutTableRotAxisToken()..'-90')
end
-- se richiesto bloccaggio differenziato su seconda tavola
elseif nDrillMillC90 == 2 then
-- verifico se è attiva la seconda tavola
local bIs2ndTable = ( EgtGetTableName() == '2ndTab')
if bIs2ndTable then
EgtSetMachiningParam( MCH_MP.INITANGS, 'C=-90')
else
if not ( bIsMultiCut and bIsTableRot) then
EgtSetMachiningParam( MCH_MP.INITANGS, 'C=90')
else
EgtSetMachiningParam( MCH_MP.INITANGS, 'C=90,'..CAM.MultiCutTableRotAxisToken()..'-90')
end
end
end
end
--
function CAM.HintWaterJetAngC( dSideAng, bOutLoop, nEntId)
local bSymmetricC = ( EgtGetAxisMin( 'C') < -180 and EgtGetAxisMax( 'C') > 180)
local dHomeC = EgtGetAxisHomePos( 'C')
local dMyWjStartC = ( dWjStartC or dHomeC)
if abs( dSideAng) < 0.1 then
dMyWjStartC = dHomeC
end
-- posizione di inizio
local sInitPos = EgtIf( dMyWjStartC > 0, 'START=XM', EgtIf( bSymmetricC, 'START=XP', 'START=YP'))
if abs( dSideAng) < 0.1 then
local ptStart = EgtGetInfo( EgtGetParent( nEntId or GDB_ID.NULL) or GDB_ID.NULL, 'Start', 'p')
if ptStart then
sInitPos = 'START='..tostring( ptStart)
end
end
EgtSetMachiningParam( MCH_MP.USERNOTES, sInitPos)
-- angoli di inizio
local sInitAngs = 'C=' .. EgtNumToString( dMyWjStartC) .. EgtIf( dSideAng > 0, ',A=-60', ',A=60')
if bOutLoop then
sInitAngs = 'C=' .. EgtNumToString( dMyWjStartC) .. EgtIf( dSideAng > 0, ',A=60', ',A=-60')
end
EgtSetMachiningParam( MCH_MP.INITANGS, sInitAngs)
end
-- Funzioni per MultiCut
function CAM.MultiCutTableRotAxisToken()
local sTokAx = EgtGetAxisToken( 'A') or 'W'
if not EgtEndsWith( sTokAx, '=') then sTokAx = sTokAx .. '=' end
return sTokAx
end
--
function CAM.MultiCutDispositionSettings( nOperId)
if bIsMultiCut and bIsTableRot then
-- imposto rotazione bloccata asse tavola nella disposizione (va usato nome asse)
-- prima si imponeva AxisBlock, ora sempre 0
EgtSetInfo( nOperId, 'BlAx', 'A=0')
end
end
--
function CAM.MultiCutMachiningSettings()
if bIsMultiCut and bIsTableRot then
-- se taglio di lama
if EgtGetMachiningParam( MCH_MP.TYPE) == MCH_MY.SAWING then
-- verifico se taglio lungo X o Y oppure generico
local nEntId = CAM.GetEntIdFromCurrMachining()
local vtDir = EgtSV( nEntId, GDB_ID.ROOT)
if abs( vtDir:getX()) > abs( vtDir:getY()) then
AxisBlock = dAngRotMultiCut + dOffsAxisBlock
else
AxisBlock = 0 + dOffsAxisBlock
end
-- altre lavorazioni
else
AxisBlock = dAngRotMultiCut + dOffsAxisBlock
end
-- se angolo fissato per test
if dSetTab then AxisBlock = dSetTab end
-- imposto rotazione bloccata asse tavola nella lavorazione
EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, CAM.MultiCutTableRotAxisToken()..AxisBlock)
end
end
--
function CAM.MultiCutRemovePairCuts( TabData)
-- Cancello accoppiamenti e riattivo lavorazioni sostituite da accoppiamento
for i = 1, #TabData do
-- se lavorazione
if EgtGetOperationType(TabData[i].Mch) ~= MCH_OY.DISP then
-- se lavorazione con accoppiamento
if EgtGetInfo( TabData[i].Mch, 'Dup') then
EgtRemoveInfo( TabData[i].Mch, 'Dup')
-- non rimuovo gli allungamenti dei duplicati perchè già modificate le lavorazioni
local dHOffsX = EgtGetInfo( TabData[i].Mch, 'HOffsX', 'd')
if dHOffsX then
EgtSetCurrMachining( TabData[i].Mch)
local dStartAddLen = EgtGetMachiningParam( MCH_MP.STARTADDLEN)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen - dHOffsX)
EgtApplyMachining()
EgtRemoveInfo( TabData[i].Mch, 'HOffsX')
end
-- se lavorazione disabilitata per accoppiamento
elseif EgtGetInfo( TabData[i].Mch, 'Dupled') then
-- la riattivo
EgtSetOperationMode( TabData[i].Mch, true)
EgtRemoveInfo( TabData[i].Mch, 'Dupled')
end
end
end
end
--
function CAM.MultiCutMakePairCuts()
local MIN_POSX = tonumber( EgtGetStringFromIni( 'Table', 'DouMinX', '', sMachIni)) or 850
local MAX_POSX = tonumber( EgtGetStringFromIni( 'Table', 'DouMaxX', '', sMachIni)) or 2950
local DIFF_Y = tonumber( EgtGetStringFromIni( 'Table', 'DiffY', '', sMachIni)) or nil
local HEAD_OFFS_X = tonumber( EgtGetStringFromIni( 'Table', 'HeadOffsX', '', sMachIni)) or 1070
local MIN_DOUXNR = tonumber( EgtGetStringFromIni( 'Table', 'DouXnrMinX', '', sMachIni)) or 1190
local MAX_DOUXNR = tonumber( EgtGetStringFromIni( 'Table', 'DouXnrMaxX', '', sMachIni)) or 3945
local MAX_DIFF = 20
local vtX = X_AX() ; vtX:rotate( Z_AX(), - dOffsAxisBlock)
local vtY = Y_AX() ; vtY:rotate( Z_AX(), - dOffsAxisBlock)
-- Funzioni locali
local function UpdateTabDup( bOnXm, bOnXp, bOnYm, bOnYp, bIsVert, dMinDist, TabDup)
-- indice inizio cicli
local nStart = EgtIf( bIsVert, 1, 2)
-- calcolo massima distanza da taglio accoppiabile
for k = nStart, #TabDup do
local TabDupK = TabDup[k]
if bOnXm or bOnXp then
TabDupK[3] = max( abs( TabDupK[2] - TabDup[1][2]), abs( TabDupK[2] - TabDup[#TabDup][2]))
else
if TabDupK[2] < MIN_POSX then
if TabDup[#TabDup][2] > MIN_POSX then
TabDupK[3] = abs( TabDupK[2] - TabDup[#TabDup][2])
else
TabDupK[3] = 0
end
elseif TabDupK[2] > MAX_POSX then
if TabDup[1][2] < MAX_POSX then
TabDupK[3] = abs( TabDupK[2] - TabDup[1][2])
else
TabDupK[3] = 0
end
else
TabDupK[3] = max( abs( TabDupK[2] - TabDup[1][2]), abs( TabDupK[2] - TabDup[#TabDup][2]))
end
end
end
-- minime distanze per tagli in X e in Y
local dMinDistX = EgtIf( bIsTableRot, dMinDist, DIFF_Y)
local dMinDistY = dMinDist
-- elimino i tagli non accoppiabili
local k = nStart
while k <= #TabDup do
if ( abs( TabDup[k][4]) == 1 and TabDup[k][3] < dMinDistX) or
( abs( TabDup[k][4]) == 2 and TabDup[k][3] < dMinDistY) then
table.remove( TabDup, k)
else
k = k + 1
end
end
end
--
local function PrintTabDup( sTitle, bOnXm, bOnXp, bOnYm, bOnYp, TabDup)
-- stampo la tavola
local sTabDup = ''
for k = 1, #TabDup do
sTabDup = sTabDup ..'('..EgtNumToString( TabDup[k][1],0)..','..EgtNumToString( TabDup[k][2],3)..
','..EgtNumToString( TabDup[k][3],3)..','..EgtNumToString( TabDup[k][4],0)..')'
end
local sDir = '??'
if bOnXm then
sDir = 'Xm'
elseif bOnXp then
sDir = 'Xp'
elseif bOnYm then
sDir = 'Ym'
elseif bOnYp then
sDir = 'Yp'
end
if #sTabDup == 0 then
EgtOutLog( sTitle .. sDir .. " Table: empty")
else
EgtOutLog( sTitle .. sDir .. " Table:"..sTabDup)
end
end
--
local function GetExtraStart( nOperId)
local nPathClId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nOperId, 'CL'), 'P1_0')
if nPathClId then
return EgtGetInfo( nPathClId, 'DLIEXT', 'd') or 0
end
end
--
local function GetExtraEnd( nOperId)
local nPathClId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nOperId, 'CL'), 'P1_0')
if nPathClId then
return EgtGetInfo( nPathClId, 'DLOEXT', 'd') or 0
end
end
--
local function GetEnds( nOperId)
local ptStart, ptEnd
local dMaxDist = -1
local nPathClId = EgtGetFirstNameInGroup( EgtGetFirstNameInGroup( nOperId, 'CL'), 'P1_0')
local nEntId = EgtGetFirstInGroup( nPathClId)
while nEntId do
if EgtGetType( nEntId) == GDB_TY.CRV_LINE then
if not ptStart then
ptStart = EgtSP( nEntId, GDB_ID.ROOT)
ptStart[3] = 0
end
local ptE = EgtEP( nEntId, GDB_ID.ROOT)
ptE[3] = 0
local dDist = dist( ptStart, ptE)
if dDist > dMaxDist then
dMaxDist = dDist
ptEnd = ptE
end
end
nEntId = EgtGetNext( nEntId)
end
return ptStart, ptEnd
end
--
-- Ciclo sulle fasi
for nPhase = 1, EgtGetPhaseCount() do
--EgtOutLog( 'Phase='..tostring( nPhase))
-- rendo corrente la fase
EgtSetCurrPhase( nPhase)
-- tabella dei dati raccolti
local TabData = {}
-- recupero le lavorazioni attive di taglio rettilineo della fase con i loro dati geometrici
local nOperId = EgtGetPhaseDisposition( nPhase)
while nOperId do
-- Se non appartiene alla fase corrente, esco
if EgtGetOperationPhase( nOperId) ~= nPhase then
break
-- Altrimenti se è taglio con lama (sempre su 1 sola entità)
elseif EgtGetOperationType( nOperId) == MCH_OY.SAWING then
EgtSetCurrMachining( nOperId)
-- recupero utensile, per determinare se fatto con testa 1 o 2
local sTool = EgtGetMachiningParam( MCH_MP.TOOL)
local nHead = EgtIf( sTool:sub(-2,-1) ~= "-2", 1, 2)
-- recupero angolo di fianco
local dAngSide = EgtGetMachiningParam( MCH_MP.SIDEANGLE) or 0
-- recupero affondamento
local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR) or ''
-- recupero lato della testa
local nHSide = EgtGetMachiningParam( MCH_MP.HEADSIDE)
-- recupero nome del layer della geometria di origine
local sLay = EgtGetInfo( nOperId, 'Lay') or 'OutLoop'
-- recupero estremi del percorso di taglio (sempre un solo percorso per lavorazione)
local ptStart, ptEnd = GetEnds( nOperId)
-- se estremi ok
if ptStart and ptEnd then
-- calcolo la direzione
ptStart[3] = 0
ptEnd[3] = 0
local vtDir = ptEnd - ptStart
vtDir:normalize()
-- calcolo se interessante
local nDir = 0
if AreSameVectorApprox( vtDir, vtX) then
nDir = 1
elseif AreSameVectorApprox( vtDir, -vtX) then
nDir = -1
elseif AreSameVectorApprox( vtDir, vtY) then
nDir = 2
elseif AreSameVectorApprox( vtDir, -vtY) then
nDir = -2
end
-- inserisco in tabella
local Data = {Id=nOperId, Start=ptStart, End=ptEnd, Dir=vtDir, Nir= nDir, AngSide=dAngSide, Depth=sDepth, HS=nHSide, HN=nHead, Lay=sLay}
table.insert( TabData, Data)
end
end
-- Passo alla successiva operazione attiva
nOperId = EgtGetNextActiveOperation( nOperId)
end
-- stampa di debug dei dati della tabella
--for i = 1, #TabData do
-- EgtOutLog( 'Mach=' .. tostring( TabData[i].Id) .. ' Start=' .. tostring( TabData[i].Start) .. ' End=' .. tostring( TabData[i].End) ..
-- ' Dir=' .. tostring( TabData[i].Dir) .. ' Nir=' .. tostring( TabData[i].Nir) .. ' AS=' .. tostring( TabData[i].AngSide) ..
-- ' Depth=' .. TabData[i].Depth .. ' HS=' .. tostring( TabData[i].HS) .. ' HN=' .. tostring( TabData[i].HN) .. ' Lay=' .. TabData[i].Lay)
--end
-- sistemazioni per tagli inversi
local nYpH1Cut = 0
local nYpH2Cut = 0
local nYmH1Cut = 0
local nYmH2Cut = 0
for i = 1, #TabData do
local DatI = TabData[i]
if DatI.Nir == 2 and abs( DatI.AngSide) < GEO.EPS_ANG_SMALL then
if DatI.HN == 1 then
nYpH1Cut = nYpH1Cut + 1
else
nYpH2Cut = nYpH2Cut + 1
end
elseif DatI.Nir == -2 and abs( DatI.AngSide) < GEO.EPS_ANG_SMALL then
if DatI.HN == 1 then
nYmH1Cut = nYmH1Cut + 1
else
nYmH2Cut = nYmH2Cut + 1
end
end
end
--EgtOutLog( 'YpH1Cut=' .. tostring( nYpH1Cut) .. ' YmH1Cut=' .. tostring( nYmH1Cut) .. ' YpH2Cut=' .. tostring( nYpH2Cut) .. ' YmH2Cut=' .. tostring( nYmH2Cut))
if nYpH1Cut >= 1 and nYpH2Cut >= 1 then
-- va già bene così
elseif nYpH2Cut >= 1 and ( ( nYmH1Cut + nYmH2Cut) % 2) == 1 then
--EgtOutLog( 'Invertire il taglio YmH1 a X min')
-- invertire il taglio YmH1 a X minima
local nI = 0
local Xmin = GEO.INFINITO
for i = 1, #TabData do
local DatI = TabData[i]
if DatI.Nir == -2 and abs( DatI.AngSide) < GEO.EPS_ANG_SMALL and DatI.Start:getX() < Xmin then
nI = i
Xmin = DatI.Start:getX()
end
end
if nI > 0 then
local DatI = TabData[nI]
EgtSetCurrMachining( DatI.Id)
CAM.InvertVerticalCutOnExtraStroke()
DatI.Start, DatI.End = DatI.End, DatI.Start
DatI.Dir = - DatI.Dir
DatI.Nir = - DatI.Nir
DatI.HS = EgtIf( DatI.HS == MCH_SAW_HS.RIGHT, MCH_SAW_HS.LEFT, MCH_SAW_HS.RIGHT)
end
elseif nYpH1Cut >= 1 and ( ( nYmH1Cut + nYmH2Cut) % 2) == 1 then
--EgtOutLog( 'Invertire il taglio YmH2 a X max')
-- invertire il taglio YmH2 a X massima
local nI = 0
local Xmax = - GEO.INFINITO
for i = 1, #TabData do
local DatI = TabData[i]
if DatI.Nir == -2 and abs( DatI.AngSide) < GEO.EPS_ANG_SMALL and DatI.Start:getX() > Xmax then
nI = i
Xmax = DatI.Start:getX()
end
end
if nI > 0 then
local DatI = TabData[nI]
EgtSetCurrMachining( DatI.Id)
CAM.InvertVerticalCutOnExtraStroke()
DatI.Start, DatI.End = DatI.End, DatI.Start
DatI.Dir = - DatI.Dir
DatI.Nir = - DatI.Nir
DatI.HS = EgtIf( DatI.HS == MCH_SAW_HS.RIGHT, MCH_SAW_HS.LEFT, MCH_SAW_HS.RIGHT)
end
end
-- cerco lavorazioni direttamente accoppiabili
for i = 1, #TabData do
local DatI = TabData[i]
if DatI.Id ~= GDB_ID.NULL then
local bOnXm = ( DatI.Nir == -1)
local bOnXp = ( DatI.Nir == 1)
local bOnYm = ( DatI.Nir == -2)
local bOnYp = ( DatI.Nir == 2)
local bIsVert = ( abs( DatI.AngSide) < GEO.EPS_ANG_SMALL)
if bOnXm or bOnXp or bOnYm or bOnYp then
-- creo tavola lavorazioni direttamente accoppiabili
local TabDup = {}
table.insert( TabDup, { i, EgtIf( bOnXm or bOnXp, DatI.Start:getY(), DatI.Start:getX()), 0, DatI.Nir})
for j = i + 1, #TabData do
local DatJ = TabData[j]
if DatJ.Id ~= GDB_ID.NULL and DatI.Depth == DatJ.Depth then
if abs( DatI.AngSide) < GEO.EPS_ANG_SMALL and abs( DatJ.AngSide) < GEO.EPS_ANG_SMALL then
if AreSameVectorApprox( DatI.Dir, DatJ.Dir) then
-- se gli estremi coincidono entro la tolleranza
local dDiffStart = ( DatI.Start - DatJ.Start) * DatI.Dir
local dDiffEnd = ( DatI.End - DatJ.End) * DatI.Dir
if abs( dDiffStart) < MAX_DIFF and abs( dDiffEnd) < MAX_DIFF then
table.insert( TabDup, { j, EgtIf( bOnXm or bOnXp, DatJ.Start:getY(), DatJ.Start:getX()), 0, DatJ.Nir})
end
end
elseif abs( DatI.AngSide - DatJ.AngSide) < GEO.EPS_ANG_SMALL then
if AreSameVectorApprox( DatI.Dir, DatJ.Dir) and DatI.HS ~= DatJ.HS then
-- se gli estremi coincidono entro la tolleranza
local dDiffStart = ( DatI.Start - DatJ.Start) * DatI.Dir
local dDiffEnd = ( DatI.End - DatJ.End) * DatI.Dir
if abs( dDiffStart) < MAX_DIFF and abs( dDiffEnd) < MAX_DIFF then
table.insert( TabDup, { j, EgtIf( bOnXm or bOnXp, DatJ.Start:getY(), DatJ.Start:getX()), 0, DatJ.Nir})
end
elseif AreOppositeVectorApprox( DatI.Dir, DatJ.Dir) and DatI.HS == DatJ.HS then
-- se gli estremi coincidono entro la tolleranza
local dDiffStart = ( DatI.Start - DatJ.End) * DatI.Dir
local dDiffEnd = ( DatI.End - DatJ.Start) * DatI.Dir
if abs( dDiffStart) < MAX_DIFF and abs( dDiffEnd) < MAX_DIFF then
table.insert( TabDup, { j, EgtIf( bOnXm or bOnXp, DatJ.Start:getY(), DatJ.Start:getX()), 0, DatJ.Nir})
end
end
end
end
end
-- se tagli verticali, ordino la tavola in senso crescente
if bIsVert then
table.sort( TabDup, function( a, b) return a[2] < b[2] end)
end
-- assegno minima distanza ammessa tra i tagli
local dMyMinDist = EgtIf( bIsVert, dMinDistHeadsMultiCut, dMinDistSlantHeadsMultiCut)
if bOnYp then dMyMinDist = dMinDistOppoHeadsMultiCut end
-- calcolo massima distanza da altro taglio accoppiabile ed elimino tagli non accoppiabili
UpdateTabDup( bOnXm, bOnXp, bOnYm, bOnYp, bIsVert, dMyMinDist, TabDup)
-- stampo la tavola
PrintTabDup( 'Direct ', bOnXm, bOnXp, bOnYm, bOnYp, TabDup)
-- accoppio i tagli
while #TabDup >= 2 do
local nK = 0
local nL = 0
-- se taglio verticale
if bIsVert then
-- se tavola rotante standard o tagli in Y
if bIsTableRot or bOnYm or bOnYp then
-- cerco il taglio intermedio
nK = ceil( #TabDup / 2)
-- cerco taglio accoppiabile a massima distanza
local nRef = 0
for l = 1, #TabDup do
if l ~= nK then
local dMinX = min( TabDup[l][2], TabDup[nK][2])
local dMaxX = max( TabDup[l][2], TabDup[nK][2])
local dDist = abs( TabDup[l][2] - TabDup[nK][2])
if ( bOnXm or bOnXp or ( dMaxX > MIN_POSX and dMinX < MAX_POSX)) and dDist > dMyMinDist - GEO.EPS_SMALL then
if abs( l - nK) > nRef then
nRef = abs( l - nK)
nL = l
end
end
end
end
-- altrimenti tavola fissa e tagli in X
else
-- cerco taglio a giusta distanza
for l = 2, #TabDup do
local dPosY1 = TabDup[l][2]
for m = 1, l - 1 do
local dPosY2 = TabDup[m][2]
if abs( ( dPosY1 - dPosY2) - DIFF_Y - 5) < 3 then
local dPosXl1 = TabData[TabDup[l][1]].Start:getX()
local dPosXl2 = TabData[TabDup[l][1]].End:getX()
local dPosXm1 = TabData[TabDup[m][1]].Start:getX()
local dPosXm2 = TabData[TabDup[m][1]].End:getX()
local dPosXmin = min( dPosXl1, dPosXl2, dPosXm1, dPosXm2)
local dPosXmax = max( dPosXl1, dPosXl2, dPosXm1, dPosXm2)
if ( dPosXmin > MIN_DOUXNR and dPosXmax < MAX_DOUXNR and
dPosXmin < b3Raw:getMin():getX() + 200 and dPosXmax > b3Raw:getMax():getX() - 200) then
nK = l
nL = m
break
end
end
end
if nK ~= 0 then
break
end
end
-- non trovati, esco dalla ricerca
if nK == 0 then
break
end
end
-- altrimenti tagli inclinati
else
-- prendo il primo taglio
nK = 1
-- cerco taglio accoppiabile a minima distanza
local dMin = GEO.INFINITO
for l = 1, #TabDup do
if l ~= nK then
local dMinX = min( TabDup[l][2], TabDup[nK][2])
local dMaxX = max( TabDup[l][2], TabDup[nK][2])
local dDist = abs( TabDup[l][2] - TabDup[nK][2])
if ( bOnXm or bOnXp or ( dMaxX > MIN_POSX and dMinX < MAX_POSX)) and dDist > dMyMinDist - GEO.EPS_SMALL then
if dDist < dMin then
dMin = dDist
nL = l
end
end
end
end
end
-- eseguo accoppiamento
local DatK = TabData[TabDup[nK][1]]
local DatL = TabData[TabDup[nL][1]]
local dDist, dSawOffs
if not bIsVert then
-- calcolo distanza ortogonale
dDist = - (( DatK.Start - DatL.Start) ^ DatK.Dir):getZ()
if AreSameVectorApprox( DatK.Dir, - vtY) or AreSameVectorApprox( DatK.Dir, vtX) then dDist = - dDist end
dSawOffs = - 2 * CAM.GetSawLength( DatK.Id) * cos( DatK.AngSide)
if ( dDist < 0 and AreSameVectorApprox( DatK.Dir, -vtX) and DatK.HS == 2) or ( dDist < 0 and AreSameVectorApprox( DatK.Dir, vtX) and DatK.HS == 1) or
( dDist > 0 and AreSameVectorApprox( DatK.Dir, vtX) and DatK.HS == 2) or ( dDist > 0 and AreSameVectorApprox( DatK.Dir, -vtX) and DatK.HS == 1) or
( dDist < 0 and AreSameVectorApprox( DatK.Dir, vtY) and DatK.HS == 2) or ( dDist < 0 and AreSameVectorApprox( DatK.Dir, -vtY) and DatK.HS == 1) or
( dDist > 0 and AreSameVectorApprox( DatK.Dir, -vtY) and DatK.HS == 2) or ( dDist > 0 and AreSameVectorApprox( DatK.Dir, vtY) and DatK.HS == 1) then
dSawOffs = - dSawOffs
end
elseif bOnXm or bOnXp or bOnYm then
-- calcolo distanza ortogonale
dDist = (( DatK.Start - DatL.Start) ^ DatK.Dir):getZ()
dSawOffs = 2 * CAM.GetSawLength( DatK.Id)
if DatK.HS == DatL.HS then dSawOffs = dSawOffs - CAM.GetSawThickness( DatK.Id) end
if not bIsTableRot and bOnXp then
dDist = -dDist
end
else
-- calcolo distanza ortogonale
dDist = - (( DatK.Start - DatL.Start) ^ DatK.Dir):getZ()
dSawOffs = - 2 * CAM.GetSawLength( DatK.Id)
if DatK.HS == DatL.HS then dSawOffs = dSawOffs + CAM.GetSawThickness( DatK.Id) end
end
local nMchMainId
if dDist > 0 then
EgtSetInfo( DatK.Id, 'Dup', dDist + dSawOffs)
EgtSetOperationMode( DatL.Id, false)
EgtSetInfo( DatL.Id, 'Dupled', '1')
nMchMainId = DatK.Id
elseif dDist < 0 then
EgtSetInfo( DatL.Id, 'Dup', -dDist + dSawOffs)
EgtSetOperationMode( DatK.Id, false)
EgtSetInfo( DatK.Id, 'Dupled', '1')
nMchMainId = DatL.Id
end
if not bIsTableRot and bOnXp and nMchMainId then
EgtSetCurrMachining( nMchMainId)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtGetMachiningParam( MCH_MP.STARTADDLEN) + GetExtraStart( nMchMainId) + HEAD_OFFS_X)
EgtSetInfo( nMchMainId, 'HOffsX', HEAD_OFFS_X)
end
DatK.Id = GDB_ID.NULL
DatL.Id = GDB_ID.NULL
-- se tagli inclinati, riparto con la ricerca
if not bIsVert then break end
-- elimino tagli accoppiati dalla tavola
table.remove( TabDup, max( nK, nL))
table.remove( TabDup, min( nK, nL))
-- ricalcolo massima distanza da altro taglio accoppiabile ed elimino tagli non accoppiabili
UpdateTabDup( bOnXm, bOnXp, bOnYm, bOnYp, true, dMyMinDist, TabDup)
end
end
end
end
-- cerco lavorazioni accoppiabili mediante allungamento (non ammesse le inclinate)
for i = 1, #TabData do
local DatI = TabData[i]
if DatI.Id ~= GDB_ID.NULL and abs( DatI.AngSide) < GEO.EPS_ANG_SMALL and bIsTableRot then
local bOnXm = ( DatI.Nir == -1)
local bOnXp = ( DatI.Nir == 1)
local bOnYm = ( DatI.Nir == -2)
local bOnYp = ( DatI.Nir == 2)
if bOnXm or bOnXp or bOnYm or bOnYp then
-- creo tavola lavorazioni potenzialmente accoppiabili
local TabDup = {}
table.insert( TabDup, { i, EgtIf( bOnXm or bOnXp, DatI.Start:getY(), DatI.Start:getX()), 0, DatI.Nir})
for j = i + 1, #TabData do
local DatJ = TabData[j]
if DatJ.Id ~= GDB_ID.NULL and DatI.Depth == DatJ.Depth and abs( DatJ.AngSide) < GEO.EPS_ANG_SMALL and AreSameVectorApprox( DatI.Dir, DatJ.Dir) then
-- se il centro di un taglio si sovrappone all'altro li considero potenzialmente accoppiabili
local ptCenI = ( DatI.Start + DatI.End) / 2
local ptCenJ = ( DatJ.Start + DatJ.End) / 2
local dCenIStart =( ptCenI - DatJ.Start) * DatJ.Dir
local dCenIEnd =( ptCenI - DatJ.End) * DatJ.Dir
local dCenJStart =( ptCenJ - DatI.Start) * DatI.Dir
local dCenJEnd =( ptCenJ - DatI.End) * DatI.Dir
if ( dCenIStart >= 0 and dCenIEnd <= 0) or ( dCenJStart >= 0 and dCenJEnd <= 0) then
table.insert( TabDup, { j, EgtIf( bOnXm or bOnXp, DatJ.Start:getY(), DatJ.Start:getX()), 0, DatJ.Nir})
end
end
end
-- ordino la tavola in senso crescente
table.sort( TabDup, function( a, b) return a[2] < b[2] end)
-- assegno minima distanza ammessa tra i tagli (verticali)
local dMyMinDist = dMinDistHeadsMultiCut
if bOnYp then dMyMinDist = dMinDistOppoHeadsMultiCut end
-- calcolo massima distanza da altro taglio accoppiabile ed elimino tagli non accoppiabili
UpdateTabDup( bOnXm, bOnXp, bOnYm, bOnYp, true, dMyMinDist, TabDup)
-- stampo la tavola
PrintTabDup( 'Allung ', bOnXm, bOnXp, bOnYm, bOnYp, TabDup)
-- accoppio i tagli
while #TabDup >= 2 do
-- cerco il taglio intermedio
nK = ceil( #TabDup / 2)
-- cerco taglio accoppiabile a massima distanza
local nL = 0
local nRef = 0
for l = 1, #TabDup do
if l ~= nK then
local dMinX = min( TabDup[l][2], TabDup[nK][2])
local dMaxX = max( TabDup[l][2], TabDup[nK][2])
local dDist = abs( TabDup[l][2] - TabDup[nK][2])
if ( bOnXm or bOnXp or ( dMaxX > MIN_POSX and dMinX < MAX_POSX)) and dDist > dMyMinDist - GEO.EPS_SMALL then
if abs( l - nK) > nRef then
nRef = abs( l - nK)
nL = l
end
end
end
end
-- eseguo accoppiamento
local DatK = TabData[TabDup[nK][1]]
local DatL = TabData[TabDup[nL][1]]
local dDist, dSawOffs
if bOnXm or bOnXp or bOnYm then
-- calcolo distanza ortogonale
dDist = (( DatK.Start - DatL.Start) ^ DatK.Dir):getZ()
dSawOffs = 2 * CAM.GetSawLength( DatK.Id)
if DatK.HS == DatL.HS then dSawOffs = dSawOffs - CAM.GetSawThickness( DatK.Id) end
else
-- calcolo distanza ortogonale
dDist = - (( DatK.Start - DatL.Start) ^ DatK.Dir):getZ()
dSawOffs = - 2 * CAM.GetSawLength( DatK.Id)
if DatK.HS == DatL.HS then dSawOffs = dSawOffs + CAM.GetSawThickness( DatK.Id) end
end
-- salvo stato iniziale lavorazioni
EgtSetCurrMachining( DatK.Id)
local dAllStartKOri = EgtGetMachiningParam( MCH_MP.STARTADDLEN)
local dAllEndKOri = EgtGetMachiningParam( MCH_MP.ENDADDLEN)
local dExtraStartKOri = GetExtraStart( DatK.Id)
local dExtraEndKOri = GetExtraEnd( DatK.Id)
EgtSetCurrMachining( DatL.Id)
local dAllStartLOri = EgtGetMachiningParam( MCH_MP.STARTADDLEN)
local dAllEndLOri = EgtGetMachiningParam( MCH_MP.ENDADDLEN)
local dExtraStartLOri = GetExtraStart( DatL.Id)
local dExtraEndLOri = GetExtraEnd( DatL.Id)
-- eventuali allungamenti
local dDiffStart = ( DatK.Start - DatL.Start) * DatK.Dir
local dDiffEnd = ( DatK.End - DatL.End) * DatK.Dir
local dAllStartKNew = EgtIf( dDiffStart > 0, dDiffStart, 0)
local dAllEndKNew = EgtIf( dDiffEnd < 0, - dDiffEnd, 0)
local bAllK = ( dAllStartKNew > GEO.EPS_SMALL or dAllEndKNew > GEO.EPS_SMALL)
local dAllStartLNew = EgtIf( dDiffStart < 0, - dDiffStart, 0)
local dAllEndLNew = EgtIf( dDiffEnd > 0, dDiffEnd, 0)
local bAllL = ( dAllStartLNew > GEO.EPS_SMALL or dAllEndLNew > GEO.EPS_SMALL)
-- verifico non interferiscano
local bInterfK = false
if bAllK then
EgtSetCurrMachining( DatK.Id)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStartKOri + dExtraStartKOri + dAllStartKNew)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEndKOri + dExtraEndKOri + dAllEndKNew)
EgtPreviewMachining()
if DatK.Lay == 'InLoop' or dAllStartKOri < - GEO.EPS_SMALL or dAllEndKOri < - GEO.EPS_SMALL then
bInterfK = true
else
bInterfK = ( EgtVerifyMachining( DatK.Id) ~= NST_FMI.NONE)
end
end
local bInterfL = false
if bAllL then
EgtSetCurrMachining( DatL.Id)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStartLOri + dExtraStartLOri + dAllStartLNew)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEndLOri + dExtraEndLOri + dAllEndLNew)
EgtPreviewMachining()
if DatL.Lay == 'InLoop' or dAllStartLOri < - GEO.EPS_SMALL or dAllEndLOri < - GEO.EPS_SMALL then
bInterfL = true
else
bInterfL = ( EgtVerifyMachining( DatL.Id) ~= NST_FMI.NONE)
end
end
if bInterfK or bInterfL then
EgtSetCurrMachining( DatK.Id)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStartKOri)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEndKOri)
EgtPreviewMachining()
EgtSetCurrMachining( DatL.Id)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStartLOri)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEndLOri)
EgtPreviewMachining()
end
local nPrevKId = EgtGetFirstNameInGroup( DatK.Id, 'PV')
EgtEmptyGroup( nPrevKId or GDB_ID.NULL)
local nPrevLId = EgtGetFirstNameInGroup( DatL.Id, 'PV')
EgtEmptyGroup( nPrevLId or GDB_ID.NULL)
-- se non intersecano, accoppio
if not bInterfK and not bInterfL then
if dDist > 0 then
EgtSetInfo( DatK.Id, 'Dup', dDist + dSawOffs)
--EgtOutLog( string.format( 'Dup %d : AllS1=%.1f AllE1=%.1f AllS2=%.1f AllE2=%.1f', DatK.Id, dAllStartKNew, dAllEndKNew, dAllStartLNew, dAllEndLNew))
if dAllStartKNew > GEO.EPS_SMALL then EgtSetInfo( DatK.Id, 'AllS1', dAllStartKNew) end
if dAllEndKNew > GEO.EPS_SMALL then EgtSetInfo( DatK.Id, 'AllE1', dAllEndKNew) end
if dAllStartLNew > GEO.EPS_SMALL then EgtSetInfo( DatK.Id, 'AllS2', dAllStartLNew) end
if dAllEndLNew > GEO.EPS_SMALL then EgtSetInfo( DatK.Id, 'AllE2', dAllEndLNew) end
EgtSetOperationMode( DatL.Id, false)
EgtSetInfo( DatL.Id, 'Dupled', '1')
elseif dDist < 0 then
EgtSetInfo( DatL.Id, 'Dup', -dDist + dSawOffs)
--EgtOutLog( string.format( 'Dup %d : AllS2=%.1f AllE2=%.1f AllS1=%.1f AllE1=%.1f', DatL.Id, dAllStartKNew, dAllEndKNew, dAllStartLNew, dAllEndLNew))
if dAllStartKNew > GEO.EPS_SMALL then EgtSetInfo( DatL.Id, 'AllS2', dAllStartKNew) end
if dAllEndKNew > GEO.EPS_SMALL then EgtSetInfo( DatL.Id, 'AllE2', dAllEndKNew) end
if dAllStartLNew > GEO.EPS_SMALL then EgtSetInfo( DatL.Id, 'AllS1', dAllStartLNew) end
if dAllEndLNew > GEO.EPS_SMALL then EgtSetInfo( DatL.Id, 'AllE1', dAllEndLNew) end
EgtSetOperationMode( DatK.Id, false)
EgtSetInfo( DatK.Id, 'Dupled', '1')
end
end
-- in ogni caso li considero fatti
DatK.Id = GDB_ID.NULL
DatL.Id = GDB_ID.NULL
-- elimino tagli accoppiati dalla tavola
table.remove( TabDup, max( nK, nL))
table.remove( TabDup, min( nK, nL))
-- ricalcolo massima distanza da altro taglio accoppiabile ed elimino tagli non accoppiabili
UpdateTabDup( bOnXm, bOnXp, bOnYm, bOnYp, true, dMyMinDist, TabDup)
end
end
end
end
end
-- Ricalcolo disposizioni e lavorazioni attive
local nOperId = EgtGetFirstActiveOperation()
while nOperId do
if EgtGetOperationType( nOperId) == MCH_OY.DISP then
-- se lavorazione con movimenti macchina
if EgtGetGroupObjs( nOperId) > 0 then
CAM.MultiCutDispositionSettings( nOperId)
if not EgtSpecialApplyDisposition( nOperId, false) then
CAM.ERR = 71
end
end
else
EgtSetCurrMachining( nOperId)
CAM.MultiCutMachiningSettings()
EgtApplyMachining( false)
end
nOperId = EgtGetNextActiveOperation( nOperId)
end
end
--
-------------------------------------------------------------------------------
-- Funzioni per variazione Feed all'inizio e alla fine dei tagli standard
-------------------------------------------------------------------------------
local function RemoveCutsFeedStartEndVaried()
-- Recupero gli identificativi dei tagli
local nCutId = EgtGetFirstActiveOperation()
while nCutId do
-- Se è un taglio con lama non vuoto
if CAM.MachiningIsStdCut( nCutId) then
EgtSetCurrMachining( nCutId)
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) or ''
sNotes = EgtAdjustNotes( sNotes, 'Fsta', nil)
sNotes = EgtAdjustNotes( sNotes, 'Fend', nil)
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
end
nCutId = EgtGetNextActiveOperation( nCutId)
end
end
--
-------------------------------------------------------------------------------
local function SetCutsFeedStartEndVaried()
-- verifico ci sia un solo grezzo (non ammesse spezzature)
--if EgtGetRawPartCount() > 1 then
-- EgtOutLog( "SetCutsFeedStartEndVaried error : too many rawparts")
-- return
--end
-- dichiarazione tabella
local TabCut = {}
-- Recupero gli identificativi dei tagli
local nCutId = EgtGetFirstActiveOperation()
while nCutId do
-- Se è un taglio con lama non vuoto
if CAM.MachiningIsStdCut( nCutId) and not EgtIsOperationEmpty( nCutId) then
table.insert( TabCut, {Id=nCutId})
end
nCutId = EgtGetNextActiveOperation( nCutId)
end
-- Se da applicare a tutti i tagli
if true then
-- Assegno ad ogni taglio Feed ridotte all'inizio/fine
for i = 1, #TabCut do
EgtSetCurrMachining( TabCut[i].Id)
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
sNotes = EgtAdjustNotes( sNotes, 'Fsta', EgtNumToString( dCutFsevLen, 3) .. ',' .. EgtNumToString( dCutFsevPerc / 100, 2))
sNotes = EgtAdjustNotes( sNotes, 'Fend', EgtNumToString( dCutFsevLen, 3) .. ',' .. EgtNumToString( dCutFsevPerc / 100, 2))
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
end
-- altrimenti solo per tagli che hanno parti vicino al bordo lastra
else
-- Recupero il contorno del grezzo
local nKerfId = EgtGetFirstNameInGroup( EgtGetFirstRawPart() or GDB_ID.NULL, 'Kerf')
if not nKerfId then
EgtOutLog( "SetCutsFeedStartEndVaried error : rawpart kerf not found")
return
end
-- Ne creo un offset interno pari alla distanza di variazione di feed più un epsilon (tengo la curva più lunga)
local nOffsId, nCount = EgtOffsetCurveAdv( nKerfId, -dCutFsevLen + 0.02)
if not nOffsId then
EgtOutLog( "SetCutsFeedStartEndVaried error : rawpart kerf offset impossible")
return
end
for i = nCount, 2, -1 do
EgtErase( nOffsId + i - 1)
end
-- Creo gruppo temporaneo
local nGrpId = EgtGroup( GDB_ID.ROOT)
if not nGrpId then
EgtOutLog( "SetCutsFeedStartEndVaried error : temp group not constructible")
return
end
EgtSetLevel( nGrpId, GDB_LV.TEMP)
-- Vi sposto l'offset
EgtRelocateGlob( nOffsId, nGrpId)
-- Ne derivo una regione
local nRegId = EgtSurfFlatRegion( nGrpId, nOffsId)
-- Per ogni taglio, ne determino la posizione rispetto al contorno lastra e di conseguenza sistemo Feed ridotte all'inizio/fine
for i = 1, #TabCut do
EgtSetCurrMachining( TabCut[i].Id)
local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES)
local ptStart = EgtGetMachiningStartPoint()
local ptEnd = EgtGetMachiningEndPoint()
if ptStart and ptEnd then
local nLineId = EgtLine( nGrpId, ptStart, ptEnd, GDB_RT.GLOB) or GDB_ID.NULL
local nTrimId, nTrimCnt = EgtTrimCurveWithRegion( nLineId, nRegId, false, false)
if nTrimCnt == 0 then
EgtOutLog( 'Feed Start/End Var = NO')
elseif nTrimCnt == 1 then
if AreSamePointEpsilon( ptStart, EgtSP( nTrimId), 1.0) then
local dStartLen = EgtCurveLength( nTrimId)
EgtOutLog( 'StartLen=' .. EgtNumToString( dStartLen, 1))
sNotes = EgtAdjustNotes( sNotes, 'Fsta', EgtNumToString( dStartLen, 3) .. ',' .. EgtNumToString( dCutFsevPerc / 100, 2))
elseif AreSamePointEpsilon( ptEnd, EgtEP( nTrimId), 1.0) then
local dEndLen = EgtCurveLength( nTrimId)
EgtOutLog( 'EndLen=' .. EgtNumToString( dEndLen, 1))
sNotes = EgtAdjustNotes( sNotes, 'Fend', EgtNumToString( dEndLen, 3) .. ',' .. EgtNumToString( dCutFsevPerc / 100, 2))
end
elseif nTrimId then
local dStartLen = EgtCurveLength( nTrimId)
local dEndLen = EgtCurveLength( nTrimId + nTrimCnt - 1)
EgtOutLog( 'StartLen=' .. EgtNumToString( dStartLen, 1) .. ' EndLen=' .. EgtNumToString( dEndLen, 1) )
sNotes = EgtAdjustNotes( sNotes, 'Fsta', EgtNumToString( dStartLen, 3) .. ',' .. EgtNumToString( dCutFsevPerc / 100, 2))
sNotes = EgtAdjustNotes( sNotes, 'Fend', EgtNumToString( dEndLen, 3) .. ',' .. EgtNumToString( dCutFsevPerc / 100, 2))
end
end
EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes)
end
EgtErase( nGrpId)
end
end
--
-------------------------------------------------------------------------------
-- Funzioni per PreTagli su Uscite (EPC)
------ Cancellazione di eventuali Pretagli sulle Uscite -----------
local function EraseAllExitPreCuts()
local nOperId = EgtGetFirstOperation()
while nOperId do
local nNextOperId = EgtGetNextOperation( nOperId)
if EgtGetType( nOperId) ~= MCH_OY.DISP and EgtExistsInfo( nOperId, 'EPC') then
EgtRemoveOperation( nOperId)
end
nOperId = nNextOperId
end
end
--
------ Creazione di eventuali Pretagli sulle Uscite (solo su tagli verticali) -----------
local function CreateExitPreCuts( TabUpdate)
-- ciclo sulle fasi
local nPhaseCount = EgtGetPhaseCount()
for nPhase = 1, nPhaseCount do
-- imposto la fase come corrente
EgtSetCurrPhase( nPhase)
-- recupero i tagli esterni attivi della fase
local TabCut = {}
local nMchId = EgtGetNextOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL)
while nMchId and EgtGetOperationPhase( nMchId) == nPhase do
if EgtGetOperationType( nMchId) == MCH_OY.SAWING and EgtGetOperationMode( nMchId) and EgtGetInfo( nMchId, 'Lay') == 'OutLoop' then
EgtSetCurrMachining( nMchId)
local dAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
local nLeadIn = EgtGetMachiningParam( MCH_MP.LEADINTYPE)
local nLeadOut = EgtGetMachiningParam( MCH_MP.LEADOUTTYPE)
local ptStart = EgtGetMachiningStartPoint( nMchId)
local ptEnd = EgtGetMachiningEndPoint( nMchId)
local vtDir = ptEnd - ptStart
vtDir:normalize()
local dRawBottomHeight = CAM.GetRawBottomHeight( nMchId)
table.insert( TabCut, { Mch=nMchId, Ang=dAng, LeadIn=nLeadIn, LeadOut=nLeadOut, Start=ptStart, End=ptEnd, Dir=vtDir, RawBottomHeight=dRawBottomHeight})
end
nMchId = EgtGetNextOperation( nMchId)
end
local RefMch
if #TabCut > 0 then
RefMch = TabCut[1].Mch
end
-- creo i pretagli
local TabEPC = {}
for i = 1, #TabCut do
-- se taglio verticale con uscita in centro
if abs( TabCut[i].Ang) < GEO.EPS_ANG_SMALL and TabCut[i].LeadOut == MCH_SAW_LO.CENT then
-- copio la lavorazione
local sSouName = EgtGetName( TabCut[i].Mch)
local nNewMchId = EgtCopyMachining( sSouName..'_EPC', sSouName)
EgtRelocateGlob( nNewMchId, RefMch, GDB_IN.BEFORE)
EgtSetInfo( nNewMchId, 'EPC', 1)
table.insert( TabEPC, { Mch=nNewMchId, Pos=TabCut[i].End, Dir=TabCut[i].Dir, Ang=TabCut[i].Ang, RawBottomHeight=TabCut[i].RawBottomHeight})
-- inverto direzione di lavoro
local bInvert = not EgtGetMachiningParam( MCH_MP.INVERT)
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
-- conseguentemente devo invertire anche il lato di lavoro
CAM.InvertWorkside()
-- devo invertire il lato mandrino
CAM.InvertHeadside()
-- devo scambiare tra loro i parametri di attacco e uscita
CAM.SwapCutLeadInOut()
-- e anche gli allungamenti iniziale e finale
CAM.SwapCutAllStartEnd()
-- e anche gli allungamenti dei baffi
CAM.SwapWhiskExtends()
-- cambio allungamento finale per fare pretaglio su inizio attuale
local dLen = dist( TabCut[i].Start, TabCut[i].End)
local dEal = EgtGetMachiningParam( MCH_MP.ENDADDLEN)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal - dLen + 2)
-- aggiorno la lavorazione
EgtApplyMachining( true)
end
end
-- li ordino
EgtSpInit()
for i = 1, #TabEPC do
local AngH = atan2( TabEPC[i].Dir:getY(), TabEPC[i].Dir:getX()) + 270
if AngH > 180.1 then
AngH = AngH - 360
elseif AngH < - 180.1 then
AngH = AngH + 360
end
if bIsMultiCut then
if abs( TabEPC[i].Dir:getX()) > abs( TabEPC[i].Dir:getY()) then
AngH = AngH + 10 * ( dAngRotMultiCut + dOffsAxisBlock)
else
AngH = AngH + 10 * ( 0 + dOffsAxisBlock)
end
end
local AngV = 90 - abs( TabEPC[i].Ang)
local dExtraZ = 40000
if TabEPC[i].RawBottomHeight > 1.0 then
dExtraZ = 0
elseif abs( TabEPC[i].Ang) > GEO.EPS_ANG_SMALL then
dExtraZ = 10000
end
local ptS = TabEPC[i].Pos + Z_AX() * dExtraZ
local ptE = ptS
EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), AngH, AngV,
ptE:getX(), ptE:getY(), ptE:getZ(), AngH, AngV)
end
EgtSpSetAngularParams( 1000, 40, 2000, 60)
EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -6000, 0, EgtIf( bCutLongDxSx, 90, -90), 90)
local vOrd = EgtSpCalculate( SHP_TY.OPEN)
EgtSpTerminate()
-- applico ordinamento calcolato
if vOrd then
-- sposto le lavorazioni di pretaglio
for i = 1, #vOrd do
local CurrMch = TabEPC[vOrd[i]].Mch
EgtRelocateGlob( CurrMch, RefMch, GDB_IN.BEFORE)
end
-- le inserisco tra quelle da aggiornare in posizione opportuna
local CurrInd
for j = 1, #TabUpdate do
if TabUpdate[j].Mch == RefMch then
CurrInd = j
break
end
end
if CurrInd then
for i = #vOrd, 1, -1 do
table.insert( TabUpdate, CurrInd, {Mch=TabEPC[vOrd[i]].Mch, Part=nil})
end
end
end
end
end
-------------------------------------------------------------------------------
------ Inserimento delle lavorazioni ---------------------
function CAM.Add()
EgtOutLog( 'CAM.Add ' .. CAMAUTO_VER)
-- Recupero gli identificativi delle entità : da tutti i pezzi del grezzo
if CAM.PARTID == GDB_ID.NULL then
-- Ciclo sui pezzi del grezzo
local nPartId = EgtGetFirstPartInRawPart(nRawId)
while nPartId do
-- Recupero gli identificativi delle entità da lavorare nel pezzo **Carico le tabelle con entità**
CAM.AnalyzePart( nPartId)
-- Passo al grezzo successivo
nPartId = EgtGetNextPartInRawPart(nPartId)
end
-- Recupero gli identificativi delle entità : da un pezzo del grezzo
else
-- Recupero gli identificativi delle entità
CAM.AnalyzePart( CAM.PARTID)
end
-- Applico le lavorazioni
CAM.ApplyMachinings()
end
----------------------------------------------------------
function CAM.UpdateSawing()
EgtOutLog( 'CAM.UpdateSawing ' .. CAMAUTO_VER)
local TabEnt = {}
local sLay = 'OutLoop'
local TabCrv = {}
local TabPart = {}
local j = nil
local nLiType = nil
local dSal = nil
local nLoType = nil
local dEal = nil
EgtSetCurrMachining( CAM.OPERID)
local Geo = EgtGetMachiningGeometry()
if type( Geo) == 'table' and type( Geo[1]) == 'table' and type( Geo[1][1]) == 'number' then
-- recupero l'entità in lavorazione
table.insert( TabEnt, Geo[1][1])
-- recupero il nome del layer cui appartiene
local sName = EgtGetName( EgtGetParent( Geo[1][1]) or GDB_ID.NULL)
if sName then sLay = sName end
-- cancello la preview nel pezzo
CAM.ErasePreview( CAM.OPERID)
-- recupero l'info da applicare in fase di costruzione della lavorazione
j = EgtGetInfo( CAM.OPERID, 'Index_j')
-- recupero variazioni su attacco e uscita
nLiType = EgtGetMachiningParam( MCH_MP.LEADINTYPE)
dSal = EgtGetMachiningParam( MCH_MP.STARTADDLEN)
nLoType = EgtGetMachiningParam( MCH_MP.LEADOUTTYPE)
dEal = EgtGetMachiningParam( MCH_MP.ENDADDLEN)
-- rimuovo la lavorazione
EgtRemoveOperation( CAM.OPERID)
end
-- aggiorno lavorazione
CAM.ApplyCuts( TabEnt, sLay, TabCrv, TabPart, j)
-- inserisco variazioni di attacco e uscita
if CAM.NEW_OPERATION and EgtSetCurrMachining( CAM.NEW_OPERATION) then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nLiType)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal)
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nLoType)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal)
EgtApplyMachining()
if EgtPreviewMachining() then
if not EgtIsMachiningEmpty() then
local nEntId = CAM.GetEntIdFromMachining( CAM.NEW_OPERATION)
local nPartId = EgtGetParent( EgtGetParent( nEntId) or GDB_ID.NULL) or GDB_ID.NULL
CAM.CopyPreviewToPiece( CAM.NEW_OPERATION, nPartId)
local sCurrSaw = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or '')
if sCurrSaw and EgtTdbSetCurrTool( sCurrSaw) then
CAM.ApplyPvColor( sCurrSaw, CAM.NEW_OPERATION)
end
end
end
else
CAM.ERR = 58
EgtOutLog( ' Error updating sawing')
end
end
------ Inserimento di una lavorazione Waterjet ---------------------
function CAM.AddWaterJet()
EgtOutLog( 'CAM.AddWaterJet ' .. CAMAUTO_VER .. ' Operation ID: ')
CAM.ApplyWaterJettings( {}, {CAM.OPERID}, 'OutLoop')
end
----------------------------------------------------------
function CAM.AddWaterJets()
EgtOutLog( 'CAM.AddWaterJets ' .. CAMAUTO_VER .. '. Nuova gestione tagli collegati. ')
local TabEnt = {}
local TabPart = {}
for i=1, #CAM.TAB_OPERID, 1 do
EgtSetCurrMachining( CAM.TAB_OPERID[i])
local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR)
sDepth = string.gsub( sDepth, "RB", tostring(dRawHeight))
local dRbH = EgtEvalNumExpr( sDepth)
if dRbH - dRawHeight < GEO.EPS_SMALL then
local Geo = EgtGetMachiningGeometry()
if type( Geo) == 'table' and type( Geo[1]) == 'table' and type( Geo[1][1]) == 'number' then
-- Taglio completo con Waterjet
table.insert( TabEnt, Geo[1][1])
-- recupero la preview dal pezzo (taglio di lama) e la elimino : la sostituisco con un taglio Waterjet
local IdPart = EgtGetFirstNameInGroup( CAM.TAB_OPERID[i], "PV")
IdPart = EgtGetInfo( IdPart, "PvId", 'i')
EgtErase(IdPart)
EgtRemoveOperation( CAM.TAB_OPERID[i])
EgtPreviewMachining( true)
end
else
-- Finitura con waterjet
table.insert( TabPart, CAM.TAB_OPERID[i])
end
end
-- **DA GESTIRE MEGLIO** l'attacco dei tagli: EgtSetMachiningParam( MCH_MP.LIHOLE, false) -anche per i tagli TabEnt?-
CAM.ApplyWaterJettings( TabEnt, TabPart, 'OutLoop')
end
------ Aggiornamento di tutti i percorsi delle lavorazioni ---------------------
function CAM.UpdateAllTp()
EgtOutLog( 'CAM.UpdateAllTp ' .. CAMAUTO_VER)
-- Se progetto di tipo cornici
local nPartId = EgtGetFirstPartInRawPart( EgtGetFirstRawPart() or GDB_ID.NULL)
if nPartId and EgtGetName( nPartId) == 'Frame' then
EgtApplyAllMachinings( false)
return
end
-- Elimino eventuali pretagli su uscite (EPC)
EraseAllExitPreCuts()
-- Tabella delle lavorazioni da aggiornare con pezzo di appartenenza
local TabUpdate = {}
-- Recupero gli identificativi di tutte le lavorazioni ( anche non attive, gestione fatta nelle funzioni chiamate)
local nOperId = EgtGetFirstOperation()
while nOperId do
if EgtGetOperationType( nOperId) ~= MCH_OY.DISP or EgtGetGroupObjs( nOperId) > 0 or not EgtIsOperationEmpty( nOperId) then
local nPartId = EgtGetParent( EgtGetParent( CAM.GetEntIdFromMachining( nOperId)))
table.insert( TabUpdate, {Mch=nOperId, Part=nPartId})
end
nOperId = EgtGetNextOperation( nOperId)
end
-- Se MultiCut elimino tagli accoppiati
if bIsMultiCut then
CAM.MultiCutRemovePairCuts( TabUpdate)
end
-- Se abilitate variazioni di feed a inizio/fine taglio
if bCutFsevEnable then
-- Devo aggiornare le operazioni (lavorazioni e disposizioni con movimento)
CAM.UpdateOperations( TabUpdate, false, true)
-- Elimino le variazioni presenti
RemoveCutsFeedStartEndVaried()
-- Se richieste, inserisco variazioni di feed nei tagli di lama
if dCutFsevLen > GEO.EPS_SMALL and dCutFsevPerc > 0.5 then
SetCutsFeedStartEndVaried()
end
end
-- Se richiesti pretagli su uscite (EPC)
if bExitPreCut then
CreateExitPreCuts( TabUpdate)
end
-- Aggiorno le operazioni (lavorazioni e disposizioni con movimento)
CAM.UpdateOperations( TabUpdate, false, true)
-- Se MultiCut e non tavola bloccata, creo tagli accoppiati
if bIsMultiCut and bUse2Heads and not dSetTab then
CAM.MultiCutMakePairCuts()
end
end
------ Cancellazione delle lavorazioni ---------------------
local function EraseWjRectification( TabPart)
if #TabPart < 1 then
return
end
for i = 1, #TabPart do
EgtErase( EgtGetNameInGroup( TabPart[i].Part, "WjRectification"))
end
end
function CAM.Erase()
EgtOutLog( 'CAM.Erase ' .. CAMAUTO_VER)
-- Recupero gli identificativi delle lavorazioni : da tutti i pezzi del grezzo
if CAM.PARTID == GDB_ID.NULL then
-- Tabella delle lavorazioni da cancellare con pezzo di appartenenza
local TabErase = {}
-- Ciclo sui pezzi del grezzo
local nPartId = EgtGetFirstPartInRawPart( nRawId)
while nPartId do
-- Recupero gli identificativi delle lavorazioni
TabErase = CAM.FindPartMachinings( nPartId, TabErase)
-- Passo al grezzo successivo
nPartId = EgtGetNextPartInRawPart( nPartId)
end
-- cancello wjRectification
EraseWjRectification( TabErase)
-- Cancello le lavorazioni
CAM.EraseAllMachinings( TabErase)
-- Cancello le lavorazioni senza pezzo associato e le fasi successive alla prima
EgtRemoveAllOperations()
-- Recupero gli identificativi delle lavorazioni : da un solo pezzo del grezzo
else
-- Tabella delle lavorazioni da cancellare con pezzo di appartenenza
local TabErase = {}
-- Recupero gli identificativi
TabErase = CAM.FindPartMachinings( CAM.PARTID, TabErase)
-- cancello wjRectification
EraseWjRectification( TabErase)
-- Cancello le lavorazioni
CAM.EraseAllMachinings( TabErase)
end
end
------ Inversione parametri di un taglio di lama verticale -----------
function CAM.InvertVerticalCut()
EgtOutLog( 'CAM.InvertVerticalCut ' .. CAMAUTO_VER)
EgtSetCurrMachining( CAM.OPERID)
-- se non è taglio di lama, esco subito
if EgtGetMachiningParam( MCH_MP.TYPE) ~= MCH_MY.SAWING then
CAM.ERR = 101
return
end
-- se non è verticale, esco subito
local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
if abs( dSideAng) > GEO.EPS_ANG_SMALL then
CAM.ERR = 102
return
end
-- inverto direzione per cercare di evitare eventuale extracorsa
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
bInvert = (not bInvert)
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
-- conseguentemente devo invertire anche il lato di lavoro
CAM.InvertWorkside()
-- devo scambiare tra loro i parametri di attacco e uscita
CAM.SwapCutLeadInOut()
-- e anche gli allungamenti iniziale e finale
CAM.SwapCutAllStartEnd()
-- e anche gli allungamenti dei baffi
CAM.SwapWhiskExtends()
end
------ Inversione parametri di una lavorazione a getto d'acqua -----------
function CAM.InvertWaterjet()
EgtOutLog( 'CAM.InvertWaterjet ' .. CAMAUTO_VER)
EgtSetCurrMachining( CAM.OPERID)
-- se non è lavorazioneo con getto d'acqua, esco subito
if EgtGetMachiningParam( MCH_MP.TYPE) ~= MCH_MY.WATERJETTING then
CAM.ERR = 101
return
end
-- inverto direzione
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
bInvert = (not bInvert)
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
-- conseguentemente devo invertire anche il lato di lavoro
CAM.InvertWorkside()
-- devo scambiare tra loro i parametri di attacco e uscita
CAM.SwapCutLeadInOut()
-- e anche gli allungamenti iniziale e finale
CAM.SwapCutAllStartEnd()
end
------ Ordinamento dei tagli, delle fresature e delle forature -------
local function SortCuts( nPhase, LastMch, sLay)
-- dichiarazione tabella
local TabCut = {}
-- Recupero gli identificativi delle lavorazioni e annullo eventuali allungamenti e Id di altre lavorazioni rappresentate
local nOperId = EgtGetPhaseDisposition( nPhase)
while nOperId do
-- Se appartiene alla fase corrente e taglio con lama non da sopra (sempre su 1 sola entità)
if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == MCH_OY.SAWING and
EgtGetInfo( nOperId, 'Lay') ~= 'OnPath' and
( not sLay or EgtGetInfo( nOperId, 'Lay') == sLay) then
-- rendo comunque attiva la lavorazione
EgtSetOperationMode(nOperId,true)
EgtSetCurrMachining(nOperId)
if not EgtIsMachiningEmpty() then
-- annullo allungamenti/accorciamenti utente (se gli allungamenti sono stati forzati in fase di costruzione allora non eseguo modifiche)
local SkipControl = EgtGetInfo( nOperId, 'StartEndModifyOnIntCorner', 'b') or EgtGetInfo( nOperId, 'ManageLeadInOnIntCorner', 'b')
if not SkipControl then
local dUsal = EgtGetInfo( nOperId, 'Usal', 'd')
if dUsal and abs( dUsal) > 10 * GEO.EPS_SMALL then
local dSal = EgtGetMachiningParam( MCH_MP.STARTADDLEN)
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal - dUsal)
EgtRemoveInfo( nOperId, 'Usal')
end
local dUeal = EgtGetInfo( nOperId, 'Ueal', 'd')
if dUeal and abs( dUeal) > 10 * GEO.EPS_SMALL then
local dEal = EgtGetMachiningParam( MCH_MP.ENDADDLEN)
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal - dUeal)
EgtRemoveInfo( nOperId, 'Ueal')
end
-- annullo allungamenti (valori positivi)
if EgtGetMachiningParam( MCH_MP.STARTADDLEN) > 0 then
EgtSetMachiningParam( MCH_MP.STARTADDLEN, 0)
EgtRemoveInfo( nOperId, 'Usal')
end
if EgtGetMachiningParam( MCH_MP.ENDADDLEN) > 0 then
EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0)
EgtRemoveInfo( nOperId, 'Ueal')
end
end
-- se disabilitato da utente e riferisce altre lavorazioni, copio disabilitazione su queste
if EgtExistsInfo( nOperId, 'UserOff') then
local sOthMIds = EgtGetInfo(nOperId, 'OthMIds')
if sOthMIds then
-- divido la lista separata da virgole nelle sue parti
for sId in string.gmatch(sOthMIds, '([^,]+)') do
local nId = tonumber(sId)
if nId then
EgtSetInfo( nId, 'UserOff', '1')
end
end
end
end
-- annullo altre lavorazioni riferite
EgtRemoveInfo(nOperId, 'OthMIds')
-- annullo eventuali cambi di attacco e/o uscita
local bOriLi, nOriLi = CAM.GetOriLeadIn( nOperId)
if bOriLi then
EgtSetMachiningParam( MCH_MP.LEADINTYPE, nOriLi)
end
local bOriLo, nOriLo = CAM.GetOriLeadOut( nOperId)
if bOriLo then
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nOriLo)
end
-- ripristino stato originale di preview
local nEntId = CAM.GetEntIdFromMachining( nOperId)
if EgtPreviewMachining( true) then
if not EgtIsMachiningEmpty() then
local nPartId = EgtGetParent( EgtGetParent( nEntId))
CAM.CopyPreviewToPiece( nOperId, nPartId)
local sCurrSaw = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or '')
if sCurrSaw and EgtTdbSetCurrTool( sCurrSaw) then
CAM.ApplyPvColor( sCurrSaw, nOperId)
end
end
end
-- recupero i dati
local bInvert = EgtGetMachiningParam( MCH_MP.INVERT)
local dAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
local dThick = CAM.GetSawThickness()
local dDeltaT = CAM.GetDeltaT( nOperId)
local dDeltaTI = CAM.GetDeltaTI( nOperId) or dDeltaT
local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR)
local dRawBottomHeight = CAM.GetRawBottomHeight( nOperId)
local dOffsL = EgtGetMachiningParam( MCH_MP.OFFSL)
local bStrictStart = ( EgtGetMachiningParam( MCH_MP.LEADINTYPE) == MCH_SAW_LI.STRICT)
local bStrictEnd = ( EgtGetMachiningParam( MCH_MP.LEADOUTTYPE) == MCH_SAW_LO.STRICT)
local dSWE, dEWE = CAM.GetWhiskExtends()
local nInterf = EgtVerifyMachining( nOperId)
local bInterfStart = (( nInterf & NST_FMI.LI) ~= 0)
local bInterfEnd = (( nInterf & NST_FMI.LO) ~= 0)
if nEntId ~= GDB_ID.NULL and EgtExistsObj( nEntId) then
local ptStart = EgtSP( nEntId, GDB_ID.ROOT)
local ptEnd = EgtEP( nEntId, GDB_ID.ROOT)
local vtDir = ptEnd - ptStart
vtDir:normalize()
-- sposto i punti a metà larghezza taglio più offset lineare
local vtNorm = Vector3d(vtDir:getY(),-vtDir:getX(),vtDir:getZ())
local dDelta = 0.5 * dThick / cos( dAng) + dOffsL
ptStart = ptStart + vtNorm * dDelta
ptEnd = ptEnd + vtNorm * dDelta
local _, EnInv = CAM.GetEnableInvert( nEntId)
-- per tagli verticali ricalcolo bInvert perchè pezzo potrebbe essere stato ruotato
if EnInv and abs( dAng) < GEO.EPS_ANG_SMALL then
local bNewInvert = CAM.GetInvertVerticalCut( ptStart, ptEnd)
if bNewInvert ~= bInvert then
bInvert = bNewInvert
EgtSetMachiningParam( MCH_MP.INVERT, bInvert)
CAM.InvertWorkside()
CAM.SwapCutLeadInOut()
CAM.SwapCutAllStartEnd()
bStrictStart, bStrictEnd = bStrictEnd, bStrictStart
dSWE, dEWE = dEWE, dSWE
bInterfStart, bInterfEnd = bInterfEnd, bInterfStart
end
end
-- con invert devo scambiare estremi e invertire direzione
if bInvert then
nEntId = - nEntId
ptStart, ptEnd = ptEnd, ptStart
vtDir = - vtDir
dDeltaT, dDeltaTI = dDeltaTI, dDeltaT
end
table.insert( TabCut, {Mch=nOperId, Ent=nEntId, Start=ptStart, End=ptEnd, Dir=vtDir, Inv=bInvert,
Ang=dAng, DT=dDeltaT, DTI=dDeltaTI, Depth=sDepth, RawBottomHeight=dRawBottomHeight, OffsL=dOffsL,
StrictStart=bStrictStart, StrictEnd=bStrictEnd, SWE=dSWE, EWE=dEWE, InterfStart=bInterfStart, InterfEnd=bInterfEnd})
else
CAM.ERR = 60
end
end
end
-- Passo alla operazione successiva
nOperId = EgtGetNextOperation( nOperId)
end
-- devo portare tutti i tagli con angolo negativo all'inizio (per garantire corretto affondamento se fusi con tagli con angolo positivo)
local IndMin = 1
local IndCurr = #TabCut
while IndCurr > IndMin do
if TabCut[IndCurr].Ang < - GEO.EPS_ANG_SMALL then
table.insert( TabCut, IndMin, table.remove( TabCut, IndCurr))
IndMin = IndMin + 1
else
IndCurr = IndCurr - 1
end
end
-- log dei dati per debug
--EgtOutLog( 'Dati lavorazioni :')
--for i = 1, #TabCut do
-- EgtOutLog( 'SawId='..tostring( TabCut[i].Mch)..' GeoId='..tostring( TabCut[i].Ent)..
-- ' Start='..tostring( TabCut[i].Start)..' End='..tostring( TabCut[i].End)..' Dir='..tostring( TabCut[i].Dir)..' Inv='..tostring( TabCut[i].Inv)..
-- ' Ang='..EgtNumToString( TabCut[i].Ang, 3)..' RBH='..EgtNumToString( TabCut[i].RawBottomHeight, 3)..' OffsL='..EgtNumToString( TabCut[i].OffsL, 3)..
-- ' SWE='..EgtNumToString( TabCut[i].SWE, 3)..' EWE='..EgtNumToString( TabCut[i].EWE, 3)..
-- ' Interf='..EgtIf( TabCut[i].InterfStart, '0', '1')..','..EgtIf( TabCut[i].InterfEnd, '0', '1'))
--end
-- unisco le lavorazioni allineate (ovviamente sono comprese le coincidenti)
local i = 1
while i <= #TabCut do
-- cerco tutti i tratti allineati e collegabili con questo
local ptStart = TabCut[i].Start
local ptEnd = TabCut[i].End
local vtDir = TabCut[i].Dir
local vtNorm = Vector3d( -vtDir:getY(), vtDir:getX(), vtDir:getZ())
local bInterfS = TabCut[i].InterfStart or TabCut[i].StrictStart
local bInterfE = TabCut[i].InterfEnd or TabCut[i].StrictEnd
local TabJoin = {}
local bIterate = ( EgtGetType( abs( TabCut[i].Ent)) == GDB_TY.CRV_LINE)
while bIterate do
bIterate = false
for j = i + 1, #TabCut do
local bUse = ( EgtGetType( abs( TabCut[j].Ent)) == GDB_TY.CRV_LINE)
for k = 1, #TabJoin do
if j == TabJoin[k] then
bUse = false
end
end
if bUse and ( (( abs( TabCut[i].Ang - TabCut[j].Ang) < GEO.EPS_ANG_SMALL and TabCut[i].Inv == TabCut[j].Inv) or
( abs( TabCut[i].Ang + TabCut[j].Ang) < GEO.EPS_ANG_SMALL and TabCut[i].Inv ~= TabCut[j].Inv)) and
( abs( TabCut[i].RawBottomHeight - TabCut[j].RawBottomHeight) < GEO.EPS_SMALL or TabCut[i].Depth == TabCut[j].Depth) and
AreSameVectorApprox( vtDir, TabCut[j].Dir)) then
-- distanza della seconda retta dalla prima
local dDist2 = max( abs(( TabCut[j].Start - ptStart) * vtNorm), abs(( TabCut[j].End - ptStart) * vtNorm))
-- posizioni dei punti lungo la retta
local dLenS1 = 0
local dLenE1 = ( ptEnd-ptStart) * vtDir
local dLenS2 = ( TabCut[j].Start - ptStart) * vtDir
local dLenE2 = ( TabCut[j].End - ptStart) * vtDir
local bInterfS2 = TabCut[j].InterfStart or TabCut[j].StrictStart
local bInterfE2 = TabCut[j].InterfEnd or TabCut[j].StrictEnd
if dLenE2 < dLenS2 then
dLenS2, dLenE2 = dLenE2, dLenS2
bInterfS2, bInterfE2 = bInterfE2, bInterfS2
end
-- se distanza inferiore a limite e si intersecano abbastanza
if dDist2 < 0.01 and
dLenS2 - TabCut[j].DTI <= dLenE1 + TabCut[i].DT and dLenS1 - TabCut[i].DTI <= dLenE2 + TabCut[j].DT then
-- verifiche su eventuali attacchi/uscite che interferiscono
-- (se non sovrapposti ne basta uno, altrimenti entrambi)
local bJoin = true
if ( dLenE1 < dLenS2 - TabCut[j].DTI and ( bInterfE or bInterfS2)) or
( dLenE1 < dLenS2 and ( bInterfE and bInterfS2)) then
bJoin = false
end
if ( dLenE2 < dLenS1 - TabCut[i].DTI and ( bInterfE2 or bInterfS)) or
( dLenE2 < dLenS1 and ( bInterfE2 and bInterfS)) then
bJoin = false
end
-- se da congiungere
if bJoin then
ptEnd = ptStart + max( dLenE1, dLenE2) * vtDir
ptStart = ptStart + min( dLenS1, dLenS2) * vtDir
if dLenS2 < dLenS1 then
bInterfS = bInterfS2
end
if dLenE2 > dLenE1 then
bInterfE = bInterfE2
end
table.insert( TabJoin, j)
bIterate = true
end
end
end
end
end
-- se ci sono tratti collegabili
if #TabJoin > 0 then
-- modifico la lavorazione principale
EgtSetCurrMachining( TabCut[i].Mch)
-- aggiorno attacco/uscita STRICT
local dDeltaStart = 0
local dDeltaEnd = 0
for j = 1, #TabJoin do
if TabCut[TabJoin[j]].StrictStart then
-- salvo attacco originale, se non già presente
local nOriLeadIn = MCH_SAW_LI.CENT
EgtGetMachiningParam( MCH_MP.LEADINTYPE, nOriLeadIn)
CAM.SaveOriLeadIn( TabCut[i].Mch, nOriLeadIn)
-- eseguo restringimento
TabCut[i].StrictStart = true
EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT)
dDeltaStart = - dDeltaIntCorner
end
if TabCut[TabJoin[j]].StrictEnd then
-- salvo uscita originale, se non già presente
local nOriLeadOut = MCH_SAW_LO.CENT
EgtGetMachiningParam(MCH_MP.LEADOUTTYPE, nOriLeadOut)
CAM.SaveOriLeadOut( TabCut[i].Mch, nOriLeadOut)
-- eseguo restringimento
TabCut[i].StrictEnd = true
EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT)
dDeltaEnd = - dDeltaIntCorner
end
end
-- aggiorno allungamenti
local dStartAll = dist( ptStart, TabCut[i].Start)
local dEndAll = dist( TabCut[i].End, ptEnd)
if dStartAll > 10 * GEO.EPS_SMALL then
EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAll + dDeltaStart)
end
if dEndAll > 10 * GEO.EPS_SMALL then
EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAll + dDeltaEnd)
end
-- aggiorno allungamenti baffi
local dSWE = TabCut[i].SWE
local dMinStartDist = dStartAll
for j = 1, #TabJoin do
local dStartDist = dist( ptStart, TabCut[TabJoin[j]].Start)
if dStartDist < dMinStartDist then
dMinStartDist = dStartDist
dSWE = TabCut[TabJoin[j]].SWE
end
end
local dEWE = TabCut[i].EWE
local dMinEndDist = dEndAll
for j = 1, #TabJoin do
local dEndDist = dist( ptEnd, TabCut[TabJoin[j]].End)
if dEndDist < dMinEndDist then
dMinEndDist = dEndDist
dEWE = TabCut[TabJoin[j]].EWE
end
end
CAM.SetWhiskExtends( dSWE, dEWE)
-- salvo in lavorazione principale gli identificativi delle lavorazioni da eliminare
local sInfo = ''
for j = 1, #TabJoin do
local OthMchId = TabCut[TabJoin[j]].Mch
local sSubInfo = EgtGetInfo( OthMchId, 'OthMIds')
if sSubInfo then
sInfo = sInfo .. sSubInfo .. ','
EgtRemoveInfo( OthMchId, 'OthMIds')
end
sInfo = sInfo .. tostring( OthMchId) .. ','
end
EgtSetInfo( TabCut[i].Mch, 'OthMIds', string.sub(sInfo,1,-2))
-- elimino le lavorazioni allineate (devo essere sicuro di farlo dalla fine, per questo ordino)
table.sort( TabJoin)
for j = #TabJoin, 1, -1 do
CAM.DeactivateMachining( TabCut, TabJoin[j])
end
-- aggiorno gli estremi in tabella
TabCut[i].Start = ptStart
TabCut[i].End = ptEnd
end
-- passo alla successiva lavorazione
i = i + 1
end
-- log dei dati per debug
--EgtOutLog( 'Dati lavorazioni dopo unione :')
--for i = 1, #TabCut do
-- EgtOutLog( 'SawId='..tostring( TabCut[i].Mch)..' GeoId='..tostring( TabCut[i].Ent)..
-- ' Start='..tostring( TabCut[i].Start)..' End='..tostring( TabCut[i].End)..' Dir='..tostring( TabCut[i].Dir))
--end
-- ordino le lavorazioni
--EgtOutLog('Dati per ShortestPath :')
EgtSpInit()
for i = 1, #TabCut do
local AngH = atan2( TabCut[i].Dir:getY(), TabCut[i].Dir:getX()) + 270
if AngH > 180.1 then
AngH = AngH - 360
elseif AngH < - 180.1 then
AngH = AngH + 360
end
if bIsMultiCut then
if abs( TabCut[i].Dir:getX()) > abs( TabCut[i].Dir:getY()) then
AngH = AngH + 10 * ( dAngRotMultiCut + dOffsAxisBlock)
else
AngH = AngH + 10 * ( 0 + dOffsAxisBlock)
end
end
local AngV = 90 - abs( TabCut[i].Ang)
local dExtraZ = 40000
if TabCut[i].RawBottomHeight > 1.0 then
dExtraZ = 0
elseif abs( TabCut[i].Ang) > GEO.EPS_ANG_SMALL then
dExtraZ = 10000
end
local ptS = TabCut[i].Start + Z_AX() * dExtraZ
local ptE = TabCut[i].End + Z_AX() * dExtraZ
EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), AngH, AngV,
ptE:getX(), ptE:getY(), ptE:getZ(), AngH, AngV)
--EgtOutLog('Start=('..tostring( ptS)..'),'..tostring( AngH)..','..tostring( AngV)..
-- ' End=('..tostring( ptE)..'),'..tostring( AngH)..','..tostring( AngV))
end
EgtSpSetAngularParams( 1000, 40, 2000, 60)
EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -6000, 0, EgtIf( bCutLongDxSx, 90, -90), 90)
local vOrd = EgtSpCalculate( SHP_TY.OPEN)
EgtSpTerminate()
-- applico ordinamento calcolato
if vOrd then
for i = 1, #vOrd do
EgtRelocateGlob( TabCut[vOrd[i]].Mch, LastMch, GDB_IN.AFTER)
LastMch = TabCut[vOrd[i]].Mch
end
end
-- disabilito le lavorazioni dichiarate tali dall'utente
for i = 1, #TabCut do
if EgtExistsInfo( TabCut[i].Mch, 'UserOff') then
EgtSetOperationMode( TabCut[i].Mch, false)
end
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function SortMills( nPhase, LastMch, sLay, sInfo)
-- dichiarazione tabella
local TabMill = {}
-- recupero le fresature e i loro centri
local nMillId = EgtGetNextOperation( LastMch)
while nMillId do
-- Se appartiene alla fase corrente e fresatura non vuota del layer voluto e con info voluta
if EgtGetOperationPhase( nMillId) == nPhase and EgtGetOperationType( nMillId) == MCH_OY.MILLING and
( not sLay or sLay == '' or EgtGetInfo( nMillId, 'Lay') == sLay) and
( not sInfo or EgtExistsInfo( nMillId, sInfo)) then
-- recupero preview
local nPvId = EgtGetInfo( EgtGetFirstNameInGroup( nMillId, 'PV'), 'PvId', 'i')
if nPvId then
local Box = EgtGetBBoxGlob( nPvId, GDB_BB.STANDARD)
if Box then
if not Box:isEmpty() then
table.insert( TabMill, {Id=nMillId, Cen=Box:getCenter()})
end
end
end
end
nMillId = EgtGetNextOperation( nMillId)
end
-- calcolo ordinamento
EgtSpInit()
for i = 1, #TabMill do
EgtSpAddPoint( TabMill[i].Cen:getX(), TabMill[i].Cen:getY())
end
EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -4000, 0, 90, 90)
local vMillOrd = EgtSpCalculate( SHP_TY.OPEN)
EgtSpTerminate()
-- applico ordinamento calcolato
-- parto da LastMch precedente
if vMillOrd then
for i = 1, #vMillOrd do
EgtRelocateGlob( TabMill[vMillOrd[i]].Id, LastMch, GDB_IN.AFTER)
LastMch = TabMill[vMillOrd[i]].Id
end
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function SortDrills( nPhase, LastMch, sLay)
-- dichiarazione tabella
local TabDri = {}
-- recupero le forature e i loro centri
local nDrillId = EgtGetPhaseDisposition( nPhase)
while nDrillId do
-- Se appartiene alla fase corrente e foratura non vuota del layer voluto
if EgtGetOperationPhase( nDrillId) == nPhase and EgtGetOperationType( nDrillId) == MCH_OY.DRILLING and
( not sLay or EgtGetInfo( nDrillId, 'Lay') == sLay) then
-- recupero preview
local nPvId = EgtGetInfo( EgtGetFirstNameInGroup( nDrillId, 'PV'), 'PvId', 'i')
if nPvId then
local Box = EgtGetBBoxGlob( nPvId, GDB_BB.STANDARD)
if Box then
if not Box:isEmpty() then
table.insert( TabDri, {Id=nDrillId, Cen=Box:getCenter()})
end
end
end
end
nDrillId = EgtGetNextOperation( nDrillId)
end
-- calcolo ordinamento
EgtSpInit()
for i = 1, #TabDri do
EgtSpAddPoint( TabDri[i].Cen:getX(), TabDri[i].Cen:getY())
end
local vDriOrd = {}
if not sLay or sLay ~= 'UnderDrill' then
EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -4000, 0, 90, 90)
vDriOrd = EgtSpCalculate( SHP_TY.OPEN)
else
EgtSpSetZzOwStep( 4000)
vDriOrd = EgtSpCalculate( SHP_TY.ONEWAY_YM)
end
EgtSpTerminate()
-- applico ordinamento calcolato
-- parto da LastMch precedente
if vDriOrd then
for i = 1, #vDriOrd do
EgtRelocateGlob( TabDri[vDriOrd[i]].Id, LastMch, GDB_IN.AFTER)
LastMch = TabDri[vDriOrd[i]].Id
end
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function SortPockets( nPhase, LastMch)
-- dichiarazione tabella
local TabPock = {}
-- Recupero gli identificativi delle lavorazioni
local nOperId = EgtGetPhaseDisposition( nPhase)
while nOperId do
-- Se appartiene alla fase corrente e svuotatura
if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == MCH_OY.POCKETING then
table.insert( TabPock, {Id=nOperId})
end
nOperId = EgtGetNextOperation( nOperId)
end
-- Inserisco le lavorazioni in coda
for i = 1, #TabPock do
EgtRelocateGlob( TabPock[i].Id, LastMch, GDB_IN.AFTER)
LastMch = TabPock[i].Id
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function SortWaterJets( nPhase, LastMch, sLay)
-- dichiarazione tabella
local TabWj = {}
-- recupero i tagli ad acqua e i loro centri
local nWjId = EgtGetPhaseDisposition( nPhase)
while nWjId do
-- Se appartiene alla fase corrente e taglio ad acqua non vuoto del layer voluto
if EgtGetOperationPhase( nWjId) == nPhase and EgtGetOperationType( nWjId) == MCH_OY.WATERJETTING and
( not sLay or EgtGetInfo( nWjId, 'Lay') == sLay) then
-- imposto come lavorazione corrente
EgtSetCurrMachining( nWjId)
-- cerco il gruppo di preview
local nMchPvId = EgtGetFirstNameInGroup( nWjId, 'PV')
local nGeoPvId = EgtGetInfo( nMchPvId or GDB_ID.NULL, 'PvId', 'i')
local nP1PvId = EgtGetFirstNameInGroup( nGeoPvId or GDB_ID.NULL, 'P1')
if nP1PvId then
local ptStart = EgtGetInfo( nP1PvId, 'START', 'p')
local ptEnd = EgtGetInfo( nP1PvId, 'END', 'p')
local dAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE)
table.insert( TabWj, {Id=nWjId, Start=ptStart, End=ptEnd, Ang=abs( dAng)})
end
end
nWjId = EgtGetNextOperation( nWjId)
end
-- se non ci sono lavorazioni waterjet, esco
if #TabWj == 0 then
return LastMch
end
-- log dei dati lavorazioni per debug
--EgtOutLog( 'Dati lavorazioni :')
--for i = 1, #TabWj do
-- EgtOutLog( 'WjId='..tostring( TabWj[i].Id)..
-- ' Start='..tostring( TabWj[i].Start)..' End='..tostring( TabWj[i].End)..' Ang='..EgtNumToString( TabWj[i].Ang, 3))
--end
-- calcolo ordinamento
EgtSpInit()
for i = 1, #TabWj do
EgtSpAddPoint( TabWj[i].Start:getX(), TabWj[i].Start:getY(), 0, 0, TabWj[i].Ang,
TabWj[i].End:getX(), TabWj[i].End:getY(), 0, 0, TabWj[i].Ang)
end
EgtSpSetAngularParams( 1000, 40, 2000, 60)
local dSpStartX = 0
local dSpStartY = -4000
if bWaterJetOptimize then
for i = 1, #TabWj do
if ( AreSamePointEpsilon( TabWj[i].Start, TabWj[i].End, 1)) then
dSpStartX = TabWj[i].Start:getX()
dSpStartY = TabWj[i].Start:getY()
break
end
end
end
EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, dSpStartX, dSpStartY, 0, 0, 90)
vWjOrd = EgtSpCalculate( SHP_TY.OPEN)
EgtSpTerminate()
-- log dell'ordinamento per debug
--if vWjOrd then
-- EgtOutLog( 'Ordinamento :'..table.concat( vWjOrd, ','))
--end
-- applico ordinamento calcolato
-- parto da LastMch precedente
if vWjOrd then
for i = 1, #vWjOrd do
EgtRelocateGlob( TabWj[vWjOrd[i]].Id, LastMch, GDB_IN.AFTER)
LastMch = TabWj[vWjOrd[i]].Id
end
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function SortOnCuts( nPhase, LastMch)
-- dichiarazione tabella
local TabCut = {}
-- Recupero gli identificativi delle lavorazioni
local nOperId = EgtGetPhaseDisposition( nPhase)
while nOperId do
-- Se appartiene alla fase corrente e taglio con lama sopra (sempre su 1 sola entità)
if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == MCH_OY.SAWING and
EgtGetInfo( nOperId, 'Lay') == 'OnPath' then
table.insert( TabCut, {Id=nOperId})
end
nOperId = EgtGetNextOperation( nOperId)
end
-- Inserisco le lavorazioni in coda
for i = 1, #TabCut do
EgtRelocateGlob( TabCut[i].Id, LastMch, GDB_IN.AFTER)
LastMch = TabCut[i].Id
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function SortDripCuts( nPhase, LastMch)
-- dichiarazione tabella
local TabCut = {}
-- Recupero gli identificativi delle lavorazioni
local nOperId = EgtGetPhaseDisposition( nPhase)
while nOperId do
-- Se appartiene alla fase corrente e taglio con lama da sotto (sempre su 1 sola entità)
if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == MCH_OY.SAWING and
EgtGetInfo( nOperId, 'Lay') == 'Drip' then
table.insert( TabCut, {Id=nOperId})
end
nOperId = EgtGetNextOperation( nOperId)
end
-- Inserisco le lavorazioni in coda
for i = 1, #TabCut do
EgtRelocateGlob( TabCut[i].Id, LastMch, GDB_IN.AFTER)
LastMch = TabCut[i].Id
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function SortDripDrills( nPhase, LastMch)
-- dichiarazione tabella
local TabDri = {}
-- recupero le forature e i loro centri
local nDrillId = EgtGetPhaseDisposition( nPhase)
while nDrillId do
-- Se appartiene alla fase corrente e foratura
if EgtGetOperationPhase( nDrillId) == nPhase and EgtGetOperationType( nDrillId) == MCH_OY.DRILLING and
EgtGetInfo( nDrillId, 'Lay') == 'UnderDrill' then
-- recupero pezzo
local nPartId = EgtGetParent( EgtGetParent( CAM.GetEntIdFromMachining( nDrillId)))
-- recupero preview
local nPvId = EgtGetInfo( EgtGetFirstNameInGroup( nDrillId, 'PV'), 'PvId', 'i')
if nPvId then
local Box = EgtGetBBoxGlob( nPvId, GDB_BB.STANDARD)
if Box and not Box:isEmpty() then
table.insert( TabDri, {Id=nDrillId, Part=nPartId, Cen=Box:getCenter()})
end
end
end
nDrillId = EgtGetNextOperation( nDrillId)
end
-- Eseguo ottimizzazione per pezzo
while #TabDri > 0 do
-- riunisco i fori di uno stesso pezzo
local nCurrPartId = TabDri[1].Part
local TabPrtDri = {}
local i = 1
while i <= #TabDri do
if TabDri[i].Part == nCurrPartId then
table.insert( TabPrtDri, TabDri[i])
table.remove( TabDri, i)
else
i = i + 1
end
end
-- calcolo ordinamento
EgtSpInit()
for i = 1, #TabPrtDri do
EgtSpAddPoint( TabPrtDri[i].Cen:getX(), TabPrtDri[i].Cen:getY())
end
local vDriOrd = {}
EgtSpSetZzOwStep( 4000)
vDriOrd = EgtSpCalculate( SHP_TY.ONEWAY_YM)
EgtSpTerminate()
-- Inserisco le lavorazioni ordinate in coda
for i = 1, #vDriOrd do
EgtRelocateGlob( TabPrtDri[vDriOrd[i]].Id, LastMch, GDB_IN.AFTER)
LastMch = TabPrtDri[vDriOrd[i]].Id
end
end
return LastMch
end
--
-------------------------------------------------------------------------------
local function VerifyDripMachinings( nPhase)
local nOperId = EgtGetNextOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL)
while nOperId do
-- Se appartiene alla fase corrente e lavorazione da sotto
if EgtGetOperationPhase( nOperId) == nPhase and
( EgtGetInfo( nOperId, 'Lay') == 'Drip' or EgtGetInfo( nOperId, 'Lay') == 'UnderDrill') then
return true
end
nOperId = EgtGetNextOperation( nOperId)
end
return false
end
--
-------------------------------------------------------------------------------
function CAM.Sort()
EgtOutLog( 'CAM.Sort ' .. CAMAUTO_VER)
-- Recupero la fase corrente
local nPhase = EgtGetCurrPhase()
local LastMch = EgtGetPhaseDisposition( nPhase)
-- Verifico se ci sono lavorazioni da sotto
local bDrips = VerifyDripMachinings( nPhase)
-- Ordinamento senza lavorazioni da sotto
if not bDrips then
-- Ordino le svuotature ---------
LastMch = SortPockets( nPhase, LastMch)
-- Ordino le fresature ----------
LastMch = SortMills( nPhase, LastMch, 'InLoop', 'FiloTop')
LastMch = SortMills( nPhase, LastMch)
-- Ordino le forature ----------
LastMch = SortDrills( nPhase, LastMch)
-- Ordino i tagli ----------
LastMch = SortCuts( nPhase, LastMch)
LastMch = SortOnCuts( nPhase, LastMch)
-- Ordino i water jet
LastMch = SortWaterJets( nPhase, LastMch)
-- Ordinamento con lavorazioni da sotto
else
-- Ordino i tagli esterni ----------
LastMch = SortCuts( nPhase, LastMch, 'OutLoop')
-- Ordino le fresature esterne ----------
LastMch = SortMills( nPhase, LastMch, 'OutLoop')
-- Ordino le forature esterne ----------
LastMch = SortDrills( nPhase, LastMch, 'OutLoop')
-- Ordino i water jet esterni ----------
LastMch = SortWaterJets( nPhase, LastMch, 'OutLoop')
-- Ordino i tagli da sotto ----------
LastMch = SortDripCuts( nPhase, LastMch)
-- Ordino le forature da sotto ----------
LastMch = SortDripDrills( nPhase, LastMch)
-- Ordino le svuotature ---------
LastMch = SortPockets( nPhase, LastMch)
-- Ordino le fresature interne ----------
LastMch = SortMills( nPhase, LastMch, 'InLoop', 'FiloTop')
LastMch = SortMills( nPhase, LastMch, 'InLoop')
LastMch = SortMills( nPhase, LastMch, 'OnPath')
-- Ordino le forature interne ----------
LastMch = SortDrills( nPhase, LastMch, 'InLoop')
-- Ordino i tagli interni ----------
LastMch = SortCuts( nPhase, LastMch, 'InLoop')
-- Ordino i tagli da sopra ----------
LastMch = SortOnCuts( nPhase, LastMch)
-- Ordino i water jet interni ----------
LastMch = SortWaterJets( nPhase, LastMch, 'InLoop')
end
end
------ Esecuzione SpecialApply su specifica Disposizione -------
function CAM.SpecApplyDisp()
EgtOutLog( 'CAM.SpecApplyDisp ' .. CAMAUTO_VER)
-- Eseguo
CAM.MultiCutDispositionSettings( CAM.DISPID)
if not EgtSpecialApplyDisposition( CAM.DISPID, CAM.RECALC) then
CAM.ERR = 72
end
end