From e1c303a5c674c5def5b1c9e66becc75d02f1be40 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 19 Jan 2026 11:05:44 +0100 Subject: [PATCH] CamAuto 3.1a1 : - corretta gestione altezza taglio finale per tagli senza impostazione ultimo step. --- CamAuto.lua | 5785 +++++++++++++++++++++++++++++++++++++++++++++++++ Polishing.lua | 242 +++ README.md | 93 - 3 files changed, 6027 insertions(+), 93 deletions(-) create mode 100644 CamAuto.lua create mode 100644 Polishing.lua delete mode 100644 README.md diff --git a/CamAuto.lua b/CamAuto.lua new file mode 100644 index 0000000..381af89 --- /dev/null +++ b/CamAuto.lua @@ -0,0 +1,5785 @@ +-- 2026/01/12 18: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 = modificiati parametri di lavorazione + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Versione +local CAMAUTO_VER = 'ver 3.1a1' + +-- 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') + +-- parametri **PreForo** WaterJet +local bHoleWj = ( EgtGetStringFromIni( 'Nest', 'DrillingWJOnCorners', '0', sMachIni) == '1') +local dHoleDiamWj = tonumber( EgtGetStringFromIni( 'Nest', 'HolesDiameterWJ', '5', sMachIni)) +local dOffsetHoleWj = tonumber( EgtGetStringFromIni( 'Nest', 'HolesOffsetWJ', '5', sMachIni)) +-- minimo raggio raccordo (se entità arco ha un raggio maggiore non esegue il preforo) +local dMinRadiusWj = tonumber( EgtGetStringFromIni( 'Nest', 'MinRadiusWJ', '5', sMachIni)) + +-- parametri **Rectification** WaterJet +local bRectificationWj = ( EgtGetStringFromIni( 'Nest', 'RectificationSubSqWJ', '0', sMachIni) == '1') +local dOffsetRectificationWj = tonumber( EgtGetStringFromIni( 'Nest', 'OffsetRectificationWJ', '0', sMachIni)) +local dMaxAngRectificationWj = tonumber( EgtGetStringFromIni( 'Nest', 'MinAngRectificationWJ', '-45', sMachIni)) + +-- 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 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) + local nCountHeel = 0 + local nCountRect = 0 + local bExists = false + + if #MyTabRtf > 0 then + -- recupero l'ID del part + local PartId = EgtGetParent( EgtGetParent( MyTabRtf[1][1])) + local RtfLay = EgtGetFirstNameInGroup( PartId, 'WjRectification') + if RtfLay then bExists = true end + end + + for index = 1 , #MyTabRtf do + + --[[ 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 nEntId = MyTabRtf[index][1] + local _, Heel = CAM.GetHeel( nEntId) + local _, dOffset = CAM.GetOffset( nEntId, 2) + local _, dSideAng = CAM.GetSideAng( nEntId, 2) + + if bExists then + if MyTabRtf[index][2] == 0 then + table.insert( TabOutCrv, nRtfId) + else + table.insert( TabInCrv, nRtfId) + end + else + -- Se è stato definito un Heel allora IGNORO la rettifica + if Heel > 0 then + EgtOutLog('Nuova gestione rettifica tagli inclinati con WJ') + nCountHeel = nCountHeel + 1 + -- costruisco i layers + local ParentId = EgtGetParent( nEntId) + ParentId = EgtGetParent( ParentId) + -- recupero il primo Layer con nome 'WjRectification', altrimenti lo creo + local RtfLay = EgtGetFirstNameInGroup( ParentId, 'WjRectification') + if not RtfLay then + RtfLay = EgtGroup( ParentId, GDB_RT.GLOB) + EgtSetName( RtfLay, 'WjRectification') + end + -- copio l'entità e aggiorno le info del secondo taglio da applicare + local nRtfId = EgtCopyGlob( nEntId, RtfLay) + -- rimuovo da entrambe le entità le info SideAng2 e Offset2 per aggiornare le info SindeAng e Offset + EgtRemoveInfo( nRtfId, 'SideAng2') + EgtRemoveInfo( nRtfId, 'Offset2') + -- indico il valore di SideAng del taglio ( + EgtSetInfo( nRtfId, 'SideAng', dSideAng, num) + + -- azzero offset (perchè mi preoccupo di applicarlo veramente) + EgtSetInfo( nRtfId, 'Offset', 0, num) + -- applico offset + EgtOffsetCurve( nRtfId, -dOffset, GDB_OT.FILLET) + -- estendo le curve della quantità calcolata + local swe = EgtGetInfo( nRtfId, 'SWE') or 0 + local ewe = EgtGetInfo( nRtfId, 'EWE') or 0 + + local dDir = 1 + -- if dSideAng < 0 then + -- dDir = -1 + -- end + + EgtExtendCurveStartByLen( nRtfId, dDir*swe) + EgtExtendCurveEndByLen( nRtfId, dDir*ewe) + EgtRemoveInfo( nRtfId, 'SWE') + EgtRemoveInfo( nRtfId, 'EWE') + + -- azzero offset (perchè mi preoccupo di applicarlo veramente) + local _, dOffset1 = CAM.GetOffset( nEntId) + EgtSetInfo( nEntId, 'Offset', 0, num) + -- applico offset + EgtOffsetCurve( nEntId, dOffset1, GDB_OT.FILLET) + + -- -- indico il valore di Offset del taglio + -- EgtSetInfo( nRtfId, 'Offset', dOffset, num) + + -- local vtDir = EgtMV( nRtfId, GDB_ID.ROOT) + -- vtDir:rotate( Z_AX(), -90) + -- local x1 = EgtSplitCurve( nRtfId, 2) + -- local x2 = x1 + 1 + -- EgtExtendCurveEndByLen( x1, -10) + -- EgtTrimCurveStartAtLen( x2, 10) + -- local l1 = EgtLinePVL( RtfLay, EgtEP( x1, GDB_ID.ROOT), vtDir, 100, GDB_ID.ROOT) + -- local l2 = EgtLinePVL( RtfLay, EgtSP( x2, GDB_ID.ROOT), vtDir, 100, GDB_ID.ROOT) + -- EgtInvertCurve( { l2}) + -- l1 = EgtCurveCompo( RtfLay, {x1, l1}) + -- l2 = EgtCurveCompo( RtfLay, {l2, x2}) + + -- assego l'entità appena creata alla tabella delle entità da lavorare + if MyTabRtf[index][2] == 0 then + table.insert( TabOutCrv, nRtfId) + -- table.insert( TabOutCrv, l1) + -- table.insert( TabOutCrv, l2) + else + table.insert( TabInCrv, nRtfId) + end + + elseif bRectificationWj then + -- solo per tagli in sotto squadra (anche se angolo dMax impostato positivo)! + if dSideAng < 0 and math.abs( dSideAng) < math.abs( dMaxAngRectificationWj) then + nCountRect = nCountRect + 1 + -- **costruisco i layers** + local ParentId = EgtGetParent( nEntId) + ParentId = EgtGetParent( ParentId) + -- recupero il primo Layer con nome 'WjRectification', altrimenti lo creo + local RtfLay = EgtGetFirstNameInGroup( ParentId, 'WjRectification') + if not RtfLay then + RtfLay = EgtGroup( ParentId, GDB_RT.GLOB) + EgtSetName( RtfLay, 'WjRectification') + end + -- ivi copio l'entità e aggiorno le info del secondo taglio da applicare + local nRtfId = EgtCopyGlob( nEntId, RtfLay) + EgtRemoveInfo( nRtfId, 'SideAng') + EgtSetInfo( nRtfId, 'Offset', dMaxAngRectificationWj, num) + + if MyTabRtf[index][2] == 0 then + table.insert( TabOutCrv, nRtfId) + else + table.insert( TabInCrv, nRtfId) + end + end + + end + end + end + if nCountHeel >0 and nCountRect >0 then + EgtOutLog('ATTENZIONE: esistono tagli di rettifica (bRectificationWj) e con Heel nello stsso progetto!') + 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 angolo + -- if sWaterJet ~= '' and ( CAM.GetSideAngNotNull( nEntId) or nType == GDB_TY.CRV_ARC) then + -- (ver 2.7e1) + if sWaterJet ~= '' and ( CAM.GetHeelNotNull( nEntId) or nType == GDB_TY.CRV_ARC) 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 sWaterJet ~= "")) + 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 angolo o arco + -- if sWaterJet ~= '' and ( CAM.GetSideAngNotNull( nEntId) or nType == GDB_TY.CRV_ARC) then + -- (ver 2.7e1) + if sWaterJet ~= '' and ( CAM.GetHeelNotNull( nEntId) or nType == GDB_TY.CRV_ARC) 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 + + -- prima di passare al layer successivo verifico se inserire delle lavorazioni di tipo fori + if bHoleWj and sWaterJet ~= '' then + for index = 1 , #MyTabInLoop do + local nEntId = MyTabInLoop[index] + -- **verifico se esistono i presupposti per creare un foro** + local nType_1 = EgtGetType(nEntId) + local ptEnd_1 = EgtEP( nEntId, GDB_ID.ROOT) + local nType_2 + local ptStr_2 + local bMakeHole = false + local _, NextAng = CAM.GetNextAngle( nEntId) + -- solo spigolo concavo (in questa sezione valutare la dimensione dell'angolo per inserire il foro) + --if NextAng < 0 then + -- bMakeHole = true + --end + -- riconosco il tipo di entità + if index == #MyTabInLoop then + nType_2 = EgtGetType(MyTabInLoop[1]) + ptStr_2 = EgtSP( MyTabInLoop[1], GDB_ID.ROOT) + else + nType_2 = EgtGetType(MyTabInLoop[index+1]) + ptStr_2 = EgtSP( MyTabInLoop[index+1], GDB_ID.ROOT) + end + -- Se retta e retta + if nType_1 == GDB_TY.CRV_LINE and nType_2 == GDB_TY.CRV_LINE and AreSamePointExact( ptEnd_1, ptStr_2) then + bMakeHole = true + -- Se arco e retta + elseif nType_1 == GDB_TY.CRV_ARC and nType_2 == GDB_TY.CRV_LINE and AreSamePointExact( ptEnd_1, ptStr_2) then + if EgtArcRadius( nEntId) >= dMinRadiusWj then + bMakeHole = false + else + bMakeHole = true + end + end + -- **Procedo alla costruzione del foro** + if bMakeHole then + local InfoArc = {} + -- **costruisco i layers** + local ParentId = EgtGetParent( nEntId) + ParentId = EgtGetParent( ParentId) + local OutLoopLay = EgtGroup( ParentId, GDB_RT.GLOB) + EgtSetName( OutLoopLay, "WjDrill") + local RegionLay = EgtGroup( ParentId, GDB_RT.GLOB) + EgtSetName( RegionLay, "RegionWjDrill") + -- **recupero le info per il posizionamento** del foro + local ptEndEnt = EgtEP( nEntId, GDB_ID.ROOT) + local vtEndEnt = EgtEV( nEntId, GDB_ID.ROOT) + local dDelta = 0 + -- se di tipo arco, verifico se il foro è tangente all'arco oppure ai lati del lavello + local bIgnoreArc = false + if nType_1 == GDB_TY.CRV_ARC then + ptEndEnt = EgtMP( nEntId, GDB_ID.ROOT) + vtEndEnt = EgtMV( nEntId, GDB_ID.ROOT) + -- se il raggio dell'arco è minore del foro + local dRadius = EgtArcRadius( nEntId) + if dRadius < dHoleDiamWj/2 then + bIgnoreArc = true + local dAngCenter = EgtArcAngCenter( nEntId) + NextAng = ( -90 + math.abs( dAngCenter/2)) *2 + -- distanza tra il punto medio dell'arco e il punto di intersezione dei lati tangenti all'arco + dDelta = dRadius / cos( dAngCenter/2) - dRadius + end + end + -- **disegno il foro** + local Diam = dHoleDiamWj + local OffsetArc = dOffsetHoleWj + -- costruisco l'entità circonferenza e cerchio e li posiziono sulla bisettrice dell'angolo + local nEntArc = EgtCircle( OutLoopLay, ptEndEnt, Diam/2) + local nCirc = EgtSurfFlatRegion( RegionLay, nEntArc) + EgtSetColor( nCirc, 'RED') + EgtSetAlpha( nCirc, 60) + EgtInvertCurve( nEntArc) + -- **posiziono il foro** + if nType_1 == GDB_TY.CRV_ARC and not bIgnoreArc then + vtEndEnt:rotate( Z_AX(), -90) + Lenght = Diam/2 + OffsetArc - dDelta + elseif nType_1 == GDB_TY.CRV_ARC and bIgnoreArc then + vtEndEnt:rotate( Z_AX(), 90) + Lenght = ( Diam/2 + OffsetArc) / sin( NextAng/2) + dDelta + else + -- determino l'angolo compreso tra le due entità + NextAng = -180 - NextAng + vtEndEnt:rotate( Z_AX(), -NextAng/2) + Lenght = ( Diam/2 + OffsetArc) / sin( NextAng/2) + end + EgtMove( { nEntArc, nCirc}, vtEndEnt*Lenght, GDB_RT.GLOB) + -- definisco il punto di inizio della lavorazione opposta all'angolo + local ptStart = EgtCP( nEntArc, GDB_ID.ROOT) + vtEndEnt*Lenght + EgtSetInfo( OutLoopLay, "Start", ptStart) + table.insert( TabInCrv, nEntArc) + end + end + MyTabInLoop = {} + end + + -- Passo al layer successivo + nInLayId = EgtGetNextName( nInLayId, 'InLoop') + end + + -- prima di passare al layer successivo verifico se la rettifica dei tagli inclinati + if sWaterJet ~= '' then + + SquaringWJ( MyTabRtf, TabOutCrv, TabInCrv) + + -- for index = 1 , #MyTabRtf do + -- local nEntId = MyTabRtf[index][1] + -- -- verifico se esiste un lato inclinato e se è stato inseriot il parametro Heel + -- local _, SideAng = CAM.GetSideAng( nEntId, 2) + -- if SideAng < dMaxAngRectificationWj then + -- -- **costruisco i layers** + -- local ParentId = EgtGetParent( nEntId) + -- ParentId = EgtGetParent( ParentId) + -- local RtfLay = EgtGroup( ParentId, GDB_RT.GLOB) + -- EgtSetName( RtfLay, 'WjRectification') + -- local nRtfId = EgtCopyGlob( nEntId, RtfLay) + -- EgtRemoveInfo( nRtfId, 'SideAng') + -- EgtSetInfo( nRtfId, 'Offset', dMaxAngRectificationWj, num) + -- + -- local ptStr = EgtSP( nEntId, GDB_ID.ROOT) + -- local ptEnd = EgtEP( nEntId, GDB_ID.ROOT) + -- EgtOutLog(' ENT: '..tostring(nEntId)) + -- EgtOutLog(' st: '..tostring(ptStr[1])..','..tostring(ptStr[2])) + -- EgtOutLog(' en: '..tostring(ptEnd[1])..','..tostring(ptEnd[2])) + -- + -- if MyTabRtf[index][2] == 0 then + -- table.insert( TabOutCrv, nRtfId) + -- else + -- table.insert( TabInCrv, nRtfId) + -- end + -- end + -- end + + MyTabRtf = {} + 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( 'Taglio '..tostring(nSaw)..' su angolo interno: nuova gestione') + 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('Taglio '..tostring(nSaw)..' ridotto: interferenza con altri pezzi') + 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('Taglio '..tostring(nSaw)..' da rinifinire con fresa') + 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[i]) + 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( math.abs(PrevSideAng)) + -- Impronta lama : SawThickness/cos(math.abs(NextSideAng)) + -- **SOPRA SQUDRA** + if PrevSideAng > 0 and bSizeAlwaysOnTop then + dStartAddLen = -dExtraLen + EgtOutLog('Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOPRA SQUDRA)') + -- **SOTTO SQUDRA** + 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(math.abs(PrevSideAng)) + end + EgtOutLog('Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOTTO SQUDRA)') + + 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( math.abs(NextSideAng)) + -- Impronta lama : SawThickness/cos(math.abs(NextSideAng)) + -- **SOPRA SQUDRA** + if NextSideAng > 0 and bSizeAlwaysOnTop then + dEndAddLen = -dExtraLen + EgtOutLog('Allungo USCITA fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOPRA SQUDRA)') + -- **SOTTO SQUDRA** + 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(math.abs(NextSideAng)) + end + EgtOutLog('Allungo USCITA fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOTTO SQUDRA)') + + elseif (NextSideAng < 0 or NextSideAng > 0) and not bSizeAlwaysOnTop then + dEndAddLen = -dRawHeight/tan( math.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 + -- preparo tabella con info circonferenze preforo + local TabEntPreDrill = {} + + local TabMPartC = {} + -- questa tabella contiene l'indice della tabella sopra che devono esseere ricopiate + local TabMNewPartC = {} + -- 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.GetIfJoinEntity( 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.GetIfJoinEntity( 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 + -- if JoinWater and RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then + -- RecMPartC.Join = true + -- else + -- RecMPartC.Join = ( Join ~= 0) + -- end + table.insert( TabMPartC, RecMPartC) + end + end + end + -- FINE: Preparo tabella info tagli parziali, solo se tipo operazione **MCH_OY.SAWING** + + -- |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 coincidono e angoli coincidono e non positivi + -- (tolti i positivi il 2021/03/24 per fare rettangoli con lati indipendenti anche con misure sul top) + if AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL) and + abs( RecMPartC.SideAng - RecMPartC2.SideAng) < 10 * GEO.EPS_ANG_SMALL then + --and ( not bSizeAlwaysOnTop or RecMPartC.SideAng <= 10 * GEO.EPS_ANG_SMALL) then + RecMPartC.PrevInd = j + RecMPartC2.NextInd = i + break + 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).. + ', StartStrict='..tostring(RecMPartC.StartStrict)..', EndStrict='..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).. + ', PrevInd='..tostring(RecMPartC.PrevInd)..', NextInd='..tostring(RecMPartC.NextInd).. + ', StartDone='..tostring(RecMPartC.StartDone)..', EndDone='..tostring(RecMPartC.EndDone).. + ', Double='..tostring(RecMPartC.Double)..', Width='..EgtNumToString(RecMPartC.Width,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 nMill = EgtAddMachining( 'Waterjet' .. tostring( RecMPartCs.EntId) .. '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 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 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'), RecMPartCs.EntId) + -- 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'), RecMPartCs.EntId) + -- 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 nMill = EgtAddMachining( 'Waterjet'..tostring(RecMPartC.EntId)..'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 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 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'), RecMPartC.EntId) + -- 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'), RecMPartC.EntId) + -- 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) + 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 nMill = EgtAddMachining( 'Waterjet'..tostring(RecMPartC.EntId)..'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'), RecMPartC.EntId) + + -- 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 nMill = EgtAddMachining( 'Waterjet'..tostring(RecMPartC.EntId)..'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'), RecMPartC.EntId) + + -- 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** (solo per contorni esterni) + local TabBridges = {} + if sLay == 'OutLoop' or sLay == 'PartStart' 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 + print(' -- WJ BRIDGE -- ELIMINO LAVORAZIONI PER CREARE COLLEGAMENTO') + -- elimino lavorazione collegata + CAM.ErasePreviewInPiece( WjOtherId, TabBridges[BriInd][sOtherPart]) + 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 + EgtDraw() + 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 = math.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 Depth = EgtGetInfo( LayId, 'Depth') + -- 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, Depth) + EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL) + local dStep = EgtGetMachiningParam( MCH_MP.STEP) + dStep = min( dStep, Depth - 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 Depth = EgtGetInfo( LayId, 'Depth') + -- 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, Depth) + 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, Depth = 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, Depth) + 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, Depth = 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, Depth) + 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 sInfo = EgtGetInfo( nId, 'MId') + if sInfo then + local nMchId = tonumber( sInfo) + if nMchId then + local nEntId = CAM.GetEntIdFromMachining( nMchId) + table.insert( TabData, {Mch= nMchId, Part=nPartId, Ent=nEntId}) + end + 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 (da ver. 2.7f1) + if vThickFeed then + local dDepth = dRawHeight / cos( RecMPartCs.SideAng) + local dFlux = GetWjFlux( dDepth) + if dFlux then EgtSetInfo( nOperId, 'Flux', dFlux) end + end + + -- se previsto, imposto feed da Q* + if vThickFeed then + local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE) + local dDepth = dRawHeight / cos( dSideAng) + local dFeed, dThRef = GetWjSpeed( dDepth) + if dFeed and dThRef then + EgtSetMachiningParam( MCH_MP.FEED, dFeed) + EgtSetMachiningParam( MCH_MP.THICKREF, dThRef) + -- EgtOutLog(' UPDATE QUALITY → ' ..sWjQuality ..' - FEED → '..dFeed) + 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 il preview nel pezzo +function CAM.ErasePreviewInPiece( nSaw, nPartId) + -- verifico se esiste gruppo preview nel pezzo + local nPrevId = EgtGetFirstNameInGroup( nPartId, 'PV') + if not nPrevId then return end + -- se esiste sottogruppo con nome della lavorazione, lo cancello + local nDestId = EgtGetFirstNameInGroup( nPrevId, EgtGetName( nSaw)) + if nDestId then + EgtErase( nDestId) + end +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: color setted in tool '..sCurrTool..' 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 sSideAng = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'SideAng', 'SideAng2')) + if sSideAng then + return true, tonumber( sSideAng) or 0 + 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 sOffset = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'Offset', 'Offset2')) + if sOffset then + return true, tonumber( sOffset) or 0 + else + return false, 0 + end +end +-- Funzione per la lettura dell'affondamento +function CAM.GetDepth( nEntId, nInd) + local sDepth = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'Depth', 'Depth2')) + if sDepth then + return true, tonumber( sDepth) or 0 + else + return false, 0 + end +end +-- Funzione per la lettura del tallone +function CAM.GetHeel( nEntId) + local sHeel = EgtGetInfo( nEntId, 'Heel') + if sHeel then + return true, tonumber( sHeel) or 0 + else + return false, 0 + end +end +-- Funzione per la lettura dell'angolo di fianco con verifica non sia nullo +function CAM.GetHeelNotNull( nEntId, nInd) + local bFound, dHeel = CAM.GetHeel( nEntId, nInd) + return ( bFound and abs( dHeel) > GEO.EPS_ANG_SMALL), dHeel +end +-- Funzione per la lettura della larghezza dell'incisione +function CAM.GetWidth( nEntId) + local sWidth = EgtGetInfo( nEntId, 'Width') + if sWidth then + return true, tonumber( sWidth) or 0 + else + return false, 0 + end +end +-- Funzione per la lettura del tipo di taglio (Diretto oppure CAD) +function CAM.GetDirectCut( nEntId) + local sDirectCut = EgtGetInfo( nEntId, 'DirectCut') + if sDirectCut then + return true, tonumber( sDirectCut) or 0 + else + return false, 0 + end +end +function CAM.GetStepType( nEntId) + local sStepType = EgtGetInfo( nEntId, 'StepType') + if sStepType then + return true, tonumber( sStepType) or MCH_MILL_ST.SPIRAL + 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 sEnInv = EgtGetInfo( nEntId, 'EnInv') + if sEnInv then + return true, ( sEnInv == '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.GetIfJoinEntity( 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 sPreAng = EgtGetInfo( nEntId, 'PrevAng') + if sPreAng then + return true, tonumber(sPreAng) or 0 + else + return false, 0 + end +end +-- Funzione per lettura angolo in piano XY con entità successiva +function CAM.GetNextAngle( nEntId) + local sNextAng = EgtGetInfo( nEntId, 'NextAng') + if sNextAng then + return true, tonumber(sNextAng) or 0 + 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) + EgtTdbSetCurrTool( sTool) + 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) + EgtTdbSetCurrTool( sTool) + 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) + EgtTdbSetCurrTool( sTool) + return EgtTdbGetCurrToolParam(MCH_TP.DIAM) or 0 +end +-- Funzione per recuperare diametro utensile da nome lavorazione in lbreria +function CAM.GetToolDiameterFromMdb( sMach) + if EgtMdbSetCurrMachining( sMach) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + local sTool = EgtTdbGetToolFromUUID( sTuuid or '') or '' + if EgtTdbSetCurrTool( sTool) then + return EgtTdbGetCurrToolParam( MCH_TP.DIAM) + end + end + return 0 +end +-- Funzione per recuperare DeltaT +function CAM.GetDeltaT( nOperId) + local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV') + local nPv2Id = EgtGetInfo( nPvId, 'PvId') + 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') + 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') + 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') + 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 sOriLeadIn = EgtGetInfo( nOperId,'OriLI') + if sOriLeadIn then + return true, tonumber( sOriLeadIn) or MCH_SAW_LI.CENT + else + return false, MCH_SAW_LI.CENT + end +end +-- Funzione per recuperare tipo uscita originale +function CAM.GetOriLeadOut( nOperId) + local sOriLeadOut = EgtGetInfo( nOperId,'OriLO') + if sOriLeadOut then + return true, tonumber( sOriLeadOut) or MCH_SAW_LO.CENT + 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 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', '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 = EgtGetPrevOperation( TabCut[1].Mch) + end + -- creo i pretagli + local TabEPC = {} + local MyRefMch = RefMch + 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, MyRefMch, GDB_IN.AFTER) + MyRefMch = nNewMchId + 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 + MyRefMch = RefMch + for i = 1, #vOrd do + local CurrMch = TabEPC[vOrd[i]].Mch + EgtRelocateGlob( CurrMch, MyRefMch, GDB_IN.AFTER) + MyRefMch = CurrMch + 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 + 1 + 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 + 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 + -- recupero la preview dal pezzo (taglio di lama) e la elimino + local IdPart = EgtGetFirstNameInGroup( CAM.OPERID, "PV") + IdPart = EgtGetInfo( IdPart, "PvId", 'i') + EgtErase( IdPart) + -- recupero l'info da applicare in fase di costruzione della lavorazione + j = EgtGetInfo( CAM.OPERID, 'Index_j') + EgtRemoveOperation( CAM.OPERID) + end + -- **DA GESTIRE MEGLIO** l'attacco dei tagli: EgtSetMachiningParam( MCH_MP.LIHOLE, false) -anche per i tagli TabEnt?- + CAM.ApplyCuts( TabEnt, sLay, TabCrv, TabPart, j) +end + +------ Inserimento di una lavorazione Waterjet --------------------- +function CAM.AddWaterJet() + EgtOutLog( ' → CAM.AddWaterJet ' .. CAMAUTO_VER .. ' Operation ID: ') + CAM.ApplyWaterJettings( {}, {CAM.OPERID}, 'OutLoop') +end + +-- ver 2.6l1 di OmagCUT +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 EraseWjDrill( TabPart) + if #TabPart < 1 then + return + end + for i = 1, #TabPart do + EgtErase( EgtGetNameInGroup( TabPart[i].Part, "WjDrill")) + EgtErase( EgtGetNameInGroup( TabPart[i].Part, "RegionWjDrill")) + end +end + +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 WjDrill + EraseWjDrill( TabErase) + -- 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 WjDrill + EraseWjDrill( 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') + 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') + 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 TabMill = {} + local TabDrill = {} + -- recupero i tagli ad acqua e i loro centri + local nMillId = EgtGetPhaseDisposition( nPhase) + while nMillId do + -- Se appartiene alla fase corrente e taglio ad acqua non vuoto del layer voluto + if EgtGetOperationPhase( nMillId) == nPhase and EgtGetOperationType( nMillId) == MCH_OY.WATERJETTING and + ( not sLay or EgtGetInfo( nMillId, 'Lay') == sLay) then + -- imposto come lavorazione corrente + EgtSetCurrMachining( nMillId) + local nStartId, nEndId = CAM.GetEntIdFromCurrMachining() + if nStartId ~= GDB_ID.NULL and EgtExistsObj( nStartId) and nEndId ~= GDB_ID.NULL and EgtExistsObj( nEndId) then + local ptStart = EgtSP( nStartId, GDB_ID.ROOT) + local ptEnd = EgtEP( nEndId, GDB_ID.ROOT) + local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) + local dAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE) + if bInvert then + ptStart, ptEnd = ptEnd, ptStart + end + local ParentId = EgtGetParent( nStartId) + local sName = EgtGetName( ParentId) + if sName == "WjDrill" then + table.insert( TabDrill, {Id=nMillId, Start= ptStart, End = ptEnd, Ang=abs( dAng)}) + else + table.insert( TabMill, {Id=nMillId, Start= ptStart, End = ptEnd, Ang=abs( dAng)}) + end + end + end + nMillId = EgtGetNextOperation( nMillId) + end + -- calcolo ordinamento + EgtSpInit() + for i = 1, #TabDrill do + EgtSpAddPoint( TabDrill[i].Start:getX(), TabDrill[i].Start:getY(), 0, 0, TabDrill[i].Ang, + TabDrill[i].End:getX(), TabDrill[i].End:getY(), 0, 0, TabDrill[i].Ang) + end + EgtSpSetAngularParams( 1000, 40, 2000, 60) + EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -4000, 0, 0, 90) + local vMillOrd = EgtSpCalculate( SHP_TY.OPEN) + EgtSpTerminate() + -- applico ordinamento calcolato + -- parto da LastMch precedente + if vMillOrd then + for i = 1, #vMillOrd do + EgtRelocateGlob( TabDrill[vMillOrd[i]].Id, LastMch, GDB_IN.AFTER) + LastMch = TabDrill[vMillOrd[i]].Id + end + end + + -- calcolo ordinamento + EgtSpInit() + for i = 1, #TabMill do + EgtSpAddPoint( TabMill[i].Start:getX(), TabMill[i].Start:getY(), 0, 0, TabMill[i].Ang, + TabMill[i].End:getX(), TabMill[i].End:getY(), 0, 0, TabMill[i].Ang) + end + EgtSpSetAngularParams( 1000, 40, 2000, 60) + EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -4000, 0, 0, 90) + 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 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') + 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 + diff --git a/Polishing.lua b/Polishing.lua new file mode 100644 index 0000000..a229bae --- /dev/null +++ b/Polishing.lua @@ -0,0 +1,242 @@ +-- 2023/05/18 09:30:00 +-- Programma per Lucidatura in OmagCut +-- Legenda codici errore (POLI.ERR) : +-- 0 = tutto bene +-- 10 = manca il grezzo +-- 20 = manca il kit +-- 30 = manca il contorno dell'area +-- 40 = kit vuoto o errore nella sua lettura +-- 50 = errore nel calcolo della lavorazione + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Versione +local POLISHING_VER = 'ver 2.5e1' + +-- Recupero il grezzo +local nRawId = EgtGetFirstRawPart() +if not nRawId then + POLI.ERR = 10 + return +end + +-- Recupero la path del file dei kits +local sKitPath = EgtGetCurrMachineDir() .. '\\Machinings\\Kits.data' +-- 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 nPolishingC90 = tonumber( EgtGetStringFromIni( 'Nest', 'PolishingC90', '0', sMachIni)) +-- Reset stato di errore +POLI.ERR = 0 + +-------------------------------------------------------------------------------- +-- Funzione locale per lettura di una lavorazione del kit +local function ReadMachKit( sSect, nMachInd) + local sKeyInd = string.format( '%02d', nMachInd or 0) + local sTuuid = EgtGetStringFromIni( sSect, sKeyInd .. '.Tool', '', sKitPath) + local sTname = EgtGetStringFromIni( sSect, sKeyInd .. '.ToolName', '', sKitPath) + if #sTuuid == 0 or #sTname == 0 then return nil end + local bActive = ( tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.Active', '', sKitPath) or 0) ~= 0) + local nCnt = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.Contour', '', sKitPath) or 0) + local dOffCnt = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.OffContour', '', sKitPath) or 0) + local nZzX = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.ZigZagX', '', sKitPath) or 0) + local dOffZzX = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.OffZigZagX', '', sKitPath) or 0) + local dStepX = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.StepX', '', sKitPath) or 0) + local dRadiusX = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.RadiusX', '', sKitPath) or 0) + local dDistanceX = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.DistanceX', '', sKitPath) or 0) + local nZzY = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.ZigZagY', '', sKitPath) or 0) + local dOffZzY = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.OffZigZagY', '', sKitPath) or 0) + local dStepY = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.StepY', '', sKitPath) or 0) + local dRadiusY = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.RadiusY', '', sKitPath) or 0) + local dDistanceY = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.DistanceY', '', sKitPath) or 0) + + local nSpiral = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.Spiral', '', sKitPath) or 0) + local dOffSpiral = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.OffSpiral', '', sKitPath) or 0) + local dStepSpiral = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.StepSpiral', '', sKitPath) or 0) + local dRadiusSpiral = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.RadiusSpiral', '', sKitPath) or 0) + local dDistanceSpiral = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.DistanceSpiral', '', sKitPath) or 0) + + local dLiLen = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.LiLen', '', sKitPath) or 0) + local dLiHei = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.LiHeight', '', sKitPath) or 0) + local dLiLoad = tonumber( EgtGetStringFromIni( sSect, sKeyInd .. '.LiLoad', '', sKitPath) or 0) + return { Tuuid=sTuuid, Tname=sTname, Act=bActive, Cnt=nCnt, OffCnt=-dOffCnt, ZigZagX=nZzX, OffZigZagX=-dOffZzX, StepX=dStepX, ZigZagY=nZzY, OffZigZagY=-dOffZzY,StepY=dStepY, + Spiral=nSpiral, OffSpiral=-dOffSpiral, StepSpiral=dStepSpiral, RadiusSpiral=dRadiusSpiral, DistanceSpiral=dDistanceSpiral, LiLen=dLiLen, LiHeight=dLiHei, LiLoad=dLiLoad} +end + +-------------------------------------------------------------------------------- +-- Funzione locale per lettura del kit +local function ReadKit( sKitName) + local kCurr = {} + local sSect = 'Kit.' .. sKitName + for nMachInd = 1, 50 do + local mkCurr = ReadMachKit( sSect, nMachInd) + if mkCurr then + table.insert( kCurr, mkCurr) + else + break + end + end + return kCurr +end + +-------------------------------------------------------------------------------- +-- Funzione per aggiungere le lucidature +function POLI.Add() + + -- Recupero il kit + local sKitName = POLI.KITNAME + if not sKitName or sKitName == '' then + POLI.ERR = 20 + return + end + + -- Recupero il contorno dell'area da lucidare + local nCntId = POLI.CNTID + if not EgtExistsObj( nCntId) then + POLI.ERR = 30 + return + end + + -- Leggo i dati del kit + local kCurr = ReadKit( sKitName) + if #kCurr == 0 then + POLI.ERR = 40 + return + end + + -- Applico le lavorazioni + local bOk = true + for i = 1, #kCurr do + -- se attivo + if kCurr[i].Act then + -- contornatura + if kCurr[i].Cnt > 0 then + EgtCreateMachining( 'Cont_'..kCurr[i].Tname, MCH_MY.MILLING, kCurr[i].Tname) + EgtSetMachiningParam( MCH_MP.USERNOTES , 'Polishing') + EgtSetMachiningParam( MCH_MP.STARTPOS, 10) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_MILL_LI.GLIDE) + EgtSetMachiningParam( MCH_MP.LITANG, kCurr[i].LiLen) + EgtSetMachiningParam( MCH_MP.LIELEV, kCurr[i].LiHeight) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_MILL_LO.AS_LI) + EgtSetMachiningParam( MCH_MP.OFFSR, kCurr[i].OffCnt) + -- se richiesto un solo giro + if kCurr[i].Cnt == 1 then + EgtSetMachiningParam( MCH_MP.DEPTH, kCurr[i].LiLoad) + -- altrimenti più giri con step di discesa trascurabile + else + local dStep = 0.002 + local dAddDepth = kCurr[i].Cnt * dStep + local sUserNotes = 'Polishing;MaxElev=' .. EgtNumToString( dAddDepth, 3) .. ';' + EgtSetMachiningParam( MCH_MP.DEPTH, kCurr[i].LiLoad + dAddDepth) + EgtSetMachiningParam( MCH_MP.STEP, dStep) + EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes) + EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL) + end + local AngC = "C=" .. EgtNumToString(90*nPolishingC90,0) + EgtSetMachiningParam( MCH_MP.INITANGS, AngC) + EgtSetMachiningGeometry( {nCntId}) + if not EgtApplyMachining() then + bOk = false + end + end + -- svuotature in X + for j = 1, kCurr[i].ZigZagX do + EgtCreateMachining( 'ZigZagX_'..kCurr[i].Tname, MCH_MY.POCKETING, kCurr[i].Tname) + EgtSetMachiningParam( MCH_MP.USERNOTES , 'Polishing') + EgtSetMachiningParam( MCH_MP.STARTPOS, 10) + EgtSetMachiningParam( MCH_MP.DEPTH, kCurr[i].LiLoad) + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.ZIGZAG) + EgtSetMachiningParam( MCH_MP.SIDESTEP, kCurr[i].StepX) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_POCK_LI.GLIDE) + EgtSetMachiningParam( MCH_MP.LITANG, kCurr[i].LiLen) + EgtSetMachiningParam( MCH_MP.LIELEV, kCurr[i].LiHeight) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_POCK_LO.GLIDE) + EgtSetMachiningParam( MCH_MP.LOTANG, kCurr[i].LiLen) + EgtSetMachiningParam( MCH_MP.LOELEV, kCurr[i].LiHeight) + EgtSetMachiningParam( MCH_MP.OFFSR, kCurr[i].OffZigZagX) + EgtSetMachiningParam( MCH_MP.INVERT, (( j % 2) == 0)) + local AngC = "C=" .. EgtNumToString(90*nPolishingC90,0) + EgtSetMachiningParam( MCH_MP.INITANGS, AngC) + EgtSetMachiningGeometry( {nCntId}) + if not EgtApplyMachining() then + bOk = false + end + end + -- svuotature in Y + for j = 1, kCurr[i].ZigZagY do + EgtCreateMachining( 'ZigZagY_'..kCurr[i].Tname, MCH_MY.POCKETING, kCurr[i].Tname) + EgtSetMachiningParam( MCH_MP.USERNOTES , 'Polishing') + EgtSetMachiningParam( MCH_MP.STARTPOS, 10) + EgtSetMachiningParam( MCH_MP.DEPTH, kCurr[i].LiLoad) + EgtSetMachiningParam( MCH_MP.SUBTYPE, MCH_POCK_SUB.ZIGZAG) + EgtSetMachiningParam( MCH_MP.SIDEANGLE, 90) + EgtSetMachiningParam( MCH_MP.SIDESTEP, kCurr[i].StepY) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_POCK_LI.GLIDE) + EgtSetMachiningParam( MCH_MP.LITANG, kCurr[i].LiLen) + EgtSetMachiningParam( MCH_MP.LIELEV, kCurr[i].LiHeight) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_POCK_LO.GLIDE) + EgtSetMachiningParam( MCH_MP.LOTANG, kCurr[i].LiLen) + EgtSetMachiningParam( MCH_MP.LOELEV, kCurr[i].LiHeight) + EgtSetMachiningParam( MCH_MP.OFFSR, kCurr[i].OffZigZagY) + EgtSetMachiningParam( MCH_MP.INVERT, (( j % 2) == 0)) + local AngC = "C=" .. EgtNumToString(90*nPolishingC90,0) + EgtSetMachiningParam( MCH_MP.INITANGS, AngC) + EgtSetMachiningGeometry( {nCntId}) + if not EgtApplyMachining() then + bOk = false + end + end + -- svuotature a spirale (con epicicli) + for j = 1, kCurr[i].Spiral do + EgtCreateMachining( 'Spiral_'..kCurr[i].Tname, MCH_MY.POCKETING, kCurr[i].Tname) + EgtSetMachiningParam( MCH_MP.USERNOTES , 'Polishing') + EgtSetMachiningParam( MCH_MP.STARTPOS, 10) + EgtSetMachiningParam( MCH_MP.DEPTH, kCurr[i].LiLoad) + EgtSetMachiningParam( MCH_MP.SUBTYPE, EgtIf( ( j % 2) == 0, MCH_POCK_SUB.SPIRALOUT, MCH_POCK_SUB.SPIRALIN)) + EgtSetMachiningParam( MCH_MP.SIDEANGLE, 0) + EgtSetMachiningParam( MCH_MP.SIDESTEP, kCurr[i].StepSpiral) + EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_POCK_LI.GLIDE) + EgtSetMachiningParam( MCH_MP.LITANG, kCurr[i].LiLen) + EgtSetMachiningParam( MCH_MP.LIELEV, kCurr[i].LiHeight) + EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_POCK_LO.GLIDE) + EgtSetMachiningParam( MCH_MP.LOTANG, kCurr[i].LiLen) + EgtSetMachiningParam( MCH_MP.LOELEV, kCurr[i].LiHeight) + EgtSetMachiningParam( MCH_MP.OFFSR, kCurr[i].OffSpiral) + EgtSetMachiningParam( MCH_MP.INVERT, (( j % 2) == 0)) + EgtSetMachiningParam( MCH_MP.EPICYCLESRAD, kCurr[i].RadiusSpiral) + EgtSetMachiningParam( MCH_MP.EPICYCLESDIST, kCurr[i].DistanceSpiral) + local AngC = "C=" .. EgtNumToString(90*nPolishingC90,0) + EgtSetMachiningParam( MCH_MP.INITANGS, AngC) + EgtSetMachiningGeometry( {nCntId}) + if not EgtApplyMachining() then + bOk = false + end + end + end + end + + POLI.ERR = EgtIf( bOk, 0, 50) + +end + +-------------------------------------------------------------------------------- +-- Funzione per cancellare le lucidature +function POLI.Remove() + -- Elimino tutte le lavorazioni di tipo lucidatura + local nOperId = EgtGetFirstOperation() + while nOperId do + local nNextOperId = EgtGetNextOperation( nOperId) + if EgtGetOperationType( nOperId) ~= MCH_OY.DISP then + EgtSetCurrMachining( nOperId) + local sUserNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) + if sUserNotes and sUserNotes:find( 'Polishing', 1, true) then + EgtErase( nOperId) + end + end + nOperId = nNextOperId + end +end diff --git a/README.md b/README.md deleted file mode 100644 index a74fda8..0000000 --- a/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# OmagCUT_CamAuto - - - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -* [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -* [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://gitlab.steamware.net/egalware-cadcam/lua/omagcut_camauto.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -* [Set up project integrations](https://gitlab.steamware.net/egalware-cadcam/lua/omagcut_camauto/-/settings/integrations) - -## Collaborate with your team - -* [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -* [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -* [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -* [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -* [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -* [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) -* [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -* [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -* [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -* [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README - -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.