From 6eaba8a577a135f7557491d427065db66275254c Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Mon, 1 Apr 2019 15:18:51 +0000 Subject: [PATCH] DataBeam : - primo rilascio. --- BatchProcess.lua | 226 ++++++++++ Beam.ini | 13 + ClearProcess.lua | 57 +++ DisableFeatures.lua | 32 ++ EnableFeatures.lua | 32 ++ HideAll.lua | 40 ++ Images/ClearProcess.png | Bin 0 -> 1132 bytes Images/DisableFeatures.png | Bin 0 -> 303 bytes Images/EnableFeatures.png | Bin 0 -> 303 bytes Images/HideAll.png | Bin 0 -> 775 bytes Images/Process.png | Bin 0 -> 901 bytes Images/Rotate.png | Bin 0 -> 528 bytes Images/ShowAll.png | Bin 0 -> 604 bytes Images/ShowBuilding.png | Bin 0 -> 785 bytes Images/Swap.png | Bin 0 -> 479 bytes LuaLibs/BeamExec.lua | 737 +++++++++++++++++++++++++++++++ LuaLibs/BeamLib.lua | 720 ++++++++++++++++++++++++++++++ LuaLibs/DiceCut.lua | 501 +++++++++++++++++++++ LuaLibs/ProcessBirdsMouth.lua | 302 +++++++++++++ LuaLibs/ProcessChamfer.lua | 64 +++ LuaLibs/ProcessCut.lua | 164 +++++++ LuaLibs/ProcessDecor.lua | 92 ++++ LuaLibs/ProcessDoubleCut.lua | 203 +++++++++ LuaLibs/ProcessDrill.lua | 171 +++++++ LuaLibs/ProcessDtMortise.lua | 119 +++++ LuaLibs/ProcessDtTenon.lua | 171 +++++++ LuaLibs/ProcessFreeContour.lua | 218 +++++++++ LuaLibs/ProcessHeadCut.lua | 87 ++++ LuaLibs/ProcessLapJoint.lua | 525 ++++++++++++++++++++++ LuaLibs/ProcessLongCut.lua | 187 ++++++++ LuaLibs/ProcessLongDoubleCut.lua | 176 ++++++++ LuaLibs/ProcessMark.lua | 102 +++++ LuaLibs/ProcessMortise.lua | 111 +++++ LuaLibs/ProcessPocket.lua | 100 +++++ LuaLibs/ProcessProfCamb.lua | 219 +++++++++ LuaLibs/ProcessProfConcave.lua | 243 ++++++++++ LuaLibs/ProcessProfConvex.lua | 243 ++++++++++ LuaLibs/ProcessProfFront.lua | 224 ++++++++++ LuaLibs/ProcessProfHead.lua | 248 +++++++++++ LuaLibs/ProcessRidgeLap.lua | 215 +++++++++ LuaLibs/ProcessRoundArch.lua | 215 +++++++++ LuaLibs/ProcessSimpleScarf.lua | 224 ++++++++++ LuaLibs/ProcessSplit.lua | 102 +++++ LuaLibs/ProcessTenon.lua | 165 +++++++ LuaLibs/ProcessText.lua | 97 ++++ LuaLibs/TwoFacesBySaw.lua | 147 ++++++ Process.lua | 220 +++++++++ Rotate.lua | 32 ++ ShowAll.lua | 18 + ShowBuilding.lua | 63 +++ Swap.lua | 31 ++ 51 files changed, 7856 insertions(+) create mode 100644 BatchProcess.lua create mode 100644 Beam.ini create mode 100644 ClearProcess.lua create mode 100644 DisableFeatures.lua create mode 100644 EnableFeatures.lua create mode 100644 HideAll.lua create mode 100644 Images/ClearProcess.png create mode 100644 Images/DisableFeatures.png create mode 100644 Images/EnableFeatures.png create mode 100644 Images/HideAll.png create mode 100644 Images/Process.png create mode 100644 Images/Rotate.png create mode 100644 Images/ShowAll.png create mode 100644 Images/ShowBuilding.png create mode 100644 Images/Swap.png create mode 100644 LuaLibs/BeamExec.lua create mode 100644 LuaLibs/BeamLib.lua create mode 100644 LuaLibs/DiceCut.lua create mode 100644 LuaLibs/ProcessBirdsMouth.lua create mode 100644 LuaLibs/ProcessChamfer.lua create mode 100644 LuaLibs/ProcessCut.lua create mode 100644 LuaLibs/ProcessDecor.lua create mode 100644 LuaLibs/ProcessDoubleCut.lua create mode 100644 LuaLibs/ProcessDrill.lua create mode 100644 LuaLibs/ProcessDtMortise.lua create mode 100644 LuaLibs/ProcessDtTenon.lua create mode 100644 LuaLibs/ProcessFreeContour.lua create mode 100644 LuaLibs/ProcessHeadCut.lua create mode 100644 LuaLibs/ProcessLapJoint.lua create mode 100644 LuaLibs/ProcessLongCut.lua create mode 100644 LuaLibs/ProcessLongDoubleCut.lua create mode 100644 LuaLibs/ProcessMark.lua create mode 100644 LuaLibs/ProcessMortise.lua create mode 100644 LuaLibs/ProcessPocket.lua create mode 100644 LuaLibs/ProcessProfCamb.lua create mode 100644 LuaLibs/ProcessProfConcave.lua create mode 100644 LuaLibs/ProcessProfConvex.lua create mode 100644 LuaLibs/ProcessProfFront.lua create mode 100644 LuaLibs/ProcessProfHead.lua create mode 100644 LuaLibs/ProcessRidgeLap.lua create mode 100644 LuaLibs/ProcessRoundArch.lua create mode 100644 LuaLibs/ProcessSimpleScarf.lua create mode 100644 LuaLibs/ProcessSplit.lua create mode 100644 LuaLibs/ProcessTenon.lua create mode 100644 LuaLibs/ProcessText.lua create mode 100644 LuaLibs/TwoFacesBySaw.lua create mode 100644 Process.lua create mode 100644 Rotate.lua create mode 100644 ShowAll.lua create mode 100644 ShowBuilding.lua create mode 100644 Swap.lua diff --git a/BatchProcess.lua b/BatchProcess.lua new file mode 100644 index 0000000..adb0202 --- /dev/null +++ b/BatchProcess.lua @@ -0,0 +1,226 @@ +-- BatchProcess.lua by Egaltech s.r.l. 2019/04/01 +-- Gestione calcolo batch disposizione e lavorazioni per Travi + + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Log dati di generazione +local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. BEAM.MACHINE .. ', ' .. tostring( BEAM.FLAG) +EgtOutLog( sLog) + +-- Cancello file di log specifico +local sLogFile = EgtChangePathExtension( BEAM.FILE, '.txt') +EgtEraseFile( sLogFile) + +-- Funzione per scrittura su file di log specifico +local function WriteLogFile( nErr, sErr, nCutId, nTaskId) + if nErr ~= 0 then + EgtOutLog( sErr .. ' (' .. tostring( nErr) ..')') + end + local hFile = io.open( sLogFile, 'w') + hFile:write( 'ERR=' .. tostring( nErr) .. '\n') + if nErr ~= 0 then + hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n') + hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n') + hFile:write( sErr .. '\n') + end + hFile:close() + if nErr ~= 0 and ( BEAM.FLAG == 1 or BEAM.FLAG == 2) then + EgtSetView( SCE_VD.ISO_SW, false) + EgtZoom( SCE_ZM.ALL) + EgtOutBox( sErr .. ' (error ' .. tostring( nErr) .. ')', 'BatchProcess', 'ERROR') + end +end + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Impostazione della macchina corrente +EgtResetCurrMachGroup() +local sMachine = 'Essetre-' .. BEAM.MACHINE +if not EgtSetCurrMachine( sMachine) then + BEAM.ERR = 11 + BEAM.MSG = 'Error selecting machine : ' .. sMachine + WriteLogFile( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + BEAM.ERR = 12 + BEAM.MSG = 'Error not configured for beams machine : ' .. sMachine + WriteLogFile( BEAM.ERR, BEAM.MSG) + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Beam BatchProcess Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Importo il file Btl +EgtNewFile() +if not EgtImportBtl( BEAM.FILE, EIB_FL.TS3_POS) then + BEAM.ERR = 13 + BEAM.MSG = 'Error importing BTL file : ' .. BEAM.FILE + WriteLogFile( BEAM.ERR, BEAM.MSG) + return +end + +-- Recupero l'elenco ordinato delle travi +local vBeam = {} +local nPartId = EgtGetFirstPart() +while nPartId do + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + nPartId = EgtGetNextPart( nPartId) +end +if #vBeam == 0 then + BEAM.ERR = 14 + BEAM.MSG = 'Error no beams in the file : ' .. BEAM.FILE + WriteLogFile( BEAM.ERR, BEAM.MSG) + return +else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi trovate : ' .. sOut, 1) +end + +-- Ne recupero le dimensioni +for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + BEAM.ERR = 15 + BEAM.MSG = 'Box undefined for beam ' .. vBeam[i].Name + WriteLogFile( BEAM.ERR, BEAM.MSG) + return + else + vBeam[i].Box = b3Solid + end +end + +-- Eseguo eventuali rotazioni e inversioni testa-coda +for i = 1, #vBeam do + local b3Solid = vBeam[i].Box + -- rotazione + local dRotAng = EgtGetInfo( vBeam[i].Id, 'ROTATED', 'd') + if dRotAng and abs( dRotAng) > GEO.EPS_ANG_SMALL then + local ptRotCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptRotCen, X_AX(), dRotAng, GDB_RT.GLOB) + b3Solid:rotate( ptRotCen, X_AX(), dRotAng) + end + -- inversione + local dInvAng = 180 - ( EgtGetInfo( vBeam[i].Id, 'INVERTED', 'd') or 0) + if abs( dInvAng) > GEO.EPS_ANG_SMALL then + local ptInvCen = b3Solid:getCenter() + EgtRotate( vBeam[i].Id, ptInvCen, Z_AX(), dInvAng, GDB_RT.GLOB) + end +end + +-- Ne verifico le dimensioni +local dRawW = vBeam[1].Box:getDimY() +local dRawH = vBeam[1].Box:getDimZ() +local vBeamErr = {} +for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end +end +if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + table.remove( vBeam, vBeamErr[i]) + end + BEAM.ERR = 16 + BEAM.MSG = sOut + WriteLogFile( BEAM.ERR, BEAM.MSG) + return +end + +-- Verifico sezione barra +if dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ')' + BEAM.ERR = 17 + BEAM.MSG = sOut + WriteLogFile( BEAM.ERR, BEAM.MSG) + return +end + +-- Lunghezza della barra +local dRawL = EgtGetInfo( EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo'), 'BARLEN', 'd') or 12000 +-- Sovramateriale di testa +local dOvmHead = EgtGetInfo( EgtGetFirstPart(), 'POSX', 'd') or 10 + +-- Sistemo le travi nel grezzo +local bPbOk, sPbErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) +if not bPbOk then + BEAM.ERR = 18 + BEAM.MSG = sPbErr + WriteLogFile( BEAM.ERR, BEAM.MSG) + return +end + +-- Imposto Nome file CN +local _, sName, _ = EgtSplitPath( BEAM.FILE) +EgtSetInfo( EgtGetCurrMachGroup(), 'NcName', sName .. '.cnc') + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +-- Lavoro le features +local bPfOk, sPfErr, nPfCutId, nPfTaskId = BE.ProcessFeatures() +if not bPfOk then + BEAM.ERR = 19 + BEAM.MSG = sPfErr + BEAM.CUTID = nPfCutId + BEAM.TASKID = nPfTaskId + WriteLogFile( BEAM.ERR, BEAM.MSG, BEAM.CUTID, BEAM.TASKID) + return +end + +-- Salvo il progetto +local sNgeFile = EgtChangePathExtension( BEAM.FILE, '.nge') +EgtSaveFile( sNgeFile) + +-- Genero programma CN, se richiesto +if BEAM.FLAG == 0 then + if not EgtGenerate( '', 'EgtCAM5 - ' .. sNgeFile) then + BEAM.ERR = 20 + BEAM.MSG = 'Error generating NC part program : ' .. sName + WriteLogFile( BEAM.ERR, BEAM.MSG) + return + end +end + +-- Imposto la vista ISO 3d, se richiesto +if BEAM.FLAG == 1 or BEAM.FLAG == 2 then + EgtSetView( SCE_VD.ISO_SW, false) +end + +-- Completamento senza errori +BEAM.ERR = 0 +BEAM.MSG = '' +WriteLogFile( BEAM.ERR, BEAM.MSG) diff --git a/Beam.ini b/Beam.ini new file mode 100644 index 0000000..6628e9a --- /dev/null +++ b/Beam.ini @@ -0,0 +1,13 @@ +[Beam] +BtlEnable=1 +BaseDir=C:\EgtData\Beam +BtlExec=BatchProcess.lua +Button1=Process.lua,Images\Process.png,Lavora Travi +Button2=ClearProcess.lua,Images\ClearProcess.png,Cancella Lavorazione Trave +Button3=Swap.lua,Images\Swap.png,Scambia estremi trave +Button4=Rotate.lua,Images\Rotate.png,Ruota trave +Button5=DisableFeatures.lua,Images\DisableFeatures.png,Disabilita lavorazioni +Button6=EnableFeatures.lua,Images\EnableFeatures.png,Abilita lavorazioni +Button7=HideAll.lua,Images\HideAll.png,Nascondi tutte le travi non selezionate +Button8=ShowAll.lua,Images\ShowAll.png,Visualizza tutte le travi +Button9=ShowBuilding.lua,Images\ShowBuilding.png,Visualizza struttura/Visualizza pezzi diff --git a/ClearProcess.lua b/ClearProcess.lua new file mode 100644 index 0000000..dc86eed --- /dev/null +++ b/ClearProcess.lua @@ -0,0 +1,57 @@ +-- ClearProcess.lua by Egaltech s.r.l. 2019/01/10 +-- Se la trave non è parte di un gruppo di lavoro, cancello geometrie aggiunte + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Recupero la prima trave selezionata +local ObjId = EgtGetFirstSelectedObj() +local PartId = EgtGetParent( EgtGetParent( ObjId or GDB_ID.NULL) or GDB_ID.NULL) +if not PartId then return end + +-- Recupero appartenenza a gruppi di lavoro +local vMGrps = {} +local sLst = EgtGetInfo( PartId, GDB_SI.LIST) +if sLst then + vLst = EgtSplitString( sLst) + if vLst then + for i = 1, #vLst do + local MGrpId = EgtGetParent( EgtGetParent( EgtGetParent( vLst[i]) or GDB_ID.NULL) or GDB_ID.NULL) + if MGrpId then + table.insert( vMGrps, EgtGetName( MGrpId)) + end + end + end +end + +-- Chiedo conferma della cancellazione +if #vMGrps > 0 then + local sOut = 'I seguenti gruppi di lavoro verranno cancellati :\n ' .. table.concat( vMGrps, ',') .. '.\nConfermi ?' + if not EgtOutBox( sOut, 'Cancella Lavorazioni', 'QUESTION') then + return + end +end + +-- Cancello i gruppi di lavoro e le geometrie aggiuntive relative +for i = 1, #vMGrps do + EgtRemoveMachGroup( EgtGetMachGroupId( vMGrps[i]) or GDB_ID.NULL) + EgtErase( EgtGetFirstNameInGroup( PartId, vMGrps[i]) or GDB_ID.NULL) +end + +-- Cancello eventuali altre geometrie aggiuntive per gruppi di lavoro +local LayId = EgtGetFirstLayer( PartId) +while LayId do + local NextLayId = EgtGetNextLayer( LayId) + if EgtGetInfo( LayId, '!MGO') then + EgtErase( LayId) + end + LayId = NextLayId +end + +-- Aggiorno interfaccia grafica +EgtDeselectPartObjs( PartId) +EgtDraw() + +-- end \ No newline at end of file diff --git a/DisableFeatures.lua b/DisableFeatures.lua new file mode 100644 index 0000000..bf26326 --- /dev/null +++ b/DisableFeatures.lua @@ -0,0 +1,32 @@ +-- DisableFeatures.lua by Egaltech s.r.l. 2018/04/25 +-- Gestione disabilitazione delle feature selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +if EgtGetSelectedObjCount() == 0 then + EgtOutBox( 'Nessuna lavorazione selezionata', 'Disabilita lavorazioni', 'ERROR') +end + +local nId = EgtGetFirstSelectedObj() +while nId do + -- verifico sia una feature + local nParentId = EgtGetParent( nId) + if EgtIsLayer( nParentId) and EgtGetName( nParentId) == 'Processings' and + EgtGetInfo( nId, 'GRP', 'i') and EgtGetInfo( nId, 'PRC', 'i') then + EgtSetInfo( nId, 'DO', 0) + EgtSetColor( nId, Color3d( 160, 160, 160)) + local nAuxId = EgtGetInfo( nId, 'AUXID', 'i') + if nAuxId then + EgtSetColor( nId + nAuxId, Color3d( 160, 160, 160)) + end + end + nId = EgtGetNextSelectedObj() +end + +EgtDeselectAll() +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/EnableFeatures.lua b/EnableFeatures.lua new file mode 100644 index 0000000..e077e94 --- /dev/null +++ b/EnableFeatures.lua @@ -0,0 +1,32 @@ +-- DisableFeatures.lua by Egaltech s.r.l. 2018/04/25 +-- Gestione abilitazione delle feature selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +if EgtGetSelectedObjCount() == 0 then + EgtOutBox( 'Nessuna lavorazione selezionata', 'Abilita lavorazioni', 'ERROR') +end + +local nId = EgtGetFirstSelectedObj() +while nId do + -- verifico sia una feature + local nParentId = EgtGetParent( nId) + if EgtIsLayer( nParentId) and EgtGetName( nParentId) == 'Processings' and + EgtGetInfo( nId, 'GRP', 'i') and EgtGetInfo( nId, 'PRC', 'i') then + EgtRemoveInfo( nId, 'DO') + EgtResetColor( nId) + local nAuxId = EgtGetInfo( nId, 'AUXID', 'i') + if nAuxId then + EgtResetColor( nId + nAuxId) + end + end + nId = EgtGetNextSelectedObj() +end + +EgtDeselectAll() +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/HideAll.lua b/HideAll.lua new file mode 100644 index 0000000..d8c7e8a --- /dev/null +++ b/HideAll.lua @@ -0,0 +1,40 @@ +-- HideAll.lua by Egaltech s.r.l. 2019/03/16 +-- Gestione nascondimento di tutte le Travi non selezionate + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- se non ci sono pezzi selezionati, esco +if not EgtGetFirstSelectedObj() then return end + +-- nascondo tutti i pezzi non selezionati +local bCurrPL = false +local nPartId = EgtGetFirstPart() +while nPartId do + local nStat = GDB_ST.ON + local nLayId = EgtGetFirstLayer( nPartId) + while nLayId do + local nEntId = EgtGetFirstInGroup( nLayId) + if nEntId then + nStat = EgtGetCalcStatus( nEntId) + break + else + nLayId = EgtGetNextLayer( nLayId) + end + end + if nStat ~= GDB_ST.SEL then + EgtSetMode( nPartId, GDB_MD.HIDDEN) + else + EgtDeselectPartObjs( nPartId) + if not bCurrPL then + bCurrPL = EgtSetCurrPartLayer( nPartId, EgtGetFirstLayer( nPartId)) + end + end + nPartId = EgtGetNextPart( nPartId) +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/Images/ClearProcess.png b/Images/ClearProcess.png new file mode 100644 index 0000000000000000000000000000000000000000..d627bcc884bd41a13847d00280f3a0add0274bd3 GIT binary patch literal 1132 zcmV-y1e5!TP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf00v@9M??Vs0RI60 zpuMM)00007bV*G`2jK!34>dBM8=9N|00Z1fL_t(oN4=IyXcIvgfd5U@s0G3L>cLu5 z3SzNPp`{>5HB}2z@PUeFZ+h`&1wB?!iwC{byMo|B>)Wc;h^JUFMbr2SOBz$?s#m|h6SwLH?5G9!M+T?|=> z*ux%G2*;Bh9F;O7e&;^hIy@Mv8f++V2z}|x<6%y2 zdl)xQ7ka9cNzL^DWfmj#W8nAu+2d@$l5^_C4P4wnnLx-0R#so4%)<5QbECC3L7Bz! z3rnGg6;dbkd~XU8{p@bAK&CMXsR7SZ1P$Ve)5Of zCUs-GTCvItarhK}M|(sjm6}V)&i9WA_&Fl-ZFPr5!YHbbQf84lzm;!iwl?yujM3K7 z|cU&l4*bV^tq!=rosD>;NwZ{9Phs1?hv+fkYXL#+blG& zKN%d?-X>kCjXI%cFZj7^2k%#ck5A`$r8e%`DbCpFVn4)lxeDxG20iecsFXxkYnc6# y9nW#_ab(zWWkuIE%ptn*jOgc{Ial=m55QkCGHLdw85(f_0000E|;>5`+)j**=o-U3d5r>oi{Qqx%IDy%Rr&(ab zgUKmR?iN3&?^(?fcJk$aQ@0Qg-ghsOfno_JOWb5lU#$pq=Y3Z6>VLX8d(PD}3s(Q` zVC?CRKQvqNfAUdD_Si3q))NXpp8kKLW>u?*ir4?iZw$Pgdmc?V^o*g%xntEu_qAJG zzM8oDwr>ouZseD8pZJ8)&29F7NuJ^lrW+&MN@qzKT|9o`M27J#FNxACD;5K-oN;>P s|NsBx6_>w}>a|;x-E{Gxs}dsv-#c@~53^L+f&O6dboFyt=akR{0AG%H$p8QV literal 0 HcmV?d00001 diff --git a/Images/EnableFeatures.png b/Images/EnableFeatures.png new file mode 100644 index 0000000000000000000000000000000000000000..1753231062b8ea4643c696682be309fa62f6fe1d GIT binary patch literal 303 zcmeAS@N?(olHy`uVBq!ia0vp^svyk41|*NpQ(y*CY)RhkE)4%caKYZ?lYt_f1s;*b z3=DinK$vl=HlH+5kiEpy*OmPdi=>E|nUKT6JwTy7o-U3d5r>oi{Qqx%IDy%Rr&(ab zgUKl=DO-NdKWMH=`N`elge_AIUabgp@3qP@ um>&G!ez(Ph;Idvf`HQ9pUwlxS$iPrwW>9}J$ZelF{r5}E*Dka~*% literal 0 HcmV?d00001 diff --git a/Images/HideAll.png b/Images/HideAll.png new file mode 100644 index 0000000000000000000000000000000000000000..3ed46afec1cf4f6c1311b307887267fc1465c131 GIT binary patch literal 775 zcmV+i1Ni)jP)C=RACgxe`l`qp)=}?4hj|q8bxkg)c?>TNP=)zP|HA9L4QJvmeMX-v}ut= zZK8IyGH4}KVnk+O;i%xp=;(YsEqX891~X=w@fLXC<#NA;^KJ43x4R2n9-k@_7y@=`ywvN>53e2adU{q<{_}4rC6S3(z`EQ@0yBp#gkOG4(q~`?=yq9Jk@Usg&Nv{ytSJYcaQ)bteab~1IN^?~VF+PA zs3`CqC;**d2w^{{EU@Ju27*E`vkSlq5OXUIbW3{SKeu?#&a@{v4zRn*(%^(XG`xA% z*v;fm4o%fu9|A^!JqHy9-uiu)e{Pd8F=`ct0c3n#FYu&qTu=WR>cAJw&I3I_63u7wguLrDFDQh;9>yd#fHJ}WQ<3%RCb|9r zF131e@r95J3ZcBlj@Q919wm&5%Cu2rz{-pk^YtmSk@8)3LMQ`iNss+|g=t%kM0rDr znD*#YiBzS^aO%1`>luye&XlBS;50B21Oiz6$W^U#wz5UPw&~R#*`;rc)$0h>?5~-% zDSMWPa1NtVgx8rHx>E0G)Yfb>?TWBOk&BjOJ04}e5l3h`)a{qdoa`r8H8y8+EZn(P zzauoge3l*>CplQ4N}2pZN?VJM0wSq(goJa1hb@Hy@XRKFYDKzRk0Z1csu4#B`@3&n zNBGl}(CYZzXcTIuvOuwRGzzt+4jPR@g*y7z>IxQ0j$>MV58;Y z+C$%HA;)T)Pp)#xYI8F7x_EbyqYa;ZejQ$pDHX$8Q?N*FppHT@A*FOaxbe*-0Ew0n zqi3)xm82XLd#*G4h}BBd4cwJ2yWsL*PT(RXC%y(yc6R>$#B4E`9bm+!1nmv9FR0Bp z%@?0eOcjT-TrD&}e%ujj>m9|UL-*w6((&HUF_QIul=cw5<{;imFtHfH)+SB>yc@eZ zQs;xAC-!hwRlYnBZ#4_h^mmc~Lv~8NxXrv9g&KC~GTS~6bhV(KYGlbH(1bvKct%_Q zS?ctFnUGA204eJnCJ?~bb9sH2Qu{f&jRE4xH0kXOx)4Tv>Ab;W8u;~xUI2bG9G8p( zTnN)(1u9>s1i0~}j|GcT83EFKj38fN+8c8bkcEwZj8+D6Ts+HXFj9zI%W$(Fj|bhl zh~i?gs-R4@mbT~wB%+kHxJSz{;OgDyGJ1J0IxT<@hElrC3!>FeuX!`cg*)#x4PPp! zmdJ~fmq-}p08WSac_6ohO18dDx7pS$@mo&NKEGCY=1B5dK&5;vq_QADnksE(IJvMv zcS0W zg~JO;zJ_E}q5vHscRYR{ti|cwNE-k<79aqj5cdXnuS+8=nj5HUEu#`mWeI1s0*rYA z`+9g~j!Uc5f1Br=ra@bXuLlYR(9}wl6~fD@-7uyFe58i^`D85_qYvfH>TaGdg#=jI zU@N-FS~81jH!QKv8BL`w*t#3YY9>@UAlKJnN0!^f_^dsgF82mH7^uVe#5#sLhB}7& bpP>E%O|sqLrw2V_00000NkvXXu0mjf2T+J* literal 0 HcmV?d00001 diff --git a/Images/Rotate.png b/Images/Rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..bd1532eb30159b477aaf019e778f9b47126cc471 GIT binary patch literal 528 zcmV+r0`L8aP)0i8)i zK~z}7?U*r+gD?<9XHf2t&}kvF99SsGmO?r9TW{v|nN`OTg>>IM!~W!{!2YnTT?jlwvEZ z%Y=Tnr_Q~MqQQz83Ux!(WkR3Zug*g`R6cMV7`Kc%RJ)frAT@HRhJZPtv;phYqfsS> z&~3Ba^Giduoq8VE;i40 z1+-rxq*$=ZTVk54SIYMy~_{g)txQ+f*L9~?8(3^hYd9O?-Nl~_7> Su6*490000q39+TZwRi7ZA3+^Fa#v>gf|aPE!JjsjAZGerNXl5QNFe zAqaI=f_cduf^7cwtv-;K`#mlpBoVwhd{eLdfiQi9C#hjggcv}fA|?3pf!ot}^kZR% z=RuEdIigwd8E;hiAi0|2!)Psrx2Wu q?_Us{g#y?Pg40l=zb>Otw(BPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D00(qQO+^Rd1Q`_r zFj&y62mk;88FWQhbW?9;ba!ELWdLwtX>N2bZe?^JG%heMGBNQWX_Wu~0&Yn}K~z{r z)tA3+6fqFS51s%)krzpbI5SvD3bP{fS3!zEZAPC4ij2 z`AK8juI3L<0p^;;5}o5eB%19&xVE4`PW#F+ue!5sCTOR{m z)AKYS5;vny#xItDEe_#xLI}>!3s4f?3cpzOll`D){W&y6yOB<)-c1I!8+bVSPyjlg z|B4oDUa|qUTOJhN%wN1&*>0_e!WMfPn^%?OX-+Ye+&(=Qs`N(sIbI$PbbPiTc#=~A zwM^#nd1=rIP|Q<2AByF{{#YGIbBdt~&s5;x;DQ+Y zJEdm|H84Vx&Qy}vo6n#yuR(qe#kX%T=ZT^8=g)HFotohak~Pck|=RX**IW1t{!xM=P;9_Y(5R zCb!&URTo(+2e1q{{`BR>l|jK6zo%mHr3F*hQ^VNOT4@1AoArSOJDw>9$MxISQ&acX zP}wlYz-CcG7J(VYUviZo22_Bd<|)V|HCaPN;ViBWA~N~Fe-V6q78Yya{F3*Vp{`~F VfhJqWz|Q~x002ovPDHLkV1h 40000 then + BD.MinRaw = BD.MINRAW_L + elseif dRawW * dRawH > 14500 then + BD.MinRaw = BD.MINRAW_M + else + BD.MinRaw = BD.MINRAW_S + end + + -- Creazione nuovo gruppo di lavoro + local sMgName = EgtGetMachGroupNewName( 'Mach_1') + local NewMgId = EgtAddMachGroup( sMgName) + if not NewMgId then + local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName + return false, sOut + end + + -- Impostazione della tavola + EgtSetTable( 'Tab') + + -- Area tavola + local b3Tab = EgtGetTableArea() + -- Calcolo posizione estremo TR della tavola rispetto a sua origine in BL + BD.OriTR = Point3d( b3Tab:getDimX(), b3Tab:getDimY(), 0) + + -- Impostazione dell'attrezzaggio di default + EgtImportSetup() + + -- Inserimento dei pezzi con il loro grezzo + local Cnt = 0 + local Len = dRawL + local DeltaS = dOvmHead + local DeltaE = BD.OVM_MID + for i = 1, #vBeam do + -- assegno identificativo pezzo + local Pz = vBeam[i].Id + -- dati del pezzo + local b3Part = EgtGetBBoxGlob( Pz or GDB_ID.NULL, GDB_BB.EXACT) + local b3Solid = vBeam[i].Box + if b3Part:isEmpty() or b3Solid:isEmpty() then break end + EgtOutLog( 'PartSez=' .. EgtNumToString( b3Part:getDimY(), 1) .. 'x' .. EgtNumToString( b3Part:getDimZ(), 1), 3) + -- se sezione compatibile e lunghezza disponibile sufficiente + local PartLen = b3Solid:getDimX() + local PartWidth = b3Solid:getDimY() + local PartHeight = b3Solid:getDimZ() + local NextLen = Len - DeltaS - DeltaE - PartLen + if (( abs( PartWidth - dRawW) < 10 * GEO.EPS_SMALL and abs( PartHeight - dRawH) < 10 * GEO.EPS_SMALL) or + ( abs( PartHeight - dRawW) < 10 * GEO.EPS_SMALL and abs( PartWidth - dRawH) < 10 * GEO.EPS_SMALL)) and + NextLen >= 0 then + -- dimensioni del grezzo + local CrawLen = PartLen + DeltaS + DeltaE + local Delta = DeltaE + -- creo e posiziono il grezzo + local nRaw = EgtAddRawPart( Point3d(0,0,0), CrawLen, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + -- creo o pulisco gruppo geometrie aggiuntive + if not BL.CreateOrEmptyAddGroup( Pz) then + local sOut = 'Error creating Additional Group in Part ' .. tostring( Pz) + return false, sOut + end + -- se primo pezzo con sovramateriale, aggiungo faccia per taglio iniziale al pezzo + if i == 1 and dOvmHead > 1. then + BL.AddPartStartFace( Pz, b3Solid) + EgtSetInfo( nRaw, 'HOVM', DeltaS) + end + -- aggiungo faccia per taglio finale al pezzo + BL.AddPartEndFace( Pz, b3Solid) + -- inserisco il pezzo nel grezzo + EgtDeselectPartObjs( Pz) + local ptPos = b3Part:getMin() - b3Solid:getMin() + Vector3d( Delta, ( dRawW - PartWidth) / 2, ( dRawH - PartHeight) / 2) + EgtAddPartToRawPart( Pz, ptPos, nRaw) + if abs( PartWidth - dRawW) > 10 * GEO.EPS_SMALL then + -- rotazione attorno a centro geometria complessiva del pezzo + EgtRotatePartInRawPart( Pz, X_AX(), 90) + -- correggo per eccentricità solido rispetto a geometria complessiva del pezzo + local vtEccOri = b3Solid:getCenter() - b3Part:getCenter() + local vtEccRot = Vector3d( vtEccOri) + vtEccRot:rotate( X_AX(), 90) + EgtMovePartInRawPart( Pz, ( vtEccOri - vtEccRot)) + end + -- aggiorno la lunghezza residua della barra + Len = Len - CrawLen + end + -- se rimasto troppo poco grezzo, esco + if Len < BD.MinRaw then break end + DeltaS = 0 + end + + -- Se rimasto materiale aggiungo grezzo dell'avanzo + if Len > 10 then + local nRaw = EgtAddRawPart( Point3d(0,0,0), Len, dRawW, dRawH, BD.RAWCOL) + EgtMoveToCornerRawPart( nRaw, BD.OriTR, MCH_CR.TR) + EgtMoveRawPart( nRaw, Vector3d( Len - dRawL, 0, 0)) + -- assegno ordine in lavorazione + Cnt = Cnt + 1 + EgtSetInfo( nRaw, 'ORD', Cnt) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX()) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() > b3Raw:getCenter():getX()) + end + -- gestioni speciali + if BirdsMouth.Identify( Proc) then + return BirdsMouth.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if LapJoint.Identify( Proc) then + return LapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if Drill.Identify( Proc) then + return Drill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + end + -- non è di testa + return false +end + +------------------------------------------------------------------------------------------------------------- +local function IsTailFeature( Proc, b3Raw) + -- feature sempre di testa o coda per il gruppo + if Proc.Grp == 1 or Proc.Grp == 2 then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX()) + end + -- feature sempre di testa o coda nonostante il gruppo + if ( Proc.Grp == 3 or Proc.Grp == 4) and + ( Proc.Prc == 51 or Proc.Prc == 56 or Proc.Prc == 100 or Proc.Prc == 101 or Proc.Prc == 102 or Proc.Prc == 103 or Proc.Prc == 106) then + return ( Proc.Box:getCenter():getX() < b3Raw:getCenter():getX()) + end + -- gestioni speciali + if BirdsMouth.Identify( Proc) then + return BirdsMouth.IsTailFeature( Proc, b3Raw) + end + if LapJoint.Identify( Proc) then + return LapJoint.IsTailFeature( Proc, b3Raw) + end + if RoundArch.Identify( Proc) then + return RoundArch.IsTailFeature( Proc, b3Raw) + end + if Drill.Identify( Proc) then + return Drill.IsTailFeature( Proc, b3Raw) + end + if FreeContour.Identify( Proc) then + return FreeContour.IsTailFeature( Proc, b3Raw) + end + -- non è di coda + return false +end + +------------------------------------------------------------------------------------------------------------- +local function CollectFeatures( PartId, b3Raw, dCurrOvmH) + -- recupero le feature + local vProc = {} + local LayerId = {} + LayerId[1] = BL.GetAddGroup( PartId) + LayerId[2] = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, 'Processings') + for nInd = 1, 2 do + local ProcId = EgtGetFirstInGroup( LayerId[nInd] or GDB_ID.NULL) + while ProcId do + local nEntType = EgtGetType( ProcId) + if nEntType == GDB_TY.SRF_MESH or nEntType == GDB_TY.EXT_TEXT or + nEntType == GDB_TY.CRV_LINE or nEntType == GDB_TY.CRV_ARC or nEntType == GDB_TY.CRV_BEZ or nEntType == GDB_TY.CRV_COMPO then + local nGrp = EgtGetInfo( ProcId, 'GRP', 'i') + local nPrc = EgtGetInfo( ProcId, 'PRC', 'i') + local nDo = EgtGetInfo( ProcId, 'DO', 'i') or 1 + if nGrp and nPrc and nDo == 1 then + local Proc = {} + Proc.Id = ProcId + Proc.Grp = nGrp + Proc.Prc = nPrc + Proc.Flg = 1 + Proc.Box = EgtGetBBoxGlob( ProcId, GDB_BB.STANDARD) + Proc.Fct = EgtSurfTmFacetCount( ProcId) or 0 + Proc.Head = IsHeadFeature( Proc, b3Raw, dCurrOvmH) + Proc.Tail = IsTailFeature( Proc, b3Raw) + Proc.Fcs = 0 + Proc.Fce = 0 + table.insert( vProc, Proc) + -- se foro + if Drill.Identify( Proc) then + -- assegno faccia di entrata e uscita (dati tabelle sempre per riferimento) + Proc.Fcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + Proc.Fce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + -- verifico se necessaria seconda lavorazione da parte opposta per foro più lungo della punta + if Drill.Split( Proc) then + -- aggiorno flag prima parte foro (dati tabelle sempre per riferimento) + Proc.Flg = 2 + -- definisco dati seconda parte + local Proc2 = {} + Proc2.Id = ProcId + Proc2.Grp = nGrp + Proc2.Prc = nPrc + Proc2.Flg = -2 + Proc2.Box = BBox3d( Proc.Box) + Proc2.Fct = Proc.Fct + Proc2.Head = Proc.Head + Proc2.Tail = Drill.IsTailFeature( Proc2, b3Raw) + Proc2.Fcs = Proc.Fce + Proc2.Fce = Proc.Fcs + table.insert( vProc, Proc2) + end + end + end + end + ProcId = EgtGetNext( ProcId) + end + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function OrderFeatures( vProc, b3Raw) + -- funzione di confronto + -- secondo centro box in X (taglio di intestazione prima di altri tagli di testa e taglio di separazione però prima di altri tagli di coda) + local function CompareFeatures( B1, B2) + -- se primo è feature di testa e l'altro è intestazione + if B1.Head and Hcut.Identify( B2) then + return false + end + -- se secondo è feature di testa e l'altro è intestazione + if B2.Head and Hcut.Identify( B1) then + return true + end + -- se primo è feature di coda e l'altro è separazione o non è feature di coda + if B1.Tail and ( Split.Identify( B2) or not B2.Tail) then + return false + end + -- se secondo è feature di coda e l'altro è separazione o non è feature di coda + if B2.Tail and ( Split.Identify( B1) or not B1.Tail) then + return true + end + -- se primo è foro e l'altro no, lo penalizzo + if B1.Prc == 40 and B2.Prc ~= 40 then + return B1.Box:getCenter():getX() - 300 > B2.Box:getCenter():getX() + end + -- se secondo è foro e l'altro no, lo penalizzo + if B2.Prc == 40 and B1.Prc ~= 40 then + return B1.Box:getCenter():getX() + 300 > B2.Box:getCenter():getX() + end + -- se sono fori e hanno posizione praticamente uguale ordino secondo la faccia di inizio (Fcs) + if B1.Prc == 40 and B2.Prc == 40 and abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) < 300 then + if B1.Fcs == B2.Fcs then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + else + return B1.Fcs > B2.Fcs + end + end + -- se primo è taglio longitudinale completo, dopo tutte le altre feature non di coda + if abs( B1.Box:getDimX() - b3Raw:getDimX()) < 100.0 then + return B1.Box:getMin():getX() + 200.0 > B2.Box:getCenter():getX() + end + -- se secondo è taglio longitudinale completo, dopo tutte le altre feature non di coda + if abs( B2.Box:getDimX() - b3Raw:getDimX()) < 100.0 then + return B1.Box:getCenter():getX() > B2.Box:getMin():getX() + 200.0 + end + -- se entrambi tenoni e si intersecano, metto prima tenone vero e poi base tenone + if Tenon.Identify( B1) and Tenon.Identify( B2) and + B1.Box:getMin():getX() < B2.Box:getMax():getX() + 100 * GEO.EPS_SMALL and B2.Box:getMin():getX() < B1.Box:getMax():getX() + 100 * GEO.EPS_SMALL then + return ( B1.Prc == 50 and B2.Prc == 52) + end + -- confronto standard + if abs( B1.Box:getCenter():getX() - B2.Box:getCenter():getX()) > 1.0 then + return B1.Box:getCenter():getX() > B2.Box:getCenter():getX() + elseif abs( B1.Box:getCenter():getY() - B2.Box:getCenter():getY()) > 1.0 then + return B1.Box:getCenter():getY() > B2.Box:getCenter():getY() + else + return B1.Box:getCenter():getZ() > B2.Box:getCenter():getZ() + end + end + -- eseguo ordinamento + table.sort( vProc, CompareFeatures) +end + +------------------------------------------------------------------------------------------------------------- +local function ClassifyFeatures( vProc, b3Raw) + local bAllOk = true + local bSomeDown = false + local nHeading + for i = 1, #vProc do + local Proc = vProc[i] + local bOk = true + local bDown = false + -- se intestatura + if Hcut.Identify( Proc) then + nHeading = i + -- se doppio taglio + elseif DoubleCut.Identify( Proc) then + bOk, bDown = DoubleCut.Classify( Proc) + -- se taglio longitudinale + elseif LongCut.Identify( Proc) then + bOk, bDown = LongCut.Classify( Proc) + -- se doppio taglio longitudinale + elseif Long2Cut.Identify( Proc) then + bOk, bDown = Long2Cut.Classify( Proc) + -- se tacca + elseif BirdsMouth.Identify( Proc) then + bOk, bDown = BirdsMouth.Classify( Proc) + -- se mezzo-legno di testa + elseif RidgeLap.Identify( Proc) then + bOk, bDown = RidgeLap.Classify( Proc) + -- se mezzo-legno + elseif LapJoint.Identify( Proc) then + bOk, bDown = LapJoint.Classify( Proc) + -- se tasca + elseif Pocket.Identify( Proc) then + bOk, bDown = Pocket.Classify( Proc) + -- se foratura + elseif Drill.Identify( Proc) then + bOk, bDown = Drill.Classify( Proc, b3Raw) + -- se tenone + elseif Tenon.Identify( Proc) then + bOk, bDown = Tenon.Classify( Proc) + -- se mortasa (anche frontale) + elseif Mortise.Identify( Proc) then + bOk, bDown = Mortise.Classify( Proc) + -- se tenone a coda di rondine + elseif DtTenon.Identify( Proc) then + bOk, bDown = DtTenon.Classify( Proc) + -- se mortasa a coda di rondine (anche frontale) + elseif DtMortise.Identify( Proc) then + bOk, bDown = DtMortise.Classify( Proc) + -- se marcatura + elseif Mark.Identify( Proc) then + bOk, bDown = Mark.Classify( Proc) + -- se testo + elseif Text.Identify( Proc) then + bOk, bDown = Text.Classify( Proc) + -- se giunto Gerber + elseif Scarf.Identify( Proc) then + bOk, bDown = Scarf.Classify( Proc) + -- se arco + elseif RoundArch.Identify( Proc) then + bOk, bDown = RoundArch.Classify( Proc) + -- se contorno libero + elseif FreeContour.Identify( Proc) then + bOk, bDown = FreeContour.Classify( Proc) + -- se decorazione + elseif Decor.Identify( Proc) then + bOk, bDown = Decor.Classify( Proc) + end + -- assegno risultato + if bOk then + -- non ammessa feature di testa o di coda da lavorare ribaltata + if ( Proc.Head or Proc.Tail) and bDown then + Proc.On = false + Proc.Down = true + bAllOk = false + -- caso normale + else + Proc.On = true + Proc.Down = bDown + if bDown then bSomeDown = true end + end + else + Proc.On = false + bAllOk = false + end + end + -- se necessario ribaltamento, assegno intestatura alla fase ribaltata + if bSomeDown and nHeading then + vProc[nHeading].Down = true + end + return bAllOk, bSomeDown +end + +------------------------------------------------------------------------------------------------------------- +local function PrintFeatures( vProc, b3Raw) + EgtOutLog( ' RawBox=' .. tostring( b3Raw)) + for i = 1, #vProc do + EgtOutLog( ' Proc=' .. string.format( '%3d', vProc[i].Id) .. ' Grp=' .. string.format( '%1d', vProc[i].Grp) .. ' Prc=' .. string.format( '%3d', vProc[i].Prc) .. + ' On=' .. EgtIf( vProc[i].On, 'T', 'F') .. ' Flg=' .. string.format( '%2d', vProc[i].Flg) .. ' Fcse=' .. string.format( '%1d,%1d', vProc[i].Fcs, vProc[i].Fce) .. + ' Down=' .. EgtIf( vProc[i].Down, 'T', 'F') .. ' Head=' .. EgtIf( vProc[i].Head, 'T', 'F') .. ' Tail=' .. EgtIf( vProc[i].Tail, 'T', 'F') .. + ' Fct=' .. string.format( '%2d', vProc[i].Fct) .. ' Box=' .. tostring( vProc[i].Box)) + end + return vProc +end + +------------------------------------------------------------------------------------------------------------- +local function AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) + local bOk = true + local sErr = '' + local bNewPhase = false + -- se intestatura ( 1-340-X ) + if Hcut.Identify( Proc) then + -- esecuzione taglio di testa + bOk, sErr = Hcut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se separazione ( 2-350-X ) + elseif Split.Identify( Proc) then + -- esecuzione separazione o eliminazione grezzo residuo + bOk, _, sErr = Split.Make( Proc, nPhase, nRawId, nPartId) + -- richiedo il passaggio alla seconda fase di lavorazione di questa trave + bNewPhase = true + -- se taglio ( 1/2-010-X) + elseif Cut.Identify( Proc) then + -- esecuzione taglio + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se doppio taglio ( 1/2-011-X) + elseif DoubleCut.Identify( Proc) then + -- se due facce, eseguo doppio taglio + if Proc.Fct == 2 then + bOk, sErr = DoubleCut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- altrimenti eseguo singolo taglio + else + bOk, sErr = Cut.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + end + -- se taglio longitudinale ( 0/3/4-010-X) + elseif LongCut.Identify( Proc) then + -- esecuzione taglio longitudinale + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + -- se doppio taglio longitudinale ( 0-012-X) + elseif Long2Cut.Identify( Proc) then + -- se due facce, eseguo doppio taglio longitudinale + if Proc.Fct == 2 then + bOk, sErr = Long2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti eseguo singolo taglio longitudinale + else + bOk, sErr = LongCut.Make( Proc, nPhase, nRawId, nPartId) + end + -- se tacca ( 3/4-020-X) + elseif BirdsMouth.Identify( Proc) then + -- esecuzione tacca + bOk, sErr = BirdsMouth.Make( Proc, nPhase, nRawId, nPartId) + -- se mezzo-legno di testa ( 1/2-030-X) + elseif RidgeLap.Identify( Proc) then + -- esecuzione mezzo-legno di testa + bOk, sErr = RidgeLap.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mezzo-legno ( 3/4-030-X) o scanalatura ( 3/4-016-X) + elseif LapJoint.Identify( Proc) then + -- esecuzione mezzo-legno o scanalatura + bOk, sErr = LapJoint.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se smusso ( 3/4-036-X) + elseif Chamfer.Identify( Proc) then + -- esecuzione smusso + bOk, sErr = Chamfer.Make( Proc, nPhase, nRawId, nPartId) + -- se tasca ( 4-039-X) o ( 3/4-032-X) + elseif Pocket.Identify( Proc) then + -- esecuzione tasca + bOk, sErr = Pocket.Make( Proc, nPhase, nRawId, nPartId) + -- se foratura ( 3/4-040-X) + elseif Drill.Identify( Proc) then + -- esecuzione foratura + bOk, sErr = Drill.Make( Proc, nPhase, nRawId, nPartId) + -- se tenone ( 1/2-050-X) + elseif Tenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = Tenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa ( 3/4-050-X) anche frontale ( 3/4-051-X) + elseif Mortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = Mortise.Make( Proc, nPhase, nRawId, nPartId) + -- se tenone a coda di rondine ( 1/2-055-X) + elseif DtTenon.Identify( Proc) then + -- esecuzione tenone + bOk, sErr = DtTenon.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se mortasa a coda di rondine ( 3/4-055-X) anche frontale ( 3/4-056-X) + elseif DtMortise.Identify( Proc) then + -- esecuzione mortasa + bOk, sErr = DtMortise.Make( Proc, nPhase, nRawId, nPartId) + -- se marcatura ( 3/4-060-X) + elseif Mark.Identify( Proc) then + -- esecuzione marcatura + bOk, sErr = Mark.Make( Proc, nPhase, nRawId, nPartId) + -- se testo ( 4-061-X) + elseif Text.Identify( Proc) then + -- esecuzione testo + bOk, sErr = Text.Make( Proc, nPhase, nRawId, nPartId) + -- se giunto Gerber ( 1/2-070-X) + elseif Scarf.Identify( Proc) then + -- esecuzione giunto Gerber + bOk, sErr = Scarf.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Front ( 3/4-100-X) + elseif ProfFront.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo concavo ( 3/4-101-X) + elseif ProfConcave.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo convesso ( 3/4-102-X) + elseif ProfConvex.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo caudato ( 3/4-103-X) + elseif ProfCamb.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se arco ( 4-104-X) + elseif RoundArch.Identify( Proc) then + -- esecuzione arco + bOk, sErr = RoundArch.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se profilo Head ( 3/4-106-X) + elseif ProfHead.Identify( Proc) then + -- esecuzione profilo + bOk, sErr = ProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se contorno libero ( 0/3/4-250-X) + elseif FreeContour.Identify( Proc) then + -- esecuzione contorno + bOk, sErr = FreeContour.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- se decorazione ( 0/3/4-959-X) + elseif Decor.Identify( Proc) then + -- esecuzione decorazione + bOk, sErr = Decor.Make( Proc, nPhase, nRawId, nPartId) + -- altrimenti feature sconosciuta + else + sErr = 'Error on process ' .. tostring( Proc.Id) .. ' unknown type (' .. tonumber( Proc.Grp) .. '-' .. tonumber( Proc.Prc) .. ')' + EgtOutLog( sErr) + bOk = false + end + return bOk, sErr, bNewPhase +end + +------------------------------------------------------------------------------------------------------------- +function BeamExec.ProcessFeatures() + local bAddOk = true + local sAddErrors = '' + local nCutId + local nTaskId + local nOrd = 1 + local nRawId = EgtGetFirstRawPart() + while nRawId do + -- verifico che il grezzo contenga pezzi oppure sia abbastanza lungo da essere scaricato coi carrelli + local nPartId = EgtGetFirstPartInRawPart( nRawId) + if not nPartId and EgtGetRawPartBBox( nRawId):getDimX() < BD.MinRaw then break end + -- aggiungo la fase, se non è la prima + if nOrd == 1 then + EgtSetCurrPhase( 1) + else + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + end + local nPhase = EgtGetCurrPhase() + local nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', EgtIf( nPartId, 'START', 'REST')) + EgtSetInfo( nDispId, 'ORD', nOrd) + EgtOutLog( 'Phase=' .. tostring( nPhase) .. ' Raw=' .. tostring( nRawId) .. ' Part=' .. tostring( nPartId), 1) + -- ingombro del grezzo e sovramateriale di testa + local b3Raw = EgtGetRawPartBBox( nRawId) + local dCurrOvmH = EgtGetInfo( nRawId, 'HOVM', 'd') or 0 + -- recupero le feature di lavorazione della trave + vProc = CollectFeatures( nPartId, b3Raw, dCurrOvmH) + -- le ordino lungo X + OrderFeatures( vProc, b3Raw) + -- le classifico + local bOk, bSomeDown = ClassifyFeatures( vProc, b3Raw) + if not bOk then + bAddOk = false + sAddErrors = 'Warning : some feature not machinable due to orientation ' + end + -- debug + if EgtGetDebugLevel() >= 1 then + PrintFeatures( vProc, b3Raw) + end + -- se richiesto ribaltamento + if bSomeDown then + -- ribalto le travi della fase corrente + local nRId = nRawId + while nRId do + EgtRotateRawPart( nRId, X_AX(), 180) + nRId = EgtGetNextRawPart( nRId) + end + EgtSetInfo( nDispId, 'ROT', -2) + -- inserisco le lavorazioni da lavorare ribaltate + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.On and Proc.Down then + local bOk, sErr = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) + if not bOk then + bAddOk = false + sAddErrors = sAddErrors .. sErr .. '\n' + if not nCutId then + nCutId = EgtGetInfo( EgtGetParent( EgtGetParent( Proc.Id)), 'CUTID', 'i') + nTaskId = EgtGetInfo( Proc.Id, 'TASKID', 'i') + end + end + end + end + -- aggiungo nuova fase con le travi in posizione standard + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, 0) + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'MID') + EgtSetInfo( nDispId, 'ORD', nOrd) + end + -- inserisco le lavorazioni non ribaltate della trave + for i = 1, #vProc do + -- creo la lavorazione + local Proc = vProc[i] + if Proc.On and not Proc.Down then + local bOk, sErr, bNewPhase = AddFeatureMachining( Proc, nPhase, nRawId, nPartId, dCurrOvmH, b3Raw) + if not bOk then + bAddOk = false + sAddErrors = sAddErrors .. sErr .. '\n' + if not nCutId then + nCutId = EgtGetInfo( EgtGetParent( EgtGetParent( Proc.Id)), 'CUTID', 'i') + nTaskId = EgtGetInfo( Proc.Id, 'TASKID', 'i') + end + end + -- se era taglio di separazione, aggiungo nuova fase + if bNewPhase then + BL.AddPhaseWithRawParts( nRawId, BD.OriTR, BD.RAW_OFFSET) + -- se grezzo successivo senza pezzi e finale, va tolto + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BD.MinRaw then + EgtRemoveRawPartFromCurrPhase( nNextRawId) + end + nPhase = EgtGetCurrPhase() + nDispId = EgtGetPhaseDisposition( nPhase) + EgtSetInfo( nDispId, 'TYPE', 'END') + EgtSetInfo( nDispId, 'ORD', nOrd) + end + end + end + -- passo al grezzo successivo + nOrd = nOrd + 1 + nRawId = EgtGetNextRawPart( nRawId) + end + + -- Aggiornamento finale di tutto + EgtSetCurrPhase( 1) + local bApplOk, sApplErrors = EgtApplyAllMachinings() + if not bAddOk or not bApplOk then + local sErrors = ( sAddErrors or '') .. ( sApplErrors or '') + return false, sErrors, nCutId, nTaskId + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +return BeamExec diff --git a/LuaLibs/BeamLib.lua b/LuaLibs/BeamLib.lua new file mode 100644 index 0000000..d6d1a00 --- /dev/null +++ b/LuaLibs/BeamLib.lua @@ -0,0 +1,720 @@ +-- BeamLib.lua by Egaltech s.r.l. 2019/03/29 +-- Libreria globale per Travi + +-- Tabella per definizione modulo +local BeamLib = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' BeamLib started', 1) + +------------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetAddGroup( PartId) + -- recupero il nome del gruppo di lavoro corrente + local sMchGrp = EgtGetMachGroupName( EgtGetCurrMachGroup() or GDB_ID.NULL) + if not sMchGrp then return nil, nil end + -- cerco il gruppo aggiuntivo omonimo nel pezzo e se esiste lo restituisco + local AddGrpId = EgtGetFirstNameInGroup( PartId or GDB_ID.NULL, sMchGrp) + -- restituisco Id e Nome + return AddGrpId, sMchGrp +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.CreateOrEmptyAddGroup( PartId) + -- recupero i dati del gruppo aggiuntivo + local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId) + if not sMchGrp then return false end + -- se esiste lo svuoto + if AddGrpId then + return EgtEmptyGroup( AddGrpId) + end + -- altrimenti lo creo + AddGrpId = EgtGroup( PartId or GDB_ID.NULL) + if not AddGrpId then return false end + -- assegno nome, flag di layer per gruppo di lavoro e colore + EgtSetName( AddGrpId, sMchGrp) + EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) + EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 50)) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartStartFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process StartFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio iniziale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMax(), X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process StartFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'StartCut') + EgtSetInfo( nStmId, 'GRP', 1) + EgtSetInfo( nStmId, 'PRC', 340) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPartEndFace( PartId, b3Solid) + -- recupero gruppo per geometria aggiuntiva + local AddGrpId = BeamLib.GetAddGroup( PartId) + if not AddGrpId then + local sErr = 'Error on process EndFace impossible to find AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo nuovo taglio finale + local nStmId = EgtSurfTmPlaneInBBox( AddGrpId, b3Solid:getMin(), -X_AX(), b3Solid, GDB_RT.GLOB) + if not nStmId then + local sErr = 'Error on process EndFace impossible to create Face' + EgtOutLog( sErr) + return false, sErr + end + -- applico gli opportuni attributi di feature + EgtSetName( nStmId, 'EndCut') + EgtSetInfo( nStmId, 'GRP', 2) + EgtSetInfo( nStmId, 'PRC', 350) + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.AddPhaseWithRawParts( nFirstRawId, OriTR, dDeltaSucc) + EgtAddPhase() + local nRawId = nFirstRawId + local dRawMove = 0 + while nRawId do + EgtKeepRawPart( nRawId) + EgtMoveToCornerRawPart( nRawId, OriTR, MCH_CR.TR) + EgtMoveRawPart( nRawId, Vector3d( - dRawMove, 0, 0)) + if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end + dRawMove = dRawMove + EgtGetRawPartBBox( nRawId):getDimX() + nRawId = EgtGetNextRawPart( nRawId) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartOnTop( nCrvId) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- cerco l'estremo più alto e lo imposto come inizio + local dUmax = 0 + local dZmax = - GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP and ptP:getZ() > dZmax + GEO.EPS_SMALL then + dZmax = ptP:getZ() + dUmax = dU + end + end + if abs( dUmax - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUmax) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.PutStartNearestToEdge( nCrvId, b3Raw) + -- verifico che la curva sia chiusa + if not EgtCurveIsClosed( nCrvId) then return false end + -- recupero il versore normale al piano di lavoro o estrusione + local vtN = EgtCurveExtrusion( nCrvId, GDB_ID.ROOT) + -- coefficienti per riportare la distanza nel piano di lavoro + local dCoeffX = 1 / ( sqrt( 1 - vtN:getX() * vtN:getX())) + local dCoeffY = 1 / ( sqrt( 1 - vtN:getY() * vtN:getY())) + local dCoeffZ = 1 / ( sqrt( 1 - vtN:getZ() * vtN:getZ())) + -- cerco l'estremo più vicino al box e lo imposto come inizio (escluso Zmin) + local dUopt = 0 + local dDopt = GEO.INFINITO + local dUi, dUf = EgtCurveDomain( nCrvId) + for dU = dUi, dUf, 0.5 do + local ptP = EgtUP( nCrvId, dU, GDB_ID.ROOT) + if ptP then + local vtMin = ptP - b3Raw:getMin() + local vtMax = ptP - b3Raw:getMax() + local dD = abs( vtMin:getX()) * dCoeffX + dD = min( abs( vtMax:getX()) * dCoeffX, dD) + dD = min( abs( vtMin:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getY()) * dCoeffY, dD) + dD = min( abs( vtMax:getZ()) * dCoeffZ, dD) + if dD < dDopt + GEO.EPS_SMALL then + dDopt = dD + dUopt = dU + end + end + end + if abs( dUopt - dUi) > GEO.EPS_ZERO then + EgtChangeClosedCurveStart( nCrvId, dUopt) + end + return true +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.GetPointDirDepth( nRawId, ptP, vtDir) + -- recupero il solido del grezzo + local nSolId = EgtGetFirstNameInGroup( nRawId, 'RawSolid') + if not nSolId then return end + -- interseco con la retta + local bOk, vType, vPar = EgtSurfTmLineInters( nSolId, ptP, vtDir, GDB_RT.GLOB) + if not bOk then return end + if not vPar or #vPar == 0 then return -2 end + local dLenIn, dLenOut + for i = 1, #vPar do + if vPar[i] < 0 then + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = -1 + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN then + dLenIn = -2 + end + else + if vType[i] == GDB_SLT.IN or vType[i] == GDB_SLT.TG_INI then + dLenIn = vPar[i] + end + if vType[i] == GDB_SLT.OUT or vType[i] == GDB_SLT.TG_FIN or vType[i] == GDB_SLT.TOUCH then + dLenOut = vPar[i] + end + end + end + return dLenIn, dLenOut +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestParalOpposite( vtRef) + if abs( vtRef:getX()) > abs( vtRef:getY()) and abs( vtRef:getX()) > abs( vtRef:getZ()) then + if vtRef:getX() > 0 then + return MCH_MILL_FU.PARAL_LEFT + else + return MCH_MILL_FU.PARAL_RIGHT + end + elseif abs( vtRef:getY()) > abs( vtRef:getZ()) then + if vtRef:getY() > 0 then + return MCH_MILL_FU.PARAL_FRONT + else + return MCH_MILL_FU.PARAL_BACK + end + else + if vtRef:getZ() > 0 then + return MCH_MILL_FU.PARAL_DOWN + else + return MCH_MILL_FU.PARAL_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetNearestOrthoOpposite( vtRef) + if abs( vtRef:getX()) > abs( vtRef:getY()) and abs( vtRef:getX()) > abs( vtRef:getZ()) then + if vtRef:getX() > 0 then + return MCH_MILL_FU.ORTHO_LEFT + else + return MCH_MILL_FU.ORTHO_RIGHT + end + elseif abs( vtRef:getY()) > abs( vtRef:getZ()) then + if vtRef:getY() > 0 then + return MCH_MILL_FU.ORTHO_FRONT + else + return MCH_MILL_FU.ORTHO_BACK + end + else + if vtRef:getZ() > 0 then + return MCH_MILL_FU.ORTHO_DOWN + else + return MCH_MILL_FU.ORTHO_TOP + end + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetOrtupOpposite( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return MCH_MILL_FU.ORTUP_LEFT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return MCH_MILL_FU.ORTUP_RIGHT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return MCH_MILL_FU.ORTUP_FRONT + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return MCH_MILL_FU.ORTUP_BACK + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return MCH_MILL_FU.ORTUP_DOWN + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return MCH_MILL_FU.ORTUP_TOP + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetVersRef( nOrthoOpposite) + if nOrthoOpposite == MCH_MILL_FU.ORTHO_LEFT then + return X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_RIGHT then + return -X_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_FRONT then + return Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_BACK then + return -Y_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_DOWN then + return Z_AX() + elseif nOrthoOpposite == MCH_MILL_FU.ORTHO_TOP then + return -Z_AX() + end + return nil +end + +--------------------------------------------------------------------- +function BeamLib.GetBoxFaceNorm( b3Box, ptP, vtV) + local vtNx = V_NULL() + if abs( ptP:getX() - b3Box:getMin():getX()) < 10 * GEO.EPS_SMALL then + vtNx = -X_AX() + elseif abs( ptP:getX() - b3Box:getMax():getX()) < 10 * GEO.EPS_SMALL then + vtNx = X_AX() + end + local vtNy = V_NULL() + if abs( ptP:getY() - b3Box:getMin():getY()) < 10 * GEO.EPS_SMALL then + vtNy = -Y_AX() + elseif abs( ptP:getY() - b3Box:getMax():getY()) < 10 * GEO.EPS_SMALL then + vtNy = Y_AX() + end + local vtNz = V_NULL() + if abs( ptP:getZ() - b3Box:getMin():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = -Z_AX() + elseif abs( ptP:getZ() - b3Box:getMax():getZ()) < 10 * GEO.EPS_SMALL then + vtNz = Z_AX() + end + local dNxDotV = vtNx * vtV + local dNyDotV = vtNy * vtV + local dNzDotV = vtNz * vtV + if dNxDotV > dNyDotV and dNxDotV > dNzDotV then + return vtNx + elseif dNyDotV > dNzDotV and dNyDotV > dNxDotV then + return vtNy + else + return vtNz + end +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceWithMostAdj( nSurfId) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( nSurfId) + -- recupero le normali delle facce + local vvtN = {} + for i = 1, nFacCnt do + local _, vtN = EgtSurfTmFacetCenter( nSurfId, i - 1, GDB_ID.ROOT) + vvtN[i] = vtN ; + end + -- adiacenze e sottosquadra delle facce + local vAdj = {} + local vUcut = {} + for i = 1, nFacCnt do + -- recupero le adiacenze del loop esterno + local vFacAdj = EgtSurfTmFacetAdjacencies( nSurfId, i - 1)[1] + -- le conto + local nCount = 0 + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + nCount = nCount + 1 + end + end + vAdj[i] = nCount + -- ne determino eventuale sottosquadra (- 3deg) + local bUcut = false + for j = 1, #vFacAdj do + if vFacAdj[j] >= 0 then + local vtN = vvtN[i] + local vtN2 = vvtN[vFacAdj[j]+1] + if vtN * vtN2 < -0.05 then + bUcut = true + end + end + end + vUcut[i] = bUcut + end + -- recupero le facce non in sottosquadra e con il maggior numero di adiacenze + local nFacInd = {} + local nMaxAdj = 0 + for i = 1, nFacCnt do + if not vUcut[i] then + if vAdj[i] > nMaxAdj then + nFacInd = {} + nFacInd[1] = i - 1 + nMaxAdj = vAdj[i] + elseif vAdj[i] == nMaxAdj and nMaxAdj > 0 then + table.insert( nFacInd, i - 1) + end + end + end + -- premio la faccia con minore elevazione + local nFacOpt + local dMinElev = GEO.INFINITO + for i = 1, #nFacInd do + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacInd[i], GDB_ID.ROOT) + local frOCS = Frame3d( ptC, vtN) ; + local b3Box = EgtGetBBoxRef( nSurfId, GDB_BB.STANDARD, frOCS) + if b3Box:getDimZ() < dMinElev then + nFacOpt = nFacInd[i] + dMinElev = b3Box:getDimZ() + end + end + return nFacOpt, dMinElev +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceBox( nSurfId, nFacet) + -- estraggo la faccia temporaneamente + local FacId = EgtCopySurfTmFacet( nSurfId, nFacet, EgtGetParent( nSurfId)) + if not FacId then return end + -- determino l'ingombro in globale + local b3Glob = EgtGetBBoxGlob( FacId, GDB_BB.STANDARD) + -- cancello la faccia temporanea + EgtErase( FacId) + -- restituisco il bounding box + return b3Glob +end + +--------------------------------------------------------------------- +function BeamLib.GetFaceHvRefDim( nSurfId, nFacet) + -- recupero centro e normale della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + if not ptC or not vtN then return end + -- riferimento tipo OCS della faccia (X orizz, Y max pendenza, Z normale) + local frHV = Frame3d( ptC, vtN) + if frHV:getVersY():getZ() < 0 then + frHV:rotate( ptC, vtN, 180) + end + -- estraggo la faccia temporaneamente + local FacId = EgtCopySurfTmFacet( nSurfId, nFacet, EgtGetParent( nSurfId)) + -- determino l'ingombro in questo riferimento + local b3HV = EgtGetBBoxRef( FacId, GDB_BB.STANDARD, frHV) + -- cancello la faccia temporanea + EgtErase( FacId) + -- restituisco i valori calcolati + return frHV, b3HV:getDimX(), b3HV:getDimY() +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutGeom( ptP1, ptP2, vtV1, vtV2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Mi assicuro che i vettori ingresso/uscita giacciano nel piano + vtV1 = vtV1 - vtV1 * vtN * vtN ; vtV1:normalize() + vtV2 = vtV2 - vtV2 * vtN * vtN ; vtV2:normalize() + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Versori di attacco e uscita + local dCos1 = vtV1 * vtRef + local dCos2 = vtV2 * vtRef + local vtLi, vtLo + if dCos1 > dCos2 then + vtLi = vtV1 + vtLo = vtV1 + else + vtLi = vtV2 + vtLo = vtV2 + end + local bRight = ( vtX * vtLi > 0) + -- Versori di attacco e uscita nel riferimento intrinseco al taglio + local vtLiL = Vector3d( vtLi) ; vtLiL:toLoc( frFace) + local vtLoL = Vector3d( vtLo) ; vtLoL:toLoc( frFace) + -- Spostamento punti per effetto dell'extra di taglio + if dCutExtra > GEO.EPS_SMALL then + ptP1 = ptP1 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + ptP2 = ptP2 + vtX * ( EgtIf( bRight, - dCutExtra, dCutExtra)) + end + -- Attacco + local dLiTang = 10000 + local dLiPerp = 10000 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtLi, b3Box) + if bLiOk and #vLiPar > 0 then + -- con la prima faccia di uscita + local dLen = vLiPar[#vLiPar] + local ptInt = ptP1 + vtLi * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtLi) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLi * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen * vtLiL:getY() + dLiPerp = EgtIf( bRight, dLiLen, - dLiLen) * vtLiL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtLi, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[#vLiPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtLi * dLen2, vtLi) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLi * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + local dLiTang2 = - dLiLen2 * vtLiL:getY() + local dLiPerp2 = EgtIf( bRight, dLiLen2, - dLiLen2) * vtLiL:getX() + if dLiLen2 < dLiLen then + dLiTang = dLiTang2 + dLiPerp = dLiPerp2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 10000 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtLo, b3Box) + if bLoOk and #vLoPar > 0 then + -- con la prima faccia di uscita + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtLo * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtLo) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - abs( vtX * vtFN)) / ( vtLo * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen * vtLoL:getY() + dLoPerp = EgtIf( bRight, dLoLen, - dLoLen) * vtLoL:getX() + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtLo, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtLo * dLen2, vtLo) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - abs( vtX * vtFN2)) / ( vtLo * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + local dLoTang2 = dLoLen2 * vtLoL:getY() + local dLoPerp2 = EgtIf( bRight, dLoLen2, - dLoLen2) * vtLoL:getX() + if dLoLen2 < dLoLen then + dLoTang = dLoTang2 + dLoPerp = dLoPerp2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dRad, vtRef, dCutExtra, b3Box) + -- Versore tangente al taglio + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + -- Sistema di riferimento intrinseco al taglio + local vtX = vtTg ^ vtN + local frFace = Frame3d( ptP1, vtX, vtTg, vtN) + if ( vtX * vtRef < 0) then + vtX = - vtX + end + EgtOutLog( 'Vref=' .. tostring( vtRef) .. ' V1=' .. tostring( vtV1) .. ' V2=' .. tostring( vtV2), 3) + -- Spostamento punti per effetto dell'extra di taglio + if dCutExtra > GEO.EPS_SMALL then + ptP1 = ptP1 - vtX * dCutExtra + ptP2 = ptP2 - vtX * dCutExtra + end + -- Attacco + local dLiTang = 10000 + local dLiPerp = 0 + local bLiOk, _, vLiPar = EgtLineBoxInters( ptP1, vtTg, b3Box) + if bLiOk and #vLiPar > 0 then + local dLen = vLiPar[1] + local ptInt = ptP1 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, -vtTg) + EgtOutLog( 'LiFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLiLen = dLen + dAddLen + EgtOutLog( 'LeadIn Dist=' .. EgtNumToString( dLiLen), 3) + dLiTang = - dLiLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLiOk2, _, vLiPar2 = EgtLineBoxInters( ptP1, vtTg, b3Mod) + if bLiOk2 and #vLiPar2 > 0 then + local dLen2 = vLiPar2[1] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP1 + vtTg * dLen2, -vtTg) + EgtOutLog( 'LiFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLiLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadIn Dist2=' .. EgtNumToString( dLiLen2), 3) + if -dLiLen2 < -dLiLen then + dLiTang = - dLiLen2 + end + end + end + -- Lunghezza di uscita + local dLoTang = 10000 + local dLoPerp = 0 + local bLoOk, _, vLoPar = EgtLineBoxInters( ptP2, vtTg, b3Box) + if bLoOk and #vLoPar > 0 then + local dLen = vLoPar[#vLoPar] + local ptInt = ptP2 + vtTg * dLen + local vtFN = BeamLib.GetBoxFaceNorm( b3Box, ptInt, vtTg) + EgtOutLog( 'LoFaceNorm=' .. tostring( vtFN), 3) + local dAddLen = dRad * ( sqrt( 1 - ( vtN * vtFN) * ( vtN * vtFN)) - ( vtX * vtFN)) / ( vtTg * vtFN) + local dLoLen = dLen + dAddLen + EgtOutLog( 'LeadOut Dist=' .. EgtNumToString( dLoLen), 3) + dLoTang = dLoLen + -- verifico se miglioro calcolando con faccia successiva + local b3Mod = BBox3d( b3Box) ; b3Mod:Add( ptInt + 1000 * vtFN) + local bLoOk2, _, vLoPar2 = EgtLineBoxInters( ptP2, vtTg, b3Mod) + if bLoOk2 and #vLoPar2 > 0 then + local dLen2 = vLoPar2[#vLoPar2] + local vtFN2 = BeamLib.GetBoxFaceNorm( b3Mod, ptP2 + vtTg * dLen2, vtTg) + EgtOutLog( 'LoFaceNorm2=' .. tostring( vtFN2), 3) + local dAddLen2 = dRad * ( sqrt( 1 - ( vtN * vtFN2) * ( vtN * vtFN2)) - ( vtX * vtFN2)) / ( vtTg * vtFN2) + local dLoLen2 = dLen2 + dAddLen2 + EgtOutLog( 'LeadOut Dist2=' .. EgtNumToString( dLoLen2), 3) + if dLoLen2 < dLoLen then + dLoTang = dLoLen2 + end + end + end + return dLiTang, dLiPerp, dLoTang, dLoPerp +end + +--------------------------------------------------------------------- +function BeamLib.MakeOneFaceBySaw( nSurfId, nFacet, sCutting, dSawDiam, nOrthoOpposite, dCutExtra, dCutSic, dCutOffset, sNotes, b3Raw) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( nSurfId, nFacet, GDB_ID.ROOT) + -- linea o bilinea di lavorazione + local ptP1, ptPm, ptP2, vtV1, vtV2, dLen, dWidth = EgtSurfTmFacetOppositeSide( nSurfId, nFacet, BeamLib.GetVersRef( nOrthoOpposite), GDB_ID.ROOT) + if dLen < 1.1 or dWidth < 1.1 then + local sWarn = 'Face ' .. string.format( '%d,%d', nSurfId, nFacet) .. ' skipped : too small' + EgtOutLog( sWarn, 1) + return true, '' + end + vtV1 = - vtV1 + local bInvert = ( ptP2:getZ() < ptP1:getZ()) + if bInvert then + ptP1, ptP2 = ptP2, ptP1 + vtV1, vtV2 = vtV2, vtV1 + end + local vtTg = ptP2 - ptP1 ; vtTg:normalize() + local dAllStart = 0 + local dAllEnd = 0 + -- se bilinea, scarto la parte corta + if ( ( ptPm - ptP1) - ( ptPm - ptP1) * vtTg * vtTg):len() > 100 * GEO.EPS_SMALL then + local dDist1 = dist( ptP1, ptPm) + local dDist2 = dist( ptP2, ptPm) + if dDist1 >= dDist2 then + ptP2 = Point3d( ptPm) + dAllEnd = - dDist2 - 10 * GEO.EPS_SMALL + else + ptP1 = Point3d( ptPm) + dAllStart = - dDist1 - 10 * GEO.EPS_SMALL + end + vtTg = ptP2 - ptP1 ; vtTg:normalize() + end + -- verifico se lavorazione con lama sotto e testa sopra + local bDownUp = ( vtN:getZ() < -0.5) + local nFaceUse = nOrthoOpposite + if bDownUp then nFaceUse = BeamLib.GetOrtupOpposite( nOrthoOpposite) end + local nWorkSide = EgtIf( ( bInvert ~= bDownUp), MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT) + -- Versore di riferimento + local vtRef = BeamLib.GetVersRef( nOrthoOpposite) + vtRef = vtRef - vtRef * vtN * vtN ; vtRef:normalize() + -- Versore esterno + local vtOut = vtN + if abs( vtOut:getZ()) > 0.866 then + vtOut = vtRef - vtRef * vtTg * vtTg ; vtOut:normalize() + end + -- Versore ausiliario (direzione braccio) + local vtAux = Vector3d( vtN:getX(), vtN:getY(), 0) ; vtAux:normalize() + vtAux:rotate( Z_AX(), 90) + if vtAux:isSmall() then + vtAux = Vector3d( vtOut:getX(), vtOut:getY(), 0) ; vtAux:normalize() + else + if abs( vtAux * vtOut) < GEO.EPS_SMALL then + if abs( vtTg:getZ()) > 0.5 then + if vtAux * vtRef < 0 then + vtAux = - vtAux + end + elseif vtAux * vtTg > 0 then + vtAux = - vtAux + end + elseif vtAux * vtOut < 0 then + vtAux = - vtAux + end + end + -- parametri di attacco/uscita + local b3Box = BBox3d( b3Raw) + b3Box:expand( dCutSic) + local dLiTang, dLiPerp, dLoTang, dLoPerp + if ( vtV1:getZ() > -0.1 or vtV2:getZ() > -0.1) then + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutGeom( ptP1, ptP2, vtV1, vtV2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + else + dLiTang, dLiPerp, dLoTang, dLoPerp = BeamLib.CalcLeadInOutTangGeom( ptP1, ptP2, vtN, dSawDiam/2, vtRef, dCutExtra, b3Box) + end + -- posizione braccio + EgtOutLog( 'vtN=' .. tostring( vtN) .. ' vtRef=' .. tostring( vtRef) .. ' vtOut=' .. tostring( vtOut) .. ' vtAux=' .. tostring( vtAux), 3) + local nSCC = MCH_SCC.NONE + if abs( vtAux:getX()) > abs( vtAux:getY()) then + nSCC = EgtIf( ( vtAux:getX() > 0), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + else + nSCC = EgtIf( ( vtAux:getY() > 0), MCH_SCC.ADIR_YP, MCH_SCC.ADIR_YM) + end + -- inserisco la lavorazione di taglio + local sName = 'Cut_' .. ( EgtGetName( nSurfId) or tostring( nSurfId)) .. '_' .. tostring( nFacet + 1) + local nMchFId = EgtAddMachining( sName, sCutting) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sCutting + EgtOutLog( sErr) + return false, sErr + end + sName = EgtGetOperationName( nMchFId) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ nSurfId, nFacet}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto inversione e lato correzione + EgtSetMachiningParam( MCH_MP.INVERT, bInvert) + EgtSetMachiningParam( MCH_MP.WORKSIDE, nWorkSide) + -- affondamento aggiuntivo + EgtSetMachiningParam( MCH_MP.OFFSR, -dCutExtra) + -- offset longitudinale + EgtSetMachiningParam( MCH_MP.OFFSL, dCutOffset) + -- imposto attacco/uscita + EgtSetMachiningParam( MCH_MP.LITANG, dLiTang) + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOTANG, dLoTang) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- imposto allungamenti iniziale e finale + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dAllStart) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dAllEnd) + -- eventuali note + if sNotes and #sNotes > 0 then EgtSetMachiningParam( MCH_MP.USERNOTES, sNotes) end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true, sName +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateHCING( nRawId, dHCI) + local dOldHCI = EgtGetInfo( nRawId, 'HCING', 'd') + if not dOldHCI or dHCI > dOldHCI then + EgtSetInfo( nRawId, 'HCING', dHCI) + end +end + +------------------------------------------------------------------------------------------------------------- +function BeamLib.UpdateTCING( nRawId, dTCI) + local dOldTCI = EgtGetInfo( nRawId, 'TCING', 'd') + if not dOldTCI or dTCI > dOldTCI then + EgtSetInfo( nRawId, 'TCING', dTCI) + end +end + +------------------------------------------------------------------------------------------------------------- +return BeamLib diff --git a/LuaLibs/DiceCut.lua b/LuaLibs/DiceCut.lua new file mode 100644 index 0000000..bc46d3f --- /dev/null +++ b/LuaLibs/DiceCut.lua @@ -0,0 +1,501 @@ +-- DiceCut.lua by Egaltech s.r.l. 2018/11/26 +-- Gestione dei piano paralleli nei tagli lunghi + +-- Tabella per definizione modulo +local DiceCut = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' DiceCut started', 1) + +-- Dati +local BD = require( 'BeamData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- creo i piani paralleli +-- GetParallelPlanes: restituisce un vettore con gli indici delle superfici +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptC: il punto centrale del piano della feature +-- vtN: il versore normale del piano della feature +-- nCopyPlane: 0 => genera una copia del piano passato, 1=> non genera una copia del piano passato +-- dOffset: offset dei piani paralleli +-- nStep: numero massimo di step +-- Color: colre del fascio di piani +-- dTolerance*: distanza tra i piani paralleli e i piani di taglio (se non esistono altre superfici può essere omesso) +-- bNoTolOnFirstCut*: elimina la tolleranza per il primo piano del fascio (se non esistono altre superfici può essere omesso) +-- ptCCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- ptCCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNCut1*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +local function GetParallelPlanes( nParent, BBoxRawPart, ptC, vtN, nCopyPlane, dOffset, nStep, Color, dTolerance, bNoTolOnFirstCut, ptCCut, vtNCut, ptCCut1, vtNCut1 ) + local ptMyCCut + if ptCCut and vtNCut then + ptMyCCut = Point3d( ptCCut + dTolerance * vtNCut) + end + local ptMyCCut1 + if ptCCut1 and vtNCut1 then + ptMyCCut1 = Point3d( ptCCut1 + 0 * vtNCut1) + end + local TabellaTmSurfParallel = {} + local i = nCopyPlane + while i < nStep do + local SurfId = EgtSurfTmPlaneInBBox( nParent, ptC + ( i * dOffset) * vtN, vtN, BBoxRawPart, GDB_RT.GLOB) + local nFacet = EgtSurfTmFacetCount( SurfId or GDB_ID.NULL) + if nFacet > 0 and vtNCut and ptMyCCut then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut, -vtNCut, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut, -vtNCut, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 and vtNCut1 and ptMyCCut1 then + if i == nCopyPlane and bNoTolOnFirstCut then + EgtCutSurfTmPlane( SurfId, ptCCut1, -vtNCut1, false, GDB_RT.GLOB) + else + EgtCutSurfTmPlane( SurfId, ptMyCCut1, -vtNCut1, false, GDB_RT.GLOB) + end + nFacet = EgtSurfTmFacetCount( SurfId) + end + if nFacet > 0 then + table.insert( TabellaTmSurfParallel, SurfId) + EgtSetColor( SurfId, Color) + else + EgtErase( SurfId) + break + end + i = i + 1 + end + return TabellaTmSurfParallel +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrderedCutTable: +-- nParent: il layer +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function GetOrderedCutTable( nParent, TabParallelPlanes, TabOrtoPlanes) + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + local TabellaOrderParallelCut1 = {} + + for IndexTmP=1, StepParallel do + TabellaOrderParallelCut1[IndexTmP] = {} + for IndexOrto=1, StepOrto do + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( TabOrtoPlanes[IndexOrto ], 0, GDB_ID.ROOT) + local Copy1Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + local Copy2Id = EgtCopySurfTmFacet( TabParallelPlanes[IndexTmP], 0, nParent) + if Copy1Id and ptOrtoN then + EgtCutSurfTmPlane( Copy1Id, ptOrtoN, -vtNOrtoN, false, GDB_RT.GLOB) + EgtCutSurfTmPlane( Copy2Id, ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + local nFacet1 = EgtSurfTmFacetCount( Copy1Id) + local nFacet2 = EgtSurfTmFacetCount( Copy2Id) + if nFacet1 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + elseif nFacet2 < 1 then + EgtErase( Copy1Id) + EgtErase( Copy2Id) + break + else + table.insert( TabellaOrderParallelCut1[IndexTmP], Copy1Id) + EgtErase( Copy2Id) + EgtCutSurfTmPlane( TabParallelPlanes[IndexTmP], ptOrtoN, vtNOrtoN, false, GDB_RT.GLOB) + end + end + end + table.insert(TabellaOrderParallelCut1[IndexTmP], TabParallelPlanes[IndexTmP]) + end + return TabellaOrderParallelCut1 +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetOrtoCutCenter: +-- idFacet: l'id della faccia +-- ptC: il punto centrale della faccia +-- vtN: il versore normale della faccia +-- vtO: il versore dei piani ortogonali +-- dOffsetEff: offset della distanza dal punto centrale +-- Verifica se l'asse X del box costruito sopra la superficie è più grande di un certo offset +local function GetOrtoCutCenter( FacetId, ptC, vtN, vtO, dOffsetEff) + -- riferimento intrinseco + local asseX = vtO + local asseY = asseX ^ vtN + local Frame = Frame3d( ptC, ptC + asseX, ptC + asseY) + -- ingombro della faccia secondo questo riferimento + local Box = EgtGetBBoxRef( FacetId, GDB_BB.STANDARD, Frame) + local dLen = Box:getDimX() + local dWidth = Box:getDimY() + + if dLen < dOffsetEff + 1.0 or dWidth < dOffsetEff + 1.0 then + return nil, nil, nil + end + + local N = ceil( dLen / dOffsetEff) + local dOffsetRel = dLen / N + local dCopyPlane + local dCenOffs = ( Box:getMax():getX() + Box:getMin():getX()) / 2 + + if dLen <= dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 1 + elseif dLen <= 2 * dOffsetRel then + dOffsetRel = 0 + dCopyPlane = 0 + else + if N % 2 == 0 then + dCopyPlane = 0 + elseif N % 2 == 1 then + dCopyPlane = 0.5 + end + end + return dOffsetRel, dCopyPlane, dCenOffs +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- TableMesh: +-- TableOrto: tabella delle superfici dei piani ortogonali +-- TableParallel: tabella delle superfici dei piani paralleli +-- Forma una tabella unica delle superfici di taglio inserendo strati di tagli ortogonali alternati da strati di taglio parallelo +local function TableMesh( TableOrto, TableParallel) + local TableUnited = {} + for i=1, #TableOrto do + table.insert( TableUnited, TableOrto[i]) + table.insert( TableUnited, TableParallel[i]) + end + return TableUnited +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- FindValue: +-- tab: tabella da scansionare +-- val: valore da cercare +-- Verifica se tab contiene val, a supporto della funzione SortOrtoCutsByNormalMethod +local function FindValue( tab, val) + for index, value in ipairs( tab) do + if value == val then + return true + end + end + return false +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- SortOrtoCutsByNormalMethod: +-- TabParallelPlanes: tabella delle superfici dei piani paralleli +-- TabOrtoPlanes: tabella delle superfici dei piani ortogonali +-- stampo l'ordine dei piani di taglio sfruttando il prodotto dei versori normali (prima tagli ortogonali piu' esterni poi taglio parallelo collettivo) +local function SortOrtoCutsByNormalMethod( TabParallelPlanes, TabOrtoPlanes) + -- tabella dei tagli ordinati + local TabOrderOrtoCut = {} + -- tabella ausiliaria dei dati inseriti nell'ordine + local TabAux = {} + -- ciclo di ordinamento + local StepParallel = #TabParallelPlanes + local StepOrto = #TabOrtoPlanes + for IndexTmP=1, StepParallel do + TabOrderOrtoCut[IndexTmP] = {} + local ptParalN, vtNParalN = EgtSurfTmFacetCenter( TabParallelPlanes[IndexTmP][1], 0, GDB_ID.ROOT) + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- controlla che l'elemento da valutare non sia gia' stato inserito nella tabella + if not FindValue( TabAux, OrtoPlaneId) then + local ptOrtoN, vtNOrtoN = EgtSurfTmFacetCenter( OrtoPlaneId, 0, GDB_ID.ROOT) + local scalarProduct = ( ptOrtoN - ptParalN) * vtNParalN + if scalarProduct > 0 then + table.insert( TabOrderOrtoCut[IndexTmP], OrtoPlaneId) + table.insert( TabAux, OrtoPlaneId) + end + end + end + end + end + -- cancello dal DB geometrico i tagli non inseriti + for IndexOrto=1, StepOrto do + for i=1, #TabOrtoPlanes[IndexOrto] do + -- identificativo del taglio + local OrtoPlaneId = TabOrtoPlanes[IndexOrto][i] + -- ricerco il taglio tra gli inseriti + if not FindValue( TabAux, OrtoPlaneId) then + EgtErase( OrtoPlaneId) + end + end + end + return TabOrderOrtoCut +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- GetSurfSum: +-- CutTable: tabella dei tagli +-- OffsetP: offset della distanza dal punto centrale +-- BBoxRawPart: il grezzo della barra +-- Verifica se l'asse X del box costruito sopra le 2 facce è più piccolo di un certo offset e quindi la faccia 12 è superflua +local function GetSurfSum( CutTable, OffsetP, BBoxRawPart) + + if not CutTable[1] or not CutTable[2] then return end + + local Cut1Id = CutTable[2][1] + local Cut2Id = CutTable[2][2] + local Cut12Id = CutTable[1][1] + + if Cut1Id and Cut2Id and Cut12Id then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Cut1Id, 0, GDB_ID.ROOT) + local _, vtO = EgtSurfTmFacetCenter( Cut12Id, 0, GDB_ID.ROOT) + vtO = vtO - vtO * vtN1 * vtN1 ; vtO:normalize() + local asseX1 = vtO + local asseY1 = vtN1 ^ asseX1 + local Frame1 = Frame3d( ptC1, ptC1+asseX1, ptC1+asseY1) + local Box1 = EgtGetBBoxRef( Cut1Id, GDB_BB.STANDARD, Frame1) + local x1 = Box1:getDimX() + + local ptC2, vtN2 = EgtSurfTmFacetCenter( Cut2Id, 0, GDB_ID.ROOT) + local asseX2 = vtO + local asseY2 = vtN2 ^ asseX2 + local Frame2 = Frame3d( ptC2, ptC2+asseX2, ptC2+asseY2) + local Box2 = EgtGetBBoxRef( Cut2Id, GDB_BB.STANDARD, Frame2) + local x2 = Box2:getDimX() + + local dLongSize = x1 + x2 + + if dLongSize <= OffsetP + 1.0 then + local nParent = EgtGetParent( Cut1Id) + local SurfId = EgtSurfTmBySewing( nParent, { Cut1Id, Cut2Id}) + EgtSetColor( SurfId, Color3d( FUCHSIA(), 60)) + EgtErase( Cut12Id) + table.remove( CutTable[1], 1) + table.remove( CutTable[2], 1) + table.remove( CutTable[2], 1) + table.insert( CutTable[2], 1, SurfId) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- DiceCut.GetDice : +-- nParent: il layer +-- BBoxRawPart: il grezzo della barra +-- ptCPlanes: il punto centrale del piano della feature +-- vtNPlanes: il versore normale del piano della feature +-- bGetOrtoPlanes*: se voglio calcolare i piani ortogonali al piano passato (se non esistono altre superfici può essere omesso) +-- ptCBond*: il punto centrale della superfice limitante (se non esistono altre superfici può essere omesso) +-- vtNBond*: il versore normale della superfice limitante (se non esistono altre superfici può essere omesso) +---------------------------------------------------------------------------------------------------------------------------------------------------- +function DiceCut.GetDice( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, bGetOrtoPlanes, ptCBond, vtNBond) + + local dTolerance = 0 -- distanza di sicurezza per i tagli ortogonali + local OffsetP = BD.MAX_DIM_DICE -- distanza tra i piani paralleli + local StepP = 10 -- numero massimo di piani paralleli da generare + local OffsetO = BD.MAX_DIM_DICE -- distanza tra i piani ortogonali + local StepO = 10 -- numero massimo di piani ortogonali da generare + + -- se normali senza componenti in Y, uso per offset i limiti dei tagli di testa e coda + if abs( vtNPlanes:getY()) < 0.1 and ( not vtNBond or abs( vtNBond:getY()) < 0.1) then + OffsetP = BD.MAX_DIM_HTCUT + OffsetO = BD.MAX_DIM_HTCUT + end + + -- aggiungo piccolo extra agli offset + OffsetP = OffsetP + 10 * GEO.EPS_SMALL + OffsetO = OffsetO + 10 * GEO.EPS_SMALL + + -- se seconda faccia non definita, forzo calcolo piani ortogonali + if not ptCBond or not vtNBond then + bGetOrtoPlanes = true + end + + -- se piani non ortogonali, diminuisco la distanza di offset opportunamente + local originalOffsetP = OffsetP + if not bGetOrtoPlanes then + local dCoeff = ( vtNPlanes ^ vtNBond):len() + OffsetP = OffsetP * dCoeff + OffsetO = OffsetO * dCoeff + end + + -- elenco di tutte le superfici generate dai tagli + local TabFUCHSIA = {} + local TabGREEN = {} + + -- PIANI PARALLELI alla faccia di taglio + local TabellaTmSurfP = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCPlanes, vtNPlanes, 0, OffsetP, StepP, Color3d( FUCHSIA(), 60), dTolerance, true, ptCBond, vtNBond) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfP, TabFromIn[i]) + end + + -- PIANI ORTOGONALI alla faccia di taglio + -- orientamento definito da seconda faccia + if not bGetOrtoPlanes then + local TabellaTmSurfOrto = {} + local TabFromIn = GetParallelPlanes( nParent, BBoxRawPart, ptCBond, vtNBond, 0, OffsetO, StepO, Color3d( GREEN(), 60), dTolerance, false, ptCPlanes, vtNPlanes) + for i = #TabFromIn, 1, -1 do + table.insert( TabellaTmSurfOrto, TabFromIn[i]) + end + local TabellaOrderParallelCut = GetOrderedCutTable( nParent, TabellaTmSurfP, TabellaTmSurfOrto) -- Ottiene la tabella dei tagli paralleli ordinati + local TabellaOrderOrtoCut = GetOrderedCutTable( nParent, TabellaTmSurfOrto, TabellaTmSurfP) -- Ottiene la tabella dei tagli ortogonali da riordinare per strato + + TabGREEN = SortOrtoCutsByNormalMethod( TabellaOrderParallelCut, TabellaOrderOrtoCut) -- I tagli ortogonali vengono ordinati per strato + TabFUCHSIA = TabellaOrderParallelCut -- I tagli paralleli sono già ordinati + + -- orientamento da definire + else + for PlnInd = 1, #TabellaTmSurfP do + -- piano interno + local ptCInner, vtNInner = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd], 0, GDB_ID.ROOT) + -- eventuale piano esterno + local ptCOuter, vtNOuter = nil, nil + if PlnInd > 1 then + ptCOuter, vtNOuter = EgtSurfTmFacetCenter( TabellaTmSurfP[PlnInd-1], 0, GDB_ID.ROOT) + vtNOuter = -vtNOuter + end + -- calcolo la direzione dei piano ortogonali + local vtO = VectorFromUprightOrtho( vtNInner) + vtO:rotate( vtNInner, 90) + -- calcolo le dimensioni dell'offset e se dove posizionare la prima faccia: + -- CopyPlane: 0 => crea la prima faccia direttamente sul punto passato + -- CopyPlane: 1 => crea la prima faccia e tutte le altre con l'offset passato + -- CopyPlane: 0.5 => crea la prima faccia a metà offset e tutte le altre con l'offest intero + local OffsetRel, CopyPlane, dCenOffs = GetOrtoCutCenter( TabellaTmSurfP[PlnInd], ptCInner, vtNInner, vtO, OffsetO) + + if OffsetRel and CopyPlane and dCenOffs then + ptCInner = ptCInner + dCenOffs * vtO + local TabRight = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, -OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + if CopyPlane == 0 then + CopyPlane = 1 + end + local TabLeft = GetParallelPlanes( nParent, BBoxRawPart, ptCInner, vtO, CopyPlane, OffsetO, StepO, Color3d( GREEN(), 60), + dTolerance, false, ptCInner, vtNInner, ptCOuter, vtNOuter) + -- carico la tabella con gli indici riordinati + local TempOrtoTab = {} + for i = #TabLeft, 1, -1 do + table.insert( TempOrtoTab, TabLeft[i]) + end + for i = 1, #TabRight do + table.insert( TempOrtoTab, TabRight[i]) + end + -- creo una tabella per ogni piano per generare i tagli sulla Inner + local TempParTab = GetOrderedCutTable( nParent, {TabellaTmSurfP[PlnInd]}, TempOrtoTab) + for i = 1, #TempParTab do + table.insert( TabFUCHSIA, TempParTab[i]) + end + table.insert( TabGREEN, TempOrtoTab) + else + table.insert( TabFUCHSIA, {TabellaTmSurfP[PlnInd]}) + table.insert( TabGREEN, {}) + end + end + end + + -- Se sono state costruite non più di una faccia parallela e una faccia perpendicolare, allora non servono e tengo le originali + if #TabGREEN == 1 and #TabGREEN[1] <= 1 and #TabFUCHSIA == 1 and #TabFUCHSIA[1] <= 1 then + if #TabGREEN[1] == 1 then + EgtErase( TabGREEN[1][1]) + end + TabGREEN = {} + if #TabFUCHSIA[1] == 1 then + EgtErase( TabFUCHSIA[1][1]) + end + TabFUCHSIA = {} + end + + -- Si uniscono le tabelle dei tagli ortogonali e paralleli in una sola tabella + local UltimateTable = TableMesh( TabGREEN, TabFUCHSIA) + + -- Se esiste la superficie limitante (nFacet == 2) verifica se il taglio più esterno è superfluo e quindi viene eliminato + if not bGetOrtoPlanes then + GetSurfSum( UltimateTable, originalOffsetP, BBoxRawPart) + end + + return UltimateTable +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +-- PrintOrderCut: +-- TabellaOrderCut: tabella delle superfici di taglio +-- stampo l'ordine dei piani di taglio ricevendo una tabella con gli strati parallelo/ortogonali già ordinati +function DiceCut.PrintOrderCut( TabellaOrderCut) + local Step = #TabellaOrderCut + if Step > 0 then + EgtOutLog( " L'ordine delle superfici da tagliare è il seguente:") + else + EgtOutLog( ' Non sono necessarie superfici aggiuntive di taglio.') + end + for i = 1, Step do + if i % 2 == 1 then + EgtOutLog( ' *** Strato di taglio ' .. EgtNumToString( ( i + 1) / 2, 0)) + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli ortogonali: ') + else + EgtOutLog( ' Tagli ortogonali assenti') + end + else + if #TabellaOrderCut[i] > 0 then + EgtOutLog( ' Tagli paralleli: ') + else + EgtOutLog( ' Tagli paralleli assenti') + end + end + for j=1, #TabellaOrderCut[i] do + EgtOutLog( ' Indice faccia ' .. (TabellaOrderCut[i][j] or 0)) + end + end +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function DiceCutTest() + + -- salvo l'indice del layer Trimesh selezionato + local SelectedIndex = EgtGetFirstSelectedObj() + -- verifico che sia selezionato un elemento + if not SelectedIndex then return end + + -- salvo l'indice del layer Processing + local nParent = EgtGetParent( SelectedIndex) + -- salvo l'indice del layer Part + local nRawPart = EgtGetParent( nParent) + local nBox = EgtGetFirstNameInGroup( nRawPart, 'Box') + -- carico il bounding box della trave + -- local BBoxRawPart = EgtGetBBoxGlob( nRawPart, GDB_BB.STANDARD ) + local BBoxRawPart = EgtGetBBoxGlob( nBox, GDB_BB.STANDARD ) + -- seleziono il Part e il Layer di destinazione + EgtSetCurrPartLayer( nRawPart, nParent) + + -- conto il numero di facce da processare + local nFacet = EgtSurfTmFacetCount( SelectedIndex) + EgtOutLog( ' Numero facce ' .. nFacet, 1) + + -- salvo + local TabPlanesFeatures = {} + for i = 1, nFacet do + local ptC, vtN = EgtSurfTmFacetCenter( SelectedIndex, i - 1, GDB_ID.ROOT) + table.insert( TabPlanesFeatures, { ptC = ptC, vtN = vtN}) + end + local ptC1 = Point3d( TabPlanesFeatures[1].ptC) + local vtN1 = Vector3d( TabPlanesFeatures[1].vtN) + + local CutTable = {} + if nFacet == 1 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, true) + elseif nFacet == 2 then + CutTable = DiceCut.GetDice( nParent, BBoxRawPart, ptC1, vtN1, false, TabPlanesFeatures[2].ptC, TabPlanesFeatures[2].vtN) + end + + if EgtGetDebugLevel() > 1 then + DiceCut.PrintOrderCut( CutTable) + end + + EgtDeselectAll() + + EgtDraw() +end + +---------------------------------------------------------------------------------------------------------------------------------------------------- +--DiceCutTest() + +return DiceCut diff --git a/LuaLibs/ProcessBirdsMouth.lua b/LuaLibs/ProcessBirdsMouth.lua new file mode 100644 index 0000000..70f0a75 --- /dev/null +++ b/LuaLibs/ProcessBirdsMouth.lua @@ -0,0 +1,302 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2019/03/25 +-- Gestione calcolo tacche per Travi + +-- Tabella per definizione modulo +local ProcessBirdsMouth = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Tfs = require( 'TwoFacesBySaw') + +EgtOutLog( ' ProcessBirdsMouth started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') +local Pocketings = require( 'PocketingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessBirdsMouth.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 20) +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessBirdsMouth.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- è di testa + return true +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessBirdsMouth.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- è di coda + return true +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessBirdsMouth.Classify( Proc) + -- recupero il numero di facce della tacca + local nFacCnt = EgtSurfTmFacetCount( Proc.Id) + -- se 1 faccia + if nFacCnt == 1 then + return false + -- se 2 facce + elseif nFacCnt == 2 then + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bDown = (( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) or vtN[1]:getZ() < BD.NZ_MINA or vtN[2]:getZ() < BD.NZ_MINA) + return true, bDown + -- se più di due facce + else + -- recupero la faccia con il maggior numero di adiacenze più grande + local nFacInd = BL.GetFaceWithMostAdj( Proc.Id) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA) + return true, bDown + end +end + +--------------------------------------------------------------------- +-- Lavorazione con fresa +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function Make2FacesByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero il numero di facce della tacca + local nFacCnt = EgtSurfTmFacetCount( Proc.Id) + -- per ora solo caso con due facce + if nFacCnt ~= 2 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' BirdsMouth facet number not supported' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- dati medi + local ptM = ( ptC[1] + ptC[2]) / 2 + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' BirdsMouth from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd + -- se entrambe possibili, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) + if bFaceOk[1] and bFaceOk[2] then + if abs( abs( vtN[1]:getX()) - abs( vtN[2]:getX())) < GEO.EPS_SMALL then + if ptM:getX() > b3Raw:getCenter():getX() then + nFacInd = EgtIf( vtN[1]:getX() > vtN[2]:getX(), 0, 1) + else + nFacInd = EgtIf( vtN[1]:getX() < vtN[2]:getX(), 0, 1) + end + else + nFacInd = EgtIf( abs( vtN[1]:getX()) < abs( vtN[2]:getX()), 0, 1) + end + elseif bFaceOk[1] then + nFacInd = 0 + else + nFacInd = 1 + end + local nOthInd = 1 - nFacInd + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN[nOthInd+1]:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_RIGHT) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto posizione braccio porta testa + if vtN[nFacInd+1]:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function FindPocketing( sType) + for i = 1, #Pocketings do + local Pocketing = Pocketings[i] + if Pocketing.Type == sType then + return i, Pocketing.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function MakeMoreFacesByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero il numero di facce della tacca + local nFacCnt = EgtSurfTmFacetCount( Proc.Id) + assert( ( nFacCnt > 2), 'Error : MakeMoreFacesByMill in BirdsMouth with ' .. tostring( nFacCnt) .. ' faces') + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id) + assert( nFacInd, 'Error : MakeMoreFacesByMill could not find reference face') + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico non sia orientata verso il basso + local bFaceOk = ( vtN:getZ() >= BD.NZ_MINB) + if not bFaceOk then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' BirdsMouth from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- eventuali tagli preliminari + -- per ora non previsti + -- recupero la lavorazione + local nMill, sPocketing = FindPocketing( 'Mortise') + if not sPocketing then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + local sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dFacElev, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMill( Proc, nPhase, nRawId, nPartId) + -- recupero il numero di facce + local nFacCnt = EgtSurfTmFacetCount( Proc.Id) + -- richiamo la routine di lavorazione opportuna a seconda del numero di facce + if nFacCnt <= 2 then + return Make2FacesByMill( Proc, nPhase, nRawId, nPartId) + else + return MakeMoreFacesByMill( Proc, nPhase, nRawId, nPartId) + end +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessBirdsMouth.Make( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- dimensioni della feature + local b3Fea = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD) + -- numero di facce + local nFacCnt = EgtSurfTmFacetCount( Proc.Id) + -- se con due facce verifico che angolo non sia concavo e minore di - 90 deg + local bConcClosed = false + if nFacCnt == 2 then + local _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConcClosed = ( dAng < - 92) + end + -- con fresa + local MAX_MILL_X = 80 + local MAX_MILL_VOL = ( 80 * 240 * 20) / 2 + -- se più di due facce o ( piccola o in coda e non concava chiusa) + if nFacCnt > 2 or + ((( b3Fea:getDimX() < MAX_MILL_X and b3Fea:getDimX() * b3Fea:getDimY() * b3Fea:getDimZ() < MAX_MILL_VOL) or + b3Fea:getMin():getX() < b3Raw:getMin():getX() + 10) and not bConcClosed) then + return MakeByMill( Proc, nPhase, nRawId, nPartId) + -- con lama + else + return Tfs.Make( Proc, nPhase, nRawId, nPartId, 'HeadSide') + end +end + +--------------------------------------------------------------------- +return ProcessBirdsMouth diff --git a/LuaLibs/ProcessChamfer.lua b/LuaLibs/ProcessChamfer.lua new file mode 100644 index 0000000..0b995d9 --- /dev/null +++ b/LuaLibs/ProcessChamfer.lua @@ -0,0 +1,64 @@ +-- ProcessChamfer.lua by Egaltech s.r.l. 2018/04/12 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessChamfer = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessChamfer started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessChamfer.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 36) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessChamfer.Make( Proc, nPhase, nRawId, nPartId) + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Chamfer') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Chm_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessChamfer diff --git a/LuaLibs/ProcessCut.lua b/LuaLibs/ProcessCut.lua new file mode 100644 index 0000000..1fb4b03 --- /dev/null +++ b/LuaLibs/ProcessCut.lua @@ -0,0 +1,164 @@ +-- ProcessCut.lua by Egaltech s.r.l. 2019/03/23 +-- Gestione calcolo singoli tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') + +--------------------------------------------------------------------- +local function FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.Type == sType then + return i, Cutting.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local bDownCut = (vtN:getZ() <= - 0.5) + -- se taglio di testa + if Proc.Head then + -- se coincide con il taglio di separazione precedente, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + return true + end + -- altrimenti taglio di coda + else + -- se coincide con taglio di separazione, non va fatto + if AreSameVectorApprox( vtN, - X_AX()) and abs( ptC:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + return true + end + end + -- recupero la lavorazione + local _, sCutting = FindCutting( EgtIf( Proc.Head, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino la direzione di taglio preferenziale + local _, dCutH, dCutV = BL.GetFaceHvRefDim( Proc.Id, 0) + local bHorizCut = (( dCutV < dMaxDepth + 10 * GEO.EPS_SMALL and dCutH > dCutV + 10 * GEO.EPS_SMALL) and not bDownCut) + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC, vtN, true) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + end + end + -- recupero la normale dei tagli ortogonali + local vtO + for i = 1, #vCuts, 2 do + for j = 1, #vCuts[i] do + _, vtO = EgtSurfTmFacetCenter( vCuts[i][j], 0, GDB_ID.ROOT) + break + end + if vtO then break end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local nOrthoOpposite + if vtO then + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtO) + end + else + if bHorizCut then + nOrthoOpposite = MCH_MILL_FU.ORTHO_DOWN + elseif vtN:getY() > -0.02 then + nOrthoOpposite = MCH_MILL_FU.ORTHO_FRONT + else + nOrthoOpposite = MCH_MILL_FU.ORTHO_BACK + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- altrimenti tagli diretti della faccia + else + -- lavoro la faccia + local nOrthoOpposite + if bHorizCut then + nOrthoOpposite = MCH_MILL_FU.ORTHO_DOWN + elseif vtN:getY() > -0.02 then + nOrthoOpposite = MCH_MILL_FU.ORTHO_FRONT + else + nOrthoOpposite = MCH_MILL_FU.ORTHO_BACK + end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, BD.CUT_EXTRA, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessCut diff --git a/LuaLibs/ProcessDecor.lua b/LuaLibs/ProcessDecor.lua new file mode 100644 index 0000000..3bb20c6 --- /dev/null +++ b/LuaLibs/ProcessDecor.lua @@ -0,0 +1,92 @@ +-- ProcessDecor.lua by Egaltech s.r.l. 2018/04/18 +-- Gestione calcolo decoro per Travi + +-- Tabella per definizione modulo +local ProcessDecor = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDecor started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDecor.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 959) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDecor.Classify( Proc) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico sia una decorazione + if not vtExtr then + return false + end + -- verifico se la decorazione è lavorabile solo da sotto + local bDown = (( vtExtr:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDecor.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati della decorazione + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico che la decorazione non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Decor from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local sToFind = EgtGetInfo( Proc.Id, 'P15') + local nMill, sMilling = FindMilling( sToFind) + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtExtr:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessDecor diff --git a/LuaLibs/ProcessDoubleCut.lua b/LuaLibs/ProcessDoubleCut.lua new file mode 100644 index 0000000..74d849d --- /dev/null +++ b/LuaLibs/ProcessDoubleCut.lua @@ -0,0 +1,203 @@ +-- ProcessDrill.lua by Egaltech s.r.l. 2019/03/29 +-- Gestione calcolo doppi tagli di lama per Travi + +-- Tabella per definizione modulo +local ProcessDoubleCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDoubleCut.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 11) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDoubleCut.Classify( Proc) + -- numero delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + -- se due facce, verifico se convesso + local bConvex = true + if nFacetCnt == 2 then + local _, _, _, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + bConvex = ( dAng > 0) + end + -- verifico le normali delle facce + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if not bConvex and vtN:getZ() < - 0.72 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +local function FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.Type == sType then + return i, Cutting.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDoubleCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- normale media per capire se taglio di testa o di coda + local vtNm = ( vtN[1] + vtN[2]) ; vtNm:normalize() + local bHead = ( vtNm:getX() > 0) + -- angolo diedro per stabilire se taglio convesso + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local vtDir = ptP1 - ptP2 ; vtDir:normalize() + local bOnY = abs( vtDir:getZ()) > 0.5 and ( abs( vtDir:getZ()) + abs( vtDir:getX()) > abs( vtDir:getY())) + local bConvex = ( dAng > 0) + local dLen = dist( ptP1, ptP2) + local ptPs = ( ptP1 + ptP2) / 2 + -- determino quale faccia è più grande + local dSqDim1 = ( ptC[1] - ptPs):sqlen() + local dSqDim2 = ( ptC[2] - ptPs):sqlen() + local nBigInd = EgtIf( dSqDim1 >= dSqDim2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local _, sCutting = FindCutting( EgtIf( bHead, 'HeadSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + end + end + -- eseguo + for i = 1, #vCuts do + -- determino il modo di tagliare + local k, l = nBigInd, nSmaInd + if ( i % 2 == 1) == ( not bConvex) then + k, l = l, k + end + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[k]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + if bConvex then + if dLen < dMaxDepth then + local bFront = ( vtN[k]:getY() < 0.02) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + local bOver = ( ptC[k]:getZ() > ptC[l]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + else + local bOver = ( ptC[k]:getZ() > ptC[l]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + end + -- se non ci sono tagli supplementari o convesso, tagli diretti delle facce + if #vCuts == 0 or bConvex then + -- imposto eventuale affondamento aggiuntivo + local dExtraCut = EgtIf( bConvex, BD.CUT_EXTRA, 0) + -- eseguo sulle due facce + for j = 1, 2 do + -- determino ordine dei tagli + local i = j + if not bOnY and ptC[1]:getZ() > ptC[2]:getZ() then + i = 3 - j + end + -- lavoro la faccia + local nOrthoOpposite + if bOnY then + local bFront = ( ptC[i]:getY() < ptPs:getY()) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + if bConvex then + if dLen < dMaxDepth then + local bFront = ( vtN[i]:getY() < 0.02) + nOrthoOpposite = EgtIf( bFront, MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT) + else + nOrthoOpposite = MCH_MILL_FU.ORTHO_DOWN + end + else + local bOver = ( ptC[i]:getZ() > ptC[3-i]:getZ()) + nOrthoOpposite = EgtIf( bOver, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_TOP) + end + end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, i - 1, sCutting, dSawDiam, nOrthoOpposite, dExtraCut, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessDoubleCut diff --git a/LuaLibs/ProcessDrill.lua b/LuaLibs/ProcessDrill.lua new file mode 100644 index 0000000..5798ef1 --- /dev/null +++ b/LuaLibs/ProcessDrill.lua @@ -0,0 +1,171 @@ +-- ProcessDrill.lua by Egaltech s.r.l. 2019/03/25 +-- Gestione calcolo forature per Travi + +-- Tabella per definizione modulo +local ProcessDrill = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDrill started', 1) + +-- Dati +local BD = require( 'BeamData') +local Drillings = require( 'DrillData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDrill.Identify( Proc) + return ( ( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 40) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDrill.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessDrill.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- se entrata principale + if Proc.Flg > 0 then + local nFcs = EgtGetInfo( Proc.Id, 'FCS', 'i') or 0 + return ( nFcs == 5 or nFcs == 6) + -- altrimenti entrata opposta + else + local nFce = EgtGetInfo( Proc.Id, 'FCE', 'i') or 0 + return ( nFce == 5 or nFce == 6) + end +end + +--------------------------------------------------------------------- +local function FindDrilling( dDiam) + for i = 1, #Drillings do + local Drilling = Drillings[i] + if abs( dDiam - Drilling.Diam) < 1.1 then + return i, Drilling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Verifica se da lavorare in due metà +function ProcessDrill.Split( Proc) + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + -- recupero i dati del foro + local dDiam = 2 * EgtArcRadius( AuxId) + local dLen = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bOpen = ( EgtGetInfo( Proc.Id, 'FCE', 'i') ~= 0) + -- recupero la lavorazione + local nDri, sDrilling = FindDrilling( dDiam) + if not sDrilling then + return bOpen + end + -- restituisco se va fatto in doppio + return ( bOpen and dLen > Drillings[nDri].MaxMat + 10 * GEO.EPS_SMALL) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDrill.Classify( Proc, b3Raw) + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + return false + end + -- recupero i dati del foro + local dDiam = 2 * EgtArcRadius( AuxId) + local dLen = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptCen = EgtCP( AuxId, GDB_RT.GLOB) + if Proc.Flg == -2 then + vtExtr = - vtExtr + ptCen = ptCen + vtExtr * dLen + end + local bOpen = ( Proc.Fce ~= 0) + local bFaceDown = ( ptCen:getZ() < b3Raw:getMin():getZ() + dDiam) + -- verifico se il foro è fattibile solo da sotto + local bDown = (( vtExtr:getZ() < BD.DRILL_VZ_MIN or bFaceDown) and ( not bOpen or Proc.Flg ~= 1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDrill.Make( Proc, nPhase, nRawId, nPartId) + -- recupero e verifico l'entità foro + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or EgtGetType( AuxId) ~= GDB_TY.CRV_ARC then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing drill geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati del foro + local dDiam = 2 * EgtArcRadius( AuxId) + local dLen = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + if Proc.Flg == -2 then vtExtr = - vtExtr end + local bOpen = ( Proc.Fcs ~= 0 and Proc.Fce ~= 0) + -- verifico che il foro non sia fattibile solo da sotto + local bToInvert = ( vtExtr:getZ() < BD.DRILL_VZ_MIN) + if bToInvert and ( not bOpen or Proc.Flg ~= 1) then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' drilling from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local nDri, sDrilling = FindDrilling( dDiam) + if not sDrilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' drilling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se foro da fare al contrario + if Proc.Flg == -2 then bToInvert = true end + -- inserisco la lavorazione + local sName = 'Drill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sDrilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sDrilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, 0}}) + -- eventuale inversione + EgtSetMachiningParam( MCH_MP.INVERT, bToInvert) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if abs( vtExtr:getY()) > 100 * GEO.EPS_ZERO and bToInvert ~= ( vtExtr:getY() > -GEO.EPS_ZERO) then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- se foro dai due lati, aggiusto l'affondamento + if Proc.Flg == 2 or Proc.Flg == -2 then + EgtSetMachiningParam( MCH_MP.DEPTH, dLen / 2 + BD.DRILL_OVERLAP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + + return true +end + +--------------------------------------------------------------------- +return ProcessDrill diff --git a/LuaLibs/ProcessDtMortise.lua b/LuaLibs/ProcessDtMortise.lua new file mode 100644 index 0000000..8fee3e2 --- /dev/null +++ b/LuaLibs/ProcessDtMortise.lua @@ -0,0 +1,119 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2019/03/22 +-- Gestione calcolo mortase a coda di rondice per Travi + +-- Tabella per definizione modulo +local ProcessDtMortise = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessDtMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 55) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 56)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtMortise.Classify( Proc) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtMortise.Make( Proc, nPhase, nRawId, nPartId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del top + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' DtMortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'DtMortise') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile + local dToolDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + end + end + -- verifico se necessarie più passate + local dDist = dist( EgtSP( AuxId, GDB_RT.GLOB), EgtEP( AuxId, GDB_RT.GLOB)) + if dDist < dToolDiam + 0.5 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Dt mortise too narrow' + EgtOutLog( sErr) + return false, sErr + end + local nPass = ceil( dDist / ( 1.9 * dToolDiam)) + local dStep = ( dDist - 0.95 * dToolDiam) / ( 2 * nPass) + for i = nPass, 1, -1 do + -- inserisco la lavorazione di contornatura + local sNameF = 'DtMt_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nPass) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- imposto offset + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtMortise diff --git a/LuaLibs/ProcessDtTenon.lua b/LuaLibs/ProcessDtTenon.lua new file mode 100644 index 0000000..63e046b --- /dev/null +++ b/LuaLibs/ProcessDtTenon.lua @@ -0,0 +1,171 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2019/03/23 +-- Gestione calcolo tenone a coda di rondine per Travi + +-- Tabella per definizione modulo +local ProcessDtTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessDtTenon.Identify( Proc) + return ( ( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 55) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessDtTenon.Classify( Proc) + -- recupero i dati della faccia top + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se il tenone è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.26) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessDtTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del top + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- verifico che il tenone non sia orientato verso il basso (-5 deg) + if vtN:getZ() < - 0.26 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' DtTenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frDtTen = Frame3d( ptC, vtN) + local b3DtTen = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frDtTen) + local dDtTenH = b3DtTen:getDimZ() + -- porto inizio curva a Zmax + BL.PutStartOnTop( AuxId) + -- se tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'DtTenon') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dTDiam = 50 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dTDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dTDiam + end + end + -- calcolo distanza massima della curva dal punto più lontano della base tenone Dt (facet 0) + local dMaxDist = 0 + local nLoopId, nLoopCnt = EgtExtractSurfTmFacetLoops( Proc.Id, 0, EgtGetParent( Proc.Id)) + local dUmin, dUmax = EgtCurveDomain( nLoopId) + for dU = dUmin, dUmax do + local ptP = EgtUP( nLoopId, dU, GDB_ID.ROOT) + local ptNear = EgtNP( AuxId, ptP, GDB_ID.ROOT) + local dDist = dist( ptP, ptNear) + if dDist > dMaxDist then + dMaxDist = dDist + end + end + for i = 1, nLoopCnt do + EgtErase( nLoopId + i - 1) + end + EgtOutLog( 'MaxDist=' .. EgtNumToString( dMaxDist, 3), 3) + -- Cicli di lavorazione + local nStep = ceil( dMaxDist / ( 0.7 * dTDiam)) + local dStep = 0 + if nStep > 1 then + dStep = ( dMaxDist - 0.7 * dTDiam) / ( nStep - 1) + end + for i = nStep, 1, -1 do + -- inserisco la passata di sgrossatura della lavorazione + local sNameR = 'DtTn_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchRId = EgtAddMachining( sNameR, sMilling) + if not nMchRId then + local sErr = 'Error adding machining ' .. sNameR .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dDtTenH, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchRId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessDtTenon diff --git a/LuaLibs/ProcessFreeContour.lua b/LuaLibs/ProcessFreeContour.lua new file mode 100644 index 0000000..1e5b1d8 --- /dev/null +++ b/LuaLibs/ProcessFreeContour.lua @@ -0,0 +1,218 @@ +-- ProcessFreeContour.lua by Egaltech s.r.l. 2019/02/23 +-- Gestione calcolo profilo libero per Travi + +-- Tabella per definizione modulo +local ProcessFreeContour = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessFreeContour started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessFreeContour.Identify( Proc) + return ( ( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 250) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessFreeContour.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessFreeContour.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessFreeContour.Classify( Proc) + -- se di testa o coda, è indifferente alla posizione + if Proc.Head or Proc.Tail then + return true, false + end + -- è intermedia, devo verificare la normale del centro + local nMidFacet = Proc.Fct // 2 + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la feature è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessFreeContour.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') or 0 + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bToolInv = ( vtExtr:getZ() < -0.1) + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'FreeContour') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- ne verifico la lunghezza per eventuale spezzatura e lavorazione in doppio + local nStep = 1 + local dStep = 0 + local dLenMax = min( BD.LONGCUT_MAXLEN, 0.5 * b3Raw:getDimX()) + local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if b3Aux:getDimX() > dLenMax then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / dLenMax) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local nDouble = 1 + local bCanDouble = ( abs( vtExtr:getZ()) < 0.5 and abs( vtExtr:getX()) < 0.1 and b3Aux:getDimY() > b3Raw:getDimY() - 1.0) + if nStep > 1 then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + if Proc.Grp == 0 then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.CENTER) + elseif ( Proc.Grp == 3 and not bToolInv) or ( Proc.Grp == 4 and bToolInv) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + elseif ( Proc.Grp == 3 and bToolInv) or ( Proc.Grp == 4 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessFreeContour diff --git a/LuaLibs/ProcessHeadCut.lua b/LuaLibs/ProcessHeadCut.lua new file mode 100644 index 0000000..74327f2 --- /dev/null +++ b/LuaLibs/ProcessHeadCut.lua @@ -0,0 +1,87 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2018/11/22 +-- Gestione calcolo tagli di testa per Travi + +-- Tabella per definizione modulo +local ProcessHeadCut = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessSplit started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') + +--------------------------------------------------------------------- +local function FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.Type == sType then + return i, Cutting.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessHeadCut.Identify( Proc) + return ( Proc.Grp == 1 and Proc.Prc == 340) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessHeadCut.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < BD.MAX_DIM_HTCUT) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > BD.MAX_DIM_HTCUT+ 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- se coincide con inizio grezzo, non va fatto + if AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then + return true + end + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- determino se più tagli con offset + local nCuts = ceil( dOvmHead / BD.MAX_LEN_SCRAP) + local dOffsL = dOvmHead / nCuts + -- recupero la lavorazione + local _, sCutting = FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- calcolo extra taglio + local dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY(), 0) + BD.CUT_EXTRA + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, dCutExtra, BD.CUT_SIC, dCutOffset, '', b3Raw) + if not bOk then return false, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, dCutExtra, BD.CUT_SIC, dCutOffset, '', b3Raw) + if not bOk then return false, sErr end + end + return true +end + +--------------------------------------------------------------------- +return ProcessHeadCut diff --git a/LuaLibs/ProcessLapJoint.lua b/LuaLibs/ProcessLapJoint.lua new file mode 100644 index 0000000..55e6a7d --- /dev/null +++ b/LuaLibs/ProcessLapJoint.lua @@ -0,0 +1,525 @@ +-- ProcessLapJoint.lua by Egaltech s.r.l. 2019/03/26 +-- Gestione calcolo mezzo-legno per Travi + +-- Tabella per definizione modulo +local ProcessLapJoint = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') +local DoubleCut = require( 'ProcessDoubleCut') +local Tfs = require( 'TwoFacesBySaw') + +EgtOutLog( ' ProcessLapJoint started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') +local Millings = require( 'MillingData') +local Pocketings = require( 'PocketingData') +local Sawings = require( 'SawingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLapJoint.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 16) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 17) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 30)) +end + +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessLapJoint.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- deve avere la normale principale diretta verso la testa + local nFacInd = BL.GetFaceWithMostAdj( Proc.Id) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getX() > 0.5 then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessLapJoint.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- deve avere la normale principale diretta verso la coda + local nFacInd = BL.GetFaceWithMostAdj( Proc.Id) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + if vtN:getX() < -0.5 then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLapJoint.Classify( Proc) + -- se 1 faccia + if Proc.Fct == 1 then + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA) + return true, bDown + -- se 2 facce + elseif Proc.Fct == 2 then + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN[1]:getZ() < BD.NZ_MINB and vtN[2]:getZ() < BD.NZ_MINB) + return true, bDown + -- se più di 2 facce + else + -- recupero la faccia con il maggior numero di adiacenze più grande + local nFacInd = BL.GetFaceWithMostAdj( Proc.Id) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se è lavorabile solo dal basso + local bDown = ( vtN:getZ() < BD.NZ_MINA) + return true, bDown + end +end + +--------------------------------------------------------------------- +-- Lavorazione con fresa +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 1), 'Error : MakeOneFaceByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati delle facce + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico non siano orientate verso il basso + local bFaceOk = ( vtN:getZ() >= BD.NZ_MINB) + if not bFaceOk then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd = 0 + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_RIGHT) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- verifico il numero di facce della tacca + assert( ( Proc.Fct == 2), 'Error : MakeTwoFacesByMill in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[0], vtN[0] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- dati medi + local ptM = ( ptC[0] + ptC[1]) / 2 + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[0] = ( vtN[0]:getZ() >= BD.NZ_MINB) + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + if not bFaceOk[0] and not bFaceOk[1] then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- scelta faccia da lavorare + local nFacInd + -- se entrambe possibili, scelgo quella con la normale più perpendicolare all'asse trave (se uguali, quella verso X+) + if bFaceOk[0] and bFaceOk[1] then + if abs( abs( vtN[0]:getX()) - abs( vtN[1]:getX())) < GEO.EPS_SMALL then + if ptM:getX() > b3Raw:getCenter():getX() then + nFacInd = EgtIf( vtN[0]:getX() > vtN[1]:getX(), 0, 1) + else + nFacInd = EgtIf( vtN[0]:getX() < vtN[1]:getX(), 0, 1) + end + else + nFacInd = EgtIf( abs( vtN[0]:getX()) < abs( vtN[1]:getX()), 0, 1) + end + elseif bFaceOk[0] then + nFacInd = 0 + else + nFacInd = 1 + end + local nOthInd = 1 - nFacInd + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'BirdsMouth') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Mill_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia e lato correzione + if vtN[nOthInd]:getX() > 0 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_RIGHT) + end + -- imposto lato di correzione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- imposto posizione braccio porta testa + if vtN[nFacInd]:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw) + -- se interessa l'intera sezione della trave, necessaria sgrossatura + if Proc.Box:getDimY() > 0.9 * b3Raw:getDimY() and Proc.Box:getDimZ() > 0.9 * b3Raw:getDimZ() then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo sgrossatura e la lavoro + local AddId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local nCutFacet = EgtSurfTmFacetCount( AddId) + if nCutFacet == 1 then + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + elseif nCutFacet == 2 then + local bOk, sErr = DoubleCut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + end + return true +end + +--------------------------------------------------------------------- +local function FindSawing( sType) + for i = 1, #Sawings do + local Sawing = Sawings[i] + if Sawing.Type == sType then + return i, Sawing.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function MakeByChainSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV) + -- Recupero le facce adiacenti alla principale + local vAdj = EgtSurfTmFacetAdjacencies( Proc.Id, nFacInd)[1] + if not vAdj or #vAdj == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' main face without adjacencies' + EgtOutLog( sErr) + return false, sErr + end + EgtOutLog( 'Adjac=' .. table.concat( vAdj, ','), 3) + -- Riordino le dimensioni per avere dH > dV + if dH < dV then + dH, dV = dV, dH + end + -- Cerco una faccia adiacente alla principale sul lato lungo + local nFacAdj + for i = 1, #vAdj do + if vAdj[i] >= 0 then + local _, ptP1, ptP2, _ = EgtSurfTmFacetsContact( Proc.Id, nFacInd, vAdj[i], GDB_ID.ROOT) + local dLen = dist( ptP1, ptP2) + if dLen > 0.5 * dH then + nFacAdj = vAdj[i] + EgtOutLog( string.format( 'Adjac=%d Len=%.3f H=%.3f V=%.3f', vAdj[i], dLen, dH, dV), 3) + break + end + end + end + -- Determino se estremi aperti o chiusi + local bOpenStart = false + local bOpenEnd = false + local vAdj2 = EgtSurfTmFacetAdjacencies( Proc.Id, nFacAdj)[1] + for j = 1, #vAdj2 do + if vAdj2[j] == nFacInd then + -- Se non esiste faccia adiacente a lato precedente -> inizio aperto + local i = EgtIf( j > 1, j - 1, #vAdj2) + bOpenStart = ( vAdj2[i] < 0) + -- Se non esiste faccia adiacente a lato successivo -> fine aperto + local k = EgtIf( j < #vAdj2, j + 1, 1) + bOpenEnd = ( vAdj2[k] < 0) + end + end + -- Calcolo uso faccia + local nFaceUse = BL.GetNearestParalOpposite( rfFac:getVersZ()) + -- Calcolo angolo 3° asse rot (da direz. utensile) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nFacAdj, GDB_ID.ROOT) + local ptP1, ptP2 = EgtSurfTmFacetOppositeSide( Proc.Id, nFacAdj, rfFac:getVersZ(), GDB_ID.ROOT) + local vtT = vtN ^ (ptP2 - ptP1) + local d3RotAng = EgtIf( abs( vtT:getZ()) < GEO.EPS_SMALL, 0, 90) + -- Recupero la lavorazione + local nSaw, sSawing = FindSawing( 'Sawing') + if not sSawing then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' chainsawing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- Recupero i dati dell'utensile + local dSawWidth = 75 + local dSawThick = 8 + if EgtMdbSetCurrMachining( sSawing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawWidth = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawWidth + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- Verifico se necessarie più passate + local nStep = ceil( ( dV - 0.5) / dSawThick) + local dStep = 0 + if nStep > 1 then + dStep = ( dV - dSawThick) / ( nStep - 1) + end + for i = 1, nStep do + -- Applico la lavorazione con sega a catena a questa faccia + local sName = 'Csaw_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sName, sSawing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sSawing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacAdj}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto accorciamento iniziale/finale per estremi aperti/chiusi + EgtSetMachiningParam( MCH_MP.STARTADDLEN, EgtIf( bOpenStart, 0, - dSawWidth / 2)) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, EgtIf( bOpenEnd, 0, - dSawWidth / 2)) + -- imposto angolo 3° asse rot + EgtSetMachiningParam( MCH_MP.BLOCKEDAXIS, 'A=' .. EgtNumToString( d3RotAng)) + -- imposto offset radiale + local dOffs = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffs) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + return true +end + +--------------------------------------------------------------------- +local function FindPocketing( sType) + for i = 1, #Pocketings do + local Pocketing = Pocketings[i] + if Pocketing.Type == sType then + return i, Pocketing.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function MakeMoreFacesByMillOrChain( Proc, nPhase, nRawId, nPartId) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero il numero di facce della tacca + assert( ( Proc.Fct > 2), 'Error : MakeMoreFacesByMillOrChain in LapJoint with ' .. tostring( Proc.Fct) .. ' faces') + -- recupero la faccia con il maggior numero di adiacenze e l'elevazione relativa + local nFacInd, dFacElev = BL.GetFaceWithMostAdj( Proc.Id) + assert( nFacInd, 'Error : MakeMoreFacesByMillOrChain could not find reference face') + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + local rfFac, dH, dV = EgtSurfTmFacetMinAreaRectangle( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico non sia orientata verso il basso + local bFaceOk = ( vtN:getZ() >= BD.NZ_MINB) + if not bFaceOk then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' LapJoint from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- eventuali tagli preliminari + do + local bOk, sErr = MakePreCuts( Proc, nPhase, nRawId, nPartId, b3Raw) + if not bOk then + return false, sErr + end + end + -- recupero la lavorazione + local nMill, sPocketing = FindPocketing( 'Mortise') + if not sPocketing then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sPocketing) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se una dimensione della faccia è più piccola del diametro utensile, va usata la sega a catena + if dH < dMillDiam or dV < dMillDiam then + return MakeByChainSaw( Proc, nPhase, nRawId, nPartId, nFacInd, rfFac, dH, dV) + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.ORTHO_CONT) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- se elevazione superiore a massimo affondamento della fresa, riduco opportunamente + if dFacElev > dMaxDepth + 10 * GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.DEPTH, dMaxDepth - dFacElev) + dFacElev = dMaxDepth + local sWarn = 'Warning in process ' .. tostring( Proc.Id) .. ' : elevation bigger than max tool depth' + EgtOutLog( sWarn) + end + -- imposto elevazione + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dMaxDepth, 1) .. ';') + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +local function MakeByMillOrChain( Proc, nPhase, nRawId, nPartId) + -- richiamo la routine di lavorazione opportuna a seconda del numero di facce + if Proc.Fct == 1 then + return MakeOneFaceByMill( Proc, nPhase, nRawId, nPartId) + elseif Proc.Fct == 2 then + return MakeTwoFacesByMill( Proc, nPhase, nRawId, nPartId) + else + return MakeMoreFacesByMillOrChain( Proc, nPhase, nRawId, nPartId) + end +end + + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +--------------------------------------------------------------------- +function ProcessLapJoint.Make( Proc, nPhase, nRawId, nPartId) + -- dimensioni della feature + local b3Fea = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD) + -- con fresa + local MAX_MILL_X = 80 + local MAX_MILL_VOL = ( 80 * 240 * 20) / 2 + if Proc.Fct > 2 or ( b3Fea:getDimX() < MAX_MILL_X and b3Fea:getDimX() * b3Fea:getDimY() * b3Fea:getDimZ() < MAX_MILL_VOL) then + return MakeByMillOrChain( Proc, nPhase, nRawId, nPartId) + -- con lama + else + return Tfs.Make( Proc, nPhase, nRawId, nPartId, 'HeadSide') + end +end + +--------------------------------------------------------------------- +return ProcessLapJoint diff --git a/LuaLibs/ProcessLongCut.lua b/LuaLibs/ProcessLongCut.lua new file mode 100644 index 0000000..563d045 --- /dev/null +++ b/LuaLibs/ProcessLongCut.lua @@ -0,0 +1,187 @@ +-- ProcessLongCut.lua by Egaltech s.r.l. 2019/02/15 +-- Gestione calcolo taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLongCut = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessLongCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLongCut.Identify( Proc) + return (( Proc.Grp == 0 or Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 10) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLongCut.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.707 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLongCut.Make( Proc, nPhase, nRawId, nPartId) + -- dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + local dLen = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD):getDimX() + -- limitazioni su inizio e fine derivanti da altre facce + local bLimXmin = false + local bLimXmax = false + if Proc.Fct >= 3 then + bLimXmin = true + bLimXmax = true + elseif Proc.Fct >= 2 then + local ptC1, vtN1 = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + if vtN1:getX() > 0 then + bLimXmin = true + else + bLimXmax = true + end + end + -- verifico che il taglio longitudinale non sia orientato verso il basso + if vtN:getZ() < 0.0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Longitudinal Cut from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Long2Cut') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero il diametro dell'utensile + local dToolDiam = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dToolDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dToolDiam + end + end + local dStartDist = 0 + if ( bLimXmin and vtN:getY() < 0) or ( bLimXmax and vtN:getY() > 0) then + dStartDist = dToolDiam / 2 + end + local dEndDist = 0 + if ( bLimXmin and vtN:getY() > 0) or ( bLimXmax and vtN:getY()< 0) then + dEndDist = dToolDiam / 2 + end + -- se va fatta in 3 o più parti + local nC = ceil( ( dLen - 2 * BD.LONGCUT_ENDLEN) / BD.LONGCUT_MAXLEN) + if nC > 0 then + local dC = ( dLen - 2 * BD.LONGCUT_ENDLEN) / nC + nC = nC + 2 + -- si percorre il lato basso della faccia + for i = 1, nC do + -- inserisco le parti di lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dStartDist, - BD.LONGCUT_ENDLEN - ( i - 2) * dC) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + local dEal = EgtIf( i == nC, -dEndDist, - BD.LONGCUT_ENDLEN - ( nC - i - 1) * dC) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- altrimenti una o due parti + else + nC = EgtIf( dLen > BD.LONGCUT_ENDLEN, 2, 1) + local dAccDist = EgtIf( nC == 2, dLen / 2, 0) + -- si percorre il lato basso della faccia + for i = 1, nC do + -- inserisco le parti di lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- limito opportunamente la lavorazione + local dSal = EgtIf( i == 1, -dStartDist, - dAccDist) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + local dEal = EgtIf( i == nC, -dEndDist, - dAccDist) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- se ci sono le facce limitanti + for i = 1, Proc.Fct - 1 do + -- inserisco la lavorazione + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( i) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, i}}) + -- lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + -- uso della faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + -- attacco e uscita + EgtSetMachiningParam( MCH_MP.LIPERP, 0) + EgtSetMachiningParam( MCH_MP.LITANG, dToolDiam / 2 + 30) + EgtSetMachiningParam( MCH_MP.LOPERP, 0) + EgtSetMachiningParam( MCH_MP.LOTANG, dToolDiam / 2 + 30) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessLongCut diff --git a/LuaLibs/ProcessLongDoubleCut.lua b/LuaLibs/ProcessLongDoubleCut.lua new file mode 100644 index 0000000..824836b --- /dev/null +++ b/LuaLibs/ProcessLongDoubleCut.lua @@ -0,0 +1,176 @@ +-- ProcessLongDoubleCut.lua by Egaltech s.r.l. 2019/03/22 +-- Gestione calcolo doppio taglio longitudinale per Travi + +-- Tabella per definizione modulo +local ProcessLong2Cut = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessLongDoubleCut started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessLong2Cut.Identify( Proc) + return ( Proc.Grp == 0 and Proc.Prc == 12) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessLong2Cut.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.707 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessLong2Cut.Make( Proc, nPhase, nRawId, nPartId) + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + local dLen = EgtGetBBoxGlob( Proc.Id, GDB_BB.STANDARD):getDimX() + -- verifico che il doppio taglio longitudinale non sia orientato verso il basso + if vtN[1]:getZ() < - 0.707 or vtN[2]:getZ() < - 0.707 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Longitudinal Double Cut from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- verifico se sopra o sui lati + local bTop = ( vtN[1]:getZ() > 0 and vtN[2]:getZ() > 0) + -- angolo diedro per stabilire se taglio convesso + local _, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + local ptM = ( ptP1 + ptP2) / 2 + local bConvex = ( dAng >= 0) + -- analisi del taglio + local vOrd = {} + local vFaceUse = {} + if bTop then + vOrd = EgtIf( ptC[1]:getY() < ptM:getY(), { 1, 2}, { 2, 1}) + vFaceUse = {[vOrd[1]] = MCH_MILL_FU.ORTHO_BACK, [vOrd[2]] = MCH_MILL_FU.ORTHO_FRONT} + else + local bFront = ( vtN[1]:getY() < 0) + if bFront then + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 1, 2}, { 2, 1}) + vFaceUse = {[vOrd[1]] = MCH_MILL_FU.ORTHO_TOP, [vOrd[2]] = MCH_MILL_FU.ORTHO_DOWN} + else + vOrd = EgtIf( ptC[1]:getZ() < ptM:getZ(), { 2, 1}, { 1, 2}) + vFaceUse = {[vOrd[1]] = MCH_MILL_FU.ORTHO_DOWN, [vOrd[2]] = MCH_MILL_FU.ORTHO_TOP} + end + end + local vWidth = {} + local vtDiff1 = ptC[vOrd[1]] - ptM + vWidth[vOrd[1]] = 2 * sqrt( vtDiff1:getY() * vtDiff1:getY() + vtDiff1:getZ() * vtDiff1:getZ()) + local vtDiff2 = ptC[vOrd[2]] - ptM + vWidth[vOrd[2]] = 2 * sqrt( vtDiff1:getY() * vtDiff1:getY() + vtDiff1:getZ() * vtDiff1:getZ()) + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Long2Cut') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 0 + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- determino il numero di parti in cui dividere la lavorazione + local dEndLen = BD.LONGCUT_ENDLEN + if dLen < 2 * dEndLen + BD.LONGCUT_MAXLEN then + dEndLen = dLen / 3 + end + local nC = ceil( ( dLen - 2 * dEndLen) / BD.LONGCUT_MAXLEN) + local dC = 0 + if nC > 0 then dC = ( dLen - 2 * dEndLen) / nC end + nC = nC + 2 + -- ciclo sulle parti + local nM = 0 + for j = 1, nC do + -- su entrambe le facce + for i = 1, 2 do + -- Limitazioni della lavorazione + local nPos = EgtIf( i == 1, j, nC - j + 1) + local dSal = EgtIf( nPos == 1, 0, - dEndLen - ( nPos - 2) * dC) + local dEal = EgtIf( nPos == nC, 0, - dEndLen - ( nC - nPos - 1) * dC) + -- Posizione braccio portatesta + local nSCC = EgtIf( ( j == 1 or j == nC - 1), MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM) + -- ciclo sulle passate + local nO = 1 + local dStep = 0 + if vWidth[vOrd[i]] > 0.75 * dMillDiam then + nO = ceil( vWidth[vOrd[i]] * 2 / dMillDiam) + dStep = vWidth[vOrd[i]] / nO + end + for k = 1, nO do + -- determino direzione di movimento + local bToLeft = ( i == 1) + -- inserisco le parti di lavorazione + nM = nM + 1 + local sNameF = 'L2C_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) .. '_' .. tostring( nM) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, vOrd[i] - 1}}) + -- limito opportunamente la lavorazione + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dSal) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEal) + -- imposto posizione braccio porta testa per non ingombrare agli estremi + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- imposto uso faccia + EgtSetMachiningParam( MCH_MP.FACEUSE, vFaceUse[vOrd[i]]) + -- imposto lato di lavoro e inversione + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, false) + -- imposto offset radiale (nullo se concavo) + if k < nO then + EgtSetMachiningParam( MCH_MP.OFFSR, ( nO - k) * dStep) + else + EgtSetMachiningParam( MCH_MP.OFFSR, EgtIf( bConvex, - BD.CUT_EXTRA, 0)) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessLong2Cut diff --git a/LuaLibs/ProcessMark.lua b/LuaLibs/ProcessMark.lua new file mode 100644 index 0000000..a974745 --- /dev/null +++ b/LuaLibs/ProcessMark.lua @@ -0,0 +1,102 @@ +-- ProcessMark.lua by Egaltech s.r.l. 2018/04/18 +-- Gestione calcolo marcatura per Travi + +-- Tabella per definizione modulo +local ProcessMark = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessMark started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMark.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 60) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessMark.Classify( Proc) + -- recupero il versore estrusione + local vtN = EgtCurveExtrusion( Proc.Id, GDB_ID.ROOT) + -- verifico sia una curva + if not vtN then + return false + end + -- verifico se la marcatura è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMark.Make( Proc, nPhase, nRawId, nPartId) + -- recupero eventuale geometria ausiliaria + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + -- recupero i dati della marcatura + local vtExtr = EgtCurveExtrusion( Proc.Id, GDB_RT.GLOB) + -- verifico sia una curva + if not vtExtr then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che la marcatura non sia orientata verso il basso (-5 deg) + if vtExtr:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mark from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Mark') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Decor_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + local vGeom = {{ Proc.Id, -1}} + if AuxId then vGeom[2] = { AuxId, -1} end + EgtSetMachiningGeometry( vGeom) + -- imposto posizione braccio porta testa + if vtExtr:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessMark diff --git a/LuaLibs/ProcessMortise.lua b/LuaLibs/ProcessMortise.lua new file mode 100644 index 0000000..cfc38db --- /dev/null +++ b/LuaLibs/ProcessMortise.lua @@ -0,0 +1,111 @@ +-- ProcessMortise.lua by Egaltech s.r.l. 2018/03/23 +-- Gestione calcolo mortase per Travi + +-- Tabella per definizione modulo +local ProcessMortise = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessMortise started', 1) + +-- Dati +local BD = require( 'BeamData') +local Pocketings = require( 'PocketingData') + +--------------------------------------------------------------------- +local function FindPocketing( sType) + for i = 1, #Pocketings do + local Pocketing = Pocketings[i] + if Pocketing.Type == sType then + return i, Pocketing.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessMortise.Identify( Proc) + return ( (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 50) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 51) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 53)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessMortise.Classify( Proc) + -- recupero i dati della faccia di fondo + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessMortise.Make( Proc, nPhase, nRawId, nPartId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- se curva aperta la allungo e chiudo + if not EgtCurveIsClosed( AuxId) then + local EXTRA_LEN = 30 + EgtExtendCurveStartByLen( AuxId, EXTRA_LEN) + EgtExtendCurveEndByLen( AuxId, EXTRA_LEN) + EgtCloseCurveCompo( AuxId) + end + -- recupero i dati della curva e del top + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Mortise from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local nPocket, sPocketing = FindPocketing( 'Mortise') + if not sPocketing then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di svuotatura + local sName = 'Mort_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() < - GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessMortise diff --git a/LuaLibs/ProcessPocket.lua b/LuaLibs/ProcessPocket.lua new file mode 100644 index 0000000..87d6e7e --- /dev/null +++ b/LuaLibs/ProcessPocket.lua @@ -0,0 +1,100 @@ +-- ProcessPocket.lua by Egaltech s.r.l. 2018/10/21 +-- Gestione calcolo tasche per Travi + +-- Tabella per definizione modulo +local ProcessPocket = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessPocket started', 1) + +-- Dati +local BD = require( 'BeamData') +local Pocketings = require( 'PocketingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessPocket.Identify( Proc) + return ( ( Proc.Grp == 4 and Proc.Prc == 39) or + (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 32)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessPocket.Classify( Proc) + -- recupero la faccia con il maggior numero di adiacenze e più grande + local nFacInd = BL.GetFaceWithMostAdj( Proc.Id) + if not nFacInd then return false end + -- recupero i dati della faccia + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + -- verifico se la mortasa è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +local function FindPocketing( sType) + for i = 1, #Pocketings do + local Pocketing = Pocketings[i] + if Pocketing.Type == sType then + return i, Pocketing.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessPocket.Make( Proc, nPhase, nRawId, nPartId) + -- recupero la faccia con il maggior numero di adiacenze e più grande + local nFacInd = BL.GetFaceWithMostAdj( Proc.Id) + if not nFacInd then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' bottom face not found' + EgtOutLog( sErr) + return false, sErr + end + -- ne recupero i dati + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nFacInd, GDB_ID.ROOT) + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- verifico che la mortasa non sia orientata verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Pocket from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local nPocket, sPocketing = FindPocketing( 'Mortise') + if not sPocketing then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' pocketing not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di svuotatura + local sName = 'Pock_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sPocketing) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sPocketing + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFacInd}}) + -- imposto posizione braccio porta testa + if vtN:getY() < - GEO.EPS_SMALL then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessPocket diff --git a/LuaLibs/ProcessProfCamb.lua b/LuaLibs/ProcessProfCamb.lua new file mode 100644 index 0000000..2bca9b7 --- /dev/null +++ b/LuaLibs/ProcessProfCamb.lua @@ -0,0 +1,219 @@ +-- ProcessProfCamb.lua by Egaltech s.r.l. 2019/04/01 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfCamb = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfCamb started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfCamb.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 103) +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtNF) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtNF) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0 + -- determino asse di rotazione + local vtRot = - Y_AX() + if vtNF:getX() < 0 then vtRot = - vtRot end + if vtNF:getZ() < -0.1 then + vtRot = - vtRot + elseif vtNF:getY() < -0.1 then + vtRot:rotate( X_AX(), 90) + elseif vtNF:getY() > 0.1 then + vtRot:rotate( X_AX(), -90) + end + -- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave) + vtNP[2] = 0 vtNP[3] = 0 + local dRot = 45 + for i = 1, 4 do + local vtNP2 = Vector3d( vtNP) + vtNP2:rotate( vtRot, dRot) + local frRef = Frame3d( ptStart, vtNP2) + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef) + if b3Box:getMax():getZ() < -3 then + vtNP = Vector3d( vtNP2) + end + dRot = dRot / 2 + end + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfCamb.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local nRefFacet = nLastFacet - 1 -- penultima faccia + local vtNF = EgtSurfTmFacetNormVersor( Proc.Id, nLastFacet, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nRefFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtNF:getX() > 0) + EgtOutLog( 'vtN=' .. tostring( vtN), 3) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtNF) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra + if vtN:getZ() > 0.1 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( vtNF:getX() > 0 and vtExtr:getY() < -0.1) or + ( vtNF:getX() < 0 and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( vtNF:getX() > 0 and vtNF:getY() > 0.1) or + ( vtNF:getX() < 0 and vtNF:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se non da sotto, inserisco lavorazione finitura angolo + if nSide ~= -1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, true) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, -0.5) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.ORTHO_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.ORTHO_FRONT, MCH_MILL_FU.ORTHO_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide == 0 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfCamb diff --git a/LuaLibs/ProcessProfConcave.lua b/LuaLibs/ProcessProfConcave.lua new file mode 100644 index 0000000..6ed3c79 --- /dev/null +++ b/LuaLibs/ProcessProfConcave.lua @@ -0,0 +1,243 @@ +-- ProcessProfConcave.lua by Egaltech s.r.l. 2019/04/01 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfConcave = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConcave started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConcave.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 101) +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getDimZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConcave.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) / 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra + if nSide == 1 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( vtN:getX() > 0 and vtExtr:getY() < -0.1) or + ( vtN:getX() < 0 and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( vtN:getX() > 0 and vtN:getY() > 0.1) or + ( vtN:getX() < 0 and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) + local dLiPerp = 0 + if ( not bInvert and not bFirstTrim) or ( bInvert and not bLastTrim) then dLiPerp = 5 end + local dLoPerp = 0 + if ( not bInvert and not bLastTrim) or ( bInvert and not bFirstTrim) then dLoPerp = 5 end + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- eventuale finitura faccia finale (ortogonale alla trave) + if nSide ~= -1 and bLastTrim then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- eventuale finitura faccia iniziale (parallela alla trave) + if nSide ~= -1 and bFirstTrim then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Raw:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConcave diff --git a/LuaLibs/ProcessProfConvex.lua b/LuaLibs/ProcessProfConvex.lua new file mode 100644 index 0000000..d4e491f --- /dev/null +++ b/LuaLibs/ProcessProfConvex.lua @@ -0,0 +1,243 @@ +-- ProcessProfConvex.lua by Egaltech s.r.l. 2019/04/01 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfConvex = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfConvex started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfConvex.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 102) +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfConvex.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) / 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra + if nSide == 1 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( vtN:getX() > 0 and vtExtr:getY() < -0.1) or + ( vtN:getX() < 0 and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( vtN:getX() > 0 and vtN:getY() > 0.1) or + ( vtN:getX() < 0 and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) + local dLiPerp = 0 + if ( not bInvert and not bFirstTrim) or ( bInvert and not bLastTrim) then dLiPerp = 5 end + local dLoPerp = 0 + if ( not bInvert and not bLastTrim) or ( bInvert and not bFirstTrim) then dLoPerp = 5 end + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- eventuale finitura faccia finale (ortogonale alla trave) + if nSide ~= -1 and bLastTrim then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- eventuale finitura faccia iniziale (parallela alla trave) + if nSide ~= -1 and bFirstTrim then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Raw:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfConvex diff --git a/LuaLibs/ProcessProfFront.lua b/LuaLibs/ProcessProfFront.lua new file mode 100644 index 0000000..f0984e0 --- /dev/null +++ b/LuaLibs/ProcessProfFront.lua @@ -0,0 +1,224 @@ +-- ProcessProfFront.lua by Egaltech s.r.l. 2019/04/01 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfFront = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfFront started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfFront.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 100) +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtSP( AuxId, GDB_ID.ROOT) + vtNP * 5.0 + -- determino asse di rotazione + local vtRot = - Y_AX() + if vtN:getX() < 0 then vtRot = - vtRot end + if vtN:getZ() < -0.1 then + vtRot = - vtRot + elseif vtN:getY() < -0.1 then + vtRot:rotate( X_AX(), 90) + elseif vtN:getY() > 0.1 then + vtRot:rotate( X_AX(), -90) + end + -- miglioro l'inclinazione (ripartendo da faccia perpendicolare asse trave) + vtNP[2] = 0 vtNP[3] = 0 + local dRot = 45 + for i = 1, 4 do + local vtNP2 = Vector3d( vtNP) + vtNP2:rotate( vtRot, dRot) + local frRef = Frame3d( ptStart, vtNP2) + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frRef) + if b3Box:getMax():getZ() < -3 then + vtNP = Vector3d( vtNP2) + end + dRot = dRot / 2 + end + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfFront.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- ultima faccia + local nRefFacet = nLastFacet - 1 -- penultima faccia + -- determino la normale media + local CvxHullId = EgtSurfTmConvexHullInBBox( EgtGetParent( Proc.Id), Proc.Id, b3Raw, GDB_ID.ROOT) + local vtN = EgtSurfTmFacetNormVersor( CvxHullId, 0, GDB_ID.ROOT) + EgtErase( CvxHullId) + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + --EgtOutLog( 'vtN=' .. tostring( vtN)) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra + if nSide == 1 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( bHead and vtExtr:getY() < -0.1) or + ( not bHead and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( bHead and vtExtr:getY() > 0.1) or + ( not bHead and vtExtr:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- se non da sotto, inserisco lavorazione finitura angolo + if nSide ~= -1 then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, 0}}) + -- aggiusto i parametri + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- imposto tipo uso faccia + local nFaceUse = MCH_MILL_FU.PARAL_DOWN + if nSide ~= 1 then + nFaceUse = EgtIf( vtN:getY() > 0.1, MCH_MILL_FU.PARAL_FRONT, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.FACEUSE, nFaceUse) + -- imposto posizione braccio porta testa + local nSCC = MCH_SCC.ADIR_YM + if vtN:getY() > 100 * GEO.EPS_ZERO then + nSCC = MCH_SCC.ADIR_YP + end + EgtSetMachiningParam( MCH_MP.SCC, nSCC) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide == 0 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfFront diff --git a/LuaLibs/ProcessProfHead.lua b/LuaLibs/ProcessProfHead.lua new file mode 100644 index 0000000..b918d9c --- /dev/null +++ b/LuaLibs/ProcessProfHead.lua @@ -0,0 +1,248 @@ +-- ProcessProfHead.lua by Egaltech s.r.l. 2019/03/29 +-- Gestione calcolo profilo caudato per Travi + +-- Tabella per definizione modulo +local ProcessProfHead = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessProfHead started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessProfHead.Identify( Proc) + return (( Proc.Grp == 3 or Proc.Grp == 4) and Proc.Prc == 106) +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +local function GetSawCutData( AuxId, vtN) + -- comincio con la normale a 45deg + local vtNP = Vector3d( vtN) + for i = 1, 3 do + if vtNP[i] > GEO.EPS_SMALL then + vtNP[i] = 1 + elseif vtNP[i] < -GEO.EPS_SMALL then + vtNP[i] = -1 + end + end + vtNP:normalize() + -- assegno un punto di passaggio + local ptStart = EgtMP( AuxId, GDB_ID.ROOT) + local frOCS = Frame3d( ptStart, vtNP) ; + local b3Box = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frOCS) + ptStart = ptStart + vtNP * ( b3Box:getMax():getZ() + 10.0) + -- restituisco i dati del piano + return ptStart, vtNP +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessProfHead.Make( Proc, nPhase, nRawId, nPartId, dCurrOvmH) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & GDB_FY.GEO_CURVE) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local nFirstFacet = 0 -- faccia iniziale + local nLastFacet = EgtSurfTmFacetCount( Proc.Id) - 1 -- faccia finale + local nMidFacet = ( nLastFacet + 1) / 2 -- faccia a metà circa + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, nMidFacet, GDB_ID.ROOT) + if abs( vtN:getX()) < 0.5 then + local vtN1 = EgtSurfTmFacetNormVersor( Proc.Id, ( 0 + nMidFacet) / 2, GDB_ID.ROOT) + local vtN2 = EgtSurfTmFacetNormVersor( Proc.Id, ( nMidFacet + nLastFacet) / 2, GDB_ID.ROOT) + vtN = vtN1 + vtN2 ; vtN:normalize() + end + -- verifico se in testa o coda + local bHead = ( vtN:getX() > 0) + -- verifico se profilo orientato verso l'alto (1), il basso (-1) o di fianco (0) + local nSide = 0 + if vtN:getZ() > 0.1 then + nSide = 1 + elseif vtN:getZ() < -0.1 then + nSide = -1 + end + -- verifico se necessari ripassi agli estremi negli angoli + local _, _, _, dFirstAng = EgtSurfTmFacetsContact( Proc.Id, nFirstFacet, nFirstFacet + 1, GDB_ID.ROOT) + local bFirstTrim = ( dFirstAng and dFirstAng < -30) + local _, _, _, dLastAng = EgtSurfTmFacetsContact( Proc.Id, nLastFacet, nLastFacet - 1, GDB_ID.ROOT) + local bLastTrim = ( dLastAng and dLastAng < -30) + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo taglio di lama di sgrossatura e lo lavoro + local ptStart, vtNP = GetSawCutData( AuxId, vtN) + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptStart, vtNP, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico la lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Prof') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione + local sName = 'Prof_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- se lavorazione da sopra + if nSide == 1 then + -- se lavorazione a destra di fronte o sinistra da dietro, inverto + if ( vtN:getX() > 0 and vtExtr:getY() < -0.1) or + ( vtN:getX() < 0 and vtExtr:getY() > 0.1) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- altrimenti lavorazione dal davanti o dal dietro + else + -- se fresa verso il basso, la porto verso l'alto + if vtExtr:getZ() < 0 then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- se lavorazione a destra da dietro o sinistra di fronte, inverto + if ( vtN:getX() > 0 and vtN:getY() > 0.1) or + ( vtN:getX() < 0 and vtN:getY() < -0.1) then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + end + -- posizione braccio porta testa + EgtSetMachiningParam( MCH_MP.SCC, EgtIf( bHead, MCH_SCC.ADIR_XP, MCH_SCC.ADIR_XM)) + -- imposto parametri di attacco e uscita + local bInvert = EgtGetMachiningParam( MCH_MP.INVERT) + local dLiPerp = 0 + if ( not bInvert and not bFirstTrim) or ( bInvert and not bLastTrim) then dLiPerp = 5 end + local dLoPerp = 0 + if ( not bInvert and not bLastTrim) or ( bInvert and not bFirstTrim) then dLoPerp = 5 end + EgtSetMachiningParam( MCH_MP.LIPERP, dLiPerp) + EgtSetMachiningParam( MCH_MP.LOPERP, dLoPerp) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + -- eventuale finitura faccia finale (ortogonale alla trave) + if nSide ~= -1 and bLastTrim then + sName = 'ProfV_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchVId = EgtAddMachining( sName, sMilling) + if not nMchVId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nLastFacet}}) + -- aggiusto i parametri + if vtN:getZ() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_DOWN) + elseif vtN:getY() > 0.1 then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_FRONT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_BACK) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchVId, false) + return false, sErr + end + end + -- eventuale finitura faccia iniziale (parallela alla trave) + if nSide ~= -1 and bFirstTrim then + sName = 'ProfV2_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchV2Id = EgtAddMachining( sName, sMilling) + if not nMchV2Id then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- calcolo massima elevazione + local _, _, _, _, _, _, dWidth = EgtSurfTmFacetOppositeSide( Proc.Id, 0, EgtIf( bHead, X_AX(), - X_AX()), GDB_ID.ROOT) + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, nFirstFacet}}) + -- aggiusto i parametri + if bHead then + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_LEFT) + else + EgtSetMachiningParam( MCH_MP.FACEUSE, MCH_MILL_FU.PARAL_RIGHT) + end + EgtSetMachiningParam( MCH_MP.INVERT, false) + EgtSetMachiningParam( MCH_MP.DEPTH_STR, 'TH') + EgtSetMachiningParam( MCH_MP.STEP, 0) + EgtSetMachiningParam( MCH_MP.OFFSR, 0) + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dWidth, 1)) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchV2Id, false) + return false, sErr + end + end + -- aggiorno ingombro testa o coda per presa + if nSide ~= 1 then + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMin():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + else + if bHead then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dCurrOvmH - Proc.Box:getMax():getX()) + else + BL.UpdateTCING( nRawId, Proc.Box:getMin():getX() - b3Raw:getMin():getX()) + end + end + return true +end + +--------------------------------------------------------------------- +return ProcessProfHead diff --git a/LuaLibs/ProcessRidgeLap.lua b/LuaLibs/ProcessRidgeLap.lua new file mode 100644 index 0000000..d48e4dd --- /dev/null +++ b/LuaLibs/ProcessRidgeLap.lua @@ -0,0 +1,215 @@ +-- ProcessRidgeLap.lua by Egaltech s.r.l. 2019/04/01 +-- Gestione calcolo mezzolegno di testa per Travi + +-- Tabella per definizione modulo +local ProcessRidgeLap = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessRidgeLap started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRidgeLap.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 30) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRidgeLap.Classify( Proc) + -- Se più corta del limite si può fare anche da sotto + if Proc.Box:getDimX() < BD.MAX_LEN_RIDGELAP_FROM_BOTTOM then + return true, false + end + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.707 then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +local function FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.Type == sType then + return i, Cutting.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRidgeLap.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getX()) < 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i-1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- recupero la lavorazione + local _, sCutting = FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, nOrthoOpposite, BD.CUT_EXTRA, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + end + end + -- calcolo riferimenti per facce inclinate + local vtRef = Vector3d( vtN[vFaceOrd[3]]) + local vtRef2 = Vector3d( vtN[vFaceOrd[2]]) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[3]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtN[vFaceOrd[2]]) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtN[vFaceOrd[3]]:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Raw:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Raw:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRidgeLap diff --git a/LuaLibs/ProcessRoundArch.lua b/LuaLibs/ProcessRoundArch.lua new file mode 100644 index 0000000..301108a --- /dev/null +++ b/LuaLibs/ProcessRoundArch.lua @@ -0,0 +1,215 @@ +-- ProcessRoundArch.lua by Egaltech s.r.l. 2018/11/26 +-- Gestione calcolo archi per Travi + +-- Tabella per definizione modulo +local ProcessRoundArch = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessRoundArch started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessRoundArch.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 104) +end +--------------------------------------------------------------------- +-- Verifica se feature di testa +function ProcessRoundArch.IsHeadFeature( Proc, b3Raw, dCurrOvmH) + -- verifico se è in testa + if Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dCurrOvmH - BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di testa + return false +end + +--------------------------------------------------------------------- +-- Verifica se feature di coda +function ProcessRoundArch.IsTailFeature( Proc, b3Raw) + -- verifico se è in coda + if Proc.Box:getMin():getX() > b3Raw:getMin():getX() + BD.MAX_DIST_HTFEA then + return false + end + -- la sua lunghezza non deve superare la metà della lunghezza della trave + if Proc.Box:getDimX() > 0.5 * b3Raw:getDimX() then + return false + end + -- deve occupare la maggior parte dell'area + if Proc.Box:getDimY() > 0.75 * b3Raw:getDimY() or Proc.Box:getDimZ() > 0.75 * b3Raw:getDimZ() then + return true + end + -- non è di coda + return false +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessRoundArch.Classify( Proc) + -- se di testa o coda, è indifferente alla posizione + if Proc.Head or Proc.Tail then + return true, false + end + -- è intermedia, devo verificare la normale del centro + local nMidFacet = Proc.Fct // 2 + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, nMidFacet, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se la feature è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessRoundArch.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del profilo + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local bToolInv = ( vtExtr:getZ() < -0.1) + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'FreeContour') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMaxDepth = 0 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMaxDepth = EgtTdbGetCurrToolMaxDepth() or dMaxDepth + end + end + -- se non di testa o coda ne verifico la lunghezza per eventuale spezzatura + local nStep = 1 + local dStep = 0 + local b3Aux = EgtGetBBoxGlob( AuxId, GDB_BB.STANDARD) + if not Proc.Head and not Proc.Tail and b3Aux:getDimX() > BD.LONGCUT_MAXLEN then + local dCrvLen = EgtCurveLength( AuxId) + nStep = ceil( dCrvLen / BD.LONGCUT_MAXLEN) + dStep = dCrvLen / nStep + EgtOutLog( string.format( 'CrvLen=%.1f StepNbr=%d StepLen=%.1f', dCrvLen, nStep, dStep), 3) + end + -- verifiche per affondamento ( possibili lavorazioni in doppio) + local nDouble = 1 + local bCanDouble = ( abs( vtExtr:getZ()) < 0.5 and abs( vtExtr:getX()) < 0.1 and b3Aux:getDimY() > b3Raw:getDimY() - 1.0) + if nStep > 1 then + -- devo lasciare un codolo + dDepth = dDepth - BD.DIM_STRIP + else + -- devo affondare un poco oltre + dDepth = dDepth + BD.CUT_EXTRA + end + if dDepth > dMaxDepth then + if bCanDouble then + nDouble = 2 + dDepth = min( 0.5 * dDepth, dMaxDepth) + else + dDepth = dMaxDepth + end + end + -- eseguo + for i = 1, nStep do + for j = 1, nDouble do + -- inserisco la lavorazione + local sName = 'Free_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchId = EgtAddMachining( sName, sMilling) + if not nMchId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- eventuale accorciamento di testa + if ( j == 1 and i > 1) or ( j == 2 and i < nStep) then + local dStartAddLen = EgtIf( j == 1, - ( i - 1) * dStep, - ( nStep - i) * dStep) + EgtSetMachiningParam( MCH_MP.STARTADDLEN, dStartAddLen) + end + -- eventuale accorciamento di coda + if ( j == 1 and i < nStep) or ( j == 2 and i > 1) then + local dEndAddLen = EgtIf( j == 1, - ( nStep - i) * dStep, - ( i - 1) * dStep) + EgtSetMachiningParam( MCH_MP.ENDADDLEN, dEndAddLen) + end + -- se estrusione da sotto, inverto direzione fresa + if ( j == 1 and bToolInv) or ( j == 2 and not bToolInv) then + EgtSetMachiningParam( MCH_MP.TOOLINVERT, true) + end + -- se seconda passata, inverto direzione di lavoro + if j == 2 then + EgtSetMachiningParam( MCH_MP.INVERT, true) + end + -- assegno affondamento + EgtSetMachiningParam( MCH_MP.DEPTH, dDepth) + -- assegno lato di lavoro + if bToolInv then + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.LEFT) + else + EgtSetMachiningParam( MCH_MP.WORKSIDE, MCH_MILL_WS.RIGHT) + end + -- posizione braccio porta testa + if Proc.Head then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XP) + elseif Proc.Tail then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_XM) + elseif AreSameOrOppositeVectorApprox( vtExtr, Z_AX()) then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchId, false) + return false, sErr + end + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessRoundArch diff --git a/LuaLibs/ProcessSimpleScarf.lua b/LuaLibs/ProcessSimpleScarf.lua new file mode 100644 index 0000000..4dc02c5 --- /dev/null +++ b/LuaLibs/ProcessSimpleScarf.lua @@ -0,0 +1,224 @@ +-- ProcessSimpleScarf.lua by Egaltech s.r.l. 2018/11/04 +-- Gestione calcolo giunto Gerber per Travi + +-- Tabella per definizione modulo +local ProcessSimpleScarf = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' ProcessSimpleScarf started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSimpleScarf.Identify( Proc) + return (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 70) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessSimpleScarf.Classify( Proc) + -- verifico le normali delle facce + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + for i = 1, nFacetCnt do + local vtN = EgtSurfTmFacetNormVersor( Proc.Id, i-1, GDB_ID.ROOT) + if vtN:getZ() < - 0.5 and Proc.Box:getDimX() / abs( vtN:getZ()) > BD.MAX_DIM_DICE then + return true, true + end + end + return true, false +end + +--------------------------------------------------------------------- +local function FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.Type == sType then + return i, Cutting.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSimpleScarf.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che ci siano almeno due facce (altrimenti non è da lavorare) + local nFacetCnt = EgtSurfTmFacetCount( Proc.Id) + if nFacetCnt < 2 then + return true + end + -- dati delle facce + local ptC = {} + local vtN = {} + for i = 1, nFacetCnt do + ptC[i], vtN[i] = EgtSurfTmFacetCenter( Proc.Id, i-1, GDB_ID.ROOT) + end + -- ordino le facce (1=esterna, 2=interna, 3=intermedia) + local vFaceOrd = { 0, 0, 0} + for i = 1, nFacetCnt do + if abs( vtN[i]:getY()) > 0.1 or abs( vtN[i]:getZ()) > 0.1 then + vFaceOrd[3] = i + break + end + end + if vFaceOrd[3] == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing intermediate face' + EgtOutLog( sErr) + return false, sErr + end + for i = 1, nFacetCnt do + if i ~= vFaceOrd[3] then + local bTouch, ptP1, ptP2, dAng = EgtSurfTmFacetsContact( Proc.Id, i - 1, vFaceOrd[3] - 1, GDB_ID.ROOT) + if bTouch and dAng > 0 then + vFaceOrd[1] = i + elseif bTouch and dAng < 0 then + vFaceOrd[2] = i + end + end + end + -- determino se di testa o di coda + local bHead = ( vtN[vFaceOrd[2]]:getX() > 0) + -- vettore di riferimento per le facce ortogonali all'asse trave + local vtRef = Vector3d( 0, vtN[vFaceOrd[3]]:getY(), vtN[vFaceOrd[3]]:getZ()) + vtRef:normalize() + -- recupero la lavorazione + local _, sCutting = FindCutting( 'HeadSide') + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- taglio sulla faccia esterna + if vFaceOrd[1] ~= 0 then + -- in generale va fatto + local bCut = true + -- se di testa e coincide con inizio grezzo, non va fatto + if bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMax():getX() + dOvmHead) < 10 * GEO.EPS_SMALL then + bCut = false + end + -- se di coda e coincide con taglio di separazione, non va fatto + if not bHead and AreSameVectorApprox( vtN[vFaceOrd[1]], - X_AX()) and abs( ptC[vFaceOrd[1]]:getX() - b3Raw:getMin():getX()) < BD.OVM_MID + 10 * GEO.EPS_SMALL then + bCut = false + end + -- se va fatto, inserisco la lavorazione + if bCut then + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[1] - 1, sCutting, dSawDiam, nOrthoOpposite, BD.CUT_EXTRA, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + end + end + -- se esistono faccia interna ed intermedia, verifico se richiedono taglio a cubetti + local vCuts = {} + if vFaceOrd[2] ~= 0 and vFaceOrd[3] ~= 0 then + vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[vFaceOrd[3]], vtN[vFaceOrd[3]], false, ptC[vFaceOrd[2]], vtN[vFaceOrd[2]]) + end + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + end + end + -- calcolo secondo riferimento per facce inclinate + local vtRef2 = Vector3d( vtN[vFaceOrd[2]]) + -- eseguo + for i = 1, #vCuts do + local nOrthoOpposite + if i % 2 == 1 then + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + else + nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + end + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + else + -- taglio sulla faccia interna + local bIntCut = false + if vFaceOrd[2] ~= 0 then + -- inserisco la lavorazione + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef) + local bOk, sNameOrErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[2] - 1, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sNameOrErr end + if #sNameOrErr > 0 then bIntCut = true end + end + -- taglio sulla faccia intermedia + if vFaceOrd[3] ~= 0 then + -- inserisco la lavorazione + local vtRef2 = vtN[vFaceOrd[2]] + if not bIntCut then + local frHV, DimH, DimV = BL.GetFaceHvRefDim( Proc.Id, vFaceOrd[2] - 1) + if DimV <= DimH then + vtRef2 = Vector3d( frHV:getVersY()) + else + vtRef2 = Vector3d( frHV:getVersX()) + end + end + local nOrthoOpposite = BL.GetNearestOrthoOpposite( vtRef2) + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, vFaceOrd[3] - 1, sCutting, dSawDiam, nOrthoOpposite, 0, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + end + end + -- aggiornamento ingombro di testa o coda + if Proc.Head then + local dHCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dHCI = b3Raw:getMax():getX() - dOvmHead - b3Fac1:getMin():getX() end + else + dHCI = b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX() + end + BL.UpdateHCING( nRawId, dHCI) + elseif Proc.Tail then + local dTCI = 0 + if abs( vtRef:getZ()) > 0.1 then + local b3Fac1 = BL.GetFaceBox( Proc.Id, vFaceOrd[1] - 1) + if b3Fac1 then dTCI = b3Fac1:getMax():getX() - b3Raw:getMin():getX() end + else + dTCI = Proc.Box:getMax():getX() - b3Raw:getMin():getX() + end + BL.UpdateTCING( nRawId, dTCI) + end + return true +end + +--------------------------------------------------------------------- +return ProcessSimpleScarf diff --git a/LuaLibs/ProcessSplit.lua b/LuaLibs/ProcessSplit.lua new file mode 100644 index 0000000..9b137ee --- /dev/null +++ b/LuaLibs/ProcessSplit.lua @@ -0,0 +1,102 @@ +-- ProcessSplit.lua by Egaltech s.r.l. 2018/11/22 +-- Gestione calcolo tagli di separazione per Travi + +-- Tabella per definizione modulo +local ProcessSplit = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') + +EgtOutLog( ' ProcessSplit started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') + +--------------------------------------------------------------------- +local function FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.Type == sType then + return i, Cutting.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessSplit.Identify( Proc) + return ( Proc.Grp == 2 and Proc.Prc == 350) +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessSplit.Make( Proc, nPhase, nRawId, nPartId) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + local bHorizCut = ( b3Raw:getDimY() > b3Raw:getDimZ() + 10 * GEO.EPS_SMALL and b3Raw:getDimZ() < BD.MAX_DIM_HTCUT) + local bDoubleCut = ( not bHorizCut and b3Raw:getDimY() > BD.MAX_DIM_HTCUT+ 10 * GEO.EPS_SMALL) + -- dati geometrici del taglio + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + -- flag di lavorazione faccia + local nOrthoOpposite = EgtIf( bHorizCut, MCH_MILL_FU.ORTHO_DOWN, MCH_MILL_FU.ORTHO_FRONT) + -- separazione solo se esiste grezzo successivo con pezzi o scaricabile + local nNextRawId = EgtGetNextRawPart( nRawId) + local bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() > BD.MinRaw)) + -- determino se più tagli con offset + local nCuts = 1 + local dOffsL = 0 + if not bSplit then + -- cerco grezzo successivo che sia nella fase + local nNextRawId = EgtGetNextRawPart( nRawId) + if nNextRawId and EgtVerifyRawPartPhase( nNextRawId, nPhase) then + local b3NextRaw = EgtGetRawPartBBox( nNextRawId) + local dLenEndRaw = ptC:getX() - b3NextRaw:getMin():getX() + nCuts = ceil( dLenEndRaw / BD.MAX_LEN_SCRAP) + dOffsL = dLenEndRaw / nCuts + end + end + -- recupero la lavorazione + local _, sCutting = FindCutting( EgtIf( bSplit, 'SplitSide', 'TailSide')) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, true, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + end + end + -- calcolo extra taglio + local dCutExtra = EgtIf( bDoubleCut, - 0.5 * b3Raw:getDimY(), 0) + BD.CUT_EXTRA + -- se necessari tagli in doppio, eseguo gli opposti + if bDoubleCut then + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes = 'Cut' + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, MCH_MILL_FU.ORTHO_BACK, dCutExtra, BD.CUT_SIC, dCutOffset, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + end + -- eseguo i tagli necessari + for i = nCuts, 1, -1 do + local dCutOffset = ( i - 1) * dOffsL + local sNotes + if not bSplit then + sNotes = EgtIf( i == 1, 'Cut', 'Precut') + end + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite, dCutExtra, BD.CUT_SIC, dCutOffset, sNotes, b3Raw) + if not bOk then return false, true, sErr end + end + -- ritorno anche flag di passaggio a fase successiva + return true, true +end + +--------------------------------------------------------------------- +return ProcessSplit diff --git a/LuaLibs/ProcessTenon.lua b/LuaLibs/ProcessTenon.lua new file mode 100644 index 0000000..56354a4 --- /dev/null +++ b/LuaLibs/ProcessTenon.lua @@ -0,0 +1,165 @@ +-- ProcessTenon.lua by Egaltech s.r.l. 2019/03/23 +-- Gestione calcolo tenone per Travi + +-- Tabella per definizione modulo +local ProcessTenon = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local Cut = require( 'ProcessCut') + +EgtOutLog( ' ProcessTenon started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessTenon.Identify( Proc) + return ( (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 50) or + (( Proc.Grp == 1 or Proc.Grp == 2) and Proc.Prc == 52)) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessTenon.Classify( Proc) + -- recupero i dati della faccia top + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico sia una superficie + if not vtN then + return false + end + -- verifico se il tenone è lavorabile solo da sotto + local bDown = ( vtN:getZ() < - 0.1) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessTenon.Make( Proc, nPhase, nRawId, nPartId, dOvmHead) + -- ingombro del grezzo + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- recupero e verifico l'entità curva + local AuxId = EgtGetInfo( Proc.Id, 'AUXID', 'i') + if AuxId then AuxId = AuxId + Proc.Id end + if not AuxId or ( EgtGetType( AuxId) & 256) == 0 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing profile geometry' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati della curva e del top + local dDepth = abs( EgtCurveThickness( AuxId)) + local vtExtr = EgtCurveExtrusion( AuxId, GDB_RT.GLOB) + local ptC, vtN = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + EgtOutLog( 'ptC=' .. tostring( ptC) ..' vtN=' .. tostring( vtN), 3) + -- verifico che il tenone non sia orientato verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Tenon from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- determino altezza del tenone + local frTen = Frame3d( ptC, vtN) + local b3Ten = EgtGetBBoxRef( Proc.Id, GDB_BB.STANDARD, frTen) + local dTenH = b3Ten:getDimZ() + -- determino larghezza massima di svuotatura + local b3Aux = EgtGetBBoxRef( AuxId, GDB_BB.STANDARD, frTen) + local dPockL = 0.5 * max( b3Ten:getDimX() - b3Aux:getDimX(), b3Ten:getDimY() - b3Aux:getDimY()) + -- porto inizio curva il più possibile sul bordo + BL.PutStartNearestToEdge( AuxId, b3Solid) + -- se vero tenone inclinato o non esattamente alle estremità, necessario taglio di lama sulla testa + if Proc.Prc ~= 52 and + ( not AreSameOrOppositeVectorApprox( vtN, X_AX()) or + ( Proc.Box:getMax():getX() < b3Raw:getMax():getX() - dOvmHead - 100 * GEO.EPS_SMALL and + Proc.Box:getMin():getX() > b3Raw:getMin():getX() + 100 * GEO.EPS_SMALL)) then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- creo piano di taglio sulla testa del tenone e lo lavoro + local b3Solid = EgtGetBBoxGlob( EgtGetFirstNameInGroup( nPartId, 'Box') or GDB_ID.NULL, GDB_BB.STANDARD) + local AddId = EgtSurfTmPlaneInBBox( EgtGetParent( Proc.Id), ptC, vtN, b3Solid, GDB_RT.GLOB) + if AddId then + EgtRelocate( AddId, nAddGrpId) + EgtSetName( AddId, 'AddCut_' .. tostring( Proc.Id)) + -- applico lavorazione + local CutProc = { Id = AddId, Grp = Proc.Grp, Prc = Proc.Prc, Box = Proc.Box, Fct = Proc.Fct, Flg = Proc.Flg} + local bOk, sErr = Cut.Make( CutProc, nPhase, nRawId, nPartId, 0) + if not bOk then return bOk, sErr end + end + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Tenon') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dMillDiam = 20 + if EgtMdbSetCurrMachining( sMilling) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dMillDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dMillDiam + end + end + -- determino il numero di passate concentriche + local nPass = ceil( dPockL / ( 0.5 * dMillDiam)) + local dStep = dPockL / nPass + for i = nPass, 1, -1 do + -- inserisco la passata finale della lavorazione + local sNameF = 'TenF_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sNameF, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sNameF .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ AuxId, -1}}) + -- sistemo i parametri + EgtSetMachiningParam( MCH_MP.USERNOTES, 'MaxElev=' .. EgtNumToString( dTenH, 1) .. ';') + local dOffset = ( i - 1) * dStep + EgtSetMachiningParam( MCH_MP.OFFSR, dOffset) + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + end + -- eventuale segnalazione ingombro di testa o coda + if Proc.Head then + BL.UpdateHCING( nRawId, b3Raw:getMax():getX() - dOvmHead - Proc.Box:getMin():getX()) + elseif Proc.Tail then + BL.UpdateTCING( nRawId, Proc.Box:getMax():getX() - b3Raw:getMin():getX()) + end + return true +end + +--------------------------------------------------------------------- +return ProcessTenon diff --git a/LuaLibs/ProcessText.lua b/LuaLibs/ProcessText.lua new file mode 100644 index 0000000..720b228 --- /dev/null +++ b/LuaLibs/ProcessText.lua @@ -0,0 +1,97 @@ +-- ProcessText.lua by Egaltech s.r.l. 2018/04/17 +-- Gestione calcolo testi per Travi + +-- Tabella per definizione modulo +local ProcessText = {} + +-- Include +require( 'EgtBase') + +EgtOutLog( ' ProcessText started', 1) + +-- Dati +local BD = require( 'BeamData') +local Millings = require( 'MillingData') + +--------------------------------------------------------------------- +local function FindMilling( sType) + for i = 1, #Millings do + local Milling = Millings[i] + if Milling.Type == sType then + return i, Milling.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +-- Riconoscimento della feature +function ProcessText.Identify( Proc) + return ( Proc.Grp == 4 and Proc.Prc == 61) +end + +--------------------------------------------------------------------- +-- Classificazione della feature +function ProcessText.Classify( Proc) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + return false + end + -- verifico se il testo è lavorabile solo da sotto + local bDown = (( vtN:getZ() < -0.1)) + return true, bDown +end + +--------------------------------------------------------------------- +-- Applicazione della lavorazione +function ProcessText.Make( Proc, nPhase, nRawId, nPartId) + -- recupero i dati del testo + local vtN = EgtTextNormVersor( Proc.Id, GDB_ID.ROOT) + -- verifico sia un testo + if not vtN then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text with geometry type not accepted' + EgtOutLog( sErr) + return false, sErr + end + -- verifico che il testo non sia orientato verso il basso (-5 deg) + if vtN:getZ() < - 0.1 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' Text from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero la lavorazione + local nMill, sMilling = FindMilling( 'Text') + if not sMilling then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' milling not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- inserisco la lavorazione di fresatura + local sName = 'Text_' .. ( EgtGetName( Proc.Id) or tostring( Proc.Id)) + local nMchFId = EgtAddMachining( sName, sMilling) + if not nMchFId then + local sErr = 'Error adding machining ' .. sName .. '-' .. sMilling + EgtOutLog( sErr) + return false, sErr + end + -- aggiungo geometria + EgtSetMachiningGeometry( {{ Proc.Id, -1}}) + -- imposto posizione braccio porta testa + if vtN:getY() <= 0 then + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YM) + else + EgtSetMachiningParam( MCH_MP.SCC, MCH_SCC.ADIR_YP) + end + -- eseguo + if not EgtApplyMachining( true, false) then + local _, sErr = EgtGetLastMachMgrError() + EgtSetOperationMode( nMchFId, false) + return false, sErr + end + return true +end + +--------------------------------------------------------------------- +return ProcessText diff --git a/LuaLibs/TwoFacesBySaw.lua b/LuaLibs/TwoFacesBySaw.lua new file mode 100644 index 0000000..589b9b0 --- /dev/null +++ b/LuaLibs/TwoFacesBySaw.lua @@ -0,0 +1,147 @@ +-- TwoFacesBySaw.lua by Egaltech s.r.l. 2019/03/28 +-- Gestione taglio con lama di feature con due facce + +-- Tabella per definizione modulo +local TwoFacesBySaw = {} + +-- Include +require( 'EgtBase') +local BL = require( 'BeamLib') +local DC = require( 'DiceCut') + +EgtOutLog( ' TwoFacesBySaw started', 1) + +-- Dati +local BD = require( 'BeamData') +local Cuttings = require( 'CutData') + +---------------------------------------------------------------------------------------------------------------------------------------------------- +local function FindCutting( sType) + for i = 1, #Cuttings do + local Cutting = Cuttings[i] + if Cutting.Type == sType then + return i, Cutting.Name + end + end + return 0 +end + +--------------------------------------------------------------------- +function TwoFacesBySaw.Make( Proc, nPhase, nRawId, nPartId, sCutName) + -- recupero l'ingombro del grezzo di appartenenza + local b3Raw = EgtGetRawPartBBox( nRawId) + -- ingombro del pezzo + local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' part box not found' + EgtOutLog( sErr) + return false, sErr + end + -- verifico il numero di facce della tacca + if Proc.Fct ~= 2 then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw facet number not supported' + EgtOutLog( sErr) + return false, sErr + end + -- dati delle facce + local ptC = {} + local vtN = {} + ptC[1], vtN[1] = EgtSurfTmFacetCenter( Proc.Id, 0, GDB_ID.ROOT) + ptC[2], vtN[2] = EgtSurfTmFacetCenter( Proc.Id, 1, GDB_ID.ROOT) + -- verifico non siano orientate verso il basso + local bFaceOk = {} + bFaceOk[1] = ( vtN[1]:getZ() >= BD.NZ_MINB) + bFaceOk[2] = ( vtN[2]:getZ() >= BD.NZ_MINB) + if not bFaceOk[1] and not bFaceOk[2] then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw from bottom impossible' + EgtOutLog( sErr) + return false, sErr + end + -- recupero dati su giunzione tra facce + local bTouch, ptT1, ptT2, dAngT = EgtSurfTmFacetsContact( Proc.Id, 0, 1, GDB_ID.ROOT) + if not bTouch then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' TwoFacesBySaw faces not touching' + EgtOutLog( sErr) + return false, sErr + end + -- calcolo direzione di lavoro + local nOrthoOpposite = {} + local vtTg = ptT2 - ptT1 ; + local vtRef1 = vtN[1] ^ vtTg + if vtRef1 * vtN[2] < 0 then vtRef1 = - vtRef1 end + local vtRef2 = vtN[2] ^ vtTg + if vtRef2 * vtN[1] < 0 then vtRef2 = - vtRef2 end + nOrthoOpposite[1] = BL.GetNearestOrthoOpposite( vtRef1) + nOrthoOpposite[2] = BL.GetNearestOrthoOpposite( vtRef2) + -- determino quale faccia è più grande + local ptPs = ( ptT1 + ptT2) / 2 + local dSqDim1 = ( ptC[1] - ptPs):sqlen() + local dSqDim2 = ( ptC[2] - ptPs):sqlen() + local nBigInd = EgtIf( dSqDim1 >= dSqDim2, 1, 2) + local nSmaInd = 3 - nBigInd + -- recupero la lavorazione + local _, sCutting = FindCutting( sCutName) + if not sCutting then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' cutting not found in library' + EgtOutLog( sErr) + return false, sErr + end + -- recupero i dati dell'utensile + local dSawDiam = 400 + local dSawThick = 5 + if EgtMdbSetCurrMachining( sCutting) then + local sTuuid = EgtMdbGetCurrMachiningParam( MCH_MP.TUUID) + if EgtTdbSetCurrTool( EgtTdbGetToolFromUUID( sTuuid) or '') then + dSawDiam = EgtTdbGetCurrToolParam( MCH_TP.DIAM) or dSawDiam + dSawThick = EgtTdbGetCurrToolParam( MCH_TP.THICK) or dSawThick + end + end + -- calcolo extra taglio + local dCutExtra = 0 + if dAngT < -92 then + dCutExtra = - dSawThick / tan( 180 + dAngT) + end + -- verifico se necessari tagli supplementari + local vCuts = DC.GetDice( EgtGetParent( Proc.Id), b3Solid, ptC[nBigInd], vtN[nBigInd], false, ptC[nSmaInd], vtN[nSmaInd]) + --DC.PrintOrderCut( vCuts) + if #vCuts > 0 then + -- recupero gruppo per geometria addizionale + local nAddGrpId = BL.GetAddGroup( nPartId) + if not nAddGrpId then + local sErr = 'Error on process ' .. tostring( Proc.Id) .. ' missing AddGroup' + EgtOutLog( sErr) + return false, sErr + end + -- sistemo posizione nel DB e nome + for i = 1, #vCuts do + for j = 1, #vCuts[i] do + EgtRelocateGlob( vCuts[i][j], nAddGrpId) + EgtSetName( vCuts[i][j], 'AddCut_' .. tostring( Proc.Id)) + end + end + -- eseguo + for i = 1, #vCuts do + -- assegno il modo di tagliare + local nOrtOpp = EgtIf( ( i % 2) == 1, nOrthoOpposite[nSmaInd], nOrthoOpposite[nBigInd]) + -- lavoro la faccia + for j = 1, #vCuts[i] do + local bOk, sErr = BL.MakeOneFaceBySaw( vCuts[i][j], 0, sCutting, dSawDiam, nOrtOpp, dCutExtra, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then + return bOk, sErr + end + end + end + return true + else + -- lavoro la prima faccia + local bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 0, sCutting, dSawDiam, nOrthoOpposite[1], dCutExtra, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + -- lavoro seconda faccia + bOk, sErr = BL.MakeOneFaceBySaw( Proc.Id, 1, sCutting, dSawDiam, nOrthoOpposite[2], dCutExtra, BD.CUT_SIC, 0, nil, b3Raw) + if not bOk then return bOk, sErr end + return true + end +end + +return TwoFacesBySaw \ No newline at end of file diff --git a/Process.lua b/Process.lua new file mode 100644 index 0000000..7e6f573 --- /dev/null +++ b/Process.lua @@ -0,0 +1,220 @@ +-- Process.lua by Egaltech s.r.l. 2019/01/15 +-- Gestione calcolo disposizione e lavorazioni per Travi +-- Si opera sulla macchina corrente + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- Imposto direttorio libreria specializzata per Travi +local sBaseDir = EgtGetSourceDir() +EgtAddToPackagePath( sBaseDir .. 'LuaLibs\\?.lua') + +-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi +local sMachDir = EgtGetCurrMachineDir() +if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then + EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR') + return +end + +-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie +EgtRemoveBaseMachineDirFromPackagePath() +EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua') + +-- Segnalazione avvio +EgtOutLog( '*** Beam Process Start ***', 1) + +-- Carico le librerie +_G.package.loaded.BeamExec = nil +local BE = require( 'BeamExec') +local BL = require( 'BeamLib') + +-- Carico i dati globali +local BD = require( 'BeamData') + +-- Variabili di modulo +local vBeam = {} +local dRawW +local dRawH + +------------------------------------------------------------------------------------------------------------- +-- *** Recupero le travi selezionate *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessInputData() + + -- Recupero le travi selezionate + local nId = EgtGetFirstSelectedObj() + while nId do + local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) + if nPartId then + local bFound = false + for i = 1, #vBeam do + if vBeam[i].Id == nPartId then + bFound = true + break + end + end + if not bFound then + table.insert( vBeam, { Id = nPartId, Name = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))}) + end + end + nId = EgtGetNextSelectedObj() + end + if #vBeam == 0 then + EgtOutBox( 'Non sono state selezionate travi', 'Lavora Travi', 'ERROR') + return false + else + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi selezionate : ' .. sOut, 1) + end + + -- Ne recupero e verifico le dimensioni + for i = 1, #vBeam do + local Ls = EgtGetFirstNameInGroup( vBeam[i].Id, 'Box') + local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) + if not b3Solid then + EgtOutBox( 'Box non definito per la trave ' .. vBeam[i].Name, 'Lavora Travi', 'ERROR') + return false + else + vBeam[i].Box = b3Solid + end + end + dRawW = vBeam[1].Box:getDimY() + dRawH = vBeam[1].Box:getDimZ() + local vBeamErr = {} + for i = 2, #vBeam do + local dDimW = vBeam[i].Box:getDimY() + local dDimH = vBeam[i].Box:getDimZ() + if ( abs( dDimW - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimH - dRawH) > 10 * GEO.EPS_SMALL) and + ( abs( dDimH - dRawW) > 10 * GEO.EPS_SMALL or abs( dDimW - dRawH) > 10 * GEO.EPS_SMALL) then + table.insert( vBeamErr, i) + end + end + if #vBeamErr > 0 then + local sOut = 'Rimosse travi con sezioni diverse dalla prima :\n' + for i = #vBeamErr, 1, -1 do + sOut = sOut .. vBeam[vBeamErr[i]].Name .. '\n' + EgtDeselectPartObjs( vBeam[vBeamErr[i]].Id) + table.remove( vBeam, vBeamErr[i]) + end + EgtOutLog( sOut, 1) + EgtOutBox( sOut, 'Lavora Travi', 'INFO') + EgtDraw() + return false + end + EgtDeselectAll() + + -- Le ordino in senso di lunghezza crescente + table.sort( vBeam, function( B1, B2) return B1.Box:getDimX() < B2.Box:getDimX() end) + do + local sOut = '' + for i = 1, #vBeam do + sOut = sOut .. vBeam[i].Name .. ', ' + end + sOut = sOut:sub( 1, -3) + EgtOutLog( 'Travi ordinate : ' .. sOut, 1) + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle travi nel grezzo *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessBeams() + -- Lunghezza totale delle travi + local dTotLen = 0 + for i = 1, #vBeam do + dTotLen = dTotLen + vBeam[i].Box:getDimX() + end + local dAddLen = BD.OVM_HEAD + #vBeam * BD.OVM_MID + EgtOutLog( 'Ltot : ' .. EgtNumToString( dTotLen, 1) .. ' Lagg : '.. EgtNumToString( dAddLen, 1), 1) + + -- Richiedo lunghezza del grezzo e sovramateriale di testa + local vsVal = EgtDialogBox( 'Lavora Travi' .. ' (Ltot='.. EgtNumToString( dTotLen + dAddLen + 0.5, 0) .. ', Lmax=' .. EgtNumToString( BD.MAX_RAW, 0) .. ')', + {'Lunghezza grezzo', EgtNumToString( BD.STD_RAW, 0)}, + {'Sovramateriale di testa', EgtNumToString( BD.OVM_HEAD, 0)}, + {'Forza sezione verticale', ' CB:true,*false'}) + if not vsVal then + EgtDraw() + return + end + local dRawL = EgtEvalNumExpr( vsVal[1]) + if not dRawL then + local sOut = 'Lunghezza grezzo errata : ' .. vsVal[1] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + dRawL = min( dRawL, BD.MAX_RAW) + local dOvmHead = EgtEvalNumExpr( vsVal[2]) + if not dOvmHead then + local sOut = 'Sovramateriale di testa errato : ' .. vsVal[2] + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo sezione barra con travi + local bVert = ( vsVal[3] == 'true') + if bVert then + if dRawW > dRawH then dRawW, dRawH = dRawH, dRawW end + end + EgtOutLog( 'Lraw : ' .. EgtNumToString( dRawL, 1) .. ' Lovm : '.. EgtNumToString( dOvmHead, 1), 1) + + -- Verifico sezione barra + if dRawW > BD.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BD.MAX_HEIGHT + 10 * GEO.EPS_SMALL then + local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' .. + 'oltre i limiti della macchina (' .. EgtNumToString( BD.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BD.MAX_HEIGHT, 2) .. ')' + EgtOutLog( sOut) + EgtOutBox( sOut, 'Lavora Travi', 'WARNING') + EgtDraw() + return false + end + + -- Sistemo le travi nel grezzo + local bOk, sErr = BE.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, vBeam) + if not bOk then + EgtOutLog( sErr) + EgtOutBox( sErr, 'Lavora Travi', 'ERROR') + EgtDraw() + return false + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Inserimento delle lavorazioni nelle travi *** +------------------------------------------------------------------------------------------------------------- +local function MyProcessFeatures() + + local bOk, sErr = BE.ProcessFeatures() + if not bOk then + EgtOutLog( sErr) + EgtOutBox( sErr, 'Lavora Travi', 'ERROR') + EgtDraw() + return false + end + + return true +end + +------------------------------------------------------------------------------------------------------------- +-- *** Esecuzione *** +------------------------------------------------------------------------------------------------------------- +if not MyProcessInputData() then return end + +if not MyProcessBeams() then return end + +-- Abilito Vmill +EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1') + +if not MyProcessFeatures() then return end diff --git a/Rotate.lua b/Rotate.lua new file mode 100644 index 0000000..547064d --- /dev/null +++ b/Rotate.lua @@ -0,0 +1,32 @@ +-- Rotate.lua by Egaltech s.r.l. 2017/11/04 +-- Gestione rotazione di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Rotate Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Rotate Trave', 'ERROR') + return +end + +-- eseguo rotazione di 90 gradi attorno asse X +local ptRot = b3Solid:getMin() + Vector3d( 0, b3Solid:getDimZ() / 2, b3Solid:getDimZ() / 2) +EgtRotate( nPartId, ptRot, X_AX(), 90, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file diff --git a/ShowAll.lua b/ShowAll.lua new file mode 100644 index 0000000..76100ee --- /dev/null +++ b/ShowAll.lua @@ -0,0 +1,18 @@ +-- ClearAll.lua by Egaltech s.r.l. 2017/11/16 +-- Gestione visualizzazione di tutte le Travi + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +local nId = EgtGetFirstPart() +while nId do + EgtSetMode( nId, GDB_MD.STD) + -- EgtSetStatus( nId, GDB_ST.ON) + nId = EgtGetNextPart( nId) +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/ShowBuilding.lua b/ShowBuilding.lua new file mode 100644 index 0000000..1f372f7 --- /dev/null +++ b/ShowBuilding.lua @@ -0,0 +1,63 @@ +-- ShowBuilding.lua by Egaltech s.r.l. 2018/11/21 +-- Gestione visualizzazione travi come struttura + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + +-- recupero il gruppo di assemblaggio +local AsseBaseId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'AsseBase') +if not AsseBaseId then return end + +-- recupero il primo oggetto nel gruppo e verifico se devo assemblare o disassemblare +local AsseId = EgtGetFirstInGroup( AsseBaseId) +if not AsseId then return end +local bMake = ( EgtGetGroupObjs( AsseId) == 0) + +-- ciclo sul gruppo di assemblaggio +while AsseId do + -- salvo il successivo nel gruppo dell'assemblato + local NextId = EgtGetNext( AsseId) + -- costruisco l'assemblato + if bMake then + -- recupero il pezzo sorgente + local SouId = EgtGetInfo( AsseId, GDB_SI.SOURCE, 'i') + if SouId then + EgtSetMode( SouId, GDB_MD.STD) + EgtSetStatus( SouId, GDB_ST.ON) + -- se già utilizzato, ne faccio una copia + if not EgtIsPart( SouId) then + local CopyId = EgtCopy( SouId, GDB_ID.ROOT) + if CopyId then + EgtRemoveInfo( CopyId, GDB_SI.BASE) + EgtRemoveInfo( CopyId, GDB_SI.LIST) + EgtSetInfo( CopyId, GDB_SI.COPY, SouId) + SouId = CopyId + EgtSetInfo( AsseId, GDB_SI.SOURCE, SouId) + end + end + EgtSetStatus( EgtGetFirstNameInGroup( SouId, 'Box') or GDB_ID.NULL, GDB_ST.OFF) + EgtGroupSwap( SouId, AsseId, true, true) + end + -- ritorno ai pezzi + else + local BasId = EgtGetInfo( AsseId, GDB_SI.BASE, 'i') + if BasId then + EgtGroupSwap( AsseId, BasId, true, true) + local CopId = EgtGetInfo( AsseId, GDB_SI.COPY, 'i') + if CopId then + EgtErase( AsseId) + EgtSetInfo( BasId, GDB_SI.SOURCE, CopId) + else + EgtSetStatus( EgtGetFirstNameInGroup( AsseId, 'Box') or GDB_ID.NULL, GDB_ST.ON) + end + end + end + -- passo al successivo + AsseId = NextId +end + +EgtZoom( SCE_ZM.ALL) + +-- end \ No newline at end of file diff --git a/Swap.lua b/Swap.lua new file mode 100644 index 0000000..e4e00a7 --- /dev/null +++ b/Swap.lua @@ -0,0 +1,31 @@ +-- Swap.lua by Egaltech s.r.l. 2017/11/02 +-- Gestione scambio testa coda di una Trave + +-- Intestazioni +require( 'EgtBase') +_ENV = EgtProtectGlobal() +EgtEnableDebug( false) + + +-- recupero il pezzo del primo oggetto selezionato +local nId = EgtGetFirstSelectedObj() +local nPartId = EgtGetParent( EgtGetParent( nId or GDB_ID.NULL) or GDB_ID.NULL) +if not nPartId or not EgtIsPart( nPartId) then + EgtOutBox( 'Nessuna trave selezionata', 'Swap Trave', 'ERROR') + return +end + +-- recupero il box del pezzo +local Ls = EgtGetFirstNameInGroup( nPartId, 'Box') +local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD) +if not b3Solid then + local sName = EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)) + EgtOutBox( 'Box non definito per la trave ' .. sName, 'Swap Trave', 'ERROR') + return +end + +-- eseguo rotazione di 180 gradi attorno asse Z +EgtRotate( nPartId, b3Solid:getCenter(), Z_AX(), 180, GDB_RT.GLOB) +EgtDraw() + +-- end \ No newline at end of file