-- 2026/02/23 16:00:00 -- Programma per Cam automatico in OmagCut -- Legenda codici errore (CAM.ERR) : -- 0 = tutto bene -- 10 = manca il grezzo -- 20 = pezzo indicato mancante -- 30 = errore nell'inserimento della lavorazione -- 4x = errore nel calcolo del preview della lavorazione -- 5x = errore nel calcolo della lavorazione -- 60 = errore nel recupero dell'entità in lavorazione (in SORT) -- 70 = errore nel calcolo della disposizione -- -10 = modificati parametri di lavorazione -- Intestazioni require( 'EgtBase') _ENV = EgtProtectGlobal() EgtEnableDebug( false) -- Versione local CAMAUTO_VER = 'ver 3.1c1' -- 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)) -- 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) --[[ Funzione che calcola le due curve per le due lavorazioni associate al tallone. Recupero le informazioni del secondo taglio ( misura OnTop): ______ ______ / | H| | / |T | |T H| a>0 | \ a<0 | | ______ | \____| dOrigSideAng>0: SideAng1=0, Offset1=(Th-H)*tan(a) | SideAng2=a, Offset2=0, Depth2=Th-H dOrigSideAng<0: SideAng1=a, Offset1=H*tan(a) | SideAng2=0, Offset2=0, Depth=H ]]-- EgtOutLog( 'Nuova gestione rettifica talloni con WJ') local TabTrimCrvs = {} for i = 1, #MyTabRtf do local nEntId = MyTabRtf[i][1] local _, dSideAng = CAM.GetSideAng( nEntId) local _, dSideAng2 = CAM.GetSideAng( nEntId, 2) local _, dPrevAng = CAM.GetPrevAngle( nEntId) local _, dNextAng = CAM.GetNextAngle( nEntId) -- verifico se è vero tallone che necessita di due lavorazioni if abs( dSideAng) > GEO.EPS_ANG_SMALL or abs( dSideAng2) > GEO.EPS_ANG_SMALL then -- recupero il primo layer del pezzo con nome 'WjRectification', altrimenti lo creo local nPartId = EgtGetParent( EgtGetParent( nEntId)) local nRtfLayId = EgtGetFirstNameInGroup( nPartId, 'WjRectification') if not nRtfLayId then nRtfLayId = EgtGroup( nPartId, GDB_RT.GLOB) EgtSetName( nRtfLayId, 'WjRectification') end -- costruisco l'entità per lavorazione inclinata local nNewId = EgtCopyGlob( nEntId, nRtfLayId) EgtSetInfo( nNewId, 'CopyEnt', nEntId) if dSideAng2 > 0 then -- riporto l'informazione su SideAng perchè è l'unica info letta nel calcolare la lavorazione EgtSetInfo( nNewId, 'SideAng', dSideAng2) end -- costruisco l'entità per lavorazione non inclinata local nRtfId = EgtCopyGlob( nEntId, nRtfLayId) EgtSetInfo( nRtfId, 'CopyEnt', nEntId) EgtSetInfo( nRtfId, 'SideAng', 0) -- offset: se sovrasquadra devo offsettare il tratto non inclinato, se sottosquadra quello inclinato local _, dOffset = CAM.GetOffset( nEntId) local nOffsEntId = EgtIf( dSideAng2 > 0, nRtfId, nNewId) EgtOffsetCurve( nOffsEntId, dOffset, GDB_OT.FILLET) EgtSetInfo( nNewId, 'Offset', 0) EgtSetInfo( nRtfId, 'Offset', 0) -- estensione: se sovrasquadra gli angoli esterni devono essere uniti, quindi allungo opportunamente le curve non inclinate per trovarle con estremi coincidenti -- durante l'analisi dei concatenamenti del waterjet if dSideAng2 > 0 then if dPrevAng > GEO.EPS_ANG_SMALL then local dSWE = EgtGetInfo( nEntId, 'SWE', 'd') or 0 EgtExtendCurveStartByLen( nRtfId, dSWE) EgtRemoveInfo( nRtfId, 'SWE') end if dNextAng > GEO.EPS_ANG_SMALL then local dEWE = EgtGetInfo( nEntId, 'EWE', 'd') or 0 EgtExtendCurveEndByLen( nRtfId, dEWE) EgtRemoveInfo( nRtfId, 'EWE') end end -- inserisco le nuove entità tra quelle da lavorare nell'ordine corretto. La prima sostituisce la curva di partenza, la seconda viene aggiunta in fondo al vettore -- Nel caso di sovrasquadra viene fatta prima la lavorazione non inclinata e poi quella inclinata, nel caso di sottosquadra il contrario local TabCrvRef = EgtIf( MyTabRtf[i][2] == 0, TabOutCrv, TabInCrv) local nFirstEnt = EgtIf( dSideAng2 > 0, nRtfId, nNewId) local nSecondEnt = EgtIf( dSideAng2 > 0, nNewId, nRtfId) for j = 1, #TabCrvRef do if MyTabRtf[i][1] == TabCrvRef[j] then TabCrvRef[j] = nFirstEnt table.insert( TabCrvRef, nSecondEnt) break end end -- se sottosquadra e angolo interno salvo la curva inclinata tra quelle da trimmare if dSideAng2 == 0 and ( dPrevAng < GEO.EPS_ANG_SMALL or dNextAng < GEO.EPS_ANG_SMALL) then table.insert( TabTrimCrvs, { nId = nNewId, nOrigId = nEntId, dSideAng = dSideAng, bStart = ( dPrevAng < GEO.EPS_ANG_SMALL), bEnd = ( dNextAng < GEO.EPS_ANG_SMALL)}) end end end -- le curve di angoli interni in sottosquadra devono essere concatenate per garantire lavorazione completa, quindi ne faccio trim per trovarle con estremi coincidenti -- durante l'analisi dei concatenamenti del waterjet for i = 1, #TabTrimCrvs do if TabTrimCrvs[i].bStart then for j = 1, #TabTrimCrvs do if i ~= j and TabTrimCrvs[j].bEnd then -- verifico se le curve originali sono concatenabili if abs( TabTrimCrvs[i].dSideAng - TabTrimCrvs[j].dSideAng) < GEO.EPS_ANG_SMALL and AreSamePointApprox( EgtSP( TabTrimCrvs[i].nOrigId, GDB_ID.ROOT), EgtEP( TabTrimCrvs[j].nOrigId, GDB_ID.ROOT), 10 * GEO.EPS_SMALL) then -- trim delle curve nel loro punto di intersezione local ptInt = EgtIP( TabTrimCrvs[i].nId, TabTrimCrvs[j].nId, EgtSP( TabTrimCrvs[i].nId, GDB_ID.ROOT), GDB_ID.ROOT) local dPar = EgtCurveParamAtPoint( TabTrimCrvs[i].nId, ptInt, 10 * GEO.EPS_SMALL, GDB_RT.GLOB) EgtTrimCurveStartAtParam( TabTrimCrvs[i].nId, dPar) local dParPrev = EgtCurveParamAtPoint( TabTrimCrvs[j].nId, ptInt, 10 * GEO.EPS_SMALL, GDB_RT.GLOB) EgtTrimCurveEndAtParam( TabTrimCrvs[j].nId, dParPrev) break end end end end end end -- Funzione che raccoglie gli identificativi delle entità di un pezzo da lavorare function CAM.AnalyzePart( nPartId) -- |OUTLOOP| local MyTabRtf = {} -- Ciclo sui layer di contorno esterno del pezzo local nOutLayId = EgtGetFirstNameInGroup( nPartId, 'OutLoop') while nOutLayId do -- Ciclo sulle entità del layer local nEntId = EgtGetFirstInGroup( nOutLayId) while nEntId do local nType = EgtGetType(nEntId) -- Se waterjet attivo ed entità con tallone if sWaterJet ~= '' and CAM.GetHeelNotNull( nEntId) then table.insert( TabOutCrv, nEntId) table.insert( MyTabRtf, {nEntId, 0}) else -- Se **RETTA** if nType == GDB_TY.CRV_LINE then table.insert( TabOutCut, nEntId) -- Se **ARCO** o **CURVA** composita elseif nType == GDB_TY.CRV_ARC or nType == GDB_TY.CRV_COMPO then table.insert( TabOutCut, nEntId) end end -- Passo all'entità successiva nEntId = EgtGetNext( nEntId) end -- Passo al layer successivo nOutLayId = EgtGetNextName( nOutLayId, 'OutLoop') end -- Ciclo sui layer di contorno interno del pezzo local bAllCrv = ( bMillingOnSinks and ( sMill ~= "" or 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 tallone if sWaterJet ~= '' and CAM.GetHeelNotNull( nEntId) then table.insert( TabInCrv, nEntId) table.insert( MyTabInLoop, nEntId) table.insert( MyTabRtf, {nEntId, 1}) else -- Se retta if nType == GDB_TY.CRV_LINE then if not bAllCrv then table.insert( TabInCut, nEntId) else table.insert( TabInCrv, nEntId) end table.insert( MyTabInLoop, nEntId) -- se arco elseif nType == GDB_TY.CRV_ARC then local dDiam = 2 * EgtArcRadius( nEntId) if abs( EgtArcAngCenter( nEntId)) > 350.0 then if sDrill ~= "" and dDrillDiam > 1 and (( dDiamToler > 0 and abs( dDrillDiam - dDiam) < dDiamToler) or ( dDiamToler < 0 and dDrillDiam < dDiam + 10 * GEO.EPS_SMALL and dDrillDiam > dDiam + dDiamToler - GEO.EPS_SMALL)) then table.insert( TabInHole, nEntId) elseif dDiam > dMillDiam + 10 * GEO.EPS_SMALL then if not bAllCrv then table.insert( TabInCut, nEntId) else table.insert( TabInCrv, nEntId) end else EgtOutLog( 'Drill skipped : too small') end else if not bAllCrv then table.insert( TabInCut, nEntId) else table.insert( TabInCrv, nEntId) end end -- se curva composita elseif nType == GDB_TY.CRV_COMPO then if not bAllCrv then table.insert( TabInCut, nEntId) else table.insert( TabInCrv, nEntId) end end end -- Passo all'entità successiva nEntId = EgtGetNext( nEntId) end -- 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 + 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 -- verifico se necessario ricalcolo delle curve di lavorazione per talloni if sWaterJet ~= '' then SquaringWJ( MyTabRtf, TabOutCrv, TabInCrv) end -- |FILOTOP| local nFTLayId = EgtGetFirstNameInGroup( nPartId, 'FiloTop') while nFTLayId do -- Se richiede FiloTop table.insert( TabFiloTopLay, nFTLayId) nFTLayId = EgtGetNextName( nFTLayId, 'FiloTop') end -- |ONPATH| -- Ciclo sui layer sopra local nOnLayId = EgtGetFirstNameInGroup( nPartId, 'OnPath') while nOnLayId do -- Ciclo sulle entità del layer local nEntId = EgtGetFirstInGroup( nOnLayId) while nEntId do local nType = EgtGetType(nEntId) -- Se retta o curva composita if nType == GDB_TY.CRV_LINE or nType == GDB_TY.CRV_COMPO then table.insert( TabOnCut, nEntId) end -- Passo all'entità successiva nEntId = EgtGetNext( nEntId) end -- Passo al layer successivo nOnLayId = EgtGetNextName( nOnLayId, 'OnPath') end -- |POCKET| -- Ciclo sui layer svuotature local nPockLayId = EgtGetFirstNameInGroup( nPartId, 'Pocket') while nPockLayId do table.insert( TabPocketLay, nPockLayId) -- Passo al layer successivo nPockLayId = EgtGetNextName( nPockLayId, 'Pocket') end -- |DRIP| -- Ciclo sui layer per tagli da sotto local nDripLayId = EgtGetFirstNameInGroup( nPartId, 'Drip') while nDripLayId do -- Ciclo sulle entità del layer local nEntId = EgtGetFirstInGroup( nDripLayId) while nEntId do local nType = EgtGetType(nEntId) -- Se retta o curva composita if nType == GDB_TY.CRV_LINE or nType == GDB_TY.CRV_COMPO then table.insert( TabDripCut, nEntId) end -- Passo all'entità successiva nEntId = EgtGetNext( nEntId) end -- Passo al layer successivo nDripLayId = EgtGetNextName( nDripLayId, 'Drip') end -- |UNDERDRILL| -- Ciclo sui layer per fori da sotto local nUdrillLayId = EgtGetFirstNameInGroup( nPartId, 'UnderDrill') while nUdrillLayId do -- Ciclo sulle entità del layer local nEntId = EgtGetFirstInGroup( nUdrillLayId) while nEntId do local nType = EgtGetType(nEntId) -- Se arco if nType == GDB_TY.CRV_ARC then local dDiam = 2 * EgtArcRadius( nEntId) if abs( EgtArcAngCenter( nEntId)) > 350.0 then if ( ( dDiamToler > 0 and abs( dDripDrillDiam - dDiam) < dDiamToler) or ( dDiamToler < 0 and dDripDrillDiam < dDiam + 10 * GEO.EPS_SMALL and dDripDrillDiam > dDiam + dDiamToler - GEO.EPS_SMALL)) then table.insert( TabDripHole, nEntId) else EgtOutLog( 'UnderDrill skipped : different diameter') end end end -- Passo all'entità successiva nEntId = EgtGetNext( nEntId) end -- Passo al layer successivo nUdrillLayId = EgtGetNextName( nUdrillLayId, 'UnderDrill') end end -- Funzione che applica i tagli |LAMA| function CAM.ApplyCuts( TabEnt, sLay, TabCrv, TabPartial, Index_j) -- nome lama corrente local sCurrSaw = sSaw -- altezza grezzo local nRawId = EgtGetFirstRawPart() or EgtGetFirstNameInGroup( EgtGetTableId( 'MainTab'), 'RawPart') local dRawH = EgtGetRawPartBBox( nRawId):getDimZ() local dAddTab = tonumber( EgtGetStringFromIni( 'Table', 'AdditionalTable', '0', sMachIni)) local bOverHeightCut = ( dRawH + dAddTab > HighPieceZ + 0.1) -- diametro della lama local SawDiam = 0 -- Ciclo sulle entità for i = 1, #TabEnt do sCurrSaw = sSaw local nEntId = TabEnt[i] local nStartInd = 1 local nEndInd = 2 -- forzo la generazione di una sola lavorazione if Index_j then nStartInd = Index_j nEndInd = Index_j end -- Ad ogni entità possono essere associate due lavorazioni: inclinato + tallonamento -- per questo motivo sulla stessa entità è eseguito un ciclo for da 1 a 2 for j = nStartInd, nEndInd do if j == 2 and not CAM.GetSideAng( nEntId, j) then break end -- **Info entita'** local bDepth, Depth = CAM.GetDepth( nEntId, j) local _, PrevAng = CAM.GetPrevAngle( nEntId) local _, NextAng = CAM.GetNextAngle( nEntId) local _, SideAng = CAM.GetSideAng( nEntId, j) local _, StFreeLen = CAM.GetStartFreeLength( nEntId) local _, EdFreeLen = CAM.GetEndFreeLength( nEntId) local _, StWhiExt = CAM.GetStartWhiskersExtend( nEntId) local _, EdWhiExt = CAM.GetEndWhiskersExtend( nEntId) local _, Offset = CAM.GetOffset( nEntId, j) local _, EnInv = CAM.GetEnableInvert( nEntId) local _, RetDir = CAM.GetReturnDir( nEntId) local bInvert = false -- |LAVORAZIONE| local sNewSaw = EgtGetInfo( nEntId, 'Def_Machining', 's') if abs( SideAng) > GEO.EPS_ANG_SMALL then sNewSaw = EgtGetInfo( nEntId, 'Def_Machining_Tilted', 's') end if sNewSaw then sCurrSaw = sNewSaw EgtOutLog('Applico nuova lavorazione '..sCurrSaw..' a EntId:'..tostring(nEntId)) end SawDiam = CAM.GetToolDiameterFromMdb( sCurrSaw) --EgtOutLog( 'Test : nEntId='..tostring( nEntId) .. ' SideAng='..tostring( SideAng) .. ' EnInv='..tostring( EnInv)) -- |-->CREAZIONE LAVORAZIONE| inserimento lavorazione local nSaw = EgtAddMachining( 'Saw'..tostring( nEntId), sCurrSaw) -- assegno una nuova info che specifica se è la prima o la seconda lavorazione associata all'entità EgtSetInfo( nSaw, 'Index_j', j) CAM.NEW_OPERATION = nSaw if nSaw then if abs( SideAng) < GEO.EPS_ANG_SMALL then if EnInv then local P1 = EgtSP( nEntId, GDB_ID.ROOT) local P2 = EgtEP( nEntId, GDB_ID.ROOT) bInvert = CAM.GetInvertVerticalCut( P1, P2) end else local nHSide = EgtGetMachiningParam( MCH_MP.HEADSIDE) bInvert = ( SideAng < 0 and nHSide == MCH_SAW_HS.RIGHT) or ( SideAng > 0 and nHSide == MCH_SAW_HS.LEFT) -- lavorazione invertibile **SOLO** se non oltre le dimensioni del grezzo if bOverHeightCut then bInvert = false end end -- **Inserisco la geometria del percorso** EgtSetMachiningGeometry( {nEntId}) if bDepth then EgtSetMachiningParam( MCH_MP.DEPTH, Depth) end -- |-->-->SETTING PARAMETRI LAVORAZIONE|) EgtSetMachiningParam( MCH_MP.SIDEANGLE, SideAng) EgtSetMachiningParam( MCH_MP.OFFSL, Offset) local nIntCorner = 0 if bInvert then EgtSetMachiningParam( MCH_MP.INVERT, true) EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_SAW_WS.LEFT) if PrevAng < - GEO.EPS_ANG_SMALL then EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dDeltaIntCorner) nIntCorner = nIntCorner + 1 end if NextAng < - GEO.EPS_ANG_SMALL then EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dDeltaIntCorner) nIntCorner = nIntCorner + 1 end StFreeLen, EdFreeLen = EdFreeLen, StFreeLen StWhiExt, EdWhiExt = EdWhiExt, StWhiExt else EgtSetMachiningParam( MCH_MP.INVERT, false) EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_SAW_WS.RIGHT) if PrevAng < - GEO.EPS_ANG_SMALL then EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dDeltaIntCorner) nIntCorner = nIntCorner + 1 end if NextAng < - GEO.EPS_ANG_SMALL then EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dDeltaIntCorner) nIntCorner = nIntCorner + 1 end end -- **BAFFI** CAM.SetWhiskExtends( StWhiExt, EdWhiExt) if RetDir == 2 then -- solo per spianature EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.RIGHT, MCH_SAW_WS.LEFT)) EgtSetMachiningParam( MCH_MP.HEADSIDE, nOthHside) end -- **OVERHEIGHTCUT** if bOverHeightCut then EgtSetMachiningParam( MCH_MP.USERNOTES, "DownSE=1") -- Outer Extended: 4 EgtSetMachiningParam( MCH_MP.LEADINTYPE, 4) -- Back and forth EgtSetMachiningParam( MCH_MP.STEPTYPE, 2) -- avviso il cambio di parametri di taglio CAM.ERR = -10 end local bInTabCrv = false local dDeltaT = 0 local dDeltaTI = 0 -- |-->-->GENERO PREVIEW| if EgtPreviewMachining() then -- se previsto, limito quota minima lama if dMinSawRbHeight then local dRbH = CAM.GetRawBottomHeight( nSaw) if dRbH < dMinSawRbHeight - GEO.EPS_SMALL then local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR) sDepth = sDepth .. '-' .. EgtNumToString( dMinSawRbHeight - dRbH, 3) EgtSetMachiningParam( MCH_MP.DEPTH_STR, sDepth) EgtPreviewMachining() end end -- controllo di non superare la eventuale lunghezza libera prima e dopo con i baffi if not EgtIsMachiningEmpty() and not bOverHeightCut then dDeltaT = CAM.GetDeltaT( nSaw) dDeltaTI = CAM.GetDeltaTI( nSaw) or dDeltaT if bInvert then dDeltaT, dDeltaTI = dDeltaTI, dDeltaT end if dDeltaTI + dDeltaIntCorner > StFreeLen or dDeltaT > EdFreeLen then if dDeltaTI > StFreeLen then EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dDeltaIntCorner) nIntCorner = nIntCorner + 1 end if dDeltaT + dDeltaIntCorner > EdFreeLen then EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dDeltaIntCorner) nIntCorner = nIntCorner + 1 end EgtPreviewMachining() end end -- se la generazione è andata a buon fine allora procedo a copiarla nel pezzo if not EgtIsMachiningEmpty() then local nPartId = EgtGetParent(EgtGetParent( nEntId)) CAM.CopyPreviewToPiece( nSaw, nPartId) CAM.ApplyPvColor( sCurrSaw, nSaw) -- |TAGLIO FINALE| -- recupero il valore di affondamento del taglio local dRbH = CAM.GetRawBottomHeight( nSaw) -- taglio VERTICALE e PASSANTE, lavorazione con richiesta di lavorazione Sovrameteriale finale if bFinalCut and abs( SideAng) < GEO.EPS_ANG_SMALL and dRbH < GEO.EPS_SMALL then local nSawFINAL = EgtCopyMachining( 'Saw_FINAL'..tostring( nEntId), 'Saw'..tostring( nEntId)) if EgtSetCurrMachining( nSawFINAL) then -- One way:1, Back and forth:2, Zig Zag:0 EgtSetMachiningParam( MCH_MP.STEPTYPE, 1) -- Un solo step di affondamento EgtSetMachiningParam( MCH_MP.STEP, dRawHeight + 0.1) -- identifico la lavorazione come ultima EgtSetInfo( nSawFINAL, 'FinalCut', true) -- imposto come feed quella dell'ultimo taglio di ritorno local dBackFeed = EgtGetMachiningParam( MCH_MP.BACKFEED) EgtSetMachiningParam( MCH_MP.FEED, dBackFeed) -- assegno il nome del layer a cui fa riferimento (se assente non è estensibile da terfaccia!) EgtSetInfo( nSawFINAL, 'Lay', sLay) EgtPreviewMachining() CAM.CopyPreviewToPiece( nSawFINAL, nPartId) CAM.ApplyPvColor( sCurrSaw, nSawFINAL) -- alle operazioni assegno i riferimenti incrociati EgtSetInfo( nSawFINAL, 'IdTwinCut', nSaw) EgtSetInfo( nSaw, 'IdTwinCut', nSawFINAL) end -- Reimposto la lavorazione creata durante questo ciclo if EgtSetCurrMachining( nSaw) then -- ridefinisco l'affondamento corretto (più in alto dall'ultimo taglio) local dLastStep = EgtGetMachiningParam( MCH_MP.STEPLAST) if dLastStep < 0.1 then dLastStep = 10 end local sNewDepth = 'Rb-'..EgtNumToString( dLastStep) EgtSetMachiningParam( MCH_MP.DEPTH_STR, sNewDepth) -- aggiusto la feed dell'ultima passata di questa lav. (che ora non è più l'ultima del taglio) local dFeed = EgtGetMachiningParam( MCH_MP.FEED) EgtSetMachiningParam( MCH_MP.BACKFEED, dFeed) EgtPreviewMachining() CAM.ApplyPvColor( sCurrSaw, nSaw) -- ... end end elseif j == 1 and not bStartEndModifyOnIntCorner and not bOverHeightCut then -- **inserisco in elenco di entità da fare con fori/fresa** table.insert( TabCrv, nEntId) bInTabCrv = true -- modifico il taglio per non rovinare il pezzo local dLen = EgtCurveLength( nEntId) if nIntCorner > 0 and dLen and dLen < SawDiam then -- Versione **2.6f4**: allungo i tagli il più possibile if nManageLeadInOnIntCorner == 1 then local dExtraLen = -dLen + 5.5 local dExtraLen_2 = 0 if PrevAng < 0 and NextAng > 0 then if bInvert then EgtSetMachiningParam( MCH_MP.LEADINTYPE ,MCH_SAW_LI.OUT) EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen_2) EgtSetInfo( EgtGetCurrMachining(), 'Usal', dExtraLen) else EgtSetMachiningParam( MCH_MP.LEADOUTTYPE ,MCH_SAW_LO.OUT) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen) EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen_2) EgtSetInfo( EgtGetCurrMachining(), 'Ueal', dExtraLen) end EgtSetInfo( EgtGetCurrMachining(), 'ManageLeadInOnIntCorner', true) elseif PrevAng > 0 and NextAng < 0 then if bInvert then EgtSetMachiningParam( MCH_MP.LEADOUTTYPE ,MCH_SAW_LO.OUT) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen) EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen_2) EgtSetInfo( EgtGetCurrMachining(), 'Ueal', dExtraLen) else EgtSetMachiningParam( MCH_MP.LEADINTYPE ,MCH_SAW_LI.OUT) EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen_2) EgtSetInfo( EgtGetCurrMachining(), 'Usal', dExtraLen) end EgtSetInfo( EgtGetCurrMachining(), 'ManageLeadInOnIntCorner', true) end if EgtIsMachiningEmpty() then EgtOutLog( 'Cut '..tostring( nSaw)..' on internal angle: new management') end else -- provo a ridurre l'affondamento local dWhiskerLen = ( dLen - nIntCorner * dDeltaIntCorner - 5) / nIntCorner local dNewDepth = 0.5 * ( SawDiam - sqrt( SawDiam * SawDiam - 4 * dWhiskerLen * dWhiskerLen)) if dNewDepth >= dReducedDepth then EgtSetMachiningParam( MCH_MP.DEPTH, min( dNewDepth, dRawHeight)) end end else EgtSetMachiningParam( MCH_MP.DEPTH, min( dReducedDepth, dRawHeight)) EgtOutLog( 'Cut ' .. tostring( nSaw) .. ' reduced: interference with other parts') end EgtPreviewMachining() --CAM.ChangePvColor( nSaw, colOnCut, colOnExt) if not EgtIsMachiningEmpty() then local nPartId = EgtGetParent(EgtGetParent( nEntId)) CAM.CopyPreviewToPiece( nSaw, nPartId) CAM.ApplyPvColor( sCurrSaw, nSaw) else EgtRemoveOperation( nSaw) nSaw = nil end elseif j == 1 and bStartEndModifyOnIntCorner and not bOverHeightCut then -- Forzo il taglio all'interno del pezzo buono bInTabCrv = true -- allungo la lavorazione local dLen = EgtCurveLength( nEntId) -- dRawHeight + Affondamento local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR) -- sostituisco ad RB lo spessore del pezzo sDepth = string.gsub( sDepth, "RB", tostring(dRawHeight)) -- converto il dato stringa in numero local dRbH = EgtEvalNumExpr( sDepth) local dExtraLen = sqrt( (SawDiam /2)*(SawDiam /2) - (SawDiam/2 - dRbH)*(SawDiam/2 - dRbH)) if SideAng then dExtraLen = sqrt( (SawDiam /2)*(SawDiam /2) - (SawDiam/2 - dRbH / cos(SideAng))*(SawDiam/2 - dRbH / cos(SideAng))) end --local dWhiskerLen = ( dLen - nIntCorner * dDeltaIntCorner - 5) / nIntCorner EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) EgtSetMachiningParam( MCH_MP.STARTADDLEN, dExtraLen) EgtSetInfo( EgtGetCurrMachining(), 'Usal', dExtraLen) EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dExtraLen) EgtSetInfo( EgtGetCurrMachining(), 'Ueal', dExtraLen) EgtSetInfo( EgtGetCurrMachining(), 'StartEndModifyOnIntCorner', true) EgtPreviewMachining() -- verfico che la lavorazione sia stata inserita if not EgtIsMachiningEmpty() then local nPartId = EgtGetParent(EgtGetParent( nEntId)) CAM.CopyPreviewToPiece( nSaw, nPartId) CAM.ApplyPvColor( sCurrSaw, nSaw) else EgtRemoveOperation( nSaw) nSaw = nil end end else CAM.ERR = 40 end -- non è stata creata la lavorazione di lama if nSaw then if not bInTabCrv and j == 1 and ( PrevAng < - GEO.EPS_ANG_SMALL or NextAng < - GEO.EPS_ANG_SMALL or dDeltaTI + dDeltaIntCorner > StFreeLen or dDeltaT + dDeltaIntCorner > EdFreeLen) then EgtOutLog( 'Cut ' .. tostring( nSaw) .. ' to refine with mill') table.insert( TabPartial, nSaw) end EgtSetOperationStatus( nSaw, false) EgtSetInfo( nSaw, 'Lay', sLay) end else -- **Lavorazione non creata** CAM.ERR = 30 end end end end -- Funzione che applica le fresature per completare i tagli function CAM.ApplyMillings( TabEnt, TabPartMch, sLay) -- recupero lo spessore lama di una lavorazione incompleta local SawThickness = 0 if #TabPartMch > 0 then SawThickness = CAM.GetSawThickness( TabPartMch[1]) end local TabMPartC = {} -- Preparo tabella info tagli completi for i = 1, #TabEnt do local nEntId = TabEnt[i] if EgtExistsObj( nEntId) then local dEntLen = EgtCurveLength( nEntId) local _, PrevAng = CAM.GetPrevAngle( nEntId) local _, NextAng = CAM.GetNextAngle( nEntId) local _, SideAng = CAM.GetSideAng(nEntId) -- inserisco i dati nella tabella local RecMPartC = {} RecMPartC.OperId = 0 RecMPartC.StartStrict = false RecMPartC.EndStrict = false RecMPartC.DeltaT = 0 RecMPartC.DeltaTI = 0 RecMPartC.EntId = nEntId RecMPartC.EntLen = dEntLen RecMPartC.PrevAng = PrevAng RecMPartC.NextAng = NextAng RecMPartC.SideAng = SideAng RecMPartC.PrevInd = 0 RecMPartC.NextInd = 0 RecMPartC.StartDone = false RecMPartC.EndDone = false table.insert( TabMPartC, RecMPartC) end end -- Preparo tabella info tagli parziali for i = 1, #TabPartMch do local nOperId = TabPartMch[i] -- verifico sia un taglio di lama if EgtGetOperationType(nOperId) == MCH_OY.SAWING then EgtSetCurrMachining(nOperId) -- recupero i dati local Geo = EgtGetMachiningGeometry() local bInvert = EgtGetMachiningParam(MCH_MP.INVERT) local bStartStrict = ( EgtGetMachiningParam(MCH_MP.LEADINTYPE) == MCH_SAW_LI.STRICT) local bEndStrict = ( EgtGetMachiningParam(MCH_MP.LEADOUTTYPE) == MCH_SAW_LO.STRICT) local dDeltaT = CAM.GetDeltaT( nOperId) local dDeltaTI = CAM.GetDeltaTI( nOperId) or dDeltaT if bInvert then bStartStrict, bEndStrict = bEndStrict, bStartStrict dDeltaT, dDeltaTI = dDeltaTI, dDeltaT end if type(Geo) == 'table' and type(Geo[1]) == 'table' and type(Geo[1][1]) == 'number' then local nEntId = Geo[1][1] local dEntLen = EgtCurveLength( nEntId) local _, PrevAng = CAM.GetPrevAngle( nEntId) local _, NextAng = CAM.GetNextAngle( nEntId) local _, SideAng = CAM.GetSideAng(nEntId) -- inserisco i dati nella tabella local RecMPartC = {} RecMPartC.OperId = nOperId RecMPartC.StartStrict = bStartStrict RecMPartC.EndStrict = bEndStrict RecMPartC.DeltaT = dDeltaT -- lunghezza baffo RecMPartC.DeltaTI = dDeltaTI -- lunghezza baffo RecMPartC.EntId = nEntId RecMPartC.EntLen = dEntLen RecMPartC.PrevAng = PrevAng RecMPartC.NextAng = NextAng RecMPartC.SideAng = SideAng RecMPartC.PrevInd = 0 RecMPartC.NextInd = 0 RecMPartC.StartDone = false RecMPartC.EndDone = false table.insert( TabMPartC, RecMPartC) end end end -- Cerco le congiunzioni for i = 1, #TabMPartC do local RecMPartC = TabMPartC[i] if RecMPartC.OperId == 0 or RecMPartC.StartStrict then local ptStart = EgtSP( RecMPartC.EntId, GDB_ID.ROOT) for j = 1, #TabMPartC do if j ~= i then local RecMPartC2 = TabMPartC[j] if RecMPartC2.OperId == 0 or RecMPartC2.EndStrict then local ptEnd = EgtEP( RecMPartC2.EntId, GDB_ID.ROOT) -- verifico se l'inizio e la fine delle lavorazioni delle entità coincidono if AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL) and ( abs( RecMPartC.SideAng - RecMPartC2.SideAng) < 10 * GEO.EPS_ANG_SMALL or (RecMPartC.SideAng < GEO.EPS_ANG_SMALL and RecMPartC2.SideAng < GEO.EPS_ANG_SMALL)) then RecMPartC.PrevInd = j RecMPartC2.NextInd = i end end end end end end -- Stampe di debug --[[for i = 1, #TabMPartC do local RecMPartC = TabMPartC[i] EgtOutLog( 'OperId='..tostring(RecMPartC.OperId).. ', StartStrict='..tostring(RecMPartC.StartStrict)..', EndStrict='..tostring(RecMPartC.EndStrict).. ', DeltaT='..EgtNumToString(RecMPartC.DeltaT,2)..', DeltaTI='..EgtNumToString(RecMPartC.DeltaTI,2).. ', EntId='..tostring(RecMPartC.EntId)..', EntLen='..EgtNumToString(RecMPartC.EntLen,2).. ', PrevAng='..EgtNumToString(RecMPartC.PrevAng,2)..', NextAng='..EgtNumToString(RecMPartC.NextAng,2).. ', SideAng='..EgtNumToString(RecMPartC.SideAng,2).. ', PrevInd='..tostring(RecMPartC.PrevInd)..', NextInd='..tostring(RecMPartC.NextInd).. ', StartDone='..tostring(RecMPartC.StartDone)..', EndDone='..tostring(RecMPartC.EndDone)) end]]-- -- Ciclo sui tratti concatenabili for i = 1, #TabMPartC do local RecMPartCs = TabMPartC[i] -- se tratto completo ed esiste precedente non lavorato passo a questo local j = i local Count = 0 while RecMPartCs.OperId == 0 and not RecMPartCs.StartDone and RecMPartCs.PrevInd ~= 0 do j = RecMPartCs.PrevInd RecMPartCs = TabMPartC[j] Count = Count + 1 -- se sono ritornato all'inizio, esco if j == i then break end -- se ho esaminato tutte le entità, esco if Count > #TabMPartC then break end end -- se concatenato con successivo if not RecMPartCs.EndDone and RecMPartCs.NextInd ~= 0 then local tabEnt = {} local tabMid = {} table.insert( tabEnt, RecMPartCs.EntId) local RecMPartCe = TabMPartC[RecMPartCs.NextInd] table.insert( tabEnt, RecMPartCe.EntId) while RecMPartCe.OperId == 0 and not RecMPartCe.StartDone and RecMPartCe.NextInd ~= 0 and RecMPartCe.NextInd ~= j do RecMPartCe = TabMPartC[RecMPartCe.NextInd] table.insert( tabEnt, RecMPartCe.EntId) table.insert( tabMid, RecMPartCe.PrevInd) end local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartCs.EntId)..'S', sMill) if nMill then -- eventuale suggerimento angolo asse C a 90 deg CAM.HintDrillMillAngC() -- eventuale offset local dRad = 0.5 * CAM.GetToolDiameter() if RecMPartCs.SideAng > GEO.EPS_ANG_SMALL then local dTotOffs = dRawHeight * tan( RecMPartCs.SideAng) EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs) end -- verifico se percorso chiuso local ptStart = EgtSP( RecMPartCs.EntId, GDB_ID.ROOT) local ptEnd = EgtEP( RecMPartCe.EntId, GDB_ID.ROOT) local bClosed = not RecMPartCs.StartStrict and not RecMPartCe.EndStrict and AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL) -- se non chiuso, sistemazioni inizio e fine if not bClosed then -- aggiusto inizio local dStartAddLen = 0 if RecMPartCs.OperId == 0 then if RecMPartCs.PrevAng > - 175 and RecMPartCs.PrevAng < - 5 then dStartAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartCs.PrevAng) + 1) / sin( 180 + RecMPartCs.PrevAng) elseif RecMPartCs.PrevAng < 175 and RecMPartCs.PrevAng > 5 then -- Verifico se devo allungare il taglio local PrevEnt = EgtGetPrev( RecMPartCs.EntId) if not PrevEnt then EgtGetFirstInGroup( EgtGetParent(RecMPartCs.EntId)) end if PrevEnt then local _, PrevSideAng = CAM.GetSideAng( PrevEnt, 1) if PrevSideAng then -- valore di riduzione lunghezza a causa del taglio in sottosquadra/soprasquadra local dExtraLen = dRawHeight * tan( abs( PrevSideAng)) -- Impronta lama : SawThickness/cos( abs( NextSideAng)) -- **SOPRA SQUADRA** if PrevSideAng > 0 and bSizeAlwaysOnTop then dStartAddLen = -dExtraLen EgtOutLog( 'Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOPRA SQUDRA)') -- **SOTTO SQUADRA** elseif PrevSideAng < 0 and bSizeAlwaysOnTop then if RecMPartCs.EntLen * ( 1 + cos( RecMPartCs.PrevAng)) - dExtraLen <= 10 * GEO.EPS_SMALL then dStartAddLen = 0 else dStartAddLen = -dExtraLen / sin( abs( PrevSideAng)) end EgtOutLog( 'Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOTTO SQUDRA)') -- ALTRO elseif ( PrevSideAng < 0 or PrevSideAng > 0) and not bSizeAlwaysOnTop then dStartAddLen = -dExtraLen EgtOutLog( 'Allungo INGRESSO fresa per compensare il taglio inclinato (SizeAlwaysOnTop=0)') end end end else -- se retta molto corta con angolo interno dopo, la allungo del raggio utensile if RecMPartCs.EntLen < dRad and EgtGetType( RecMPartCs.EntId) == GDB_TY.CRV_LINE and RecMPartCs.NextAng > - 175 and RecMPartCs.NextAng < - 5 then dStartAddLen = RecMPartCs.EntLen - dRad - 1.0 else dStartAddLen = 0 end end else dStartAddLen = RecMPartCs.EntLen - RecMPartCs.DeltaT - dDeltaIntCorner - dDeltaLenPartMilling end EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dStartAddLen) -- aggiusto fine local dEndAddLen = 0 if RecMPartCe.OperId == 0 then if RecMPartCe.NextAng > - 175 and RecMPartCe.NextAng < - 5 then dEndAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartCe.NextAng) + 1) / sin( 180 + RecMPartCe.NextAng) elseif RecMPartCe.NextAng < 175 and RecMPartCe.NextAng > 5 then -- Verifico se devo allungare il taglio local NextEnt = EgtGetNext( RecMPartCe.EntId) if not NextEnt then EgtGetFirstInGroup( EgtGetParent( RecMPartCe.EntId)) end if NextEnt then local _, NextSideAng = CAM.GetSideAng( NextEnt, 1) if NextSideAng then -- valore di riduzione lunghezza a causa del taglio in sottosquadra/soprasquadra local dExtraLen = dRawHeight * tan( abs( NextSideAng)) -- Impronta lama : SawThickness / cos( abs( NextSideAng)) -- **SOPRA SQUADRA** if NextSideAng > 0 and bSizeAlwaysOnTop then dEndAddLen = -dExtraLen EgtOutLog( 'Allungo USCITA fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOPRA SQUDRA)') -- **SOTTO SQUADRA** elseif NextSideAng < 0 and bSizeAlwaysOnTop then if RecMPartCe.EntLen *( 1 + cos( RecMPartCs.PrevAng)) - dExtraLen <= 10 * GEO.EPS_SMALL then dEndAddLen = 0 else dEndAddLen = -dExtraLen / sin( abs( NextSideAng)) end EgtOutLog( 'Allungo USCITA fresa per compensare il taglio inclinato (SizeAlwaysOnTop=1 SOTTO SQUDRA)') -- ALTRO elseif ( NextSideAng < 0 or NextSideAng > 0) and not bSizeAlwaysOnTop then dEndAddLen = -dRawHeight / tan( abs( NextSideAng))- dRad EgtOutLog( 'Allungo USCITA fresa '..tostring( dEndAddLen)..' per compensare il taglio inclinato (SizeAlwaysOnTop=0)') end end end else -- se retta molto corta con angolo interno prima, la allungo del raggio utensile if RecMPartCe.EntLen < dRad and EgtGetType( RecMPartCe.EntId) == GDB_TY.CRV_LINE and RecMPartCe.PrevAng > - 175 and RecMPartCe.PrevAng < - 5 then dEndAddLen = RecMPartCe.EntLen - dRad - 1.0 else dEndAddLen = 0 end end else dEndAddLen = RecMPartCe.EntLen - RecMPartCe.DeltaTI - dDeltaIntCorner - dDeltaLenPartMilling end EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen) end -- altri aggiustamenti EgtSetMachiningParam(MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL) EgtSetMachiningParam(MCH_MP.LIELEV, 2.0) -- assegno geometria if EgtSetMachiningGeometry( tabEnt) then if EgtPreviewMachining() then local nPartId = EgtGetParent(EgtGetParent( RecMPartCs.EntId)) CAM.CopyPreviewToPiece( nMill, nPartId) else CAM.ERR = 41 end EgtSetOperationStatus( nMill, false) EgtSetInfo( nMill, 'Lay', sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end -- segnalazione lavorazioni applicate RecMPartCs.EndDone = true if RecMPartCs.OperId == 0 then RecMPartCs.StartDone = true end RecMPartCe.StartDone = true if RecMPartCe.OperId == 0 then RecMPartCe.EndDone = true end for k = 1, #tabMid do TabMPartC[tabMid[k]].StartDone = true TabMPartC[tabMid[k]].EndDone = true end end end -- Ciclo sui tratti singoli rimasti for i = 1, #TabMPartC do local RecMPartC = TabMPartC[i] -- completo singolo if not RecMPartC.StartDone and RecMPartC.OperId == 0 then local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartC.EntId)..'S', sMill) if nMill then -- eventuale suggerimento angolo asse C a 90 deg CAM.HintDrillMillAngC() -- aggiustamenti vari local dRad = 0.5 * CAM.GetToolDiameter() if RecMPartC.SideAng > GEO.EPS_ANG_SMALL then local dTotOffs = dRawHeight * tan( RecMPartC.SideAng) EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs) end local dStartAddLen = 0 if RecMPartC.PrevAng < - 5 and RecMPartC.PrevAng > - 175 then dStartAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.PrevAng) + 1) / sin( 180 + RecMPartC.PrevAng) end EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen) local dEndAddLen = 0 if RecMPartC.NextAng < - 5 and RecMPartC.NextAng > - 175 then dEndAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.NextAng) + 1) / sin( 180 + RecMPartC.NextAng) end EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen) EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL) --EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_MILL_LI.GLIDE) EgtSetMachiningParam( MCH_MP.LIELEV, 2.0) if EgtSetMachiningGeometry( {RecMPartC.EntId}) then if EgtPreviewMachining() then local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId)) CAM.CopyPreviewToPiece(nMill, nPartId) else CAM.ERR = 42 end EgtSetOperationStatus(nMill,false) EgtSetInfo(nMill,'Lay',sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end RecMPartC.StartDone = true RecMPartC.EndDone = true end -- parziale singolo su inizio if not RecMPartC.StartDone and RecMPartC.StartStrict then local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartC.EntId)..'S', sMill) if nMill then -- eventuale suggerimento angolo asse C a 90 deg CAM.HintDrillMillAngC() -- aggiustamenti vari local dRad = 0.5 * CAM.GetToolDiameter() if RecMPartC.SideAng > GEO.EPS_ANG_SMALL then local dTotOffs = dRawHeight * tan( RecMPartC.SideAng) EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs) end local dStartAddLen = 0 if RecMPartC.PrevAng < - 5 and RecMPartC.PrevAng > - 175 then dStartAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.PrevAng) + 1) / sin( 180 + RecMPartC.PrevAng) end EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen) local dEndAddLen = RecMPartC.EntLen - RecMPartC.DeltaTI - dDeltaIntCorner - dDeltaLenPartMilling EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen) EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL) --EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_MILL_LI.GLIDE) EgtSetMachiningParam( MCH_MP.LIELEV, 2.0) if EgtSetMachiningGeometry( {RecMPartC.EntId}) then if EgtPreviewMachining() then local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId)) CAM.CopyPreviewToPiece(nMill, nPartId) else CAM.ERR = 43 end EgtSetOperationStatus(nMill,false) EgtSetInfo(nMill,'Lay',sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end RecMPartC.StartDone = true end -- parziale singolo su fine if not RecMPartC.EndDone and RecMPartC.EndStrict then local nMill = EgtAddMachining( 'Mill'..tostring(RecMPartC.EntId)..'E', sMill) if nMill then -- eventuale suggerimento angolo asse C a 90 deg CAM.HintDrillMillAngC() -- aggiustamenti vari local dRad = 0.5 * CAM.GetToolDiameter() if RecMPartC.SideAng > GEO.EPS_ANG_SMALL then local dTotOffs = dRawHeight * tan( RecMPartC.SideAng) EgtSetMachiningParam(MCH_MP.OFFSR, dTotOffs) end local dStartAddLen = RecMPartC.EntLen - RecMPartC.DeltaT - dDeltaIntCorner - dDeltaLenPartMilling EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dStartAddLen) local dEndAddLen = 0 if RecMPartC.NextAng < - 5 and RecMPartC.NextAng > - 175 then dEndAddLen = ( dRad + 0.5) * ( cos( 180 + RecMPartC.NextAng) + 1) / sin( 180 + RecMPartC.NextAng) end EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dEndAddLen) EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL) --EgtSetMachiningParam(MCH_MP.LEADINTYPE, MCH_MILL_LI.GLIDE) EgtSetMachiningParam( MCH_MP.LIELEV, 2.0) if EgtSetMachiningGeometry( {RecMPartC.EntId}) then if EgtPreviewMachining() then local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId)) CAM.CopyPreviewToPiece(nMill, nPartId) else CAM.ERR = 44 end EgtSetOperationStatus(nMill,false) EgtSetInfo(nMill,'Lay',sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end RecMPartC.EndDone = true end end end -- Funzione che applica waterjet per completare i tagli: -- **TabEnt**: tabella delle entità che devono essere lavorate function CAM.ApplyWaterJettings( TabEnt, TabPartMch, sLay) -- determino tabella spessore-feed da utilizzare: **vThickFeed** local vThickFeed = nil if sMaterial and sWjQuality and dRawHeight then vThickFeed = {} local sWjDbPath = EgtGetCurrMachineDir() .. '\\Machinings\\WaterjetDB.data' for i = 1, 20 do local sLine = EgtGetStringFromIni( sMaterial, tostring( i), '', sWjDbPath) if #sLine == 0 then break end local vVal = EgtSplitString( sLine, ',') local dThick = tonumber( vVal[1] or '') local dFeed if sWjQuality == 'Q1' then dFeed = tonumber( vVal[2] or '') elseif sWjQuality == 'Q2' then dFeed = tonumber( vVal[3] or '') elseif sWjQuality == 'Q3' then dFeed = tonumber( vVal[4] or '') elseif sWjQuality == 'Q4' then dFeed = tonumber( vVal[5] or '') elseif sWjQuality == 'Q5' then dFeed = tonumber( vVal[6] or '') else dFeed = tonumber( vVal[7] or '') end local dTaperAng = tonumber( vVal[8] or '') or 0 local dFlux = tonumber( vVal[9] or '') or 250 if dThick and dFeed then table.insert( vThickFeed, { Th=dThick, F=dFeed, Ta=dTaperAng, Fl=dFlux}) end end end -- funzione locale per tabella spessore-feed local function GetWjSpeed( dDepth) for i = 1, #( vThickFeed or {}) do if dDepth < vThickFeed[i].Th + 0.1 then if i == 1 or ( vThickFeed[i].Th - vThickFeed[i-1].Th) < 0.1 then return vThickFeed[i].F, 0 else local dCoeff = ( dDepth - vThickFeed[i-1].Th) / ( vThickFeed[i].Th - vThickFeed[i-1].Th) return ( 1 - dCoeff) * vThickFeed[i-1].F + dCoeff * vThickFeed[i].F, 0 end end end if #( vThickFeed or {}) > 0 then return vThickFeed[#vThickFeed].F, vThickFeed[#vThickFeed].Th end end -- funzione locale per tabella spessore-conicità local function GetWjTaperAng( dDepth) for i = 1, #( vThickFeed or {}) do if dDepth < vThickFeed[i].Th + 0.1 then if i == 1 or ( vThickFeed[i].Th - vThickFeed[i-1].Th) < 0.1 then return vThickFeed[i].Ta else local dCoeff = ( dDepth - vThickFeed[i-1].Th) / ( vThickFeed[i].Th - vThickFeed[i-1].Th) return ( 1 - dCoeff) * vThickFeed[i-1].Ta + dCoeff * vThickFeed[i].Ta end end end if #( vThickFeed or {}) > 0 then return vThickFeed[#vThickFeed].Ta end return 0 end -- funzione locale per tabella spessore-flusso sabbia local function GetWjFlux( dDepth) for i = 1, #( vThickFeed or {}) do if dDepth < vThickFeed[i].Th + 0.1 then return vThickFeed[i].Fl end end if #( vThickFeed or {}) > 0 then return vThickFeed[#vThickFeed].Fl end return 250 end -- Inizio elaborazioni -- local nIntAngLiType = MCH_WJET_LI.LINEAR local dIntAngLiTang = -1 local dIntAngLiPerp = 3 local nIntAngLoType = MCH_WJET_LO.LINEAR local dIntAngLoTang = 0 local dIntAngLoPerp = 2 -- 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.GetJoinEntity( nEntId) -- inserisco i dati nella tabella: creo record per la tabella local RecMPartC = {} RecMPartC.OperId = 0 RecMPartC.StartStrict = false RecMPartC.EndStrict = false RecMPartC.Sal = 0 RecMPartC.Eal = 0 RecMPartC.DeltaT = 0 RecMPartC.DeltaTI = 0 RecMPartC.EntId = nEntId RecMPartC.EntLen = dEntLen RecMPartC.PrevAng = PrevAng RecMPartC.NextAng = NextAng RecMPartC.SideAng = SideAng RecMPartC.Offset = Offset RecMPartC.StWhiExt = StWhiExt RecMPartC.EdWhiExt = EdWhiExt RecMPartC.PrevInd = 0 RecMPartC.NextInd = 0 RecMPartC.StartDone = false RecMPartC.EndDone = false RecMPartC.Join = ( Join ~= 0) table.insert( TabMPartC, RecMPartC) end end -- Preparo tabella info tagli parziali, solo se tipo operazione **MCH_OY.SAWING** for i = 1, #TabPartMch do local nOperId = TabPartMch[i] -- verifico sia un taglio di lama if EgtGetOperationType( nOperId) == MCH_OY.SAWING then EgtSetCurrMachining( nOperId) -- recupero i dati local Geo = EgtGetMachiningGeometry() local bInvert = EgtGetMachiningParam(MCH_MP.INVERT) local bStartStrict = ( EgtGetMachiningParam(MCH_MP.LEADINTYPE) == MCH_SAW_LI.STRICT) local bEndStrict = ( EgtGetMachiningParam(MCH_MP.LEADOUTTYPE) == MCH_SAW_LO.STRICT) local dSal = EgtGetMachiningParam( MCH_MP.STARTADDLEN) local dEal = EgtGetMachiningParam( MCH_MP.ENDADDLEN) local dDeltaT = CAM.GetDeltaT( nOperId) local dDeltaTI = CAM.GetDeltaTI( nOperId) or dDeltaT local dWidth = CAM.GetSawThickness() -- Affondamento lavorazione local sDepth = EgtGetMachiningParam( MCH_MP.DEPTH_STR) sDepth = string.gsub( sDepth, "RB", tostring(dRawHeight)) local dRbH = EgtEvalNumExpr( sDepth) if bInvert then bStartStrict, bEndStrict = bEndStrict, bStartStrict dDeltaT, dDeltaTI = dDeltaTI, dDeltaT dSal, dEal = dEal, dSal end local bDouble = false local sOthMIds = EgtGetInfo( nOperId, 'OthMIds') if sOthMIds then -- divido la lista separata da virgole nelle sue parti for sId in string.gmatch(sOthMIds, '([^,]+)') do local nId = tonumber(sId) if nId then local nOthPvId = EgtGetInfo( EgtGetFirstNameInGroup( nId, 'PV') or GDB_ID.NULL, 'PvId') if not nOthPvId or EgtGetGroupObjs( nOthPvId) == 0 then bDouble = true break end end end end if type( Geo) == 'table' and type( Geo[1]) == 'table' and type( Geo[1][1]) == 'number' then local nEntId = Geo[1][1] local dEntLen = EgtCurveLength( nEntId) local _, PrevAng = CAM.GetPrevAngle( nEntId) local _, NextAng = CAM.GetNextAngle( nEntId) local _, SideAng = CAM.GetSideAng( nEntId) local _, Offset = CAM.GetOffset( nEntId) local _, StWhiExt = CAM.GetStartWhiskersExtend( nEntId) local _, EdWhiExt = CAM.GetEndWhiskersExtend( nEntId) local _, Join = CAM.GetJoinEntity( nEntId) -- inserisco i dati nella tabella local RecMPartC = {} RecMPartC.OperId = nOperId RecMPartC.StartStrict = bStartStrict RecMPartC.EndStrict = bEndStrict RecMPartC.Sal = dSal RecMPartC.Eal = dEal RecMPartC.DeltaT = dDeltaT RecMPartC.DeltaTI = dDeltaTI RecMPartC.EntId = nEntId RecMPartC.EntLen = dEntLen RecMPartC.PrevAng = PrevAng RecMPartC.NextAng = NextAng RecMPartC.SideAng = SideAng RecMPartC.Offset = Offset RecMPartC.StWhiExt = StWhiExt RecMPartC.EdWhiExt = EdWhiExt RecMPartC.PrevInd = 0 RecMPartC.NextInd = 0 RecMPartC.StartDone = false RecMPartC.EndDone = false RecMPartC.Double = bDouble RecMPartC.Width = dWidth RecMPartC.Join = ( Join ~= 0) RecMPartC.Depth = dRbH table.insert( TabMPartC, RecMPartC) end end end -- FINE: Preparo tabella info tagli parziali, solo se tipo operazione **MCH_OY.SAWING** -- |CONGIUNZIONI TAGLI| -- Cerco le congiunzioni -> aggiorno i campi della tabella **RecMPartC.PrevInd** e **RecMPartC2.NextInd** !ATTENZIONE! sono gli indici della tabella (NON dell'entità) for i = 1, #TabMPartC do local RecMPartC = TabMPartC[i] if RecMPartC.OperId == 0 or RecMPartC.StartStrict then local ptStart = EgtSP( RecMPartC.EntId, GDB_ID.ROOT) -- se il taglio WaterJet è solo parziale allora #TabEnt=0, quindi non deve essere separato if RecMPartC.Join or #TabEnt == 0 then for j = 1, #TabMPartC do if j ~= i then local RecMPartC2 = TabMPartC[j] if ( RecMPartC2.OperId == 0 or RecMPartC2.EndStrict) and ( RecMPartC2.Join or #TabEnt == 0) then local ptEnd = EgtEP( RecMPartC2.EntId, GDB_ID.ROOT) -- se estremi e angoli coincidono -- (tolti i positivi il 2021/03/24 per fare rettangoli con lati indipendenti anche con misure sul top, poi reintrodotti) 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 -- se angoli interni in sovrasquadra le curve di lavorazione non hanno estremi coincidenti ma le lavorazioni devono essere unite per essere complete -- quindi confronto le curve del loop originale if RecMPartC.PrevAng < - GEO.EPS_ANG_SMALL and RecMPartC.SideAng > GEO.EPS_ANG_SMALL and abs( RecMPartC.SideAng - RecMPartC2.SideAng) < 10 * GEO.EPS_ANG_SMALL then -- recupero tratto di riferimento ( se entità per tallone è in una info altrimenti è l'entità stessa) local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId -- recupero la curva originale local nLoopLayer = EgtGetParent( nRefEntId) local nPart = EgtGetParent( nLoopLayer) local nOrigLoopLayer = EgtGetFirstNameInGroup( nPart, EgtGetName( nLoopLayer) .. '.orig') local nOrig = EgtGetFirstNameInGroup( nOrigLoopLayer, EgtGetName( nRefEntId)) local nRefEntId2 = EgtGetInfo( RecMPartC2.EntId, 'CopyEnt', 'i') or RecMPartC2.EntId local nLoopLayer2 = EgtGetParent( nRefEntId2) local nPart2 = EgtGetParent( nLoopLayer2) local nOrigLoopLayer2 = EgtGetFirstNameInGroup( nPart2, EgtGetName( nLoopLayer2) .. '.orig') local nOrig2 = EgtGetFirstNameInGroup( nOrigLoopLayer2, EgtGetName( nRefEntId2)) if AreSamePointEpsilon( EgtSP( nOrig, GDB_ID.ROOT), EgtEP( nOrig2, GDB_ID.ROOT), 10 * GEO.EPS_SMALL) then -- estendo le curve in modo che vengano trovate come consecutive e salvo l'info di accorciamento per tornare alla dimensione originale ( per separazione) local dLenOld = EgtCurveLength( RecMPartC.EntId) EgtModifyCurveStartPoint( RecMPartC.EntId, EgtSP( nOrig, GDB_ID.ROOT), GDB_RT.GLOB) EgtSetInfo( RecMPartC.EntId, 'SWE', dLenOld - EgtCurveLength( RecMPartC.EntId)) local dLenOld2 = EgtCurveLength( RecMPartC2.EntId) EgtModifyCurveEndPoint( RecMPartC2.EntId, EgtEP( nOrig2, GDB_ID.ROOT), GDB_RT.GLOB) EgtSetInfo( RecMPartC2.EntId, 'EWE', dLenOld2 - EgtCurveLength( RecMPartC2.EntId)) RecMPartC.PrevInd = j RecMPartC2.NextInd = i break end end end end end end end end -- FINE: Cerco le congiunzioni --[[Stampe di debug for i = 1, #TabMPartC do local RecMPartC = TabMPartC[i] EgtOutLog( 'OperId='..tostring( RecMPartC.OperId).. ', 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 nRefEntId = EgtGetInfo( RecMPartCs.EntId, 'CopyEnt', 'i') or RecMPartCs.EntId local nMill = EgtAddMachining( 'Waterjet' .. tostring( nRefEntId) .. 'S', sWaterJet) if nMill then local sName = EgtGetName( nMill) -- assegno il valore di flusso (da ver. 2.7f1) if vThickFeed then local dDepth = dRawHeight / cos( RecMPartCs.SideAng) local dFlux = GetWjFlux( dDepth) if dFlux then EgtSetInfo( nMill, 'Flux', dFlux) end end -- aggiustamenti vari local dRad = 0.5 * CAM.GetToolDiameter() -- diametro utensile local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR) -- offset radiale -- verifico se percorso chiuso: tra punto **i-esimo** e **j-esimo** local ptStart = EgtSP( RecMPartCs.EntId, GDB_ID.ROOT) local ptEnd = EgtEP( RecMPartCe.EntId, GDB_ID.ROOT) local bClosed = AreSamePointEpsilon( ptStart, ptEnd, 10 * GEO.EPS_SMALL) -- se aperto, sistemazioni inizio e fine if not bClosed then -- aggiusto inizio local dStartAddLen = 0 if RecMPartCs.OperId == 0 then if 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'), nRefEntId) -- assegno geometria if EgtSetMachiningGeometry( tabEnt) then if EgtPreviewMachining() then local nPartId = EgtGetParent(EgtGetParent( RecMPartCs.EntId)) CAM.CopyPreviewToPiece( nMill, nPartId) -- se inclinata e non sta nelle corse if abs( RecMPartCs.SideAng + dTaperAng) > GEO.EPS_ANG_SMALL and not EgtApplyMachining( true) and EgtGetOutstrokeInfo() then -- se aperto, cambio gli angoli iniziali if not bClosed then CAM.HintWaterJetAngC( RecMPartCs.SideAng + dTaperAng, ( sLay ~= 'OutLoop'), nRefEntId) -- altrimenti chiuso, spezzo a metà else -- lunghezza della geometria local dPathLen = 0 for k = 1, #tabEnt do dPathLen = dPathLen + EgtCurveLength( tabEnt[k]) end -- accorcio la lavorazione alla metà EgtSetMachiningParam( MCH_MP.OVERL, 0) EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dPathLen/2) if EgtPreviewMachining() then CAM.CopyPreviewToPiece( nMill, nPartId) end -- copio la lavorazione per lavorare l'altra metà local nMill2 = EgtCopyMachining( sName .. '2', sName) EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dPathLen/2) EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) if EgtPreviewMachining() then CAM.CopyPreviewToPiece( nMill2, nPartId) end EgtSetOperationStatus( nMill2, false) EgtSetInfo( nMill2, 'Lay', sLay) end end else CAM.ERR = 41 end EgtSetOperationStatus( nMill, false) EgtSetInfo( nMill, 'Lay', sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end -- segnalazione lavorazioni applicate RecMPartCs.EndDone = true if RecMPartCs.OperId == 0 then RecMPartCs.StartDone = true end RecMPartCe.StartDone = true if RecMPartCe.OperId == 0 then RecMPartCe.EndDone = true end for k = 1, #tabMid do TabMPartC[tabMid[k]].StartDone = true TabMPartC[tabMid[k]].EndDone = true end end end -- FINE: Ciclo sui tratti concatenabili -- Se necessario riduco ingresso/uscita per occupare il solco del taglio di lama (dWidth) local function VerifyInterference( nMill, dWidth) local dRad = 0.5 * CAM.GetToolDiameter() EgtPreviewMachining() local nRet = EgtVerifyMachining( nMill) if nRet == NST_FMI.RM then -- Recupero i parametri di uscita local Tang = EgtGetMachiningParam( MCH_MP.LOTANG) local Perp = EgtGetMachiningParam( MCH_MP.LOPERP) if Perp and dWith and Perp > dWidth then EgtSetMachiningParam( MCH_MP.LOTANG, dWidth - dRad) EgtSetMachiningParam( MCH_MP.LOPERP, dWidth - 2*dRad) EgtPreviewMachining() end end nRet = EgtVerifyMachining( nMill) if nRet == NST_FMI.RM then -- Recupero i parametri di ingresso local Tang = EgtGetMachiningParam( MCH_MP.LITANG) local Perp = EgtGetMachiningParam( MCH_MP.LIPERP) if Perp and dWith and Perp > dWidth then EgtSetMachiningParam( MCH_MP.LITANG, dWidth - dRad) EgtSetMachiningParam( MCH_MP.LIPERP, dWidth - 2*dRad) EgtSetMachiningParam( MCH_MP.LIHOLE, false) end end end -- Ciclo sui tratti singoli rimasti for i = 1, #TabMPartC do local RecMPartC = TabMPartC[i] -- completo singolo if not RecMPartC.StartDone and RecMPartC.OperId == 0 then -- |LAVORAZIONE| local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId local nMill = EgtAddMachining( 'Waterjet'..tostring( nRefEntId)..'S', sWaterJet) if nMill then local sName = EgtGetName( nMill) -- aggiustamenti vari local dRad = 0.5 * CAM.GetToolDiameter() local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR) local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) -- verifico se percorso chiuso local bClosed = EgtCurveIsClosed( RecMPartC.EntId) -- se aperto, sistemazioni inizio e fine if not bClosed then -- dati inizio-fine dipendono da inverti lavorazione local dPrevAng = RecMPartC.PrevAng local dNextAng = RecMPartC.NextAng if bInvert then dPrevAng, dNextAng = dNextAng, dPrevAng end local dStWhiExt = RecMPartC.StWhiExt local dEdWhiExt = RecMPartC.EdWhiExt if bInvert then dStWhiExt, dEdWhiExt = dEdWhiExt, dStWhiExt end -- aggiusto inizio local dStartAddLen = 0 if 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'), nRefEntId) -- aggiungo la geometria if EgtSetMachiningGeometry( {RecMPartC.EntId}) then -- verifico che la lavorazione parziale non interferisca con altri pezzi VerifyInterference( nMill, RecMPartC.Width) if EgtPreviewMachining() then local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId)) CAM.CopyPreviewToPiece( nMill, nPartId) -- se inclinata e non sta nelle corse if abs( RecMPartC.SideAng + dTaperAng) > GEO.EPS_ANG_SMALL and not EgtApplyMachining( true) and EgtGetOutstrokeInfo() then -- se aperto, cambio gli angoli iniziali if not bClosed then CAM.HintWaterJetAngC( RecMPartC.SideAng + dTaperAng, ( sLay ~= 'OutLoop'), nRefEntId) -- altrimenti chiuso, spezzo a metà else -- lunghezza della geometria local dPathLen = EgtCurveLength( RecMPartC.EntId) -- accorcio la lavorazione alla metà EgtSetMachiningParam( MCH_MP.OVERL, 0) EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dPathLen/2) if EgtPreviewMachining() then CAM.CopyPreviewToPiece( nMill, nPartId) end -- copio la lavorazione per lavorare l'altra metà local nMill2 = EgtCopyMachining( sName .. '2', sName) EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dPathLen/2) EgtSetMachiningParam( MCH_MP.ENDADDLEN, 0) if EgtPreviewMachining() then CAM.CopyPreviewToPiece( nMill2, nPartId) end EgtSetOperationStatus( nMill2, false) EgtSetInfo( nMill2, 'Lay', sLay) end end -- se aperta e necessaria lavorazione doppia if not bClosed and RecMPartC.Double then -- copio la lavorazione per fare il doppio local nMill2 = EgtCopyMachining( sName .. '2', sName) CAM.InvertWorkside() EgtSetMachiningParam( MCH_MP.OFFSR, -RecMPartC.Width) if EgtPreviewMachining() then CAM.CopyPreviewToPiece( nMill2, nPartId) end EgtSetOperationStatus( nMill2, false) EgtSetInfo( nMill2, 'Lay', sLay) end else CAM.ERR = 42 end EgtSetOperationStatus( nMill, false) EgtSetInfo( nMill, 'Lay', sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end RecMPartC.StartDone = true RecMPartC.EndDone = true end -- parziale singolo su **inizio** if not RecMPartC.StartDone and RecMPartC.StartStrict and RecMPartC.PrevAng >= - 5 then local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId local nMill = EgtAddMachining( 'Waterjet'..tostring( nRefEntId)..'S', sWaterJet) if nMill then local sName = EgtGetName( nMill) -- aggiustamenti vari local dRad = 0.5 * CAM.GetToolDiameter() local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR) local dEndAddLen = RecMPartC.EntLen - RecMPartC.DeltaTI - dDeltaLenPartMilling - RecMPartC.EdWhiExt + RecMPartC.Sal -- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!! if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then dEndAddLen = 0 end EgtSetMachiningParam( MCH_MP.ENDADDLEN, -dEndAddLen) local dStartAddLen = 0 if RecMPartC.PrevAng < - 5 and RecMPartC.PrevAng > - 175 then dStartAddLen = dRad * ( cos( 180 + RecMPartC.PrevAng) + 1) / sin( 180 + RecMPartC.PrevAng) EgtSetMachiningParam( MCH_MP.LEADINTYPE, nIntAngLiType) EgtSetMachiningParam( MCH_MP.LITANG, dIntAngLiTang) EgtSetMachiningParam( MCH_MP.LIPERP, dIntAngLiPerp) end dStartAddLen = dStartAddLen - RecMPartC.StWhiExt - RecMPartC.Sal - dDeltaCutSafety -- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!! if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then dStartAddLen = 0 end EgtSetMachiningParam( MCH_MP.STARTADDLEN, - dStartAddLen) -- se previsto, imposto feed e conicità da Q* local dTaperAng = 0 if vThickFeed then local dDepth = dRawHeight / cos( RecMPartC.SideAng) local dFeed, dThRef = GetWjSpeed( dDepth) if dFeed and dThRef then EgtSetMachiningParam( MCH_MP.FEED, dFeed) EgtSetMachiningParam( MCH_MP.THICKREF, dThRef) end dTaperAng = GetWjTaperAng( dDepth) end -- eventuale angolo di lato e offset associato EgtSetMachiningParam( MCH_MP.SIDEANGLE, RecMPartC.SideAng + dTaperAng) EgtSetMachiningParam( MCH_MP.OFFSR, RecMPartC.Offset + dUserOffsR) -- suggerisco angoli iniziali CAM.HintWaterJetAngC( RecMPartC.SideAng + dTaperAng, ( sLay == 'OutLoop'), nRefEntId) -- disattivo foro di ingresso EgtSetMachiningParam( MCH_MP.LIHOLE, false) -- riduco le lavorazioni per rimanere nel solco della lama dRad = 0.5 * CAM.GetToolDiameter() local Perp = EgtGetMachiningParam( MCH_MP.LIPERP) if Perp > RecMPartC.Width then EgtSetMachiningParam( MCH_MP.LITANG, RecMPartC.Width/2) EgtSetMachiningParam( MCH_MP.LIPERP, RecMPartC.Width/2 - dRad) end -- Recupero i parametri di uscita Perp = EgtGetMachiningParam( MCH_MP.LOPERP) if Perp > RecMPartC.Width then EgtSetMachiningParam( MCH_MP.LOTANG, RecMPartC.Width/2) EgtSetMachiningParam( MCH_MP.LOPERP, RecMPartC.Width/2 - dRad) end if EgtSetMachiningGeometry( {RecMPartC.EntId}) then -- verifico che la lavorazione parziale non interferisca con altri pezzi -- VerifyInterference( nMill, RecMPartC.Width) if EgtPreviewMachining() then local nPartId = EgtGetParent( EgtGetParent( RecMPartC.EntId)) CAM.CopyPreviewToPiece( nMill, nPartId) if RecMPartC.Double then -- copio la lavorazione per fare il doppio local nMill2 = EgtCopyMachining( sName .. '2', sName) CAM.InvertWorkside() EgtSetMachiningParam( MCH_MP.OFFSR, -RecMPartC.Width - RecMPartC.Offset - dUserOffsR) if EgtPreviewMachining() then CAM.CopyPreviewToPiece( nMill2, nPartId) end EgtSetOperationStatus( nMill2, false) EgtSetInfo( nMill2, 'Lay', sLay) end else CAM.ERR = 43 end EgtSetOperationStatus(nMill,false) EgtSetInfo(nMill,'Lay',sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end RecMPartC.StartDone = true end -- parziale singolo su **fine** if not RecMPartC.EndDone and RecMPartC.EndStrict and RecMPartC.NextAng >= - 5 then local nRefEntId = EgtGetInfo( RecMPartC.EntId, 'CopyEnt', 'i') or RecMPartC.EntId local nMill = EgtAddMachining( 'Waterjet'..tostring( nRefEntId)..'E', sWaterJet) if nMill then local sName = EgtGetName( nMill) -- aggiustamenti vari local dRad = 0.5 * CAM.GetToolDiameter() local dUserOffsR = EgtGetMachiningParam( MCH_MP.OFFSR) local dStartAddLen = RecMPartC.EntLen - RecMPartC.DeltaT - dDeltaLenPartMilling - RecMPartC.StWhiExt + RecMPartC.Eal -- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!! if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then dStartAddLen = 0 end EgtSetMachiningParam( MCH_MP.STARTADDLEN, -dStartAddLen) local dEndAddLen = 0 if RecMPartC.NextAng < - 5 and RecMPartC.NextAng > - 175 then dEndAddLen = dRad * ( cos( 180 + RecMPartC.NextAng) + 1) / sin( 180 + RecMPartC.NextAng) EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, nIntAngLoType) EgtSetMachiningParam( MCH_MP.LOTANG, dIntAngLoTang) EgtSetMachiningParam( MCH_MP.LOPERP, dIntAngLoPerp) end dEndAddLen = dEndAddLen - RecMPartC.EdWhiExt - RecMPartC.Eal - dDeltaCutSafety -- se taglio con affondamento ridotto |NON RIDURRE| !!!!!!!!!!!!!!! if RecMPartC.Depth - dRawHeight < GEO.EPS_SMALL then dEndAddLen = 0 end EgtSetMachiningParam( MCH_MP.ENDADDLEN, - dEndAddLen) -- se previsto, imposto feed e conicità da Q* local dTaperAng = 0 if vThickFeed then local dDepth = dRawHeight / cos( RecMPartC.SideAng) local dFeed, dThRef = GetWjSpeed( dDepth) if dFeed and dThRef then EgtSetMachiningParam( MCH_MP.FEED, dFeed) EgtSetMachiningParam( MCH_MP.THICKREF, dThRef) end dTaperAng = GetWjTaperAng( dDepth) end -- eventuale angolo di lato e offset associato EgtSetMachiningParam( MCH_MP.SIDEANGLE, RecMPartC.SideAng + dTaperAng) EgtSetMachiningParam( MCH_MP.OFFSR, RecMPartC.Offset + dUserOffsR) -- suggerisco angoli iniziali CAM.HintWaterJetAngC( RecMPartC.SideAng + dTaperAng, ( sLay == 'OutLoop'), nRefEntId) -- disattivo foro di ingresso EgtSetMachiningParam( MCH_MP.LIHOLE, false) -- riduco le lavorazioni per rimanere nel solco della lama dRad = 0.5 * CAM.GetToolDiameter() local Perp = EgtGetMachiningParam( MCH_MP.LIPERP) if Perp > RecMPartC.Width then EgtSetMachiningParam( MCH_MP.LITANG, RecMPartC.Width/2) EgtSetMachiningParam( MCH_MP.LIPERP, RecMPartC.Width/2 - dRad) end -- Recupero i parametri di uscita Perp = EgtGetMachiningParam( MCH_MP.LOPERP) if Perp > RecMPartC.Width then EgtSetMachiningParam( MCH_MP.LOTANG, RecMPartC.Width/2) EgtSetMachiningParam( MCH_MP.LOPERP, RecMPartC.Width/2 - dRad) end -- aggiungo la geometria if EgtSetMachiningGeometry( {RecMPartC.EntId}) then -- verifico che la lavorazione parziale non interferisca con altri pezzi -- VerifyInterference( nMill, RecMPartC.Width) if EgtPreviewMachining() then local nPartId = EgtGetParent(EgtGetParent( RecMPartC.EntId)) CAM.CopyPreviewToPiece(nMill, nPartId) if RecMPartC.Double then -- copio la lavorazione per fare il doppio local nMill2 = EgtCopyMachining( sName .. '2', sName) CAM.InvertWorkside() EgtSetMachiningParam( MCH_MP.OFFSR, -RecMPartC.Width - RecMPartC.Offset - dUserOffsR) if EgtPreviewMachining() then CAM.CopyPreviewToPiece( nMill2, nPartId) end EgtSetOperationStatus( nMill2, false) EgtSetInfo( nMill2, 'Lay', sLay) end else CAM.ERR = 44 end EgtSetOperationStatus(nMill,false) EgtSetInfo(nMill,'Lay',sLay) else EgtRemoveOperation( nMill) end else CAM.ERR = 30 end RecMPartC.EndDone = true end end -- FINE: Ciclo sui tratti singoli rimasti -- Preparo tabella collegamenti : **TabBridges** (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 = floor( Depth / dStep) + 1 dStep = Depth / nStep -- assegno un nuovo affondamento alla prima lavorazione local nCountEnt = #TabOnCut for i = 1 , nCountEnt, 1 do EgtSetInfo( TabOnCut[i], 'Depth', dStep) EgtSetInfo( TabOnCut[i], 'StepType', 1) end -- recupero l'ultima direzione di taglio local _, LastDir = CAM.GetReturnDir( TabOnCut[nCountEnt]) -- aggiungo tutte le altre entità per gestire l'affondamento di taglio for j = 2, nStep, 1 do for i = #TabOnCut, #TabOnCut - nCountEnt + 1, -1 do table.insert( TabOnCut, EgtCopyGlob( TabOnCut[i], EgtGetParent(TabOnCut[i]))) end for i = #TabOnCut - nCountEnt + 1, #TabOnCut, 1 do EgtSetInfo( TabOnCut[i], 'Depth', j * dStep) EgtSetInfo( TabOnCut[i], 'StepType', 1) if LastDir == 1 then LastDir = 2 else LastDir = 1 end EgtSetInfo( TabOnCut[i], 'Dir', LastDir) end end end end end PreVerifyMachining( TabOnCut) -- Ciclo sulle entità for i = 1, #TabOnCut do local nOnCutId = TabOnCut[i] -- leggo la direzione di taglio local _, RetDir = CAM.GetReturnDir( nOnCutId) local bDepth, Depth = CAM.GetDepth( nOnCutId) if not bDepth then Depth = dEngravingDepth end local bWidth, Width = CAM.GetWidth( nOnCutId) if not bWidth then Width = dEngravingWidth end local _, EnInv = CAM.GetEnableInvert( nOnCutId) -- **gestione incisioni inclinate** local _, SideAng = CAM.GetSideAng( nOnCutId, 1) local Offset = 0 local bInvert = false -- if Width < GEO.EPS_SMALL then Width = SawTh end local nStrict = EgtGetInfo( nOnCutId, 'Strict', 'i') or nWhiskerLen -- verifico se entità composta quante parti lavorare local _, nParts = EgtCurveDomain( nOnCutId) -- eseguo uno o più tagli if Width > SawTh - 0.3 then local nCuts = ceil( Width / ( SawTh + 10 * GEO.EPS_SMALL)) if abs( SideAng) > GEO.EPS_ANG_SMALL then nCuts = 1 end local dSideStep = EgtIf( nCuts <= 1, 0, ( Width - SawTh) / ( nCuts - 1)) -- EgtOutLog(" → # Cuts ← "..nCuts) -- EgtOutLog(" → SideStep ← "..dSideStep) for j = 1, nParts do for k = 1, nCuts do -- EgtOutLog(" → # current Cuts ← "..i) -- inserimento lavorazione local nSaw = EgtAddMachining( 'OnSaw'..tostring( nOnCutId), sOnSaw) if nSaw then if abs( SideAng) < GEO.EPS_ANG_SMALL then if EnInv then local P1 = EgtSP( nOnCutId, GDB_ID.ROOT) local P2 = EgtEP( nOnCutId, GDB_ID.ROOT) bInvert = CAM.GetInvertVerticalCut(P1,P2) end else local nHSide = EgtGetMachiningParam( MCH_MP.HEADSIDE) bInvert = ( SideAng < 0 and nHSide == MCH_SAW_HS.RIGHT) or ( SideAng > 0 and nHSide == MCH_SAW_HS.LEFT) end EgtSetMachiningGeometry( EgtIf( nParts == 1, { nOnCutId}, {{ nOnCutId, j - 1}})) EgtSetMachiningParam( MCH_MP.DEPTH, min( Depth, dRawHeight)) if nStrict == 1 or nStrict == 3 then EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) end if nStrict == 2 or nStrict == 3 then EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) end -- |WARNING| : EgtSetMachiningParam( MCH_MP.OFFSL, -Width / 2 + ( k - 1) * dSideStep) -- Verifico di essere nei tagli diretti **Ver_2.6f2** local bDirectCut, _ = CAM.GetDirectCut( nOnCutId) if bDirectCut then EgtOutLog(' → OnCuts da taglio diretto') -- tipologia di step local _, nStepType = CAM.GetStepType( nOnCutId) EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType) else EgtOutLog(' → OnCuts da taglio CAD') end -- inizio settattaggio parametri per **incisione inclinata** if abs( SideAng) > GEO.EPS_ANG_SMALL then Offset = - SawTh/2 EgtSetMachiningParam( MCH_MP.OFFSL, Offset) EgtSetMachiningParam( MCH_MP.SIDEANGLE, SideAng) end if RetDir ~= 2 then EgtSetMachiningParam( MCH_MP.INVERT, bInvert) EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.LEFT, MCH_SAW_WS.RIGHT)) else -- solo per spianature EgtSetMachiningParam( MCH_MP.INVERT, not bInvert) EgtSetMachiningParam( MCH_MP.WORKSIDE, EgtIf( bInvert, MCH_SAW_WS.RIGHT, MCH_SAW_WS.LEFT)) EgtSetMachiningParam( MCH_MP.HEADSIDE, nOthHside) end -- fine settaggio if EgtPreviewMachining() then -- se lavorazione non applicata, provo a ridurre l'affondamento if EgtIsMachiningEmpty() then local dLen = EgtCurveLength( nOnCutId) if dLen and dLen < SawDiam then local dRedLen = dLen - 5 local dNewDepth = 0.5 * ( SawDiam - sqrt( SawDiam * SawDiam - dRedLen * dRedLen)) if dNewDepth > 1.0 then EgtSetMachiningParam( MCH_MP.DEPTH, min( dNewDepth, dRawHeight)) EgtPreviewMachining() end end end if not EgtIsMachiningEmpty() then local nPartId = EgtGetParent( EgtGetParent( nOnCutId)) CAM.ChangePvColor( nSaw, colOnCut, colOnExt) CAM.CopyPreviewToPiece( nSaw, nPartId) end else CAM.ERR = 46 end EgtSetOperationStatus( nSaw, false) EgtSetInfo( nSaw, 'Lay', sLay) else CAM.ERR = 30 end end end end end end -- Funzione che applica le fresature da sopra function CAM.ApplyOnMillings( TabOnCut, sLay) -- Diametro della fresa local MillDiam = CAM.GetToolDiameterFromMdb( sOnMill) if MillDiam < GEO.EPS_SMALL then CAM.ERR = 30 return end -- Ciclo sulle entità for i = 1, #TabOnCut do local nOnCutId = TabOnCut[i] local bDepth, Depth = CAM.GetDepth( nOnCutId) if not bDepth then Depth = dEngravingDepth end if Depth > dRawHeight then Depth = dRawHeight end local bWidth, Width = CAM.GetWidth( nOnCutId) if not bWidth then Width = dEngravingWidth end if Width < GEO.EPS_SMALL then Width = MillDiam end local nStrict = EgtGetInfo( nOnCutId, 'Strict', 'i') or 3 -- eseguo uno o più tagli if Width > MillDiam - 0.3 then local nMills = ceil( Width / ( MillDiam + 10 * GEO.EPS_SMALL)) local dSideStep = EgtIf( nMills <= 1, 0, ( Width - MillDiam) / ( nMills - 1)) for i = 1, nMills do -- inserimento lavorazione local nMill = EgtAddMachining( 'OnMill'..tostring( nOnCutId), sOnMill) if nMill then CAM.HintDrillMillAngC() EgtSetMachiningGeometry( { nOnCutId}) EgtSetMachiningParam( MCH_MP.DEPTH, Depth) -- Verifico di essere nei tagli diretti **Ver_2.6f2** local bDirectCut, _ = CAM.GetDirectCut( nOnCutId) if bDirectCut then EgtOutLog(' → OnMilling da taglio diretto') -- tipologia di step local _, nStepType = CAM.GetStepType( nOnCutId) EgtSetMachiningParam( MCH_MP.STEPTYPE, nStepType) -- tipo di ingresso local sLeadInType = EgtGetMachiningParam( MCH_MP.LEADINTYPE) EgtSetMachiningParam( MCH_MP.LEADINTYPE, sLeadInType or MCH_MILL_ST.GLIDE) -- affondameto di step local dStep = EgtGetMachiningParam( MCH_MP.STEP) EgtSetMachiningParam( MCH_MP.STEP, dStep) else EgtOutLog(' → OnMilling da taglio CAD') local dStep = EgtGetMachiningParam( MCH_MP.STEP) dStep = min( dStep, Depth - 0.1) EgtSetMachiningParam( MCH_MP.STEP, dStep) end EgtSetMachiningParam( MCH_MP.LIELEV, 2.0) if nStrict == 1 or nStrict == 3 then EgtSetMachiningParam( MCH_MP.STARTADDLEN, -MillDiam/2) end if nStrict == 2 or nStrict == 3 then EgtSetMachiningParam( MCH_MP.ENDADDLEN, -MillDiam/2) end EgtSetMachiningParam( MCH_MP.OFFSR, -Width / 2 + ( i - 1) * dSideStep) if EgtPreviewMachining() then if not EgtIsMachiningEmpty() then local nPartId = EgtGetParent( EgtGetParent( nOnCutId)) CAM.ChangePvColor( nMill, colOnCut, colOnExt) CAM.CopyPreviewToPiece( nMill, nPartId) end else CAM.ERR = 46 end EgtSetOperationStatus( nMill, false) EgtSetInfo( nMill, 'Lay', sLay) else CAM.ERR = 30 end end end end end -- Funzione che applica le fresature Filo Top **riceve direttamente il percorso utensile** function CAM.ApplyFiloTopMillings( TabFiloTopLay) -- Ciclo sui layer for i = 1, #TabFiloTopLay do local LayId = TabFiloTopLay[i] local dDepth = EgtGetInfo( LayId, 'Depth', 'd') -- applico la lavorazione local nMill = EgtAddMachining( 'FiloTop'..tostring( LayId), sMill) if nMill then CAM.HintDrillMillAngC() local vGeom = {} local EntId = EgtGetFirstInGroup( LayId) while EntId do table.insert( vGeom, EntId) EntId = EgtGetNext( EntId) end EgtSetMachiningGeometry( vGeom) EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) EgtSetMachiningParam( MCH_MP.STEPTYPE, MCH_MILL_ST.SPIRAL) local dStep = EgtGetMachiningParam( MCH_MP.STEP) dStep = min( dStep, dDepth - 0.1) EgtSetMachiningParam( MCH_MP.STEP, dStep) EgtSetMachiningParam( MCH_MP.LIELEV, 2.0) if EgtPreviewMachining() then if not EgtIsMachiningEmpty() then local nPartId = EgtGetParent( LayId) CAM.ChangePvColor( nMill, colOnCut, colOnExt) CAM.CopyPreviewToPiece( nMill, nPartId) end else CAM.ERR = 46 end EgtSetOperationStatus( nMill, false) EgtSetInfo( nMill, 'Lay', 'InLoop') EgtSetInfo( nMill, 'FiloTop', 1) else CAM.ERR = 30 end end end -- Funzione che applica le Svuotature function CAM.ApplyPocketings( TabPocketLay) -- Ciclo sui layer for i = 1, #TabPocketLay do local LayId = TabPocketLay[i] local dDepth = EgtGetInfo( LayId, 'Depth', 'd') -- applico la lavorazione local nPock = EgtAddMachining( 'Pocket'..tostring( LayId), sPocket) if nPock then CAM.HintDrillMillAngC() local vGeom = {} local EntId = EgtGetFirstInGroup( LayId) while EntId do if EgtGetType( EntId) == GDB_TY.CRV_COMPO then table.insert( vGeom, EntId) end EntId = EgtGetNext( EntId) end EgtSetMachiningGeometry( vGeom) EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) EgtSetMachiningParam( MCH_MP.LIELEV, 2.0) if EgtPreviewMachining() then if not EgtIsMachiningEmpty() then local nPartId = EgtGetParent( LayId) CAM.ChangePvColor( nPock, colOnCut, colOnExt) CAM.CopyPreviewToPiece( nPock, nPartId) end else CAM.ERR = 46 end EgtSetOperationStatus( nPock, false) EgtSetInfo( nPock, 'Lay', 'Pocket') EgtSetInfo( nPock, 'Pocket', 1) else CAM.ERR = 30 end end end -- Funzione che applica i tagli da sotto function CAM.ApplyUnderCuts( TabDripCut, sLay) -- Ciclo sulle entità for i = 1, #TabDripCut do local nDripId = TabDripCut[i] local bDepth, dDepth = CAM.GetDepth( nDripId) local bStrict = ( EgtGetInfo( nDripId, 'Strict') ~= nil) local nPartId = EgtGetParent( EgtGetParent( nDripId)) -- inserimento lavorazione local nSaw = EgtAddMachining( 'DripSaw'..tostring(nDripId), sDripSaw) if nSaw then EgtSetMachiningGeometry( {nDripId}) if bDepth then EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) end if bStrict then EgtSetMachiningParam( MCH_MP.LEADINTYPE, MCH_SAW_LI.STRICT) EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, MCH_SAW_LO.STRICT) end -- calcolo il centro del pezzo local ptPartCen = CAM.GetPartCenter( nPartId) -- distanza della linea da lavorare dal centro local ptSt = EgtSP( nDripId, GDB_ID.ROOT) local vtNrm = EgtSV( nDripId, GDB_ID.ROOT) vtNrm:rotate( Z_AX(), 90) local dDist = abs( ( ptPartCen - ptSt) * vtNrm) --EgtOutLog( 'DripDist=' .. EgtNumToString( dDist, 1)) -- se la distanza supera il limite e il lato mandrino è a sinistra if dDist > dDripCutYmMaxDist and EgtGetMachiningParam( MCH_MP.HEADSIDE) == MCH_SAW_HS.LEFT then -- inverto la direzione di lavoro (per portare il taglio a Ymax) EgtSetMachiningParam( MCH_MP.INVERT, true) -- conseguentemente devo invertire anche il lato di lavoro CAM.InvertWorkside() end if EgtPreviewMachining() then if not EgtIsMachiningEmpty() then CAM.ChangePvColor( nSaw, colDripCut, colDripExt) CAM.CopyPreviewToPiece( nSaw, nPartId) end else CAM.ERR = 46 end EgtSetOperationStatus( nSaw, false) EgtSetInfo( nSaw, 'Lay', sLay) else CAM.ERR = 30 end end end -- Funzione che applica le forature da sotto function CAM.ApplyUnderDrillings( TabDripHole, sLay) -- Ciclo sulle entità curva for i = 1, #TabDripHole do local nEntId = TabDripHole[i] local bDepth, dDepth = CAM.GetDepth( nEntId) local nPartId = EgtGetParent( EgtGetParent( nEntId)) local nDrill = EgtAddMachining( 'UnderDrill'..tostring( nEntId), sDripDrill) if nDrill then -- foro standard local bSetOk = EgtSetMachiningGeometry( {nEntId}) if bSetOk then -- calcolo il centro del pezzo local ptPartCen = CAM.GetPartCenter( nPartId) -- calcolo il centro del foro local ptCen = EgtCP( nEntId, GDB_ID.ROOT) -- porto il foro sempre a Y max if ptCen:getY() < ptPartCen:getY() - 10 then EgtSetMachiningParam( MCH_MP.INITANGS, "V=180") else EgtSetMachiningParam( MCH_MP.INITANGS, "V=0") end if bDepth then EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) end if EgtPreviewMachining() then CAM.ChangePvColor( nDrill, colDripCut, colDripExt) CAM.CopyPreviewToPiece( nDrill, nPartId) else CAM.ERR = 45 end EgtSetOperationStatus( nDrill, false) EgtSetInfo( nDrill, 'Lay', sLay) else EgtRemoveOperation( nDrill) end else CAM.ERR = 30 end end end -- Funzione che applica le lavorazioni function CAM.ApplyMachinings() -- calcolo flag fresature sugli angoli local bCalcMoC = ( ( sMill ~= '' and bMillingOnCorners) or sDrill == '') -- |OUTLOOP| lavorazioni esterne if sSaw ~= '' then CAM.ApplyCuts( TabOutCut, 'OutLoop', TabOutCrv, TabOutPartial) elseif sSawTilted ~= '' then local TabIndex = {} for i = 1, #TabOutCut, 1 do local bExists, dAng = CAM.GetSideAng( TabOutCut[i]) if not bExists then table.insert( TabOutCrv, TabOutCut[i]) table.insert( TabIndex, i) end end for i = #TabIndex, 1, -1 do table.remove( TabOutCut, TabIndex[i]) end CAM.ApplyCuts( TabOutCut, 'OutLoop', TabOutCrv, TabOutPartial) else TabOutCrv = EgtJoinTables( TabOutCut, TabOutCrv) end if sMill ~= '' then local TabPart = EgtIf( bCalcMoC, TabOutPartial, {}) CAM.ApplyMillings( TabOutCrv, TabPart, 'OutLoop') elseif sDrill ~= '' then CAM.ApplyDrillings( TabOutCrv, 'OutLoop') end if sDrill ~= '' then if not bCalcMoC then CAM.ApplyDrillingsOnPartialCuts( TabOutPartial, 'OutLoop') end end -- **APPLY WATERJETTING** if sWaterJet ~= '' then CAM.ApplyWaterJettings( TabOutCrv, TabOutPartial, 'OutLoop') end -- |INLOOP| lavorazioni interne if sSaw ~= '' then CAM.ApplyCuts( TabInCut, 'InLoop', TabInCrv, TabInPartial) else TabInCrv = EgtJoinTables( TabInCut, TabInCrv) end if sMill ~= '' then local TabPart = EgtIf( bCalcMoC, TabInPartial, {}) CAM.ApplyMillings( TabInCrv, TabPart, 'InLoop') elseif sDrill ~= '' then CAM.ApplyDrillings( TabInCrv, 'InLoop') end if sDrill ~= '' then CAM.ApplyDrillings( TabInHole, 'InLoop') if not bCalcMoC then CAM.ApplyDrillingsOnPartialCuts( TabInPartial, 'InLoop') end end if sWaterJet ~= '' then CAM.ApplyWaterJettings( TabInCrv, TabInPartial, 'InLoop') end -- |ONPATH| lavorazioni di incisione if #TabOnCut > 0 then -- dalla versione **2.6f2** cerco nelle info dell'entità il tipo di utensile da usare local _, ToolInFLattening = CAM.GetFlattenigTool( TabOnCut[1]) --if bEngravingWithMill and sOnMill then if ToolInFLattening==1 and sOnMill then CAM.ApplyOnMillings( TabOnCut, 'OnPath') elseif sOnSaw ~= '' then CAM.ApplyOnCuts( TabOnCut, 'OnPath') end end -- **APPLY FILOTOP** if sMill ~= '' and #TabFiloTopLay > 0 then CAM.ApplyFiloTopMillings( TabFiloTopLay) end -- lavorazioni di Svuotatura if sPocket ~= '' and #TabPocketLay > 0 then CAM.ApplyPocketings( TabPocketLay) end -- lavorazioni di taglio da sotto if sDripSaw ~= '' and #TabDripCut > 0 then CAM.ApplyUnderCuts( TabDripCut, 'Drip') end -- lavorazioni di foratura da sotto if sDripDrill ~= '' and #TabDripHole then CAM.ApplyUnderDrillings( TabDripHole, 'UnderDrill') end end -- -- Funzione che raccoglie gli identificativi delle lavorazioni di un pezzo function CAM.FindPartMachinings( nPartId, TabData) -- cerco il gruppo di preview local nPrevId = EgtGetFirstNameInGroup( nPartId, 'PV') -- analizzo i gruppi del preview local nId = EgtGetFirstGroupInGroup( nPrevId or GDB_ID.NULL) while nId do local nMchId = EgtGetInfo( nId, 'MId', 'i') if nMchId then local nEntId = CAM.GetEntIdFromMachining( nMchId) table.insert( TabData, {Mch= nMchId, Part=nPartId, Ent=nEntId}) end nId = EgtGetNextGroup( nId) end return TabData end -- Funzione che aggiorna le lavorazioni function CAM.UpdateOperations( TabData, bPreview, bClPath) -- Reset flag presenza tagli inclinati EgtRemoveInfo( EgtGetCurrMachGroup(), 'SIDECUTS') local bSideCuts = false -- Imposto come fase corrente la prima local nCurrPhase = 1 EgtSetCurrPhase( nCurrPhase) -- Ciclo sulle lavorazioni da aggiornare for i = 1, #TabData do local nOperId = TabData[i].Mch local nPartId = TabData[i].Part -- verifico se cambiata la fase local nPhase = EgtGetOperationPhase( nOperId) if nPhase ~= nCurrPhase then nCurrPhase = nPhase EgtSetCurrPhase( nCurrPhase) end -- se disposizione if EgtGetOperationType( nOperId) == MCH_OY.DISP then CAM.MultiCutDispositionSettings( nOperId) if not EgtSpecialApplyDisposition( nOperId, true) then if EgtEmptyGroup( nOperId) then EgtOutLog("The phase "..tostring(nCurrPhase).." is empty: see *.mlse to understand the problem!" ) end CAM.ERR = 70 end -- altrimenti lavorazione else -- imposto la lavorazione come corrente EgtSetCurrMachining( nOperId) -- verifico se tagli standard, da sopra o da sotto local bCut = CAM.MachiningIsStdCut( nOperId) local bOn = CAM.MachiningIsOnCut( nOperId) local bDrip = CAM.MachiningIsDripCut( nOperId) -- aggiorno anteprima se richiesto if bPreview and nPartId then if EgtPreviewMachining( true) then if bOn then CAM.ChangePvColor( nOperId, colOnCut, colOnExt) elseif bDrip then CAM.ChangePvColor( nOperId, colDripCut, colDripExt) elseif bCut then local sCurrSaw = EgtTdbGetToolFromUUID( EgtGetMachiningParam( MCH_MP.TUUID) or '') if sCurrSaw and EgtTdbSetCurrTool( sCurrSaw) then CAM.ApplyPvColor( sCurrSaw, nOperId) end end CAM.CopyPreviewToPiece( nOperId, nPartId) else CAM.ERR = 48 end end -- aggiorno percorso di lavoro se richiesto e lavorazione attiva if bClPath and EgtGetOperationMode( nOperId) then -- verifico se taglio inclinato local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE) local bSideAng = ( dSideAng and abs( dSideAng) > GEO.EPS_ANG_SMALL) if bSideAng then bSideCuts = true end CAM.MultiCutMachiningSettings() -- verifico waterjet -- setto la feed letta da operation ------------------------------------------------------------------------------ local sWjQuality = EgtGetInfo( nOperId, 'Quality') if EgtGetOperationType( nOperId) == MCH_OY.WATERJETTING and sWjQuality then -- determino tabella spessore-feed da utilizzare: **vThickFeed** local vThickFeed = nil if sMaterial and sWjQuality and dRawHeight then vThickFeed = {} local sWjDbPath = EgtGetCurrMachineDir() .. '\\Machinings\\WaterjetDB.data' for i = 1, 20 do local sLine = EgtGetStringFromIni( sMaterial, tostring( i), '', sWjDbPath) if #sLine == 0 then break end local vVal = EgtSplitString( sLine, ',') local dThick = tonumber( vVal[1] or '') local dFeed if sWjQuality == 'Q1' then dFeed = tonumber( vVal[2] or '') elseif sWjQuality == 'Q2' then dFeed = tonumber( vVal[3] or '') elseif sWjQuality == 'Q3' then dFeed = tonumber( vVal[4] or '') elseif sWjQuality == 'Q4' then dFeed = tonumber( vVal[5] or '') elseif sWjQuality == 'Q5' then dFeed = tonumber( vVal[6] or '') else dFeed = tonumber( vVal[7] or '') end local dFlux = tonumber( vVal[9] or '') or 250 if dThick and dFeed then table.insert( vThickFeed, { Th=dThick, F=dFeed, Fl=dFlux}) end end end -- funzione locale per tabella spessore-feed local function GetWjSpeed( dDepth) for i = 1, #( vThickFeed or {}) do if dDepth < vThickFeed[i].Th + 0.1 then if i == 1 or ( vThickFeed[i].Th - vThickFeed[i-1].Th) < 0.1 then return vThickFeed[i].F, 0 else local dCoeff = ( dDepth - vThickFeed[i-1].Th) / ( vThickFeed[i].Th - vThickFeed[i-1].Th) return ( 1 - dCoeff) * vThickFeed[i-1].F + dCoeff * vThickFeed[i].F, 0 end end end if #( vThickFeed or {}) > 0 then return vThickFeed[#vThickFeed].F, vThickFeed[#vThickFeed].Th end end -- funzione locale per tabella spessore-flusso sabbia local function GetWjFlux( dDepth) for i = 1, #( vThickFeed or {}) do if dDepth < vThickFeed[i].Th + 0.1 then return vThickFeed[i].Fl end end if #( vThickFeed or {}) > 0 then return vThickFeed[#vThickFeed].Fl end return 250 end -- assegno valore di flusso (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 dSideAng = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'SideAng', 'SideAng2'), 'd') if dSideAng then return true, dSideAng else return false, 0 end end -- Funzione per la lettura dell'angolo di fianco con verifica non sia nullo function CAM.GetSideAngNotNull( nEntId, nInd) local bFound, dSideAng = CAM.GetSideAng( nEntId, nInd) return ( bFound and abs( dSideAng) > GEO.EPS_ANG_SMALL), dSideAng end -- Funzione per la lettura dell'offset function CAM.GetOffset( nEntId, nInd) local dOffset = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'Offset', 'Offset2'), 'd') if dOffset then return true, dOffset else return false, 0 end end -- Funzione per la lettura dell'affondamento function CAM.GetDepth( nEntId, nInd) local dDepth = EgtGetInfo( nEntId, EgtIf( nInd ~= 2, 'Depth', 'Depth2'), 'd') if dDepth then return true, dDepth else return false, 0 end end -- Funzione per la lettura del tallone function CAM.GetHeel( nEntId) local dHeel = EgtGetInfo( nEntId, 'Heel', 'd') if dHeel then return true, dHeel else return false, 0 end end -- Funzione per la lettura del tallone con verifica non sia nullo function CAM.GetHeelNotNull( nEntId, nInd) local bFound, dHeel = CAM.GetHeel( nEntId, nInd) return ( bFound and abs( dHeel) > GEO.EPS_SMALL), dHeel end -- Funzione per la lettura della larghezza dell'incisione function CAM.GetWidth( nEntId) local dWidth = EgtGetInfo( nEntId, 'Width', 'd') if dWidth then return true, dWidth else return false, 0 end end -- Funzione per la lettura del tipo di taglio (Diretto oppure CAD) function CAM.GetDirectCut( nEntId) local nDirectCut = EgtGetInfo( nEntId, 'DirectCut', 'i') if nDirectCut then return true, nDirectCut else return false, 0 end end function CAM.GetStepType( nEntId) local nStepType = EgtGetInfo( nEntId, 'StepType', 'i') if nStepType then return true, nStepType else return false, MCH_MILL_ST.SPIRAL end end function CAM.GetFlattenigTool( nEntId) local sTool = EgtGetInfo( nEntId, 'EngravingWithMill') -- sTool=1 -> Mill, sTool=0 -> Saw if sTool then return true, tonumber( sTool) or EgtIf( bEngravingWithMill, 1, 0) else return false, EgtIf( bEngravingWithMill, 1, 0) end end -- Funzione per lettura abilitazione possibilità di inversione su tagli verticali function CAM.GetEnableInvert( nEntId) local nEnInv = EgtGetInfo( nEntId, 'EnInv', 'i') if nEnInv then return true, ( nEnInv == 1) else return false, true end end -- Funzione per abilitare possibilità di inversione su tagli verticali (default) function CAM.SetEnableInvert( nEntId) EgtRemoveInfo( nEntId, 'EnInv') end -- Funzione per lettura se lato concatenato in lavorazione waterjet (1=true, 0=false, nil=true) function CAM.GetJoinEntity( nEntId) local nJoinEntity = EgtGetInfo( nEntId, 'JoinEntity', 'i') if nJoinEntity then return ( nJoinEntity ~= 0), nJoinEntity or 1 else return true, 1 end end -- Funzione per lettura angolo in piano XY con entità precedente function CAM.GetPrevAngle( nEntId) local dPreAng = EgtGetInfo( nEntId, 'PrevAng', 'd') if dPreAng then return true, dPreAng else return false, 0 end end -- Funzione per lettura angolo in piano XY con entità successiva function CAM.GetNextAngle( nEntId) local dNextAng = EgtGetInfo( nEntId, 'NextAng', 'd') if dNextAng then return true, dNextAng else return false, 0 end end -- Funzione per lettura distanza libera all'inizio function CAM.GetStartFreeLength( nEntId) local dSFL = EgtGetInfo( nEntId, 'SFL', 'd') if dSFL then return true, dSFL else return false, 10000 end end -- Funzione per lettura distanza libera alla fine function CAM.GetEndFreeLength( nEntId) local dEFL = EgtGetInfo( nEntId, 'EFL', 'd') if dEFL then return true, dEFL else return false, 10000 end end -- Funzione per lettura allungamento baffo all'inizio function CAM.GetStartWhiskersExtend( nEntId) local dSWE = EgtGetInfo( nEntId, 'SWE', 'd') if dSWE then return true, dSWE else return false, 0 end end -- Funzione per lettura allungamento baffo alla fine function CAM.GetEndWhiskersExtend( nEntId) local dEWE = EgtGetInfo( nEntId, 'EWE', 'd') if dEWE then return true, dEWE else return false, 0 end end -- Funzione per la lettura direzione di ritorno function CAM.GetReturnDir( nEntId) local nDir = EgtGetInfo( nEntId, 'Dir', 'i') if nDir then return true, nDir else return false, 1 end end -- Funzione per recuperare spessore lama da nome lavorazione in DB function CAM.GetSawThicknessFromMdb( sMchName) if not EgtMdbSetCurrMachining( sMchName) then return 0 end local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if not EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then return 0 end return EgtTdbGetCurrToolParam( MCH_TP.THICK) or 0 end -- Funzione per recuperare diametro utensile da nome lavorazione in DB function CAM.GetToolDiameterFromMdb( sMchName) if not EgtMdbSetCurrMachining( sMchName) then return 0 end local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) if not EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then return 0 end return EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0 end -- Funzione per recuperare spessore lama function CAM.GetSawThickness( nOperId) if nOperId then EgtSetCurrMachining( nOperId) end local sTool = EgtGetMachiningParam( MCH_MP.TOOL) if not EgtTdbSetCurrTool( sTool or '') then return 0 end return EgtTdbGetCurrToolParam( MCH_TP.THICK) or 0 end -- Funzione per recuperare lunghezza lama function CAM.GetSawLength( nOperId) if nOperId then EgtSetCurrMachining( nOperId) end local sTool = EgtGetMachiningParam( MCH_MP.TOOL) if not EgtTdbSetCurrTool( sTool or '') then return 0 end return EgtTdbGetCurrToolParam( MCH_TP.LEN) or 0 end -- Funzione per recuperare diametro utensile function CAM.GetToolDiameter( nOperId) if nOperId then EgtSetCurrMachining( nOperId) end local sTool = EgtGetMachiningParam( MCH_MP.TOOL) if not EgtTdbSetCurrTool( sTool or '') then return 0 end return EgtTdbGetCurrToolParam( MCH_TP.DIAM) or 0 end -- Funzione per recuperare DeltaT function CAM.GetDeltaT( nOperId) local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV') local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i') if nPv2Id then nPvId = nPv2Id end if nPvId then local nGrpId = EgtGetFirstGroupInGroup( nPvId) if nGrpId then return EgtGetInfo( nGrpId, 'DT', 'd') or 0 end end return 0 end -- Funzione per recuperare DeltaTI (ritorna nil se non trovato) function CAM.GetDeltaTI( nOperId) local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV') local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i') if nPv2Id then nPvId = nPv2Id end if nPvId then local nGrpId = EgtGetFirstGroupInGroup( nPvId) if nGrpId then return EgtGetInfo( nGrpId, 'DTI', 'd') end end end -- Funzione per recuperare ExtraCut function CAM.GetExtraCut( nOperId) local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV') local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i') if nPv2Id then nPvId = nPv2Id end if nPvId then local nGrpId = EgtGetFirstGroupInGroup( nPvId) if nGrpId then return EgtGetInfo( nGrpId, 'EC', 'd') or 0 end end return 0 end -- Funzione per recuperare RawBottomHeight function CAM.GetRawBottomHeight( nOperId) local nPvId = EgtGetFirstNameInGroup( nOperId, 'PV') local nPv2Id = EgtGetInfo( nPvId, 'PvId', 'i') if nPv2Id then nPvId = nPv2Id end if nPvId then local nGrpId = EgtGetFirstGroupInGroup( nPvId) if nGrpId then return EgtGetInfo( nGrpId, 'RBH', 'd') or 0 end end return 0 end -- Funzione per salvare tipo attacco originale function CAM.SaveOriLeadIn( nOperId, nLeadIn) if not EgtExistsInfo( nOperId, 'OriLI') then EgtSetInfo( nOperId, 'OriLI', nLeadIn) end end -- Funzione per salvare tipo uscita originale function CAM.SaveOriLeadOut( nOperId, nLeadOut) if not EgtExistsInfo( nOperId, 'OriLO') then EgtSetInfo( nOperId, 'OriLO', nLeadOut) end end -- Funzione per recuperare tipo attacco originale function CAM.GetOriLeadIn( nOperId) local nOriLeadIn = EgtGetInfo( nOperId, 'OriLI', 'i') if nOriLeadIn then return true, nOriLeadIn else return false, MCH_SAW_LI.CENT end end -- Funzione per recuperare tipo uscita originale function CAM.GetOriLeadOut( nOperId) local nOriLeadOut = EgtGetInfo( nOperId, 'OriLO', 'i') if nOriLeadOut then return true, nOriLeadOut else return false, MCH_SAW_LO.CENT end end -- Funzione per disattivare una lavorazione e toglierla dalle tabelle function CAM.DeactivateMachining( TabSort, j) EgtSetOperationMode( TabSort[j].Mch, false) EgtRemoveInfo( TabSort[j].Mch, 'UserOff') table.remove( TabSort, j) end -- Funzione per impostare lunghezze aggiuntive per baffi function CAM.SetWhiskExtends( dSWE, dEWE) local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) or '' if abs( dSWE) > GEO.EPS_SMALL then sNotes = EgtAdjustNotes( sNotes, 'SWE', EgtNumToString( dSWE, 3)) else sNotes = EgtAdjustNotes( sNotes, 'SWE', nil) end if abs( dEWE) > GEO.EPS_SMALL then sNotes = EgtAdjustNotes( sNotes, 'EWE', EgtNumToString( dEWE, 3)) else sNotes = EgtAdjustNotes( sNotes, 'EWE', nil) end EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end -- Funzione per scambiare gli allungamenti dei baffi dei tagli function CAM.SwapWhiskExtends() local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) if not sNotes then return end sNotes = string.gsub( sNotes, 'SWE=', 'FWE=') sNotes = string.gsub( sNotes, 'EWE=', 'SWE=') sNotes = string.gsub( sNotes, 'FWE=', 'EWE=') EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end -- Funzione che restituisce gli allungamenti dei baffi dei tagli function CAM.GetWhiskExtends() local dSWE, dEWE = 0, 0 local sNotes = EgtGetMachiningParam( MCH_MP.USERNOTES) if not sNotes then return dSWE, dEWE end local vItem = EgtSplitString( sNotes, ';') or {} for i = 1, #vItem do local sItem = EgtTrim( vItem[i]) if sItem and #sItem > 0 then if sItem:find( 'SWE=', 1, true) then dSWE = tonumber( sItem:sub( 5)) elseif sItem:find( 'EWE=', 1, true) then dEWE = tonumber( sItem:sub( 5)) end end end return dSWE, dEWE end -- Funzione per invertire il lato di lavoro della lavorazione corrente function CAM.InvertWorkside() local nWorkside = EgtGetMachiningParam( MCH_MP.WORKSIDE) if nWorkside == MCH_SAW_WS.LEFT then nWorkside = MCH_SAW_WS.RIGHT elseif nWorkside == MCH_SAW_WS.RIGHT then nWorkside = MCH_SAW_WS.LEFT end EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkside) end -- Funzione per invertire il lato mandrino della lavorazione corrente function CAM.InvertHeadside() local nHeadside = EgtGetMachiningParam( MCH_MP.HEADSIDE) if nHeadside == MCH_SAW_HS.RIGHT then nHeadside = MCH_SAW_HS.LEFT else nHeadside = MCH_SAW_HS.RIGHT end EgtSetMachiningParam( MCH_MP.HEADSIDE, nHeadside) end -- Funzione per invertire tagli di lama verticali in caso di fuori corsa function CAM.InvertVerticalCutOnExtraStroke() -- se non è taglio di lama, esco subito if EgtGetMachiningParam( MCH_MP.TYPE) ~= MCH_MY.SAWING then return false end -- se angolo di fianco non nullo, esco subito local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE) if abs(dSideAng) > GEO.EPS_ANG_SMALL then return false end -- inverto direzione per cercare di evitare eventuale extracorsa local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) bInvert = (not bInvert) EgtSetMachiningParam( MCH_MP.INVERT, bInvert) -- conseguentemente devo invertire anche il lato di lavoro CAM.InvertWorkside() -- devo scambiare tra loro i parametri di attacco e uscita CAM.SwapCutLeadInOut() -- e anche gli allungamenti iniziale e finale CAM.SwapCutAllStartEnd() -- e anche gli allungamenti dei baffi CAM.SwapWhiskExtends() -- ricalcolo CAM.MultiCutMachiningSettings() if EgtApplyMachining() then return true end return false end -- Funzione per invertire tagli di lama con angolo di fianco function CAM.InvertSideAngCut() -- se non è taglio di lama, esco subito if EgtGetMachiningParam( MCH_MP.TYPE) ~= MCH_MY.SAWING then return false end -- se angolo di fianco nullo, esco subito local dSideAng = EgtGetMachiningParam( MCH_MP.SIDEANGLE) if abs( dSideAng) < GEO.EPS_ANG_SMALL then return false end -- inverto direzione local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) bInvert = ( not bInvert) EgtSetMachiningParam( MCH_MP.INVERT, bInvert) -- conseguentemente devo invertire anche il lato di lavoro CAM.InvertWorkside() -- e il lato mandrino local nHeadside = EgtGetMachiningParam( MCH_MP.HEADSIDE) if nHeadside == MCH_SAW_HS.RIGHT then nHeadside = MCH_SAW_HS.LEFT else nHeadside = MCH_SAW_HS.RIGHT end EgtSetMachiningParam( MCH_MP.HEADSIDE, nHeadside) -- devo scambiare tra loro i parametri di attacco e uscita CAM.SwapCutLeadInOut() -- e anche gli allungamenti iniziale e finale CAM.SwapCutAllStartEnd() -- ricalcolo CAM.MultiCutMachiningSettings() return EgtApplyMachining() end -- Funzione per scambiare i parametri di ingresso e uscita dei tagli di lama function CAM.SwapCutLeadInOut() local LeadIn = EgtGetMachiningParam( MCH_MP.LEADINTYPE) local LeadOut = EgtGetMachiningParam( MCH_MP.LEADOUTTYPE) local NewLeadOut = MCH_SAW_LO.STRICT if LeadIn == MCH_SAW_LI.CENT then NewLeadOut = MCH_SAW_LO.CENT elseif LeadIn == MCH_SAW_LI.OUT then NewLeadOut = MCH_SAW_LO.OUT elseif LeadIn == MCH_SAW_LI.EXT_CENT then NewLeadOut = MCH_SAW_LO.EXT_CENT elseif LeadIn == MCH_SAW_LI.EXT_OUT then NewLeadOut = MCH_SAW_LO.EXT_OUT end local NewLeadIn = MCH_SAW_LI.STRICT if LeadOut == MCH_SAW_LO.CENT then NewLeadIn = MCH_SAW_LI.CENT elseif LeadOut == MCH_SAW_LO.OUT then NewLeadIn = MCH_SAW_LI.OUT elseif LeadOut == MCH_SAW_LO.EXT_CENT then NewLeadIn = MCH_SAW_LI.EXT_CENT elseif LeadOut == MCH_SAW_LO.EXT_OUT then NewLeadIn = MCH_SAW_LI.EXT_OUT end EgtSetMachiningParam( MCH_MP.LEADINTYPE, NewLeadIn) EgtSetMachiningParam( MCH_MP.LEADOUTTYPE, NewLeadOut) end -- Funzione per scambiare gli allungamenti iniziale e finale dei tagli di lama function CAM.SwapCutAllStartEnd() local AllStart = EgtGetMachiningParam( MCH_MP.STARTADDLEN) local AllEnd = EgtGetMachiningParam( MCH_MP.ENDADDLEN) AllStart, AllEnd = AllEnd, AllStart EgtSetMachiningParam( MCH_MP.STARTADDLEN, AllStart) EgtSetMachiningParam( MCH_MP.ENDADDLEN, AllEnd) end -- function CAM.HintDrillMillAngC() -- se richiesto bloccaggio standard if nDrillMillC90 < 2 then if not ( bIsMultiCut and bIsTableRot) then EgtSetMachiningParam( MCH_MP.INITANGS, 'C=' .. EgtNumToString( nDrillMillC90 * 90, 0)) else EgtSetMachiningParam( MCH_MP.INITANGS, 'C=90,'..CAM.MultiCutTableRotAxisToken()..'-90') end -- se richiesto bloccaggio differenziato su seconda tavola elseif nDrillMillC90 == 2 then -- verifico se è attiva la seconda tavola local bIs2ndTable = ( EgtGetTableName() == '2ndTab') if bIs2ndTable then EgtSetMachiningParam( MCH_MP.INITANGS, 'C=-90') else if not ( bIsMultiCut and bIsTableRot) then EgtSetMachiningParam( MCH_MP.INITANGS, 'C=90') else EgtSetMachiningParam( MCH_MP.INITANGS, 'C=90,'..CAM.MultiCutTableRotAxisToken()..'-90') end end end end -- function CAM.HintWaterJetAngC( dSideAng, bOutLoop, nEntId) local 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 = TabCut[1].Mch end -- creo i pretagli local TabEPC = {} for i = 1, #TabCut do -- se taglio verticale con uscita in centro if abs( TabCut[i].Ang) < GEO.EPS_ANG_SMALL and TabCut[i].LeadOut == MCH_SAW_LO.CENT then -- copio la lavorazione local sSouName = EgtGetName( TabCut[i].Mch) local nNewMchId = EgtCopyMachining( sSouName..'_EPC', sSouName) EgtRelocateGlob( nNewMchId, RefMch, GDB_IN.BEFORE) EgtSetInfo( nNewMchId, 'EPC', 1) table.insert( TabEPC, { Mch=nNewMchId, Pos=TabCut[i].End, Dir=TabCut[i].Dir, Ang=TabCut[i].Ang, RawBottomHeight=TabCut[i].RawBottomHeight}) -- inverto direzione di lavoro local bInvert = not EgtGetMachiningParam( MCH_MP.INVERT) EgtSetMachiningParam( MCH_MP.INVERT, bInvert) -- conseguentemente devo invertire anche il lato di lavoro CAM.InvertWorkside() -- devo invertire il lato mandrino CAM.InvertHeadside() -- devo scambiare tra loro i parametri di attacco e uscita CAM.SwapCutLeadInOut() -- e anche gli allungamenti iniziale e finale CAM.SwapCutAllStartEnd() -- e anche gli allungamenti dei baffi CAM.SwapWhiskExtends() -- cambio allungamento finale per fare pretaglio su inizio attuale local dLen = dist( TabCut[i].Start, TabCut[i].End) local dEal = EgtGetMachiningParam( MCH_MP.ENDADDLEN) EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal - dLen + 2) -- aggiorno la lavorazione EgtApplyMachining( true) end end -- li ordino EgtSpInit() for i = 1, #TabEPC do local AngH = atan2( TabEPC[i].Dir:getY(), TabEPC[i].Dir:getX()) + 270 if AngH > 180.1 then AngH = AngH - 360 elseif AngH < - 180.1 then AngH = AngH + 360 end if bIsMultiCut then if abs( TabEPC[i].Dir:getX()) > abs( TabEPC[i].Dir:getY()) then AngH = AngH + 10 * ( dAngRotMultiCut + dOffsAxisBlock) else AngH = AngH + 10 * ( 0 + dOffsAxisBlock) end end local AngV = 90 - abs( TabEPC[i].Ang) local dExtraZ = 40000 if TabEPC[i].RawBottomHeight > 1.0 then dExtraZ = 0 elseif abs( TabEPC[i].Ang) > GEO.EPS_ANG_SMALL then dExtraZ = 10000 end local ptS = TabEPC[i].Pos + Z_AX() * dExtraZ local ptE = ptS EgtSpAddPoint( ptS:getX(), ptS:getY(), ptS:getZ(), AngH, AngV, ptE:getX(), ptE:getY(), ptE:getZ(), AngH, AngV) end EgtSpSetAngularParams( 1000, 40, 2000, 60) EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -6000, 0, EgtIf( bCutLongDxSx, 90, -90), 90) local vOrd = EgtSpCalculate( SHP_TY.OPEN) EgtSpTerminate() -- applico ordinamento calcolato if vOrd then -- sposto le lavorazioni di pretaglio for i = 1, #vOrd do local CurrMch = TabEPC[vOrd[i]].Mch EgtRelocateGlob( CurrMch, RefMch, GDB_IN.BEFORE) end -- le inserisco tra quelle da aggiornare in posizione opportuna local CurrInd for j = 1, #TabUpdate do if TabUpdate[j].Mch == RefMch then CurrInd = j break end end if CurrInd then for i = #vOrd, 1, -1 do table.insert( TabUpdate, CurrInd, {Mch=TabEPC[vOrd[i]].Mch, Part=nil}) end end end end end -- ------------------------------------------------------------------------------- ------ Inserimento delle lavorazioni --------------------- function CAM.Add() EgtOutLog( 'CAM.Add ' .. CAMAUTO_VER) -- Recupero gli identificativi delle entità : da tutti i pezzi del grezzo if CAM.PARTID == GDB_ID.NULL then -- Ciclo sui pezzi del grezzo local nPartId = EgtGetFirstPartInRawPart(nRawId) while nPartId do -- Recupero gli identificativi delle entità da lavorare nel pezzo **Carico le tabelle con entità** CAM.AnalyzePart( nPartId) -- Passo al grezzo successivo nPartId = EgtGetNextPartInRawPart(nPartId) end -- Recupero gli identificativi delle entità : da un pezzo del grezzo else -- Recupero gli identificativi delle entità CAM.AnalyzePart( CAM.PARTID) end -- Applico le lavorazioni CAM.ApplyMachinings() end function CAM.UpdateSawing() EgtOutLog( 'CAM.UpdateSawing ' .. CAMAUTO_VER) local TabEnt = {} local sLay = 'OutLoop' local TabCrv = {} local TabPart = {} local j = nil 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', 'i') if nPvId then local Box = EgtGetBBoxGlob( nPvId, GDB_BB.STANDARD) if Box then if not Box:isEmpty() then table.insert( TabMill, {Id=nMillId, Cen=Box:getCenter()}) end end end end nMillId = EgtGetNextOperation( nMillId) end -- calcolo ordinamento EgtSpInit() for i = 1, #TabMill do EgtSpAddPoint( TabMill[i].Cen:getX(), TabMill[i].Cen:getY()) end EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -4000, 0, 90, 90) local vMillOrd = EgtSpCalculate( SHP_TY.OPEN) EgtSpTerminate() -- applico ordinamento calcolato -- parto da LastMch precedente if vMillOrd then for i = 1, #vMillOrd do EgtRelocateGlob( TabMill[vMillOrd[i]].Id, LastMch, GDB_IN.AFTER) LastMch = TabMill[vMillOrd[i]].Id end end return LastMch end -- ------------------------------------------------------------------------------- local function SortDrills( nPhase, LastMch, sLay) -- dichiarazione tabella local TabDri = {} -- recupero le forature e i loro centri local nDrillId = EgtGetPhaseDisposition( nPhase) while nDrillId do -- Se appartiene alla fase corrente e foratura non vuota del layer voluto if EgtGetOperationPhase( nDrillId) == nPhase and EgtGetOperationType( nDrillId) == MCH_OY.DRILLING and ( not sLay or EgtGetInfo( nDrillId, 'Lay') == sLay) then -- recupero preview local nPvId = EgtGetInfo( EgtGetFirstNameInGroup( nDrillId, 'PV'), 'PvId', 'i') if nPvId then local Box = EgtGetBBoxGlob( nPvId, GDB_BB.STANDARD) if Box then if not Box:isEmpty() then table.insert( TabDri, {Id=nDrillId, Cen=Box:getCenter()}) end end end end nDrillId = EgtGetNextOperation( nDrillId) end -- calcolo ordinamento EgtSpInit() for i = 1, #TabDri do EgtSpAddPoint( TabDri[i].Cen:getX(), TabDri[i].Cen:getY()) end local vDriOrd = {} if not sLay or sLay ~= 'UnderDrill' then EgtSpSetOpenBound( true, SHP_OB.NEAR_PNT, 0, -4000, 0, 90, 90) vDriOrd = EgtSpCalculate( SHP_TY.OPEN) else EgtSpSetZzOwStep( 4000) vDriOrd = EgtSpCalculate( SHP_TY.ONEWAY_YM) end EgtSpTerminate() -- applico ordinamento calcolato -- parto da LastMch precedente if vDriOrd then for i = 1, #vDriOrd do EgtRelocateGlob( TabDri[vDriOrd[i]].Id, LastMch, GDB_IN.AFTER) LastMch = TabDri[vDriOrd[i]].Id end end return LastMch end -- ------------------------------------------------------------------------------- local function SortPockets( nPhase, LastMch) -- dichiarazione tabella local TabPock = {} -- Recupero gli identificativi delle lavorazioni local nOperId = EgtGetPhaseDisposition( nPhase) while nOperId do -- Se appartiene alla fase corrente e svuotatura if EgtGetOperationPhase( nOperId) == nPhase and EgtGetOperationType( nOperId) == MCH_OY.POCKETING then table.insert( TabPock, {Id=nOperId}) end nOperId = EgtGetNextOperation( nOperId) end -- Inserisco le lavorazioni in coda for i = 1, #TabPock do EgtRelocateGlob( TabPock[i].Id, LastMch, GDB_IN.AFTER) LastMch = TabPock[i].Id end return LastMch end -- ------------------------------------------------------------------------------- local function SortWaterJets( nPhase, LastMch, sLay) -- dichiarazione tabella local 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', 'i') if nPvId then local Box = EgtGetBBoxGlob( nPvId, GDB_BB.STANDARD) if Box and not Box:isEmpty() then table.insert( TabDri, {Id=nDrillId, Part=nPartId, Cen=Box:getCenter()}) end end end nDrillId = EgtGetNextOperation( nDrillId) end -- Eseguo ottimizzazione per pezzo while #TabDri > 0 do -- riunisco i fori di uno stesso pezzo local nCurrPartId = TabDri[1].Part local TabPrtDri = {} local i = 1 while i <= #TabDri do if TabDri[i].Part == nCurrPartId then table.insert( TabPrtDri, TabDri[i]) table.remove( TabDri, i) else i = i + 1 end end -- calcolo ordinamento EgtSpInit() for i = 1, #TabPrtDri do EgtSpAddPoint( TabPrtDri[i].Cen:getX(), TabPrtDri[i].Cen:getY()) end local vDriOrd = {} EgtSpSetZzOwStep( 4000) vDriOrd = EgtSpCalculate( SHP_TY.ONEWAY_YM) EgtSpTerminate() -- Inserisco le lavorazioni ordinate in coda for i = 1, #vDriOrd do EgtRelocateGlob( TabPrtDri[vDriOrd[i]].Id, LastMch, GDB_IN.AFTER) LastMch = TabPrtDri[vDriOrd[i]].Id end end return LastMch end -- ------------------------------------------------------------------------------- local function VerifyDripMachinings( nPhase) local nOperId = EgtGetNextOperation( EgtGetPhaseDisposition( nPhase) or GDB_ID.NULL) while nOperId do -- Se appartiene alla fase corrente e lavorazione da sotto if EgtGetOperationPhase( nOperId) == nPhase and ( EgtGetInfo( nOperId, 'Lay') == 'Drip' or EgtGetInfo( nOperId, 'Lay') == 'UnderDrill') then return true end nOperId = EgtGetNextOperation( nOperId) end return false end -- ------------------------------------------------------------------------------- function CAM.Sort() EgtOutLog( 'CAM.Sort ' .. CAMAUTO_VER) -- Recupero la fase corrente local nPhase = EgtGetCurrPhase() local LastMch = EgtGetPhaseDisposition( nPhase) -- Verifico se ci sono lavorazioni da sotto local bDrips = VerifyDripMachinings( nPhase) -- Ordinamento senza lavorazioni da sotto if not bDrips then -- Ordino le svuotature --------- LastMch = SortPockets( nPhase, LastMch) -- Ordino le fresature ---------- LastMch = SortMills( nPhase, LastMch, 'InLoop', 'FiloTop') LastMch = SortMills( nPhase, LastMch) -- Ordino le forature ---------- LastMch = SortDrills( nPhase, LastMch) -- Ordino i tagli ---------- LastMch = SortCuts( nPhase, LastMch) LastMch = SortOnCuts( nPhase, LastMch) -- Ordino i water jet LastMch = SortWaterJets( nPhase, LastMch) -- Ordinamento con lavorazioni da sotto else -- Ordino i tagli esterni ---------- LastMch = SortCuts( nPhase, LastMch, 'OutLoop') -- Ordino le fresature esterne ---------- LastMch = SortMills( nPhase, LastMch, 'OutLoop') -- Ordino le forature esterne ---------- LastMch = SortDrills( nPhase, LastMch, 'OutLoop') -- Ordino i water jet esterni ---------- LastMch = SortWaterJets( nPhase, LastMch, 'OutLoop') -- Ordino i tagli da sotto ---------- LastMch = SortDripCuts( nPhase, LastMch) -- Ordino le forature da sotto ---------- LastMch = SortDripDrills( nPhase, LastMch) -- Ordino le svuotature --------- LastMch = SortPockets( nPhase, LastMch) -- Ordino le fresature interne ---------- LastMch = SortMills( nPhase, LastMch, 'InLoop', 'FiloTop') LastMch = SortMills( nPhase, LastMch, 'InLoop') LastMch = SortMills( nPhase, LastMch, 'OnPath') -- Ordino le forature interne ---------- LastMch = SortDrills( nPhase, LastMch, 'InLoop') -- Ordino i tagli interni ---------- LastMch = SortCuts( nPhase, LastMch, 'InLoop') -- Ordino i tagli da sopra ---------- LastMch = SortOnCuts( nPhase, LastMch) -- Ordino i water jet interni ---------- LastMch = SortWaterJets( nPhase, LastMch, 'InLoop') end end ------ Esecuzione SpecialApply su specifica Disposizione ------- function CAM.SpecApplyDisp() EgtOutLog( 'CAM.SpecApplyDisp ' .. CAMAUTO_VER) -- Eseguo CAM.MultiCutDispositionSettings( CAM.DISPID) if not EgtSpecialApplyDisposition( CAM.DISPID, CAM.RECALC) then CAM.ERR = 72 end end