104 Commits

Author SHA1 Message Date
andrea.villa 74279896e9 - Gestione utensili profilati, esclusi da calcolo automatico 2024-07-15 08:36:37 +02:00
luca.mazzoleni b270e150c0 - in SLOTBYCHAINSAW aggiunta lettura step utensile 2024-06-27 18:01:24 +02:00
luca.mazzoleni d9a36c0c5f - creata strategia core SLOTBYBLADE per le tasche con lama
- adattata STR0003 per contemplare SLOTBYBLADE
2024-06-27 17:07:35 +02:00
luca.mazzoleni e189c0d518 - in SLOTBYCHAINSAW rimosse parti non utili
- in STR0003 piccole correzioni
2024-06-27 09:52:48 +02:00
luca.mazzoleni 380eb9450b Merge branch 'CORESTRATEGY_SlotByChainSaw' into develop 2024-06-27 09:25:54 +02:00
luca.mazzoleni 5bbebcbbde - in SLOTBYCHAINSAW corretto calcolo LeadIn e LeadOut per lavorazione delle sole impronte 2024-06-27 09:25:26 +02:00
luca.mazzoleni 3319d8b271 - in MachiningLib dStartPos diventa dStartSafetyLength
- migliorie stilistiche
2024-06-26 18:18:06 +02:00
luca.mazzoleni 86fd80ee61 - in BeamExec -> RunStrategyLibraries corretti percorsi require
- in FaceData piccole correzioni
- in MachiningLib pesanti modifiche per contemplare cloni lavorazioni con parametri diversi (es: per step aggiuntivi o spezzatura). Parametri lavorazione  ora sono tutti scritti in tabella e ciclati invece di essere scritti uno a uno.
- in SLOTBYCHAINSAW alcune correzioni
- in STR0003 gestita aggiunta lavorazioni a MACHININGS e output risultati strategia
2024-06-26 17:26:00 +02:00
luca.mazzoleni 67bb860185 - in SLOTBYCHAINSAW modifiche varie 2024-06-21 18:37:21 +02:00
luca.mazzoleni 0b172e2be2 Strategies contine ora tutte le strategie, suddivise in cartelle che ne definiscono il tipo: core, standard, special 2024-06-20 17:12:08 +02:00
luca.mazzoleni d66bb615c9 Merge remote-tracking branch 'origin/develop' into CORESTRATEGY_SlotByChainSaw 2024-06-20 17:09:11 +02:00
luca.mazzoleni e3d73e9805 - modificata STR0003 per contemplare strategia di base SlotByChainsaw 2024-06-20 17:04:48 +02:00
luca.mazzoleni f5f362c318 - creazione BasicStrategies e strategia SLOTBYCHAINSAW
- modifiche a STR0003 per contemplare strategie base
- modifiche parziali da completare
2024-06-14 18:47:14 +02:00
andrea.villa 81c9a40618 Merge branch 'STR0002_ImproveSplitting' into develop 2024-06-12 15:08:00 +02:00
andrea.villa e5e9e7b876 - Corretto calcolo percentuale lavorata e MRR
- Inserito spezzatura su faccia tunnel
2024-06-12 15:07:25 +02:00
andrea.villa f5cbd7bfee - Gestione Tunnel-4-Through in STR0002
- Migliorie a scelta lavorazione
- Migliorie spezzatura
- Corretta condizione scelta utensile con minimo residuo
2024-06-11 12:45:17 +02:00
andrea.villa 546a60d8a3 Merge commit '62ca7479c72d02c99665d0f4c3a85a759ae2a5e9' into STR0002_ImproveSplitting 2024-06-10 15:25:45 +02:00
andrea.villa 62ca7479c7 - Creata variabile PARTS globale
- Aggiunte informazioni sul grezzo restante, distanza prossimo pezzo e se il successivo è un grezzo o no
2024-06-10 15:24:35 +02:00
andrea.villa 4127bb5eef Merge branch 'develop' into STR0002_ImproveSplitting 2024-06-10 12:48:35 +02:00
andrea.villa 9a6036dc4c Piccole modifiche per lettura diametro 2024-06-10 12:48:25 +02:00
andrea.villa 13c6eb3e06 Corretto gestione in caso di errore durante applicazione lavorazioni nella 'MachiningLib.AddOperations' 2024-06-10 09:50:47 +02:00
andrea.villa 4facba3389 Aggiunta "VerifySplitMachiningNeeded" per verifica split 2024-06-10 09:31:17 +02:00
andrea.villa cd1f892a6c - Creazione lista MACHINING
- STR0002 adeguata a nuovo standard
- MachiningLib.AddNewMachining salva lavorazione in lista MACHINING
- MachiningLib.AddOperations inseriwsce effettivamente lavorazione
2024-06-07 17:01:16 +02:00
luca.mazzoleni 67899a5835 - rimosso il calcolo dei MainEdges dalle BottomFace secondarie 2024-06-07 15:45:16 +02:00
luca.mazzoleni 5dec2dc821 - BottomFace diventa BottomFaces e comprende tutte le possibili facce di fondo. La [1] è sempre quella a minore elevazione (sono ordinate).
- modifiche a AddNewMachining e di conseguenza alle strategie
2024-06-07 12:57:36 +02:00
luca.mazzoleni c21de95a47 - modifiche a STR0003 per utilizzare AddNewMachining da MachiningLib come STR0002 2024-06-06 18:43:04 +02:00
andrea.villa db5ec90fbf Merge branch 'STR0002_ImprovePocketing' into develop 2024-06-05 10:36:23 +02:00
andrea.villa 285f3bc78d - Calcolo automatiso SIDESTEP portato a 1/3 del diametro
- Migliorato calcolo percentuale lavorata
- Gestione topologia Rabbet-2-Through
- Varie migliorie calcoli svuotature da applicare
2024-06-05 10:36:06 +02:00
luca.mazzoleni cb37a14305 - correzioni a STR0003 2024-06-05 10:32:19 +02:00
luca.mazzoleni d80a780886 Merge remote-tracking branch 'origin/STR0002_ImprovePocketing' into develop 2024-06-04 09:27:21 +02:00
andrea.villa 9a8c0386d9 Merge remote-tracking branch 'origin/develop' into STR0002_ImprovePocketing 2024-06-04 09:03:46 +02:00
andrea.villa 435075014d Corretto problema su calcolo percentuale lavorata. Da utlimare 2024-06-04 09:02:19 +02:00
luca.mazzoleni 2b3630ee3a piccole correzioni a STR0002 e STR0003 2024-06-03 18:33:52 +02:00
luca.mazzoleni 6d2037e0c5 Merge remote-tracking branch 'origin/STR0002_ImprovePocketing' into develop 2024-06-03 17:24:29 +02:00
andrea.villa 2df3069711 Merge remote-tracking branch 'origin/develop' into STR0002_ImprovePocketing 2024-06-03 17:05:47 +02:00
andrea.villa 5fc2b80cc1 Corretta letture lato lungo su Tunnel 2024-06-03 17:05:38 +02:00
luca.mazzoleni 2edfd52628 - in FaceData GetMainFaces aggiunti MainEdges per SideFaces e piccole correzioni 2024-06-03 16:41:24 +02:00
luca.mazzoleni 342082bb82 Merge remote-tracking branch 'origin/STR0002_ImprovePocketing' into develop 2024-06-03 12:25:11 +02:00
andrea.villa 7e0bee34cc - Rimossa funzione BeamLib.GetFaceHvRefDim
- Per larghezza/altezza faccia si utilizzano gli  "Edges"
- Corretto errore ricerca utensili MILL_STD e MILL_NOTIP
- Adeguamento STR0002 a nuovo standard
2024-06-03 12:08:24 +02:00
andrea.villa 21ec48bc2d Merge remote-tracking branch 'origin/develop' into STR0002_ImprovePocketing 2024-06-03 08:10:45 +02:00
andrea.villa f67f9530f5 - Calcolo strategia di lavorazione, bottom o dai lati 2024-06-03 08:07:22 +02:00
luca.mazzoleni 0e634c7f0d - per STR0002 gestite anche Groove-3-blind e Rabbet-2-Through
- GetAffectedFaces modificata per utilizzare Part
- la profonfdità di lavorazione si passa ora sempre come DEPTH_STR
- aggiunti box con tempi di calcolo collect e machining
- corretti typo in nome variabili
2024-05-31 17:47:15 +02:00
luca.mazzoleni b6049893de Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2024-05-31 14:37:46 +02:00
luca.mazzoleni 0cdee9cfcb - in BeamLib aggiunta funzione GetNearestParalOpposite da automatismo vecchio
- in STR0003 abilitata sega a catena e parziale refactoring
2024-05-31 14:37:40 +02:00
andrea.villa d8b8a79a78 Merge remote-tracking branch 'origin/develop' into STR0002_ImprovePocketing 2024-05-31 12:55:20 +02:00
andrea.villa 26c6cc68c9 In MachiningLib.FindMill se si cerca una fresa che non può lavorare di testa, quelle che lavorano di testa sono comunque ammesse 2024-05-31 12:54:50 +02:00
andrea.villa 58c9630563 Merge remote-tracking branch 'origin/develop' into STR0002_ImprovePocketing 2024-05-31 11:52:33 +02:00
andrea.villa 04f40edd16 In MachiningLib.FindMill si controlla direzione utensile e se fresa lavora di testa 2024-05-31 11:52:19 +02:00
luca.mazzoleni 52fb5100ff - corretto calcolo MRR per STR0002 e STR0003 2024-05-30 18:48:27 +02:00
luca.mazzoleni c49e81bcc4 Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2024-05-30 18:17:41 +02:00
luca.mazzoleni 4160190886 - migliorie a GetMainFaces
- correzioni varie a STR0003
- piccola correzione a STR0002 in caso di groove passante (da completare)
2024-05-30 18:17:30 +02:00
andrea.villa b20ab1013a - Modificata funzione calcolo MRR. In Input una tabella con i valori
- Adeguamento STR0002 a nuova funzione MRR
2024-05-30 14:34:03 +02:00
luca.mazzoleni a5382e0847 - alcune modifiche a nomi variabili (Part.b3Raw, nToolTypeId)
- in BeamLib aggiunte GetChainSawInitAngs e GetBlockedAxis da automatismo vecchio, con qualche adattamento
- prima versione funzionante di STR0003
2024-05-30 10:44:24 +02:00
andrea.villa 60bac29b1e - Calcolo MRR spostato in MachiningLib. Funzione: GetToolMRR
-  Aggiornato strategia STR0002
2024-05-30 09:33:43 +02:00
luca.mazzoleni cc597ce890 - modifiche a STR0003 per restituizione Result (ora funzionante, modificare per usare AddMachining nuova)
- in BeamExec GetBestStrategy eliminato check strategyOk (ora è relativo solo all'applicazione delle lavorazioni)
2024-05-29 19:19:53 +02:00
luca.mazzoleni e0b4a8b852 Merge remote-tracking branch 'origin/develop' into develop 2024-05-29 18:13:24 +02:00
andrea.villa a312f715c7 - Funzione FindMill considera se utensile su aggregato. Serve BeamData nella macchina aggiornato
- Calcolo Rating con parametri: "MRR, Quality, CompletionIndex" come da ultima specifica
- Adeguamentio strategia STR0002 a nuovo stantdard per calcolo Rating
2024-05-29 16:56:36 +02:00
andrea.villa d191825118 - Modifica a strategie per nuovo standard parametri custom
- Funzione apposita per calcolo 'CompletionIndex'
- Modifica valori di ritorno delle strategie. BOOL + TABLE
- Versione primordiale funzione OrderFeature
- Aggiornamento finale lavorazioni
2024-05-28 17:10:01 +02:00
andrea.villa 8eeb7fa6d8 Merge remote-tracking branch 'origin/STR0003_BladePlusChainsaw' into develop 2024-05-28 13:13:16 +02:00
luca.mazzoleni b2a8279eb5 - in STR0003 modifiche per contemplare la restituzione dei risultati del calcolo al di fuori della strategia 2024-05-28 13:07:16 +02:00
luca.mazzoleni c7687419a6 - in MachiningLib corrette FindBlade e FindChainsaw (ancora da completare ma funzionano)
- in STR0003 altre modifiche nomi variabili
2024-05-24 18:37:53 +02:00
luca.mazzoleni 8cff8827a0 - in FaceData GetSideFaces allineata alle altre e piccole modifiche a GetLongFaces
- in BeamLib riportata la funzione GetNearestOrthoOpposite da automatismo vecchio
- in MachiningLib piccole modifiche
- in STR0003 corpose modifiche, in particolare allineamento con standard nomenclatura
2024-05-22 16:59:06 +02:00
luca.mazzoleni 404938a6be Merge remote-tracking branch 'origin/develop' into STR0003_BladePlusChainsaw 2024-05-22 10:00:45 +02:00
andrea.villa 69f97362b9 - MachiningLib scrittura parametri di sistema
- Piccola correzione STR0002 per uniformare a nuovi nomi parametri
2024-05-22 09:26:33 +02:00
luca.mazzoleni 01bf95c56c Merge remote-tracking branch 'origin/develop' into STR0003_BladePlusChainsaw 2024-05-22 08:40:19 +02:00
andrea.villa 32a16f97f3 - Piccola correzione STR0002
- In Process.lua spostato GetDataConfig dopo caricamento setup fatto nella ProcessBeams
2024-05-21 08:41:28 +02:00
luca.mazzoleni 297dcba66b - in STR0003_BladePlusChainsaw modifiche parziali per adattarla all' automatismo
- in MachiningLib aggiunta FindChainsaw e varie modifiche
- altre modifiche minori
2024-05-20 18:44:11 +02:00
andrea.villa c1c6e2a220 - Aggiunta funzione AddNewMachining in MachiningLib
- Adeguamento STR0002 per utilizzo nuova funzione di aggiunta lavorazione
2024-05-20 14:33:12 +02:00
andrea.villa 230b5f871d In BeamExec, lettura parametri di Setup da BeamData. Serve funzione macchina. 2024-05-20 09:11:38 +02:00
luca.mazzoleni d53fdca890 Merge remote-tracking branch 'origin/develop' into STR0003_BladePlusChainsaw 2024-05-17 18:47:42 +02:00
luca.mazzoleni 7165db47f6 - modifiche per aggiunta strategia BladePlusChain
- in BeamExec versione  primordiale di FindBlade
2024-05-17 18:45:36 +02:00
andrea.villa 7b09634461 Modifica nomi variabili che non rispettavano lo standard 2024-05-17 17:15:52 +02:00
andrea.villa 5dcc75587d Merge branch 'updateMerge' into develop 2024-05-17 09:47:38 +02:00
andrea.villa c3069a962a - Rimosso comando inserimento strategie in tabella in BasicStrategies
- Gestione spezzatura feature lunga STR0002
2024-05-17 09:45:42 +02:00
luca.mazzoleni 1a82df39ad - tutti i campi Id sostituiti con id (minuscolo)
- in FaceData aggiunta scrittura Edges (GetFaceInfo) e MainEdges (BottomFace e LongFaces)
2024-05-16 18:16:22 +02:00
luca.mazzoleni 6a89e6e29d - in FaceData.GetFacesInfo aggiunta raccolta informazioni lati, ancora da gestire
- in FaceData ora funziona anche il tunnel
- in FaceData aggiunto campo Type per identificare le facce ('Bottom', 'Long', 'Side', 'Tunnel')
- in FaceData si usa ora la funzione più prestante EgtSurfTmResetTwoColors per resettare i colori delle facce della trimesh
2024-05-15 19:06:27 +02:00
andrea.villa 5f30714a56 Migliorie a strategia STR0002 e funzioni correlate 2024-05-14 16:34:13 +02:00
andrea.villa 30fa7c8cbd Modifica nomi variabili secondo nuovo standard 2024-05-14 11:47:53 +02:00
andrea.villa 59bbf159e4 - Migliorie varie per adeguamento strategia e funzioni necessarie 2024-05-13 09:47:42 +02:00
andrea.villa d45fc8e89b - Prima versione file INI interfaccia selezione strategie Beam&Wall
- BeamLib : nuova funzione 'LoadCustomParametersInStrategy'
- Piccoli aggiustamenti vari
2024-05-08 15:32:51 +02:00
andrea.villa ecf89edf59 - b3Raw sostituito da tabella 'Part', che contiene Id e altre info del pezzo
- 'GetUpdateCustomParameters' spostato in BeamLib, da chiamare all'inizio di ogni strategia.
- Aggiornamento strategie a nuovo standard
2024-05-08 12:12:26 +02:00
andrea.villa 3c1814ebdc In BeamExec : Creata funzione unica GestBestStrategy che include le ex CalculateRatingStrategies e ChooseStrategy 2024-05-07 15:33:30 +02:00
andrea.villa 5ea5c78605 Implementata funzione per scelta strategia migliore (tra quelle disponibili che sono state analizzate) 2024-05-07 09:20:25 +02:00
luca.mazzoleni fedfc92ef0 -- in FaceData aggiunta colorazione faccia di fondo, se livello di Debug >= 3 2024-05-03 14:33:47 +02:00
luca.mazzoleni 03e4b4457d - in BeamLib GetProcessAffectedFaces diventa GetAffectedFaces
- in BeamExec GetAffectedFaces calcolata prima della topologia
- in FeatureData piccola correzione a ClassifyTopology
2024-05-03 13:01:32 +02:00
andrea.villa 80dcdb0003 - Facce e adiacenze calcolate solo per feature con topologia
- Prima versione GetMainFaces funzionante
- Prima bozza struttura codice per scelta strategie
- Calcolo delle 4 rotazioni per il recupero dei dati
- Prima bozza struttura calcolo voto strategie
- Modificate strategie di prova STR0001 e STR0002 con nuovo standard
2024-04-30 16:30:49 +02:00
andrea.villa 385143fb00 Merge remote-tracking branch 'origin/feature/GetMainFaces' into develop 2024-04-23 08:23:13 +02:00
luca.mazzoleni 7bcce7463b -GetMainFaces completa, da testare; da risolvere problema tunnel
-in FaceData migliorie varie
2024-04-22 18:37:46 +02:00
luca.mazzoleni 8cda36a838 - piccola correzione in GetMainFaces 2024-04-19 19:15:08 +02:00
luca.mazzoleni 10399347f0 - in GetMainFaces aggiunta faccia di mezzo tunnel e varie migliorie
- in GetFacesData non si trimmano più le superfici
2024-04-19 19:12:51 +02:00
andrea.villa 38540c5685 Merge branch 'feature/GetForcedStrategy' into develop 2024-04-19 15:43:26 +02:00
andrea.villa 69f172863b Piccole correzioni commenti 2024-04-19 15:43:11 +02:00
andrea.villa 76ec20260e - caricamento e reset librerie caricate
- corretto formattazione parametri strategia
2024-04-19 15:14:33 +02:00
luca.mazzoleni 10c1cd55f3 Merge remote-tracking branch 'origin/feature/GetForcedStrategy' into feature/GetMainFaces 2024-04-19 13:03:11 +02:00
luca.mazzoleni ea588844c5 - aggiunte e modifiche a GetMainFaces 2024-04-19 13:01:16 +02:00
andrea.villa fb47b28173 - Librerie con nome esteso
- Piccole correzioni dopo merge con Branch GetMainFaces
2024-04-19 12:49:21 +02:00
andrea.villa 4f90b0704d Merge remote-tracking branch 'origin/feature/GetMainFaces' into feature/GetForcedStrategy 2024-04-19 12:01:14 +02:00
andrea.villa ce156606e6 - Corretto campo nome topologia 2024-04-19 11:51:48 +02:00
andrea.villa e58cf7e398 - BasicStrategies se JSON non presente o in JSON nessuna strategia 2024-04-19 11:38:19 +02:00
andrea.villa bdc7c45204 - Aggiunti HeadCut e SplitCut a Identify
- Piccole correzioni lettura e salvataggio strategie lette da JSON su Vproc
2024-04-19 10:33:28 +02:00
andrea.villa 7193f2595d - Per valori default strategia si legge Config.lua e non più JSON-Strategia
- piccole correzioni gestione lista strategie
- creazione cartelle delle prime due strategie (vuote, solo per test)
2024-04-19 09:59:59 +02:00
luca.mazzoleni 65fec1e05d - implementata parzialmente GetMainFaces e funzioni accessorie
- migliorie stilistiche e refactoring parziale
2024-04-18 18:34:09 +02:00
luca.mazzoleni a8a0ac5875 - aggiunto gitignore 2024-04-17 12:15:11 +02:00
andrea.villa 904b15a4c9 Primo commit nuovo automatismo BEAM con strategie 2024-04-11 16:02:03 +02:00
27 changed files with 5739 additions and 93 deletions
+1
View File
@@ -0,0 +1 @@
.vscode/settings.json
+7
View File
@@ -0,0 +1,7 @@
[Beam]
BtlEnable=1
BaseDir=C:\EgtData\Beam
BtlExec=BatchProcess.lua
Button1=Process.lua,Images\Process.png,Lavora Travi
Button2=Swap.lua,Images\Swap.png,Scambia estremi trave
Button3=Rotate.lua,Images\Rotate.png,Ruota trave
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

+565
View File
@@ -0,0 +1,565 @@
--BasicCustomerStrategies.lua by Egalware s.r.l. 2024/04/02
-- Libreria strategie di base disponibili per i clienti
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
-- Tabella per definizione modulo
local BasicCustomerStrategies = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local BeamData = require( 'BeamData')
local ID = require( 'Identity')
----------------------------------------------------------------------------------
-- *** EGALWARE ***
----------------------------------------------------------------------------------
local function GetStrategies_Egalware( Proc)
local Strategies = {}
-- TODO tabella da compleatare man mano che si inseriscono le varie strategie
---------------------------------------------------------------------
-- Feature : Cut
if ID.IsHeadCut( Proc) then
---------------------------------------------------------------------
-- Feature : Cut
elseif ID.IsSplitCut( Proc) then
---------------------------------------------------------------------
-- Feature : Cut
elseif ID.IsCut( Proc) then
---------------------------------------------------------------------
-- Feature : Longitudinal Cut
elseif ID.IsLongitudinalCut( Proc) then
---------------------------------------------------------------------
-- Feature : Double Cut
elseif ID.IsDoubleCut( Proc) then
---------------------------------------------------------------------
-- Feature : Ridge or Valley Cut
elseif ID.IsDoubleLongitudinalCut( Proc) then
---------------------------------------------------------------------
-- Feature : Saw Cut
elseif ID.IsSawCut( Proc) then
---------------------------------------------------------------------
-- Feature : Slot
elseif ID.IsSlot( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Front Slot
elseif ID.IsFrontSlot( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Birds Mouth
elseif ID.IsBirdsMouth( Proc) then
---------------------------------------------------------------------
-- Feature : Hip or Valley Rafter Notch
elseif ID.IsHipValleyRafterNotch( Proc) then
---------------------------------------------------------------------
-- Feature : Ridge Lap
elseif ID.IsRidgeLap( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Lap Joint
elseif ID.IsLapJoint( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Notch/Rabbet
elseif ID.IsNotchRabbet( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Block Haus
elseif ID.IsBlockHaus( Proc) then
---------------------------------------------------------------------
-- Feature : Notch
elseif ID.IsNotch( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : French Ridge Lap
elseif ID.IsFrenchRidgeLap( Proc) then
---------------------------------------------------------------------
-- Feature : Chamfer
elseif ID.IsChamfer( Proc) then
---------------------------------------------------------------------
-- Feature : Block Haus Half Lap
elseif ID.IsHalfBlockHaus( Proc) then
---------------------------------------------------------------------
-- Feature : Block Haus Front
elseif ID.IsFrontBlockHaus( Proc) then
---------------------------------------------------------------------
-- Feature : Pocket
elseif ID.IsPocket( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Drilling
elseif ID.IsDrilling( Proc) then
---------------------------------------------------------------------
-- Feature : Tenon
elseif ID.IsTenon( Proc) then
---------------------------------------------------------------------
-- Feature : Mortise
elseif ID.IsMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Front Mortise
elseif ID.IsFrontMortise( Proc) then
---------------------------------------------------------------------
-- Feature : House
elseif ID.IsHouse( Proc) then
---------------------------------------------------------------------
-- Feature : House Mortise
elseif ID.IsHouseMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail Tenon
elseif ID.IsDovetailTenon( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail Mortise
elseif ID.IsDovetailMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail Mortise Front
elseif ID.IsFrontDovetailMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Marking
elseif ID.IsMarking( Proc) then
---------------------------------------------------------------------
-- Feature : Text
elseif ID.IsText( Proc) then
---------------------------------------------------------------------
-- Feature : Scarf Simple
elseif ID.IsScarfSimple( Proc) then
---------------------------------------------------------------------
-- Feature : Scarf Joint
elseif ID.IsScarfJoint( Proc) then
---------------------------------------------------------------------
-- Feature : Step Joint
elseif ID.IsStepJoint( Proc) then
---------------------------------------------------------------------
-- Feature : Step Joint Notch
elseif ID.IsStepJointNotch( Proc) then
---------------------------------------------------------------------
-- Feature : Planing
elseif ID.IsPlaning( Proc) then
---------------------------------------------------------------------
-- Feature : Front Profile
elseif ID.IsFrontProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Head Concave Profile
elseif ID.IsHeadConcaveProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Head Convex Profile
elseif ID.IsHeadConvexProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Head Cambered Profile
elseif ID.IsHeadCamberedProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Round Arch
elseif ID.IsRoundArch( Proc) then
---------------------------------------------------------------------
-- Feature : Head Profile
elseif ID.IsHeadProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Sphere
elseif ID.IsSphere( Proc) then
---------------------------------------------------------------------
-- Feature : Triangle Cut
elseif ID.IsTriangleCut( Proc) then
---------------------------------------------------------------------
-- Feature : TyroleanDovetail
elseif ID.IsTyroleanDovetail( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail
elseif ID.IsDovetail( Proc) then
---------------------------------------------------------------------
-- Feature : Free Contour
elseif ID.IsFreeContour( Proc) then
---------------------------------------------------------------------
-- Feature : Outline
elseif ID.IsOutline( Proc) then
---------------------------------------------------------------------
-- Feature : Aperture
elseif ID.IsAperture( Proc) then
---------------------------------------------------------------------
-- Feature : Variant
elseif ID.IsVariant( Proc) then
---------------------------------------------------------------------
end
return Strategies
end
----------------------------------------------------------------------------------
-- *** ESSETRE ***
----------------------------------------------------------------------------------
local function GetStrategies_Essetre( Proc)
local Strategies = {}
-- TODO tabella da compleatare man mano che si inseriscono le varie strategie
---------------------------------------------------------------------
-- Feature : Cut
if ID.IsHeadCut( Proc) then -- TODO TOGLIERE STRATEGIA. Inserita solo per mostrare come devono essere scritti i dati
if Proc.Topology.sName == 'QQQQQQQQQ' then
Strategies = {
{ sStrategyId = 'STR9999',
Parameters = {
{ sName = 'Step', sValue = '15', sType = 'd'},
{ sName = 'AntiSplint', sValue = 'false', sType = 'b'}
}
}
}
end
---------------------------------------------------------------------
-- Feature : Cut
elseif ID.IsSplitCut( Proc) then
---------------------------------------------------------------------
-- Feature : Cut
elseif ID.IsCut( Proc) then
---------------------------------------------------------------------
-- Feature : Longitudinal Cut
elseif ID.IsLongitudinalCut( Proc) then
---------------------------------------------------------------------
-- Feature : Double Cut
elseif ID.IsDoubleCut( Proc) then
---------------------------------------------------------------------
-- Feature : Ridge or Valley Cut
elseif ID.IsDoubleLongitudinalCut( Proc) then
---------------------------------------------------------------------
-- Feature : Saw Cut
elseif ID.IsSawCut( Proc) then
---------------------------------------------------------------------
-- Feature : Slot
elseif ID.IsSlot( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Front Slot
elseif ID.IsFrontSlot( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Birds Mouth
elseif ID.IsBirdsMouth( Proc) then
---------------------------------------------------------------------
-- Feature : Hip or Valley Rafter Notch
elseif ID.IsHipValleyRafterNotch( Proc) then
---------------------------------------------------------------------
-- Feature : Ridge Lap
elseif ID.IsRidgeLap( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Lap Joint
elseif ID.IsLapJoint( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Notch/Rabbet
elseif ID.IsNotchRabbet( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Block Haus
elseif ID.IsBlockHaus( Proc) then
---------------------------------------------------------------------
-- Feature : Notch
elseif ID.IsNotch( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : French Ridge Lap
elseif ID.IsFrenchRidgeLap( Proc) then
---------------------------------------------------------------------
-- Feature : Chamfer
elseif ID.IsChamfer( Proc) then
---------------------------------------------------------------------
-- Feature : Block Haus Half Lap
elseif ID.IsHalfBlockHaus( Proc) then
---------------------------------------------------------------------
-- Feature : Block Haus Front
elseif ID.IsFrontBlockHaus( Proc) then
---------------------------------------------------------------------
-- Feature : Pocket
elseif ID.IsPocket( Proc) then
if Proc.Topology.sName == 'Pocket-5-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}}
elseif Proc.Topology.sName == 'Groove-3-Blind' then
Strategies = { { sStrategyId = 'STR0002'}}
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
Strategies = { { sStrategyId = 'STR0002'}}
end
---------------------------------------------------------------------
-- Feature : Drilling
elseif ID.IsDrilling( Proc) then
---------------------------------------------------------------------
-- Feature : Tenon
elseif ID.IsTenon( Proc) then
---------------------------------------------------------------------
-- Feature : Mortise
elseif ID.IsMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Front Mortise
elseif ID.IsFrontMortise( Proc) then
---------------------------------------------------------------------
-- Feature : House
elseif ID.IsHouse( Proc) then
---------------------------------------------------------------------
-- Feature : House Mortise
elseif ID.IsHouseMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail Tenon
elseif ID.IsDovetailTenon( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail Mortise
elseif ID.IsDovetailMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail Mortise Front
elseif ID.IsFrontDovetailMortise( Proc) then
---------------------------------------------------------------------
-- Feature : Marking
elseif ID.IsMarking( Proc) then
---------------------------------------------------------------------
-- Feature : Text
elseif ID.IsText( Proc) then
---------------------------------------------------------------------
-- Feature : Scarf Simple
elseif ID.IsScarfSimple( Proc) then
---------------------------------------------------------------------
-- Feature : Scarf Joint
elseif ID.IsScarfJoint( Proc) then
---------------------------------------------------------------------
-- Feature : Step Joint
elseif ID.IsStepJoint( Proc) then
---------------------------------------------------------------------
-- Feature : Step Joint Notch
elseif ID.IsStepJointNotch( Proc) then
---------------------------------------------------------------------
-- Feature : Planing
elseif ID.IsPlaning( Proc) then
---------------------------------------------------------------------
-- Feature : Front Profile
elseif ID.IsFrontProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Head Concave Profile
elseif ID.IsHeadConcaveProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Head Convex Profile
elseif ID.IsHeadConvexProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Head Cambered Profile
elseif ID.IsHeadCamberedProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Round Arch
elseif ID.IsRoundArch( Proc) then
---------------------------------------------------------------------
-- Feature : Head Profile
elseif ID.IsHeadProfile( Proc) then
---------------------------------------------------------------------
-- Feature : Sphere
elseif ID.IsSphere( Proc) then
---------------------------------------------------------------------
-- Feature : Triangle Cut
elseif ID.IsTriangleCut( Proc) then
---------------------------------------------------------------------
-- Feature : TyroleanDovetail
elseif ID.IsTyroleanDovetail( Proc) then
---------------------------------------------------------------------
-- Feature : Dovetail
elseif ID.IsDovetail( Proc) then
---------------------------------------------------------------------
-- Feature : Free Contour
elseif ID.IsFreeContour( Proc) then
---------------------------------------------------------------------
-- Feature : Outline
elseif ID.IsOutline( Proc) then
---------------------------------------------------------------------
-- Feature : Aperture
elseif ID.IsAperture( Proc) then
---------------------------------------------------------------------
-- Feature : Variant
elseif ID.IsVariant( Proc) then
---------------------------------------------------------------------
end
return Strategies
end
----------------------------------------------------------------------------------
-- *** Esecuzione ***
----------------------------------------------------------------------------------
-- script delle strategie di base standard definito con cliente (statico e non modificabile)
-- se non esiste JSON configurazione, o se non ha trovato nessuna strategia, prova a cercare in questi script
function BasicCustomerStrategies.GetStrategiesFromBasicCustomerStrategies( Proc)
local StrategiesFromScript = {}
-- se nessuno script specifico in BeamData, si carica standard di default EGALWARE
if not BeamData.STRATEGIES_SCRIPT or BeamData.STRATEGIES_SCRIPT == 'Egalware' then
StrategiesFromScript = GetStrategies_Egalware( Proc)
-- CLIENTE : ESSETRE
elseif BeamData.STRATEGIES_SCRIPT == 'Essetre' then
StrategiesFromScript = GetStrategies_Essetre( Proc)
else
StrategiesFromScript = nil
end
return StrategiesFromScript
end
-------------------------------------------------------------------------------------------------------------
return BasicCustomerStrategies
+1020
View File
File diff suppressed because it is too large Load Diff
+355
View File
@@ -0,0 +1,355 @@
-- BeamLib.lua by Egalware s.r.l. 2024/04/02
-- Libreria globale per Travi
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
-- Tabella per definizione modulo
local BeamLib = {}
-- Include
require( 'EgtBase')
local BeamData = require( 'BeamData')
EgtOutLog( ' BeamLib started', 1)
--TODO refactoring di queste funzioni
-------------------------------------------------------------------------------------------------------------
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)
-- verifico se sostituisce un taglio di testa già presente
local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL)
while nProcId do
local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0
local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0
if ( nGrp == 1 or nGrp == 2) and nProc == 10 then
local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT)
if ptC and vtN and AreSameVectorApprox( vtN, X_AX()) and abs( ptC:getX() - b3Solid:getMax():getX()) < 10 * GEO.EPS_SMALL then
EgtSetInfo( nStmId, 'ORI', nProcId)
end
end
nProcId = EgtGetNext( nProcId)
end
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)
-- verifico se sostituisce un taglio di coda già presente
local nProcId = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PartId, 'Processings') or GDB_ID.NULL)
while nProcId do
local nGrp = EgtGetInfo( nProcId, 'GRP', 'i') or 0
local nProc = EgtGetInfo( nProcId, 'PRC', 'i') or 0
if ( nGrp == 1 or nGrp == 2) and nProc == 10 then
local ptC, vtN = EgtSurfTmFacetCenter( nProcId, 0, GDB_ID.ROOT)
if ptC and vtN and AreSameVectorApprox( vtN, -X_AX()) and abs( ptC:getX() - b3Solid:getMin():getX()) < 10 * GEO.EPS_SMALL then
EgtSetInfo( nStmId, 'ORI', nProcId)
end
end
nProcId = EgtGetNext( nProcId)
end
return true
end
-------------------------------------------------------------------------------------------------------------
function BeamLib.AddPhaseWithRawParts( Part, OriXR, PosXR, dDeltaSucc)
EgtAddPhase()
local nRawId = Part.idRaw
local dRawMove = 0
while nRawId do
EgtKeepRawPart( nRawId)
EgtMoveToCornerRawPart( nRawId, OriXR, PosXR)
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.CreateOrEmptyAddGroup( PartId)
-- recupero i dati del gruppo aggiuntivo
local AddGrpId, sMchGrp = BeamLib.GetAddGroup( PartId)
if not sMchGrp then
return false
end
-- se esiste, aggiorno riferimento al gruppo di lavoro e lo svuoto
if AddGrpId then
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
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.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
-------------------------------------------------------------------------------------------------------------
-- restituisce le facce della parte interessate dalla feature Proc
function BeamLib.GetAffectedFaces( Proc, Part)
local vtFacesAffected = { bTop = false, bBottom = false, bFront = false, bBack = false, bLeft = false, bRight = false}
if Proc.b3Box and not Proc.b3Box:isEmpty() then
if Proc.b3Box:getMax():getZ() > Part.b3Solid:getMax():getZ() - 500 * GEO.EPS_SMALL then
vtFacesAffected.bTop = true
end
if Proc.b3Box:getMin():getZ() < Part.b3Solid:getMin():getZ() + 500 * GEO.EPS_SMALL then
vtFacesAffected.bBottom = true
end
if Proc.b3Box:getMin():getY() < Part.b3Solid:getMin():getY() + 500 * GEO.EPS_SMALL then
vtFacesAffected.bFront = true
end
if Proc.b3Box:getMax():getY() > Part.b3Solid:getMax():getY() - 500 * GEO.EPS_SMALL then
vtFacesAffected.bBack = true
end
if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + 500 * GEO.EPS_SMALL then
vtFacesAffected.bLeft = true
end
if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - 500 * GEO.EPS_SMALL then
vtFacesAffected.bRight = true
end
end
return vtFacesAffected
end
---------------------------------------------------------------------
function BeamLib.GetNearestOrthoOpposite( vtRef, vtNorm)
-- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa
local vtMyRef = Vector3d( vtRef)
if vtNorm then
vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm
vtMyRef:normalize()
end
-- se prevalente una componente orizzontale (con piccolissimo vantaggio)
if abs( vtMyRef:getX()) > 0.91 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.91 * abs( vtMyRef:getZ()) then
-- se prevale la componente destra/sinistra
if abs( vtMyRef:getX()) > 0.95 * abs( vtMyRef:getY()) then
if vtMyRef:getX() > -GEO.EPS_SMALL then
return MCH_MILL_FU.ORTHO_LEFT
else
return MCH_MILL_FU.ORTHO_RIGHT
end
else
if vtMyRef:getY() > -GEO.EPS_SMALL then
return MCH_MILL_FU.ORTHO_FRONT
else
return MCH_MILL_FU.ORTHO_BACK
end
end
-- altrimenti prevale la verticale
else
if vtMyRef:getZ() > -GEO.EPS_SMALL then
return MCH_MILL_FU.ORTHO_DOWN
else
return MCH_MILL_FU.ORTHO_TOP
end
end
return nil
end
---------------------------------------------------------------------
function BeamLib.GetNearestParalOpposite( vtRef, vtNorm)
-- se definita anche la normale alla faccia, elimino la parte di vtRef parallela a questa
local vtMyRef = Vector3d( vtRef)
if vtNorm then
vtMyRef = vtMyRef - ( vtMyRef * vtNorm) * vtNorm
vtMyRef:normalize()
end
-- se prevalente una componente orizzontale (con piccolissimo vantaggio)
if abs( vtMyRef:getX()) > 0.95 * abs( vtMyRef:getZ()) or abs( vtMyRef:getY()) > 0.95 * abs( vtMyRef:getZ()) then
if abs( vtMyRef:getX()) > 0.95 * abs( vtMyRef:getY()) then
if vtMyRef:getX() > -GEO.EPS_SMALL then
return MCH_MILL_FU.PARAL_LEFT
else
return MCH_MILL_FU.PARAL_RIGHT
end
else
if vtMyRef:getY() > -GEO.EPS_SMALL then
return MCH_MILL_FU.PARAL_FRONT
else
return MCH_MILL_FU.PARAL_BACK
end
end
-- altrimenti prevale la verticale
else
if vtMyRef:getZ() > -GEO.EPS_SMALL then
return MCH_MILL_FU.PARAL_DOWN
else
return MCH_MILL_FU.PARAL_TOP
end
end
return nil
end
---------------------------------------------------------------------
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
nAddGrpId = nAddGrpId or BeamLib.GetAddGroup( Proc.idPart)
if not nAddGrpId then
local nEdges = #(EgtSurfTmFacetAdjacencies( Proc.id, idFace)[1])
return ( nEdges == 3)
end
local bResult = false
local nContourId, nContourCnt = EgtExtractSurfTmFacetLoops( Proc.id, idFace, nAddGrpId)
if not nContourId then
return false
end
EgtMergeCurvesInCurveCompo( nContourId)
-- recupero il numero effettivo di lati
local _, nEntityCount = EgtCurveDomain( nContourId)
local nEdges = nEntityCount
if nEntityCount and nEntityCount == 3 then
bResult = true
-- rimuovo i lati molto corti dal conteggio totale
elseif nEntityCount then
for i = 1, nEntityCount do
local dLength = EgtCurveCompoLength( nContourId, i - 1)
if dLength < 15 then nEdges = nEdges - 1 end
end
end
if nEdges == 3 then bResult = true end
-- cancello tutti i contorni appena creati
EgtErase( EgtTableFill( nContourId, nContourCnt))
return bResult
end
-------------------------------------------------------------------------------------------------------------
-- sovrascrivo i parametri personalizzati salvati su Proc a quelli di default dalla strategia
-- N.B. : I parametri personalizzati non più presenti tra i default della strategia, verranno ignorati. Quelli extra avranno valore di default
-- Il controllo deve essere fatto SEMPRE all'inizio di ogni strategia, per controllare conformità parametri custom
function BeamLib.GetUpdateCustomParameters( CustomStrategyParamList, DefaultStrategyParamList)
if CustomStrategyParamList and #CustomStrategyParamList > 0 then
for i = 1, #DefaultStrategyParamList do
for j = 1, #CustomStrategyParamList do
if DefaultStrategyParamList[i].sName == CustomStrategyParamList[j].sName then
DefaultStrategyParamList[i].sValue = CustomStrategyParamList[j].sValue
end
end
end
end
return DefaultStrategyParamList
end
-------------------------------------------------------------------------------------------------------------
-- si traduce la tabella dei parametri con tutte le informazioni in una lista contenente i parametri utilizzabili con accesso diretto
function BeamLib.LoadCustomParametersInStrategy( CustomParameters)
local Parameters = {}
if CustomParameters and #CustomParameters > 0 then
for i=1, #CustomParameters do
if CustomParameters[i].sType == 'b' then
Parameters[CustomParameters[i].sName] = CustomParameters[i].sValue == 'true'
elseif CustomParameters[i].Type == 'd' then
Parameters[CustomParameters[i].sName] = tonumber( CustomParameters[i].sValue)
else -- CustomParameters.Type == 's'
Parameters[CustomParameters[i].sName] = CustomParameters[i].sValue
end
end
end
return Parameters
end
---------------------------------------------------------------------
function BeamLib.GetChainSawInitAngs( vtN, vtO, nInd)
if BeamData.GetChainSawInitAngs then
return BeamData.GetChainSawInitAngs( vtN, vtO, nInd)
else
if BeamData.C_SIMM then
return EgtIf( vtN:getY() > 0, 'C=180', 'C=-180')
else
if nInd == 1 then
return ''
else
return EgtIf( vtN:getY() > 0, 'C=180', 'C=-180')
end
end
end
end
---------------------------------------------------------------------
function BeamLib.GetBlockedAxis( nToolIndex, sBlockedAxis, b3Raw, vtTool, vtOut)
-- se presente funzione specifica nella macchina, la richiamo
if BeamData.GetBlockedAxis then
return BeamData.GetBlockedAxis( TOOLS[nToolIndex].sHead, TOOLS[nToolIndex].nTypeId, sBlockedAxis, b3Raw, vtTool, vtOut) or ''
-- sezione mantenuta per retrocompatibilità con GetChainSawBlockedAxis
elseif TOOLS[nToolIndex].nTypeId == MCH_TY.MORTISE_STD then
local nInd = EgtIf( sBlockedAxis == 'parallel', 0, 1)
if BeamData.GetChainSawBlockedAxis then
return BeamData.GetChainSawBlockedAxis( nInd)
else
if nInd == 1 then
return EgtIf( BeamData.C_SIMM, 'A=90', 'A=90')
else
return EgtIf( BeamData.C_SIMM, 'A=0', 'A=0')
end
end
end
return ''
end
-------------------------------------------------------------------------------------------------------------
return BeamLib
+513
View File
@@ -0,0 +1,513 @@
-- FaceData.lua by Egalware s.r.l. 2024/04/18
-- Libreria lettura o calcolo dati e proprietà delle facce di una trimesh
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
-- Tabella per definizione modulo
local FaceData = {}
-- carico librerie
local BeamLib = require( 'BeamLib')
---------------------------------------------------------------------
-- restituisce la matrice delle adiacenze di Proc dove i e j sono le facce e a(ij) è l'angolo tra di esse; 0 se nessuna adiacenza
function FaceData.GetAdjacencyMatrix( Proc)
local vAdj = {}
-- essendo la matrice simmetrica a diagonale nulla, ne calcolo solo la metà superiore
for i = 1, Proc.nFct do
vAdj[i] = {}
for j = i + 1, Proc.nFct do
_, _, _, vAdj[i][j] = EgtSurfTmFacetsContact( Proc.id, i - 1, j - 1, GDB_ID.ROOT)
if not vAdj[i][j] then
vAdj[i][j] = 0
end
end
end
-- riempio di conseguenza il resto della matrice
for i = 1, Proc.nFct do
vAdj[i][i] = 0
for j = i + 1, Proc.nFct do
vAdj[j][i] = vAdj[i][j]
end
end
return vAdj
end
---------------------------------------------------------------------
-- restituisce un vettore con gli indici (0 based) delle facce triangolari (o quasi) di Proc
function FaceData.GetTriangularFaces( Proc)
-- se la feature ha una sola faccia, esco subito
if Proc.nFct <= 1 then
return
end
local vTriangularFaces = {}
for i = 1, Proc.nFct do
if BeamLib.Is3EdgesApprox( Proc, i - 1) then
table.insert( vTriangularFaces, i - 1)
end
end
return vTriangularFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetNotAdjacentFaces( Proc, idFace)
local NotAdjacentFaces = {}
for i = 1, Proc.nFct do
if Proc.Faces[i].id ~= idFace then
local bIsAdjacent = false
for j = 1, #Proc.Faces[idFace + 1].Adjacencies do
if Proc.Faces[i].id == Proc.Faces[idFace + 1].Adjacencies[j] then
bIsAdjacent = true
end
end
if not bIsAdjacent then
table.insert( NotAdjacentFaces, Proc.Faces[i])
end
end
end
return NotAdjacentFaces
end
---------------------------------------------------------------------
-- restituisce una tabella che correla numero di adiacenze e id delle facce con quello stesso numero di adiacenze
function FaceData.GetFacesByAdjacencyNumber( Proc)
-- se la feature ha una sola faccia, esco subito
if Proc.nFct <= 1 then
return
end
local FacesByAdjacencyNumber = {}
for i = 1, 10 do
FacesByAdjacencyNumber[i] = {}
end
for i = 1, Proc.nFct do
table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i])
end
return FacesByAdjacencyNumber
end
-------------------------------------------------------------------------------------------------------------
function FaceData.GetFacesInfo( Proc, Part)
EgtOutLog( '---Faces START---')
local Faces = {}
local vAdj
if Proc.AdjacencyMatrix then
vAdj = Proc.AdjacencyMatrix
else
vAdj = FaceData.GetAdjacencyMatrix( Proc)
end
-- reset eventuali visualizzazioni facce a due colori
EgtSurfTmResetTwoColors( Proc.id)
for i = 1, Proc.nFct do
Faces[i] = {}
Faces[i].id = i - 1
Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT)
if Proc.nFct < 6 then
-- frame OCS faccia
Faces[i].vtFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
-- elevazione calcolata rispetto al box della parte
Faces[i].dElevation = EgtSurfTmFacetElevationInBBox( Proc.id, i - 1, Part.b3Solid, true, GDB_ID.ROOT)
-- TODO qui sarebbe meglio l'area vera e non quella del rettangolo minimo
local _, dLongEdgeDimension, dShortEdgeDimension = EgtSurfTmFacetMinAreaRectangle( Proc.id, i - 1, GDB_ID.ROOT)
Faces[i].dArea = dShortEdgeDimension * dLongEdgeDimension
local nFaceType, vEdges = EgtSurfTmGetFacetOutlineInfo( Proc.id, i - 1, GDB_ID.ROOT)
Faces[i].bIsOkForMachining = nFaceType < 1
Faces[i].Edges = vEdges
-- TODO valutare se fare un output unico alla fine o gestire log in altro modo
EgtOutLog( 'Facet ' .. Faces[i].id .. ' of ' .. Proc.nFct - 1)
EgtOutLog( ' vtN: ' .. tostring( Faces[i].vtN))
-- adiacenze della faccia
-- TODO chiamarle in modo che si capisca che sono solo gli id e non l'intero oggetto faccia
Faces[i].Adjacencies = {}
for j = 1, Proc.nFct do
if vAdj[i][j] and vAdj[i][j] ~= 0 and ( i ~= j) then
table.insert( Faces[i].Adjacencies, j - 1)
if EgtGetDebugLevel() >= 3 then
EgtOutLog( ' Adjacent to facet: ' .. j - 1)
end
end
end
end
end
EgtOutLog( '---Faces END---')
return Faces
end
-------------------------------------------------------------------------------------------------------------
-- TODO valutare refactoring per mettere i calcoli del tunnel in una funzione
-- TODO creare le facce tunnel solo se non ci sono già. Verirficare all'inizio se già presente in AddGrpId e nel caso riferire all'id di quella esistente e ricalcolare solo le informazioni della faccia.
local function GetTunnelFaces( Proc, Part)
local TunnelAddedFaces = {}
if not ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5) then
error( 'GetTunnelFaces : Topology not implemented')
end
-- direzione del tunnel
local vtTunnelDirection = Proc.Faces[1].vtN ^ Proc.Faces[ Proc.Faces[1].Adjacencies[1] + 1].vtN
-- centro del tunnel
local frTunnel = Frame3d( Proc.Faces[1].ptCenter, vtTunnelDirection)
local b3Tunnel = EgtGetBBoxRef( Proc.id, GDB_BB.STANDARD, frTunnel)
local ptTunnelCenter = b3Tunnel:getCenter()
ptTunnelCenter:toGlob( frTunnel)
-- recupero gruppo per geometria addizionale
local nAddGrpId = BeamLib.GetAddGroup( Proc.idPart)
if not nAddGrpId then
-- TODO gestire meglio questo errore. Non conviene creare e verificare all'inizio se il gruppo esiste?
EgtOutLog( 'Error : missing AddGroup')
return TunnelAddedFaces
end
-- faccia centrale, si crea larga come la parte e poi si trimma
TunnelAddedFaces.MiddleFaceTm = {}
TunnelAddedFaces.MiddleFaceTm.id = EgtSurfTmPlaneInBBox( nAddGrpId, ptTunnelCenter, vtTunnelDirection, Part.b3Solid, GDB_ID.ROOT)
-- TODO se non si riesce a costruire la faccia bisogna dare errore o semplicemente non ritornarla??
for i = 1, Proc.nFct do
EgtCutSurfTmPlane( TunnelAddedFaces.MiddleFaceTm.id, Proc.Faces[i].ptCenter, -Proc.Faces[i].vtN, false, GDB_ID.ROOT)
end
-- TODO c'è un modo più elegante per raccogliere le informazioni delle facce aggiunte
TunnelAddedFaces.MiddleFaceTm.sType = 'Tunnel'
TunnelAddedFaces.MiddleFaceTm.nFct = 1
TunnelAddedFaces.MiddleFaceTm.Faces = FaceData.GetFacesInfo( TunnelAddedFaces.MiddleFaceTm, Part)
return TunnelAddedFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetBottomFaces( Proc)
local BottomFaces = {}
if Proc.Topology.sFamily == 'Tunnel' then
return nil
elseif not ( Proc.Topology.sFamily == 'Rabbet' or Proc.Topology.sFamily == 'VGroove' or Proc.Topology.sFamily == 'Groove' or Proc.Topology.sFamily == 'Pocket') then
error( 'GetBottomFace : Topology not implemented')
end
-- la faccia di fondo ha sempre Fct - 1 adiacenze
local FacesByAdjacencyNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
if FacesByAdjacencyNumber then
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct - 1]
-- si rimuovono le facce non adatte ad essere lavorate
local nBottomFaces = #BottomFaces
local nCurrentFace = 1
while nCurrentFace <= nBottomFaces do
if not BottomFaces[nCurrentFace].bIsOkForMachining then
table.remove( BottomFaces, nCurrentFace)
nBottomFaces = nBottomFaces - 1
end
nCurrentFace = nCurrentFace + 1
end
-- la BottomFace 1 è sempre quella con minor elevazione
table.sort( BottomFaces, function (a, b) return a.dElevation < b.dElevation end)
end
if #BottomFaces == 0 then
return nil
end
BottomFaces[1].sType = 'Bottom'
BottomFaces[1].MainEdges = {}
BottomFaces[1].MainEdges.LongEdges = {}
BottomFaces[1].MainEdges.SideEdges = {}
local ClosedEdgesSortedByGreatestLength = {}
for i = 1, #BottomFaces[1].Edges do
if not BottomFaces[1].Edges[i].Open then
table.insert( ClosedEdgesSortedByGreatestLength, {})
ClosedEdgesSortedByGreatestLength[#ClosedEdgesSortedByGreatestLength].nIndex = i
ClosedEdgesSortedByGreatestLength[#ClosedEdgesSortedByGreatestLength].dLength = BottomFaces[1].Edges[i].Len
end
end
table.sort( ClosedEdgesSortedByGreatestLength, function (a, b) return a.dLength > b.dLength end)
local nFirstLongEdgeIndex = ClosedEdgesSortedByGreatestLength[1].nIndex
for i = 1, #BottomFaces[1].Edges do
local nPreviousEdgeIndex = i - 1
if i == 1 then
nPreviousEdgeIndex = #BottomFaces[1].Edges
end
local nNextEdgeIndex = i + 1
if i == #BottomFaces[1].Edges then
nNextEdgeIndex = 1
end
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = BottomFaces[1].Edges[i].Adj
CurrentEdge.vtToolDirection = Vector3d( BottomFaces[1].Edges[i].Norm)
CurrentEdge.dLength = BottomFaces[1].Edges[i].Len
CurrentEdge.dElevation = BottomFaces[1].Edges[i].Elev
CurrentEdge.bIsOpen = BottomFaces[1].Edges[i].Open
CurrentEdge.bIsStartOpen = BottomFaces[1].Edges[nPreviousEdgeIndex].Open
CurrentEdge.bIsEndOpen = BottomFaces[1].Edges[nNextEdgeIndex].Open
if i == nFirstLongEdgeIndex then
BottomFaces[1].MainEdges.LongEdges[1] = CurrentEdge
BottomFaces[1].MainEdges.LongEdges[1].sType = 'Long'
elseif nNextEdgeIndex == nFirstLongEdgeIndex then
BottomFaces[1].MainEdges.SideEdges[1] = CurrentEdge
BottomFaces[1].MainEdges.SideEdges[1].sType = 'Side'
elseif nPreviousEdgeIndex == nFirstLongEdgeIndex then
BottomFaces[1].MainEdges.SideEdges[2] = CurrentEdge
BottomFaces[1].MainEdges.SideEdges[2].sType = 'Side'
else
BottomFaces[1].MainEdges.LongEdges[2] = CurrentEdge
BottomFaces[1].MainEdges.LongEdges[2].sType = 'Long'
end
end
return BottomFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetLongFaces( Proc, MainFaces)
local LongFaces = {}
if Proc.nFct > 5 then
error( 'GetLongFaces : Topology not implemented')
end
local BottomFace
local BottomFaces = MainFaces.BottomFaces or GetBottomFaces( Proc)
if BottomFaces and #BottomFaces > 0 then
BottomFace = BottomFaces[1]
end
local idFirstLongFace = GDB_ID.NULL
local idSecondLongFace = GDB_ID.NULL
if not BottomFace then
local FacesSortedByGreatestArea = {}
for i = 1, Proc.nFct do
FacesSortedByGreatestArea[i] = {}
FacesSortedByGreatestArea[i].id = Proc.Faces[i].id
FacesSortedByGreatestArea[i].dArea = Proc.Faces[i].dArea
end
table.sort( FacesSortedByGreatestArea, function (a, b) return a.dArea > b.dArea end)
idFirstLongFace = FacesSortedByGreatestArea[1].id
local FacesNotAdjacent = GetNotAdjacentFaces( Proc, idFirstLongFace)
idSecondLongFace = FacesNotAdjacent[1].id
else
if not BottomFace.MainEdges.LongEdges[1].bIsOpen then
idFirstLongFace = BottomFace.MainEdges.LongEdges[1].idAdjacentFace
end
if not BottomFace.MainEdges.LongEdges[2].bIsOpen then
idSecondLongFace = BottomFace.MainEdges.LongEdges[2].idAdjacentFace
end
end
if idFirstLongFace > -1 and Proc.Faces[idFirstLongFace + 1].bIsOkForMachining then
table.insert( LongFaces, Proc.Faces[idFirstLongFace + 1])
end
if idSecondLongFace > -1 and Proc.Faces[idSecondLongFace + 1].bIsOkForMachining then
table.insert( LongFaces, Proc.Faces[idSecondLongFace + 1])
end
for i = 1, #LongFaces do
LongFaces[i].sType = 'Long'
LongFaces[i].MainEdges = {}
LongFaces[i].MainEdges.SideEdges = {}
LongFaces[i].MainEdges.OppositeEdges = {}
for j = 1, #LongFaces[i].Edges do
local nPreviousEdgeIndex = j - 1
if j == 1 then
nPreviousEdgeIndex = #LongFaces[1].Edges
end
local nNextEdgeIndex = j + 1
if j == #LongFaces[i].Edges then
nNextEdgeIndex = 1
end
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = LongFaces[i].Edges[j].Adj
CurrentEdge.vtToolDirection = Vector3d( LongFaces[i].Edges[j].Norm)
CurrentEdge.dLength = LongFaces[i].Edges[j].Len
CurrentEdge.dElevation = LongFaces[i].Edges[j].Elev
CurrentEdge.bIsOpen = LongFaces[i].Edges[j].Open
CurrentEdge.bIsStartOpen = LongFaces[i].Edges[nPreviousEdgeIndex].Open
CurrentEdge.bIsEndOpen = LongFaces[i].Edges[nNextEdgeIndex].Open
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
table.insert( LongFaces[i].MainEdges.SideEdges, CurrentEdge)
LongFaces[i].MainEdges.SideEdges[#LongFaces[i].MainEdges.SideEdges].sType = 'Side'
else
table.insert( LongFaces[i].MainEdges.OppositeEdges, CurrentEdge)
LongFaces[i].MainEdges.OppositeEdges[#LongFaces[i].MainEdges.OppositeEdges].sType = 'Opposite'
end
else
if CurrentEdge.idAdjacentFace == BottomFace.id then
LongFaces[i].MainEdges.BottomEdge = CurrentEdge
LongFaces[i].MainEdges.BottomEdge.sType = 'Bottom'
elseif LongFaces[i].Edges[nNextEdgeIndex].Adj == BottomFace.id then
LongFaces[i].MainEdges.SideEdges[1] = CurrentEdge
LongFaces[i].MainEdges.SideEdges[1].sType = 'Side'
elseif LongFaces[i].Edges[nPreviousEdgeIndex].Adj == BottomFace.id then
LongFaces[i].MainEdges.SideEdges[2] = CurrentEdge
LongFaces[i].MainEdges.SideEdges[2].sType = 'Side'
else
table.insert( LongFaces[i].MainEdges.OppositeEdges, CurrentEdge)
LongFaces[i].MainEdges.OppositeEdges[#LongFaces[i].MainEdges.OppositeEdges].sType = 'Opposite'
end
end
end
end
return LongFaces
end
-------------------------------------------------------------------------------------------------------------
local function GetSideFaces( Proc, MainFaces)
local SideFaces = {}
if Proc.nFct > 5 then
error( 'GetSideFaces : Topology not implemented')
end
local BottomFace
local BottomFaces = MainFaces.BottomFaces or GetBottomFaces( Proc)
if BottomFaces and #BottomFaces > 0 then
BottomFace = BottomFaces[1]
end
local LongFaces = MainFaces.LongFaces or GetLongFaces( Proc, MainFaces)
local idFirstSideFace = GDB_ID.NULL
local idSecondSideFace = GDB_ID.NULL
if not LongFaces[1].MainEdges.SideEdges[1].bIsOpen then
idFirstSideFace = LongFaces[1].MainEdges.SideEdges[1].idAdjacentFace
end
if not LongFaces[1].MainEdges.SideEdges[2].bIsOpen then
idSecondSideFace = LongFaces[1].MainEdges.SideEdges[2].idAdjacentFace
end
if idFirstSideFace > -1 and Proc.Faces[idFirstSideFace + 1].bIsOkForMachining then
table.insert( SideFaces, Proc.Faces[idFirstSideFace + 1])
SideFaces[#SideFaces].sType = 'Side'
end
if idSecondSideFace > -1 and Proc.Faces[idSecondSideFace + 1].bIsOkForMachining then
table.insert( SideFaces, Proc.Faces[idSecondSideFace + 1])
SideFaces[#SideFaces].sType = 'Side'
end
for i = 1, #SideFaces do
SideFaces[i].sType = 'Side'
SideFaces[i].MainEdges = {}
SideFaces[i].MainEdges.LongEdges = {}
SideFaces[i].MainEdges.OppositeEdges = {}
for j = 1, #SideFaces[i].Edges do
local nPreviousEdgeIndex = j - 1
if j == 1 then
nPreviousEdgeIndex = #SideFaces[1].Edges
end
local nNextEdgeIndex = j + 1
if j == #SideFaces[i].Edges then
nNextEdgeIndex = 1
end
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = SideFaces[i].Edges[j].Adj
CurrentEdge.vtToolDirection = Vector3d( SideFaces[i].Edges[j].Norm)
CurrentEdge.dLength = SideFaces[i].Edges[j].Len
CurrentEdge.dElevation = SideFaces[i].Edges[j].Elev
CurrentEdge.bIsOpen = SideFaces[i].Edges[j].Open
CurrentEdge.bIsStartOpen = SideFaces[i].Edges[nPreviousEdgeIndex].Open
CurrentEdge.bIsEndOpen = SideFaces[i].Edges[nNextEdgeIndex].Open
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
table.insert( SideFaces[i].MainEdges.LongEdges, CurrentEdge)
else
table.insert( SideFaces[i].MainEdges.OppositeEdges, CurrentEdge)
end
else
if CurrentEdge.idAdjacentFace == BottomFace.id then
SideFaces[i].MainEdges.BottomEdge = CurrentEdge
SideFaces[i].MainEdges.BottomEdge.sType = 'Bottom'
elseif SideFaces[i].Edges[nNextEdgeIndex].Adj == BottomFace.id then
SideFaces[i].MainEdges.LongEdges[1] = CurrentEdge
SideFaces[i].MainEdges.LongEdges[1].sType = 'Long'
elseif SideFaces[i].Edges[nPreviousEdgeIndex].Adj == BottomFace.id then
SideFaces[i].MainEdges.LongEdges[2] = CurrentEdge
SideFaces[i].MainEdges.LongEdges[2].sType = 'Long'
else
table.insert( SideFaces[i].MainEdges.OppositeEdges, CurrentEdge)
SideFaces[i].MainEdges.OppositeEdges[#SideFaces[i].MainEdges.OppositeEdges].sType = 'Opposite'
end
end
end
end
return SideFaces
end
-------------------------------------------------------------------------------------------------------------
-- recupero facce principali della feature, in base alla topologia
function FaceData.GetMainFaces( Proc, Part)
EgtOutLog( '---MainFaces START---')
local MainFaces = {}
-- CASO 1 : Feature tipo LapJoint
if Proc.Topology.sFamily == 'Rabbet' or Proc.Topology.sFamily == 'VGroove' or Proc.Topology.sFamily == 'Groove' or Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' then
if Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5 then
MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc, Part)
end
MainFaces.BottomFaces = GetBottomFaces( Proc)
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
-- TODO funzione apposita per informazioni log?
if EgtGetDebugLevel() >= 3 then
if MainFaces.BottomFaces then
for i = 1, #MainFaces.BottomFaces do
EgtOutLog( 'Bottom Face : ' .. MainFaces.BottomFaces[i].id)
end
-- colore differente per la faccia di fondo principale
EgtSurfTmSetFaceColor( Proc.id, MainFaces.BottomFaces[1].id, 1)
end
if MainFaces.LongFaces then
for i = 1, #MainFaces.LongFaces do
EgtOutLog( 'Long Face : ' .. MainFaces.LongFaces[i].id)
end
end
if MainFaces.SideFaces then
for i = 1, #MainFaces.SideFaces do
EgtOutLog( 'Side Face : ' .. MainFaces.SideFaces[i].id)
end
end
if MainFaces.TunnelAddedFaces then
EgtOutLog( 'Middle Face (Trimesh): ' .. MainFaces.TunnelAddedFaces.MiddleFaceTm.id)
end
end
else
EgtOutLog( '---MainFaces NOT NEEDED---')
end
EgtOutLog( '---MainFaces END---')
return MainFaces
end
-------------------------------------------------------------------------------------------------------------
return FaceData
+282
View File
@@ -0,0 +1,282 @@
-- FeatureData.lua by Egalware s.r.l. 2024/04/02
-- Libreria lettura o calcolo dati e proprietà della feature
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
-- Tabella per definizione modulo
local FeatureData = {}
-- Carico i dati globali
local BeamData = require( 'BeamData')
-- carico librerie
local BeamLib = require( 'BeamLib')
local FaceData = require( 'FaceData')
local ID = require( 'Identity')
-------------------------------------------------------------------------------------------------------------
-- recupero topologia della feature
function FeatureData.NeedTopologyFeature( Proc)
-- features tipo taglio
if ID.IsCut( Proc) then
return true
elseif ID.IsDoubleCut( Proc) then
return true
elseif ID.IsSawCut( Proc) then
return true
-- features tipo taglio longitudinale
elseif ID.IsLongitudinalCut( Proc) then
return true
elseif ID.IsDoubleLongitudinalCut( Proc) then
return true
elseif ID.IsChamfer( Proc) then
return true
-- features tipo LapJoint
elseif ID.IsSlot( Proc) then
return true
elseif ID.IsFrontSlot( Proc) then
return true
elseif ID.IsRidgeLap( Proc) then
return true
elseif ID.IsLapJoint( Proc) then
return true
elseif ID.IsNotchRabbet( Proc) then
return true
elseif ID.IsNotch( Proc) then
return true
elseif ID.IsPocket( Proc) then
return true
-- calcolo topologia SOLO se non raggiata
-- TODO oppure riconoscerla come feature speciale; valutare se controllare il numero di facce è un metodo efficace
elseif ID.IsMortise( Proc) and Proc.nFct < 6 then
return true
-- calcolo topologia SOLO se non raggiata
-- TODO oppure riconoscerla come feature speciale; valutare se controllare il numero di facce è un metodo efficace
elseif ID.IsFrontMortise( Proc) and Proc.nFct < 6 then
return true
end
-- se feature non tra quelle sopra, riconoscimento topologico non necessario
return false
end
---------------------------------------------------------------------
-- restituisce true se Proc ha tutti gli angoli concavi (bAllConcave) e, nei casi in cui ha senso, se questi sono esattamente 90 deg (bAllRight)
local function AreAllAnglesConcaveOrRight( vAdj)
-- se la feature ha una sola faccia, esco subito
if #vAdj <= 1 then
return
end
local bAllConcave, bAllRight = true, true
local nFct = #( vAdj or {})
for i = 1, nFct do
for j = 1, nFct do
-- se trovo un angolo convesso restituisco falso e esco subito
if vAdj[i][j] and vAdj[i][j] > 0 then
bAllConcave = false
bAllRight = false
break
elseif vAdj[i][j] and vAdj[i][j] ~= 0 and vAdj[i][j] + 90 > 500 * GEO.EPS_ANG_SMALL then
bAllRight = false
end
end
end
-- se 1 faccia oppure 2 facce con angolo convesso non ha senso ritornare valori per bAllRight
if nFct < 2 or ( nFct == 2 and vAdj[1][2] > 0) then
return bAllConcave
else
return bAllConcave, bAllRight
end
end
---------------------------------------------------------------------
-- restituisce true se almeno una delle dimensioni della feature è maggiore o uguale ad una delle dimensioni principali del pezzo (tolleranza 1 mm)
local function IsAnyDimensionLongAsPart( Proc)
local bResult = false
local nBoxSolidId = EgtGetFirstNameInGroup( Proc.idPart or GDB_ID.NULL, 'Box')
local b3Solid = EgtGetBBoxGlob( nBoxSolidId, GDB_BB.STANDARD)
if Proc.b3Box:getDimX() > b3Solid:getDimX() - 1000 * GEO.EPS_SMALL or
Proc.b3Box:getDimY() > b3Solid:getDimY() - 1000 * GEO.EPS_SMALL or
Proc.b3Box:getDimZ() > b3Solid:getDimZ() - 1000 * GEO.EPS_SMALL then
bResult = true
end
return bResult
end
-------------------------------------------------------------------------------------------------------------
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra, rappresentata dalle sue dimensioni W e H
local function IsFeatureCuttingEntireSection( b3Proc, Part)
return ( b3Proc:getDimY() > ( Part.b3Raw:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Raw:getDimZ() - 500 * GEO.EPS_SMALL))
end
-------------------------------------------------------------------------------------------------------------
-- restituisce vero se la feature con box b3Proc taglia l'intera lunghezza della barra, rappresentata dalle sue dimensioni W e L oppure H e L
local function IsFeatureCuttingEntireLength( b3Proc, Part)
return ( ( b3Proc:getDimY() > ( Part.b3Raw:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimX() > ( Part.b3Raw:getDimX() - 500 * GEO.EPS_SMALL)) or
( b3Proc:getDimZ() > ( Part.b3Raw:getDimZ() - 500 * GEO.EPS_SMALL) and b3Proc:getDimX() > ( Part.b3Raw:getDimX() - 500 * GEO.EPS_SMALL)))
end
---------------------------------------------------------------------
-- restituisce una stringa con il nome esteso della topologia della feature
-- *famiglia - numero di facce - passante*
local function GetTopologyName( sFamily, nNumberOfFaces, bIsThrough)
return sFamily .. '-' .. tostring( nNumberOfFaces) .. '-' .. EgtIf( bIsThrough, 'Through', 'Blind')
end
---------------------------------------------------------------------
-- recupera topologia feature
function FeatureData.ClassifyTopology( Proc, Part)
local FeatureTopology = {}
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part)
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc)
local vAdj = Proc.AdjacencyMatrix
local bAllAnglesConcave, bAllRightAngles = AreAllAnglesConcaveOrRight( vAdj)
local vTriangularFaces = FaceData.GetTriangularFaces( Proc)
local vFacesByAdjNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
local sFamily
local bIsThrough
if Proc.nFct == 1 and ( bIsFeatureCuttingEntireSection or bIsFeatureCuttingEntireLength) then
sFamily = 'Cut'
bIsThrough = true
elseif Proc.nFct == 1 then
sFamily = 'Bevel'
bIsThrough = true
elseif Proc.nFct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then
sFamily = 'Bevel'
bIsThrough = false
elseif Proc.nFct == 2 and bAllAnglesConcave and ( Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight) and ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) then
sFamily = 'Rabbet'
bIsThrough = true
elseif Proc.nFct == 2 and bAllAnglesConcave then
sFamily = 'VGroove'
bIsThrough = true
elseif Proc.nFct == 2 and not bAllAnglesConcave and bIsAnyDimensionLongAsPart then
sFamily = 'DoubleBevel'
bIsThrough = true
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and #vTriangularFaces == 2 then
sFamily = 'Bevel'
bIsThrough = false
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and bIsAnyDimensionLongAsPart then
sFamily = 'Groove'
bIsThrough = true
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 3 then
sFamily = 'Groove'
bIsThrough = false
elseif Proc.nFct == 4 and #vFacesByAdjNumber[2] == 4 and #vTriangularFaces == 2 then
sFamily = 'DoubleBevel'
bIsThrough = false
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then
sFamily = 'Groove'
bIsThrough = false
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 4 and bIsAnyDimensionLongAsPart then
sFamily = 'Tunnel'
bIsThrough = true
elseif Proc.nFct >= 4 and #vFacesByAdjNumber[1] == 2 and bIsAnyDimensionLongAsPart then
sFamily = 'Strip'
bIsThrough = true
elseif Proc.nFct == 5 and bAllAnglesConcave and #vFacesByAdjNumber[4] == 1 then
sFamily = 'Pocket'
bIsThrough = false
elseif Proc.nFct == 6 and #vFacesByAdjNumber[2] == 4 and #vFacesByAdjNumber[3] == 2 and #vTriangularFaces == 4 then
sFamily = 'DoubleBevel'
bIsThrough = false
end
if sFamily then
FeatureTopology.sFamily = sFamily
FeatureTopology.bIsThrough = bIsThrough
FeatureTopology.bAllRightAngles = bAllRightAngles
FeatureTopology.sName = GetTopologyName( sFamily, Proc.nFct, bIsThrough)
FeatureTopology.AdjacencyMatrix = vAdj
-- feature che necessita di essere catalogata, ma non si capisce come
else
FeatureTopology.sFamily = 'NOT_IMPLEMENTED'
FeatureTopology.sName = FeatureTopology.sFamily
end
return FeatureTopology
end
-------------------------------------------------------------------------------------------------------------
-- Recupero dati foro e adattamento se speciale
function FeatureData.GetDrillingData( Proc)
local AuxId = EgtGetInfo( Proc.id, 'AUXID', 'i')
-- verifico se foro da adattare
if EgtExistsInfo( Proc.id, 'DiamUser') then
if AuxId then AuxId = AuxId + Proc.id end
if AuxId and EgtGetType( AuxId) == GDB_TY.CRV_ARC and BeamData.USER_HOLE_DIAM and BeamData.USER_HOLE_DIAM > 1 then
EgtModifyArcRadius( AuxId, BeamData.USER_HOLE_DIAM / 2)
end
end
local dDiam = EgtGetInfo( Proc.id, 'P12', 'd') or 0
local dLen = abs( EgtCurveThickness( Proc.id + AuxId)) or 0
local nFcs = EgtGetInfo( Proc.id, 'FCS', 'i') or 0
local nFce = EgtGetInfo( Proc.id, 'FCE', 'i') or 0
return dDiam, dLen, nFcs, nFce
end
-------------------------------------------------------------------------------------------------------------
-- funzione che restituisce indice di completamento in base alla percentuale di volume lavorato
function FeatureData.GetFeatureCompletionIndex( dCompletionPercentage)
-- indice di completamento
local nCompletionIndex = 0
-- nullo
if dCompletionPercentage < 5 then
nCompletionIndex = 0
-- Low
elseif dCompletionPercentage < 50 then
nCompletionIndex = 1
-- Medium
elseif dCompletionPercentage < 80 then
nCompletionIndex = 2
-- High / Complete
else
nCompletionIndex = 5
end
return nCompletionIndex
end
-------------------------------------------------------------------------------------------------------------
-- funzione che restituisce qualità della lavorazione in base agli utensili utilizzati
function FeatureData.GetFeatureQuality( sTypeTools)
local nQuality = 5
local TypeTools = EgtSplitString( sTypeTools)
-- indice in base a utensile
for i=1, #TypeTools do
if TypeTools[i] == 'Blade' then
nQuality = min( nQuality, 5)
elseif TypeTools[i] == 'Mill' then
nQuality = min( nQuality, 4)
elseif TypeTools[i] == 'Chainsaw' then
nQuality = min( nQuality, 2)
else
nQuality = min( nQuality, 1)
end
end
-- se si utilizzano più utensili si perde in qualità
if #TypeTools > 1 then
nQuality = nQuality - 1
end
return nQuality
end
-------------------------------------------------------------------------------------------------------------
return FeatureData
+275
View File
@@ -0,0 +1,275 @@
-- Identity.lua by Egalware s.r.l. 2024/04/02
-- Libreria Riconoscimento della feature
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
-- Tabella per definizione modulo
local Identity = {}
---------------------------------------------------------------------
------------------------ EGALWARE FEATURES ------------------------
---------------------------------------------------------------------
-- Feature : Head Cut
function Identity.IsHeadCut( Proc)
return ( Proc.nGrp == 1 and Proc.nPrc == 340)
end
---------------------------------------------------------------------
-- Feature : Split Cut
function Identity.IsSplitCut( Proc)
return ( Proc.nGrp == 2 and Proc.nPrc == 350)
end
---------------------------------------------------------------------
------------------------ STANDARD FEATURES ------------------------
---------------------------------------------------------------------
-- Feature : Cut
function Identity.IsCut( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 10)
end
---------------------------------------------------------------------
-- Feature : Longitudinal Cut
function Identity.IsLongitudinalCut( Proc)
return (( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 10)
end
---------------------------------------------------------------------
-- Feature : Double Cut
function Identity.IsDoubleCut( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 11)
end
---------------------------------------------------------------------
-- Feature : Ridge or Valley Cut
function Identity.IsDoubleLongitudinalCut( Proc)
return ( Proc.nGrp == 0 and Proc.nPrc == 12)
end
---------------------------------------------------------------------
-- Feature : Saw Cut
function Identity.IsSawCut( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 13)
end
---------------------------------------------------------------------
-- Feature : Slot
function Identity.IsSlot( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 16)
end
---------------------------------------------------------------------
-- Feature : Front Slot
function Identity.IsFrontSlot( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 17)
end
---------------------------------------------------------------------
-- Feature : Birds Mouth
function Identity.IsBirdsMouth( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 20)
end
---------------------------------------------------------------------
-- Feature : Hip or Valley Rafter Notch
function Identity.IsHipValleyRafterNotch( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 25)
end
---------------------------------------------------------------------
-- Feature : Ridge Lap
function Identity.IsRidgeLap( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 30)
end
---------------------------------------------------------------------
-- Feature : Lap Joint
function Identity.IsLapJoint( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 30)
end
---------------------------------------------------------------------
-- Feature : Notch/Rabbet
function Identity.IsNotchRabbet( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 32)
end
---------------------------------------------------------------------
-- Feature : Block Haus
function Identity.IsBlockHaus( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 33)
end
---------------------------------------------------------------------
-- Feature : Notch
function Identity.IsNotch( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 34)
end
---------------------------------------------------------------------
-- Feature : French Ridge Lap
function Identity.IsFrenchRidgeLap( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 35)
end
---------------------------------------------------------------------
-- Feature : Chamfer
function Identity.IsChamfer( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 36)
end
---------------------------------------------------------------------
-- Feature : Block Haus Half Lap
function Identity.IsHalfBlockHaus( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 37)
end
---------------------------------------------------------------------
-- Feature : Block Haus Front
function Identity.IsFrontBlockHaus( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 38)
end
---------------------------------------------------------------------
-- Feature : Pocket
function Identity.IsPocket( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 39)
end
---------------------------------------------------------------------
-- Feature : Drilling
function Identity.IsDrilling( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 40)
end
---------------------------------------------------------------------
-- Feature : Tenon
function Identity.IsTenon( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 50)
end
---------------------------------------------------------------------
-- Feature : Mortise
function Identity.IsMortise( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 50)
end
---------------------------------------------------------------------
-- Feature : Front Mortise
function Identity.IsFrontMortise( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 51)
end
---------------------------------------------------------------------
-- Feature : House
function Identity.IsHouse( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 52)
end
---------------------------------------------------------------------
-- Feature : House Mortise
function Identity.IsHouseMortise( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 53)
end
---------------------------------------------------------------------
-- Feature : Dovetail Tenon
function Identity.IsDovetailTenon( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 55)
end
---------------------------------------------------------------------
-- Feature : Dovetail Mortise
function Identity.IsDovetailMortise( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 55)
end
---------------------------------------------------------------------
-- Feature : Dovetail Mortise Front
function Identity.IsFrontDovetailMortise( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 56)
end
---------------------------------------------------------------------
-- Feature : Marking
function Identity.IsMarking( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 60)
end
---------------------------------------------------------------------
-- Feature : Text
function Identity.IsText( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 61)
end
---------------------------------------------------------------------
-- Feature : Scarf Simple
function Identity.IsScarfSimple( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 70)
end
---------------------------------------------------------------------
-- Feature : Scarf Joint
function Identity.IsScarfJoint( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 71)
end
---------------------------------------------------------------------
-- Feature : Step Joint
function Identity.IsStepJoint( Proc)
return ( ( Proc.nGrp == 1 or Proc.nGrp == 2) and Proc.nPrc == 80)
end
---------------------------------------------------------------------
-- Feature : Step Joint Notch
function Identity.IsStepJointNotch( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 80)
end
---------------------------------------------------------------------
-- Feature : Planing
function Identity.IsPlaning( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 90)
end
---------------------------------------------------------------------
-- Feature : Front Profile
function Identity.IsFrontProfile( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 100)
end
---------------------------------------------------------------------
-- Feature : Head Concave Profile
function Identity.IsHeadConcaveProfile( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 101)
end
---------------------------------------------------------------------
-- Feature : Head Convex Profile
function Identity.IsHeadConvexProfile( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 102)
end
---------------------------------------------------------------------
-- Feature : Head Cambered Profile
function Identity.IsHeadCamberedProfile( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 103)
end
---------------------------------------------------------------------
-- Feature : Round Arch
function Identity.IsRoundArch( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 104)
end
---------------------------------------------------------------------
-- Feature : Head Profile
function Identity.IsHeadProfile( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 106)
end
---------------------------------------------------------------------
-- Feature : Sphere
function Identity.IsSphere( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 107)
end
---------------------------------------------------------------------
-- Feature : Triangle Cut
function Identity.IsTriangleCut( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 120)
end
---------------------------------------------------------------------
-- Feature : TyroleanDovetail
function Identity.IsTyroleanDovetail( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 1 or Proc.nGrp == 2 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 136)
end
---------------------------------------------------------------------
-- Feature : Dovetail
function Identity.IsDovetail( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 1 or Proc.nGrp == 2 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 138)
end
---------------------------------------------------------------------
-- Feature : Free Contour
function Identity.IsFreeContour( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 250)
end
---------------------------------------------------------------------
-- Feature : Outline
function Identity.IsOutline( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 251)
end
---------------------------------------------------------------------
-- Feature : Aperture
function Identity.IsAperture( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 252)
end
---------------------------------------------------------------------
-- Feature : Variant
function Identity.IsVariant( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 1 or Proc.nGrp == 2 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 900)
end
---------------------------------------------------------------------
-- Feature Decor
function Identity.IsDecor( Proc)
return ( ( Proc.nGrp == 0 or Proc.nGrp == 3 or Proc.nGrp == 4) and Proc.nPrc == 959)
end
---------------------------------------------------------------------
return Identity
+548
View File
@@ -0,0 +1,548 @@
-- MachiningLib.lua by Egalware s.r.l. 2024/04/02
-- Libreria ricerca lavorazioni per Travi
-- 2024/04/02 PRIMA VERSIONE CALCOLO LAVORAZIONI CON STRATEGIE
-- Tabella per definizione modulo
local MachiningLib = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local BeamData = require( 'BeamData')
EgtOutLog( ' MachiningLib started', 1)
---------------------------------------------------------------------
-- TODO da considerare solo angolo 2D??
local function GetToolEntryAngle( Proc, vtTool)
local Angle = {}
local dSinAngle = -10 * GEO.EPS_SMALL
local vtNorm
if Proc.AffectedFaces.bTop then
vtNorm = Z_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bBottom then
vtNorm = -Z_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bFront then
vtNorm = -Y_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bBack then
vtNorm = Y_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bLeft then
vtNorm = -X_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
if Proc.AffectedFaces.bRight then
vtNorm = X_AX()
dSinAngle = max( dSinAngle, vtTool * vtNorm)
end
local dCosAngle = sqrt( 1 - sqr( dSinAngle))
local dAngle = acos( dCosAngle)
local dTanAngle
if dAngle ~= 0 and dAngle ~= 90 then
dTanAngle = sqrt( 1 - dCosAngle * dCosAngle) / dCosAngle
end
Angle.dValue = dAngle
Angle.dSin = dSinAngle
Angle.dCos = dCosAngle
Angle.dTan = dTanAngle
return Angle
end
-------------------------------------------------------------------------------------------------------------
function MachiningLib.GetMachiningSteps( dMachiningDepth, dStep)
local MachiningSteps = {}
MachiningSteps.dStep = 0
MachiningSteps.nCount = ceil( ( dMachiningDepth - 10 * GEO.EPS_SMALL) / dStep)
if MachiningSteps.nCount > 1 then
MachiningSteps.dStep = ( dMachiningDepth - dStep) / ( MachiningSteps.nCount - 1)
end
return MachiningSteps
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo FRESA con certe caratteristiche
function MachiningLib.FindMill( Proc, ToolSearchParameters)
local ToolInfo = {}
local nBestToolIndex
local dBestToolResidualDepth = 0
for i = 1, #TOOLS do
-- prima verifico che utensile sia compatibile
local bIsToolCompatible = true
-- se viene passato il nome, tutti gli altri sono incompatibili
if ToolSearchParameters.sName and ToolSearchParameters.sName ~= TOOLS[i].sName then
bIsToolCompatible = false
-- si cercano solo frese standard. Se utensile disegnato manualmente, si setta subito che è incompatibile
elseif TOOLS[i].bIsProfiledTool then
bIsToolCompatible = false
-- controlli standard
elseif TOOLS[i].dDiameter > ToolSearchParameters.dMaxToolDiameter then
bIsToolCompatible = false
elseif TOOLS[i].SetupInfo.bIsTopHead and ToolSearchParameters.vtToolDirection:getZ() < TOOLS[i].SetupInfo.dMaxNegativeAngle then
bIsToolCompatible = false
elseif TOOLS[i].SetupInfo.bIsBottomHead and ToolSearchParameters.vtToolDirection:getZ() > TOOLS[i].SetupInfo.dMaxPositiveAngle then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape == 'STANDARD' and ( TOOLS[i].dSideAngle ~= 0 or TOOLS[i].bIsPen) then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape == 'DOVETAIL' and not TOOLS[i].bIsDoveTail then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape == 'TSHAPEMILL' and not TOOLS[i].bIsTMill then
bIsToolCompatible = false
elseif ToolSearchParameters.sMillShape == 'PEN' and not TOOLS[i].bIsPen then
bIsToolCompatible = false
elseif TOOLS[i].sType ~= ToolSearchParameters.sType then
-- se sto cercando una fresa che non può lavorare di testa, quelle che lavorano di testa sono comunque ammesse
if TOOLS[i].sType == 'MILL_STD' and ToolSearchParameters.sType == 'MILL_NOTIP' then
bIsToolCompatible = true
else
bIsToolCompatible = false
end
end
-- scelgo il migliore
if bIsToolCompatible then
-- calcolo riduzione del massimo materiale utilizzabile
local ToolEntryAngle = GetToolEntryAngle( Proc, ToolSearchParameters.vtToolDirection)
-- se ToolHolder più grande dell'utensile, il primo oggetto in collisione è il ToolHolder. Altrimenti il motore.
local dDimObjToCheck = EgtIf( TOOLS[i].ToolHolder.dDiameter > TOOLS[i].dDiameter, TOOLS[i].ToolHolder.dDiameter, BeamData.C_SIMM_ENC)
local dCurrentMaxMatReduction = BeamData.COLL_SIC or 5
-- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom)
-- TODO considerare anche il caso in cui lo stelo sia più grande del diametro utensile
-- TODO nei confronti tra valori gestire tolleranze
-- calcolo riduzione per non toccare con ToolHolder / Motore
if ToolEntryAngle.dValue > 0 and ToolEntryAngle.dValue < 90 then
dCurrentMaxMatReduction = dCurrentMaxMatReduction / ToolEntryAngle.dSin + ( ( dDimObjToCheck - TOOLS[i].dDiameter) / 2) / ToolEntryAngle.dTan
end
-- dCurrMachReduction = negativo -> limitare, positivo -> mm extra disponibili
local dCurrentResidualDepth = ToolSearchParameters.dElevation + dCurrentMaxMatReduction - TOOLS[i].dMaxDepth
-- se non ancora trovato, oppure se completo e il migliore fino ad ora non è completo: corrente è il migliore
if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 0) then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
-- altrimenti scelgo il migliore
else
-- se entrambi completi
if dBestToolResidualDepth <= 0 and dCurrentResidualDepth <= 0 then
-- se il migliore era su aggregato e corrente montanto direttamente, prediligo utensile montato direttamente
if not TOOLS[i].SetupInfo.bToolOnAggregate and TOOLS[i].SetupInfo.bToolOnAggregate then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
-- se hanno stesso montaggio
elseif TOOLS[i].SetupInfo.bToolOnAggregate == TOOLS[nBestToolIndex].SetupInfo.bToolOnAggregate then
-- scelgo utensile con indice di bontà utensile calcolato come: lunghezza / massimo materiale / diametro
if ( TOOLS[i].dLength / TOOLS[i].dMaxMaterial) / TOOLS[i].dDiameter < ( TOOLS[nBestToolIndex].dLength / TOOLS[nBestToolIndex].dMaxMaterial) / TOOLS[nBestToolIndex].dDiameter then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
end
-- se entrambi incompleti
elseif dBestToolResidualDepth > 0 and dCurrentResidualDepth > 0 then
--scelgo quello che lavora di più
if dCurrentResidualDepth < dBestToolResidualDepth then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
end
end
end
end
ToolInfo.nToolIndex = nBestToolIndex
ToolInfo.dResidualDepth = dBestToolResidualDepth
return ToolInfo
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo LAMA con certe caratteristiche
-- TODO da completare
function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local ToolInfo = {}
-- parametri obbligatori
if type( ToolSearchParameters.vtToolDirection) ~= 'table' then
error( 'FindBlade : missing tool direction')
end
if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then
error( 'FindBlade : missing top head info')
end
if type( ToolSearchParameters.bAllowBottomHead) ~= 'boolean' then
error( 'FindBlade : missing bottom head info')
end
if not ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
error( 'FindBlade : wrong head info')
end
-- parametri opzionali
ToolSearchParameters.dElevation = ToolSearchParameters.dElevation or 0
ToolSearchParameters.bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false
local nBestToolIndex
for i = 1, #TOOLS do
local bIsToolCompatible = false
if TOOLS[i].sFamily == 'SAWBLADE' then
if ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsTopHead
elseif ToolSearchParameters.bAllowBottomHead and not ToolSearchParameters.bAllowTopHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsBottomHead
end
end
if bIsToolCompatible then
nBestToolIndex = i
break
end
end
ToolInfo.nToolIndex = nBestToolIndex
return ToolInfo
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo PUNTA A FORARE con certe caratteristiche
-- TODO da fare
function MachiningLib.FindDrill()
end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo SEGA A CATENA con certe caratteristiche
-- TODO da completare
function MachiningLib.FindChainSaw( Proc, ToolSearchParameters)
local ToolInfo = {}
-- parametri obbligatori
if type( ToolSearchParameters.vtToolDirection) ~= 'table' then
error( 'FindBlade : missing tool direction')
end
if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then
error( 'FindBlade : missing top head info')
end
if type( ToolSearchParameters.bAllowBottomHead) ~= 'boolean' then
error( 'FindBlade : missing bottom head info')
end
if not ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
error( 'FindBlade : wrong head info')
end
-- parametri opzionali
ToolSearchParameters.dElevation = ToolSearchParameters.dElevation or 0
ToolSearchParameters.bExtendWithCornerRadius = ToolSearchParameters.bExtendWithCornerRadius or false
local nBestToolIndex
local dBestToolResidualDepth = 0
for i = 1, #TOOLS do
local bIsToolCompatible = false
if TOOLS[i].sFamily == 'MORTISE' then
if ToolSearchParameters.bAllowTopHead and not ToolSearchParameters.bAllowBottomHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsTopHead
elseif ToolSearchParameters.bAllowBottomHead and not ToolSearchParameters.bAllowTopHead then
bIsToolCompatible = TOOLS[i].SetupInfo.bIsBottomHead
else
bIsToolCompatible = true
end
end
-- TODO nei confronti tra valori gestire tolleranze
if bIsToolCompatible then
if ToolSearchParameters.dElevation > 10 * GEO.EPS_SMALL and ToolSearchParameters.bExtendWithCornerRadius then
ToolSearchParameters.dElevation = ToolSearchParameters.dElevation + TOOLS[i].dCornerRadius
end
-- TODO gestire accorciamento massimo materiale per inclinazione
local dCurrentResidualDepth = ToolSearchParameters.dElevation - TOOLS[i].dMaxDepth
-- se non ancora trovato, oppure se completo e il migliore fino ad ora non è completo: corrente è il migliore
if not nBestToolIndex or ( dBestToolResidualDepth > 0 and dCurrentResidualDepth <= 0) then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
-- altrimenti scelgo il migliore
else
-- se entrambi completi
if dBestToolResidualDepth <= 0 and dCurrentResidualDepth <= 0 then
-- scelgo utensile con rapporto lunghezza / diametro minore
if ( TOOLS[i].dLength / pow( TOOLS[i].dDiameter, 1.5)) < ( TOOLS[nBestToolIndex].dLength / pow( TOOLS[nBestToolIndex].dDiameter, 1.5)) then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
-- se entrambi incompleti
elseif dBestToolResidualDepth > 0 and dCurrentResidualDepth > 0 then
--scelgo quello che lavora di più
if dCurrentResidualDepth > dBestToolResidualDepth then
nBestToolIndex = i
dBestToolResidualDepth = dCurrentResidualDepth
end
end
end
end
end
ToolInfo.nToolIndex = nBestToolIndex
ToolInfo.dResidualDepth = dBestToolResidualDepth
return ToolInfo
end
-------------------------------------------------------------------------------------------------------------
-- salva in lista globale la lavorazione appena calcolata
function MachiningLib.AddNewMachining( ProcToAdd, MachiningToAdd, AuxiliaryDataToAdd)
-- Controllo parametri obbligatori
if not MachiningToAdd.nType or not MachiningToAdd.nToolIndex or not MachiningToAdd.Geometry or not ProcToAdd.id then
return false
end
-- Drilling
if MachiningToAdd.nType == MCH_MY.DRILLING then
MachiningToAdd.sTypeName = 'Drill_'
-- Milling
elseif MachiningToAdd.nType == MCH_MY.MILLING then
-- se utensile lama
if TOOLS[MachiningToAdd.nToolIndex].sFamily == 'SAWBLADE' then
MachiningToAdd.sTypeName = 'Cut_'
else
MachiningToAdd.sTypeName = 'Mill_'
end
-- Pocketing
elseif MachiningToAdd.nType == MCH_MY.POCKETING then
MachiningToAdd.sTypeName = 'Pocket_'
-- Mortising
elseif MachiningToAdd.nType == MCH_MY.MORTISING then
MachiningToAdd.sTypeName = 'ChSaw_'
end
-- se nome non definito, assegno alla lavorazioen un nome standard
if not MachiningToAdd.sOperationName then
MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) .. '_' .. tostring( MachiningToAdd.Geometry[1][2])
end
if not MachiningToAdd.sToolName then
MachiningToAdd.sToolName = TOOLS[MachiningToAdd.nToolIndex].sName
end
local Machining = {}
Machining.Proc = ProcToAdd
Machining.Machining = MachiningToAdd
Machining.AuxiliaryData = AuxiliaryDataToAdd or {}
table.insert( MACHININGS, Machining)
return true
end
-------------------------------------------------------------------------------------------------------------
-- funzione per aggiungere una nuova lavorazione
function MachiningLib.AddOperations( vProc, Part)
local nErr
local sErr = ''
local bAreAllMachiningApplyOk = true
-- parametri generali lavorazione
local MachiningParameters = {
{ sName = 'sDepth', nMchParam = MCH_MP.DEPTH_STR},
{ sName = 'bInvert', nMchParam = MCH_MP.INVERT},
{ sName = 'nWorkside', nMchParam = MCH_MP.WORKSIDE},
{ sName = 'nFaceuse', nMchParam = MCH_MP.FACEUSE},
{ sName = 'nSCC', nMchParam = MCH_MP.SCC},
{ sName = 'bToolInvert', nMchParam = MCH_MP.TOOLINVERT},
{ sName = 'sBlockedAxis', nMchParam = MCH_MP.BLOCKEDAXIS},
{ sName = 'sInitialAngles', nMchParam = MCH_MP.INITANGS},
{ sName = 'nHeadSide', nMchParam = MCH_MP.HEADSIDE},
{ sName = 'nSubType', nMchParam = MCH_MP.SUBTYPE},
{ sName = 'dOverlap', nMchParam = MCH_MP.OVERL},
{ sName = 'nStepType', nMchParam = MCH_MP.STEPTYPE},
{ sName = 'dStartSafetyLength', nMchParam = MCH_MP.STARTPOS},
{ sName = 'dReturnPos', nMchParam = MCH_MP.RETURNPOS},
{ sName = 'dRadialOffset', nMchParam = MCH_MP.OFFSR},
{ sName = 'dLongitudinalOffset', nMchParam = MCH_MP.OFFSL},
{ sName = 'dStartSlowLen', nMchParam = MCH_MP.STARTSLOWLEN},
{ sName = 'dEndSlowLen', nMchParam = MCH_MP.ENDSLOWLEN},
{ sName = 'dThrouAddLen', nMchParam = MCH_MP.THROUADDLEN},
{ sName = 'sSystemNotes', nMchParam = MCH_MP.SYSNOTES},
{ sName = 'sUserNotes', nMchParam = MCH_MP.USERNOTES}
}
-- parametri relativi allo step
MachiningParameters.Steps = {
{ sName = 'nStepType', nMchParam = MCH_MP.STEPTYPE},
{ sName = 'dStep', nMchParam = MCH_MP.STEP},
{ sName = 'dSideStep', nMchParam = MCH_MP.SIDESTEP}
}
-- parametri relativi all'approccio
MachiningParameters.LeadIn = {
{ sName = 'nType', nMchParam = MCH_MP.LEADINTYPE},
{ sName = 'dStartAddLength', nMchParam = MCH_MP.STARTADDLEN},
{ sName = 'dTangentDistance', nMchParam = MCH_MP.LITANG},
{ sName = 'dPerpDistance', nMchParam = MCH_MP.LIPERP},
{ sName = 'dElevation', nMchParam = MCH_MP.LIELEV},
{ sName = 'dCompLength', nMchParam = MCH_MP.LICOMPLEN}
}
-- parametri relativi alla retrazione
MachiningParameters.LeadOut = {
{ sName = 'nType', nMchParam = MCH_MP.LEADOUTTYPE},
{ sName = 'dEndAddLength', nMchParam = MCH_MP.ENDADDLEN},
{ sName = 'dTangentDistance', nMchParam = MCH_MP.LOTANG},
{ sName = 'dPerpDistance', nMchParam = MCH_MP.LOPERP},
{ sName = 'dElevation', nMchParam = MCH_MP.LOELEV},
{ sName = 'dCompLength', nMchParam = MCH_MP.LOCOMPLEN}
}
-- parametri da scrivere nelle note utente
local UserNotes = {
{ sName = 'dMaxElev', sMchParam = 'MaxElev'}
}
-- parametri da scrivere nelle note di sistema
local SystemNotes = {
}
for i = 1, #MACHININGS do
local nClonesToAdd = 1
if MACHININGS[i].AuxiliaryData.Clones then
nClonesToAdd = #MACHININGS[i].AuxiliaryData.Clones
end
for j = 1, nClonesToAdd do
-- creazione lavorazione
local nOperationId = EgtCreateMachining( MACHININGS[i].Machining.sOperationName, MACHININGS[i].Machining.nType, MACHININGS[i].Machining.sToolName)
if nOperationId then
-- impostazione geometria
EgtSetMachiningGeometry( MACHININGS[i].Machining.Geometry)
-- impostazione parametri lavorazione
-- TODO scrivere sempre Steps, LeadIn, LeadOut nelle tabelle in modo da non dover controllare ogni volta che ci siano
for k = 1, #MachiningParameters do
local sValue
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][MachiningParameters[k].sName] then
sValue = MACHININGS[i].AuxiliaryData.Clones[j][MachiningParameters[k].sName]
elseif MACHININGS[i].Machining[MachiningParameters[k].sName] then
sValue = MACHININGS[i].Machining[MachiningParameters[k].sName]
end
if sValue then
EgtSetMachiningParam( MachiningParameters[k].nMchParam, sValue)
end
end
for k = 1, #MachiningParameters.Steps do
local sValue
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].Steps and MACHININGS[i].AuxiliaryData.Clones[j].Steps[MachiningParameters.Steps[k].sName] then
sValue = MACHININGS[i].AuxiliaryData.Clones[j].Steps[MachiningParameters.Steps[k].sName]
elseif MACHININGS[i].Machining.Steps and MACHININGS[i].Machining.Steps[MachiningParameters.Steps[k].sName] then
sValue = MACHININGS[i].Machining.Steps[MachiningParameters.Steps[k].sName]
end
if sValue then
EgtSetMachiningParam( MachiningParameters.Steps[k].nMchParam, sValue)
end
end
for k = 1, #MachiningParameters.LeadIn do
local sValue
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].LeadIn and MACHININGS[i].AuxiliaryData.Clones[j].LeadIn[MachiningParameters.LeadIn[k].sName] then
sValue = MACHININGS[i].AuxiliaryData.Clones[j].LeadIn[MachiningParameters.LeadIn[k].sName]
elseif MACHININGS[i].Machining.LeadIn and MACHININGS[i].Machining.LeadIn[MachiningParameters.LeadIn[k].sName] then
sValue = MACHININGS[i].Machining.LeadIn[MachiningParameters.LeadIn[k].sName]
end
if sValue then
EgtSetMachiningParam( MachiningParameters.LeadIn[k].nMchParam, sValue)
end
end
for k = 1, #MachiningParameters.LeadOut do
local sValue
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].LeadOut and MACHININGS[i].AuxiliaryData.Clones[j].LeadOut[MachiningParameters.LeadOut[k].sName] then
sValue = MACHININGS[i].AuxiliaryData.Clones[j].LeadOut[MachiningParameters.LeadOut[k].sName]
elseif MACHININGS[i].Machining.LeadOut and MACHININGS[i].Machining.LeadOut[MachiningParameters.LeadOut[k].sName] then
sValue = MACHININGS[i].Machining.LeadOut[MachiningParameters.LeadOut[k].sName]
end
if sValue then
EgtSetMachiningParam( MachiningParameters.LeadOut[k].nMchParam, sValue)
end
end
for k = 1, #UserNotes do
local sValue
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][UserNotes[k].sName] then
sValue = MACHININGS[i].AuxiliaryData.Clones[j][UserNotes[k].sName]
elseif MACHININGS[i].Machining[UserNotes[k].sName] then
sValue = MACHININGS[i].Machining[UserNotes[k].sName]
end
if sValue then
local sUserNotes = ''
sUserNotes = EgtSetValInNotes( sUserNotes, UserNotes[k].sMchParam, sValue)
EgtSetMachiningParam( MCH_MP.USERNOTES, sUserNotes)
end
end
-- parametri da settare nelle note di sistema
-- TODO da decidere quali sono le note da salvare qui. Probabilmente tutte quelle relative all'ordine delle lavorazioni
--if MACHININGS[i].Machining.nMachiningOrder then
-- sSystemNotes = EgtSetValInNotes( sSystemNotes, 'MachiningOrder', MACHININGS[i].Machining.nMachiningOrder)
--end
for k = 1, #SystemNotes do
local sValue
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j][SystemNotes[k].sName] then
sValue = MACHININGS[i].AuxiliaryData.Clones[j][SystemNotes[k].sName]
elseif MACHININGS[i].Machining[SystemNotes[k].sName] then
sValue = MACHININGS[i].Machining[SystemNotes[k].sName]
end
if sValue then
local sSystemNotes = ''
sSystemNotes = EgtSetValInNotes( sSystemNotes, SystemNotes[k].sMchParam, sValue)
EgtSetMachiningParam( MCH_MP.SYSNOTES, sSystemNotes)
end
end
local bIsApplyOk = MachiningLib.ApplyMachining( true, false)
if not bIsApplyOk then
bAreAllMachiningApplyOk = false
nErr, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nOperationId, false)
end
else
return false, 'UNEXPECTED ERROR: Error on creating machining'
end
end
end
return bAreAllMachiningApplyOk, sErr
end
-------------------------------------------------------------------------------------------------------------
function MachiningLib.ApplyMachining( bRecalc, bApplyPost)
local bResult = EgtApplyMachining( bRecalc, bApplyPost)
return bResult
end
-------------------------------------------------------------------------------------------------------------
-- funzione che restituisce l'indice MRR (Material Removal Rate) della strategia. Dati in ingresso: Step, SideStep, Feed, ToolIndex, MachiningType
function MachiningLib.GetToolMRR( Parameters)
local dMRR = 1
-- se ho già tutti i parametri
if not Parameters.dStep or not Parameters.dSideStep or not Parameters.dFeed then
-- se manca qualche parametro, lo recupero da parametro di default dell'utensile
if Parameters.nToolIndex then
Parameters.dStep = Parameters.dStep or TOOLS[Parameters.nToolIndex].dStep
Parameters.dSideStep = Parameters.dSideStep or TOOLS[Parameters.nToolIndex].dSideStep
Parameters.dFeed = Parameters.dFeed or TOOLS[Parameters.nToolIndex].Feeds.dFeed
-- se non riesco a calcolare, ritorno un indice molto basso
else
return GEO.EPS_SMALL
end
end
dMRR = Parameters.dStep * Parameters.dSideStep * Parameters.dFeed
-- Unità: dm/min per avere un indice vicino alle unità
return dMRR / pow( 10, 6)
end
-------------------------------------------------------------------------------------------------------------
return MachiningLib
+343
View File
@@ -0,0 +1,343 @@
-- Process.lua by Egalware s.r.l. 2024/04/02
-- Gestione calcolo disposizione e lavorazioni per Travi
-- Si opera sulla macchina corrente
-- 2024/04/02 PRIMA VERSIONE
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
-- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua')
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Core\\?.lua')
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
local sMachDir = EgtGetCurrMachineDir()
if not sMachDir then
EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR')
return
end
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
_G.package.loaded.BeamLib = nil
_G.package.loaded.BeamData = nil
_G.package.loaded.Identity = nil
_G.package.loaded.BasicCustomerStrategies = nil
_G.package.loaded.FeatureData = nil
_G.package.loaded.FaceData = nil
_G.package.loaded.MachiningLib = nil
-- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente
-- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento.
-- Infatti difficile ci siano 9999 strategie.
-- reset strategie caricate come librerie
for i = 1, 9999 do
local IdSTRTemp = EgtReplaceString( tostring( i/10000, 4), '0.', '')
local sLibraryToReload = "STR" .. IdSTRTemp .. "\\STR" .. IdSTRTemp
local sLibraryConfigToReload = sLibraryToReload .. "Config"
if _G.package.loaded[sLibraryToReload] then
_G.package.loaded[sLibraryToReload] = nil
end
if _G.package.loaded[sLibraryConfigToReload] then
_G.package.loaded[sLibraryConfigToReload] = nil
end
end
local vtCoreStrategiesNames = EgtFindAllFiles( BEAM.BASEDIR .. '\\Strategies\\Core\\*.lua')
for i = 1, #vtCoreStrategiesNames do
local sCurrentName = EgtSplitString( vtCoreStrategiesNames[i], '.')[1]
if _G.package.loaded[sCurrentName] then
_G.package.loaded[sCurrentName] = nil
end
end
local BeamExec = require( 'BeamExec')
-- Variabili globali
PARTS = {}
-- Carico i dati globali
local BeamData = require( 'BeamData')
-- Variabili di modulo
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, #PARTS do
if PARTS[i].id == nPartId then
bFound = true
break
end
end
if not bFound then
table.insert( PARTS, { nInd = #PARTS + 1, id = nPartId, sName = ( EgtGetName( nPartId) or ( 'Id=' .. tonumber( nPartId)))})
end
end
nId = EgtGetNextSelectedObj()
end
if #PARTS == 0 then
EgtOutBox( 'Non sono state selezionate travi', 'Lavora Travi', 'ERROR')
return false
else
local sOut = ''
for i = 1, #PARTS do
sOut = sOut .. PARTS[i].sName .. ', '
end
sOut = sOut:sub( 1, -3)
EgtOutLog( 'Travi selezionate : ' .. sOut, 1)
end
-- Ne recupero e verifico le dimensioni
for i = 1, #PARTS do
local Ls = EgtGetFirstNameInGroup( PARTS[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 ' .. PARTS[i].sName, 'Lavora Travi', 'ERROR')
return false
else
PARTS[i].b3Box = b3Solid
end
end
dRawW = PARTS[1].b3Box:getDimY()
dRawH = PARTS[1].b3Box:getDimZ()
local vBeamErr = {}
for i = 2, #PARTS do
local dDimW = PARTS[i].b3Box:getDimY()
local dDimH = PARTS[i].b3Box: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 .. PARTS[vBeamErr[i]].sName .. '\n'
EgtDeselectPartObjs( PARTS[vBeamErr[i]].id)
table.remove( PARTS, vBeamErr[i])
end
EgtOutLog( sOut, 1)
EgtOutBox( sOut, 'Lavora Travi', 'INFO')
EgtDraw()
return false
end
EgtDeselectAll()
return true
end
-------------------------------------------------------------------------------------------------------------
local function GetDataConfig()
-- recupero utensili dal magazzino
BeamExec.GetToolsFromDB()
-- se si utilizza interfaccia B&W, si carica il file JSON
local bIsBeamWall = true -- TODO serve parametro per capire se stiamo utilizzando B&W
if bIsBeamWall then
BeamExec.GetStrategiesFromJSONinBD()
end
-- TODO da gestire eventuali errori bloccanti
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle travi nel grezzo ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessBeams()
-- Determinazione minimo grezzo scaricabile
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
-- Lunghezza totale delle travi
local dTotLen = 0
for i = 1, #PARTS - 1 do
dTotLen = dTotLen + PARTS[i].b3Box:getDimX()
end
dTotLen = dTotLen + max( PARTS[#PARTS].b3Box:getDimX(), BeamData.dMinRaw)
local dAddLen = BeamData.OVM_HEAD + ( #PARTS - 1) * BeamData.OVM_MID
EgtOutLog( 'Ltot : '..EgtNumToString( dTotLen, 1) .. ' Lagg : '..EgtNumToString( dAddLen, 1)..' MinUnloadRaw : '.. EgtNumToString( BeamData.dMinRaw + BeamData.OVM_MID, 1), 1)
-- Richiedo lunghezza del grezzo, sovramateriale di testa, forzatura verticale e ordinamento automatico secondo la lunghezza
local vsVal = EgtDialogBox( 'Lavora Travi' .. ' (Ltot='..EgtNumToString( dTotLen + dAddLen + 0.5, 0)..
', Lmax='..EgtNumToString( BeamData.MAX_RAW, 0)..',MinUlr='..EgtNumToString( BeamData.dMinRaw + BeamData.OVM_MID, 0)..')',
--{'Lunghezza grezzo', EgtNumToString( BeamData.STD_RAW, 0)}, -- TODO RIPRISTINARE
{'Lunghezza grezzo', EgtNumToString( 0)},
{'Sovramateriale di testa', EgtNumToString( BeamData.OVM_HEAD, 0)},
{'Offset intermedio', EgtNumToString( BeamData.OVM_MID, 0)},
{'Forza sezione verticale', ' CB:true,*false'},
{'Ordina per lunghezza', ' CB:true,*false'},
{'Calcolo Lavorazioni', ' CB:*Da progetto,Ricalcolo standard,Ricalcolo IA'})
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
if dRawL < GEO.EPS_SMALL then dRawL = dTotLen + dAddLen + 0.5 end
dRawL = min( dRawL, BeamData.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
local dOvmMid = EgtEvalNumExpr( vsVal[3])
if not dOvmMid then
local sOut = 'Offset intermedio : ' .. vsVal[3]
EgtOutLog( sOut)
EgtOutBox( sOut, 'Lavora Travi', 'WARNING')
EgtDraw()
return false
end
-- Sistemo sezione barra con travi
local bVert = ( vsVal[4] == '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 non troppo grande
if not BeamData.MAX_WIDTH2 or not BeamData.MAX_HEIGHT2 then
if ( dRawW > BeamData.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then
local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' ..
'oltre i limiti della macchina (' .. EgtNumToString( BeamData.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BeamData.MAX_HEIGHT, 2) .. ') '
EgtOutLog( sOut)
EgtOutBox( sOut, 'Lavora Travi', 'WARNING')
EgtDraw()
return false
end
else
if ( dRawW > BeamData.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT + 10 * GEO.EPS_SMALL) and
( dRawW > BeamData.MAX_WIDTH2 + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT2 + 10 * GEO.EPS_SMALL) then
local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' ..
'oltre i limiti della macchina (' .. EgtNumToString( BeamData.MAX_WIDTH, 2) .. ' x ' .. EgtNumToString( BeamData.MAX_HEIGHT, 2) .. ') ' ..
'e (' .. EgtNumToString( BeamData.MAX_WIDTH2, 2) .. ' x ' .. EgtNumToString( BeamData.MAX_HEIGHT2, 2) .. ')'
EgtOutLog( sOut)
EgtOutBox( sOut, 'Lavora Travi', 'WARNING')
EgtDraw()
return false
end
end
-- Verifico sezione barra non troppo piccola
if dRawW < BeamData.MIN_WIDTH - 10 * GEO.EPS_SMALL or dRawH < BeamData.MIN_HEIGHT - 10 * GEO.EPS_SMALL then
local sOut = 'Sezione (' .. EgtNumToString( dRawW, 2) .. ' x ' .. EgtNumToString( dRawH, 2) .. ') ' ..
'sotto i limiti della macchina (' .. EgtNumToString( BeamData.MIN_WIDTH, 2) .. ' x ' .. EgtNumToString( BeamData.MIN_HEIGHT, 2) .. ')'
EgtOutLog( sOut)
EgtOutBox( sOut, 'Lavora Travi', 'WARNING')
EgtDraw()
return false
end
-- Se richiesto, ordino le travi in senso di lunghezza crescente
local bOrd = ( vsVal[5] == 'true')
if bOrd then
table.sort( PARTS, function( B1, B2)
if abs( B1.b3Box:getDimX() - B2.b3Box:getDimX()) < 1 then
return B1.nInd < B2.nInd
else
return B1.b3Box:getDimX() < B2.b3Box:getDimX()
end
end)
end
do
local sOut = ''
for i = 1, #PARTS do
sOut = sOut .. PARTS[i].sName .. ', '
end
sOut = sOut:sub( 1, -3)
EgtOutLog( 'Travi ordinate : ' .. sOut, 1)
end
-- Sistemo le travi nel grezzo
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS)
if not bOk then
EgtOutLog( sErr)
EgtOutBox( sErr, 'Lavora Travi', 'ERROR')
return false
end
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle lavorazioni nelle travi ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessFeatures()
local bOk, Stats = BeamExec.ProcessFeatures( PARTS)
local nErrCnt = 0
local nWarnCnt = 0
local sOutput = ''
for i = 1, #Stats do
if Stats[i].nErr > 0 then
nErrCnt = nErrCnt + 1
sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].idCut, Stats[i].idTask, Stats[i].sMsg)
elseif Stats[i].nErr < 0 then
-- se segnalazione scarico pezzo standard, incompleto o a caduta
if Stats[i].nErr == -100 or Stats[i].nErr == -101 or Stats[i].nErr == -102 then
-- non faccio niente
else
nWarnCnt = nWarnCnt + 1
sOutput = sOutput .. string.format( '[%d,%d] %s\n', Stats[i].idCut, Stats[i].idTask, Stats[i].sMsg)
end
end
end
if #sOutput > 0 then EgtOutLog( sOutput) end
if nErrCnt > 0 then
EgtOutBox( sOutput, 'Lavora Travi', 'ERRORS')
return false
elseif nWarnCnt > 0 then
EgtOutBox( sOutput, 'Lavora Travi', 'WARNINGS')
return true
end
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Esecuzione ***
-------------------------------------------------------------------------------------------------------------
if not MyProcessInputData() then return end
if not MyProcessBeams() then return end
if not GetDataConfig() then return end
-- Abilito Vmill
EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1')
if not MyProcessFeatures() then return end
-93
View File
@@ -1,93 +0,0 @@
# DataBeamNEW
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
+32
View File
@@ -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
+257
View File
@@ -0,0 +1,257 @@
-- Strategia: SLOTBYBLADE
-- Descrizione
-- Strategia di base per la lavorazione delle slot o tasche con lama
-- Feature: tipo lapjoint
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
-- Tabella per definizione modulo
local SLOTBYBLADE = {}
-------------------------------------------------------------------------------------------------------------
local function CalculateLeadInOut( Machining, EdgeToMachine)
-- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom)
-- si determina l'eventuale riduzione da applicare in caso di inizio o fine chiusi
local dAddLengthToReduce = 0
dAddLengthToReduce = sqrt( Machining.dDepthToMachine * TOOLS[Machining.nToolIndex].dDiameter - Machining.dDepthToMachine * Machining.dDepthToMachine)
if Machining.bInvert then
Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed
end
local LeadIn = {}
local LeadOut = {}
LeadIn.dStartAddLength = 0
LeadOut.dEndAddLength = 0
LeadIn.nType = MCH_MILL_LI.LINEAR
LeadOut.nType = MCH_MILL_LI.LINEAR
LeadIn.dTangentDistance = 0
LeadOut.dTangentDistance = 0
if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then
LeadIn.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC
LeadOut.dPerpDistance = EdgeToMachine.dElevation + BeamData.CUT_SIC
else
LeadIn.dPerpDistance = BeamData.CUT_SIC
LeadOut.dPerpDistance = BeamData.CUT_SIC
end
LeadIn.dElevation = 0
LeadOut.dElevation = 0
LeadIn.dCompLength = 0
LeadOut.dCompLength = 0
if Machining.bIsStartClosed and Machining.bIsEndClosed then
LeadIn.dStartAddLength = -dAddLengthToReduce
LeadOut.dEndAddLength = -dAddLengthToReduce
elseif Machining.bIsStartClosed then
LeadIn.dStartAddLength = -dAddLengthToReduce
-- eventuale correzione per accorciamento maggiore di larghezza tasca
LeadOut.dEndAddLength = max( -LeadIn.dStartAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA)
elseif Machining.bIsEndClosed then
LeadOut.dEndAddLength = -dAddLengthToReduce
-- eventuale correzione per accorciamento maggiore di larghezza tasca
LeadIn.dStartAddLength = max( -LeadOut.dEndAddLength - EdgeToMachine.dLength + 10 * BeamData.CUT_EXTRA, BeamData.CUT_EXTRA)
else
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
end
return LeadIn, LeadOut
end
local function GetSCC( vtMachiningDirection)
-- TODO implementare SCC come per FacesBySaw
local nSCC = MCH_SCC.NONE
if AreSameVectorApprox( vtMachiningDirection, Z_AX()) then
nSCC = MCH_SCC.ADIR_ZP
elseif AreOppositeVectorApprox( vtMachiningDirection, Z_AX()) then
nSCC = MCH_SCC.ADIR_ZM
elseif AreSameVectorApprox( vtMachiningDirection, Y_AX()) then
nSCC = MCH_SCC.ADIR_YP
elseif AreOppositeVectorApprox( vtMachiningDirection, Y_AX()) then
nSCC = MCH_SCC.ADIR_YM
elseif AreSameVectorApprox( vtMachiningDirection, X_AX()) then
nSCC = MCH_SCC.ADIR_XP
elseif AreOppositeVectorApprox( vtMachiningDirection, X_AX()) then
nSCC = MCH_SCC.ADIR_XM
end
return nSCC
end
-- TODO calcolo area lavorata per completamento
function SLOTBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters)
local Cutting = {}
Cutting.bIsApplicable = true
Cutting.dDepthToMachine = 0
Cutting.sMessage = ''
Cutting.idProc = Proc.id
Cutting.dResidualDepth = abs( EdgeToMachine.dElevation)
Cutting.dBladeMarkLength = 0
Cutting.sEdgeType = EdgeToMachine.sType
-- parametri opzionali
local bForceLongcutBlade = OptionalParameters.bForceLongcutBlade or false
local dPocketHeight = 0
if Proc.Topology.sFamily == 'Tunnel' then
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
else
if FaceToMachine.sType == 'Long' then
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
elseif FaceToMachine.sType == 'Side' then
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength
end
end
-- ricerca utensile
local ToolSearchParameters = {}
ToolSearchParameters.dElevation = abs( EdgeToMachine.dElevation)
ToolSearchParameters.vtToolDirection = EdgeToMachine.vtToolDirection
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = false
ToolSearchParameters.bForceLongcutBlade = bForceLongcutBlade
local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
Cutting.nToolIndex = ToolInfo.nToolIndex
Cutting.nType = MCH_OY.MILLING
if not TOOLS[Cutting.nToolIndex].sName then
Cutting.sMessage = 'Blade not found'
Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation
end
-- verifica dimensioni tasca compatibili
-- se tasca meno spessa della lama la strategia non è applicabile
if TOOLS[Cutting.nToolIndex].dThickness > dPocketHeight + 10 * GEO.EPS_SMALL then
Cutting.sMessage = 'Pocket too narrow for blade thickness'
Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation
end
if #( Proc.MainFaces.SideFaces) > 1 then
-- se tasca più stretta della lama la strategia non è applicabile
if TOOLS[Cutting.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then
Cutting.sMessage = 'Pocket too narrow for blade diameter'
Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation
end
end
-- parametri della lavorazione
-- profondità (parametro DEPTH) non usata
Cutting.sDepth = 0
-- inizio e fine aperti o chiusi
Cutting.bIsStartClosed = not EdgeToMachine.bIsStartOpen
Cutting.bIsEndClosed = not EdgeToMachine.bIsEndOpen
-- lato di lavoro e inversioni
if TOOLS[Cutting.nToolIndex].bIsCCW then
Cutting.nWorkside = MCH_MILL_WS.RIGHT
Cutting.bInvert = true
else
Cutting.nWorkside = MCH_MILL_WS.LEFT
Cutting.bInvert = false
end
if EdgeToMachine.dElevation < -10 * GEO.EPS_SMALL then
Cutting.bInvert = not Cutting.bInvert
end
-- TODO gestire lama da sotto e lama downUp
if FaceToMachine.vtN:getZ() < - 10 * GEO.EPS_SMALL then
Cutting.bToolInvert = true
Cutting.bInvert = not Cutting.bInvert
else
Cutting.bToolInvert = false
end
-- profondità da lavorare e offset radiale
if TOOLS[Cutting.nToolIndex].dMaxDepth > abs( EdgeToMachine.dElevation) - 10 * GEO.EPS_SMALL then
-- TODO la depth dovrebbe essere quella del machining
Cutting.dDepthToMachine = abs( EdgeToMachine.dElevation)
Cutting.dResidualDepth = 0
if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then
Cutting.dRadialOffset = 0
else
Cutting.dRadialOffset = EdgeToMachine.dElevation
end
else
Cutting.dDepthToMachine = TOOLS[Cutting.nToolIndex].dMaxDepth - 1
Cutting.dResidualDepth = abs( EdgeToMachine.dElevation) - Cutting.dDepthToMachine
if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then
Cutting.dRadialOffset = EdgeToMachine.dElevation - Cutting.dDepthToMachine
else
Cutting.dRadialOffset = -Cutting.dDepthToMachine
end
end
-- completamento
Cutting.dCompletionPercentage = 100 - Cutting.dResidualDepth / Cutting.dDepthToMachine
-- step verticale e offset longitudinale
Cutting.Steps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Cutting.nToolIndex].dThickness)
Cutting.Steps.nStepType = MCH_MILL_ST.ONEWAY
Cutting.dMaxElev = Cutting.Steps.dStep * Cutting.Steps.nCount - 10 * GEO.EPS_SMALL
if Cutting.bToolInvert and Cutting.Steps.nCount > 1 then
Cutting.dLongitudinalOffset = - dPocketHeight
else
Cutting.dLongitudinalOffset = 0
end
-- distanza di sicurezza
Cutting.dStartSafetyLength = 10
-- overlap
Cutting.dOverlap = 0
-- faceuse
if EdgeToMachine.dElevation > - 10 * GEO.EPS_SMALL then
Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( EdgeToMachine.vtToolDirection)
else
Cutting.nFaceuse = BeamLib.GetNearestOrthoOpposite( -EdgeToMachine.vtToolDirection)
end
-- SCC
Cutting.nSCC = GetSCC( EdgeToMachine.vtToolDirection)
-- asse bloccato
Cutting.sBlockedAxis = BeamLib.GetBlockedAxis( Cutting.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN, EgtIf( FaceToMachine.vtN:getX() > 0, X_AX(), -X_AX()))
-- approccio e retrazione
Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( Cutting, EdgeToMachine)
-- eventuale step orizzontale
Cutting.HorizontalSteps = {}
if TOOLS[Cutting.nToolIndex].dSideStep then
Cutting.HorizontalSteps = MachiningLib.GetMachiningSteps( Cutting.dDepthToMachine, TOOLS[Cutting.nToolIndex].dSideStep)
else
Cutting.HorizontalSteps.nCount = 1
Cutting.HorizontalSteps.dStep = 0
end
-- lunghezza impronta lama
if Cutting.bIsStartClosed and Cutting.bIsEndClosed then
Cutting.dBladeMarkLength = abs( min( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength))
elseif Cutting.bIsStartClosed then
Cutting.dBladeMarkLength = abs( Cutting.LeadIn.dStartAddLength)
elseif Cutting.bIsEndClosed then
Cutting.dBladeMarkLength = abs( Cutting.LeadOut.dEndAddLength)
end
-- geometria
Cutting.Geometry = {{Proc.id, FaceToMachine.id}}
-- nome operazione
Cutting.sOperationName = 'Cut_' .. ( EgtGetName( Cutting.idProc) or tostring( Cutting.idProc)) .. '_' .. tostring( FaceToMachine.id + 1)
-- eventuale avviso di danneggiamento pezzo successivo
-- TODO da sostituire con check se si riesce a separare e il grezzo dietro è lungo a sufficienza
-- local dOffsideLength = max( Cutting.LeadIn.dStartAddLength, Cutting.LeadOut.dEndAddLength) + TOOLS[Cutting.nToolIndex].dDiameter / 2 + 10 * GEO.EPS_SMALL
-- if ( not Proc.bTail or Proc.bAdvTail) and Proc.AffectedFaces.bLeft and ( Proc.dDistanceToNextPart < dOffsideLength) then
-- local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : sawblade can damage next piece.'
-- if #Cutting.sMessage > 0 then
-- Cutting.sMessage = Cutting.sMessage .. '\n' .. sDamageNextPieceMessage
-- else
-- Cutting.sMessage = sDamageNextPieceMessage
-- end
-- EgtOutLog( sDamageNextPieceMessage)
-- end
return Cutting
end
-------------------------------------------------------------------------------------------------------------
return SLOTBYBLADE
+232
View File
@@ -0,0 +1,232 @@
-- Strategia: SLOTBYCHAINSAW
-- Descrizione
-- Strategia di base per la lavorazione delle slot o tasche con sega a catena
-- Feature: tipo lapjoint
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
-- Tabella per definizione modulo
local SLOTBYCHAINSAW = {}
-------------------------------------------------------------------------------------------------------------
local function CalculateLeadInOut( Machining, EdgeToMachine, sSideToMachine, dLengthToMachine)
-- TODO implementare le funzioni di Tool Collision Avoidance (vedi wiki e FacesBysaw -> CalcLeadInOutPerpGeom)
-- si determina l'eventuale riduzione da applicare in caso di inizio o fine chiusi
local dAddLengthToReduce = 0
dAddLengthToReduce = TOOLS[Machining.nToolIndex].dDiameter / 2
if Machining.bInvert then
Machining.bIsStartClosed, Machining.bIsEndClosed = Machining.bIsEndClosed, Machining.bIsStartClosed
end
local LeadIn = {}
local LeadOut = {}
LeadIn.dStartAddLength = 0
LeadOut.dEndAddLength = 0
if sSideToMachine == 'End' then
LeadIn.dStartAddLength = dAddLengthToReduce + dLengthToMachine + BeamData.CUT_EXTRA - EdgeToMachine.dLength
elseif Machining.bIsStartClosed then
LeadIn.dStartAddLength = -dAddLengthToReduce
else
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
end
if sSideToMachine == 'Start' then
LeadOut.dEndAddLength = dAddLengthToReduce + dLengthToMachine + BeamData.CUT_EXTRA - EdgeToMachine.dLength
elseif Machining.bIsEndClosed then
LeadOut.dEndAddLength = -dAddLengthToReduce
else
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
end
return LeadIn, LeadOut
end
-- TODO calcolo area lavorata per completamento
function SLOTBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters)
local Mortising = {}
Mortising.bIsApplicable = true
Mortising.dDepthToMachine = 0
Mortising.dResidualDepth = abs( EdgeToMachine.dElevation)
Mortising.sMessage = ''
Mortising.idProc = Proc.id
Mortising.sEdgeType = EdgeToMachine.sType
-- parametri opzionali
local bUseZigZagMortising = OptionalParameters.bUseZigZagMortising or false
local sSideToMachine = OptionalParameters.sSideToMachine or ''
local dLengthToMachine = OptionalParameters.dLengthToMachine or EdgeToMachine.dLength
local dCustomMaxElev = OptionalParameters.dMaxElev or abs( EdgeToMachine.dElevation)
local bStopAtHalfElevation = OptionalParameters.bStopAtHalfElevation or false
-- altezza tasca, in base alla topologia
local dPocketHeight = 0
if Proc.Topology.sFamily == 'Tunnel' then
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
else
if FaceToMachine.sType == 'Long' then
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
elseif FaceToMachine.sType == 'Side' then
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength
end
end
-- ricerca utensile
local bExtendWithCornerRadius = false
if not bStopAtHalfElevation then
if ( EdgeToMachine.sType == 'Side' and Proc.Topology.sName == 'Groove-3-Through') or
( EdgeToMachine.sType == 'Opposite' and Proc.Topology.sFamily == 'Tunnel') then
bExtendWithCornerRadius = true
Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation) + BeamData.CUT_EXTRA
else
Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation)
end
else
bExtendWithCornerRadius = true
Mortising.dDepthToMachine = abs( EdgeToMachine.dElevation) / 2 + BeamData.CUT_EXTRA_MIN
end
local ToolSearchParameters = {}
local ToolInfo = {}
ToolSearchParameters.vtToolDirection = EdgeToMachine.vtToolDirection
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = true
ToolSearchParameters.dElevation = Mortising.dDepthToMachine
ToolSearchParameters.bExtendWithCornerRadius = bExtendWithCornerRadius
ToolInfo = MachiningLib.FindChainSaw( Proc, ToolSearchParameters)
Mortising.nToolIndex = ToolInfo.nToolIndex
Mortising.nType = MCH_OY.MORTISING
if not TOOLS[Mortising.nToolIndex] or not TOOLS[Mortising.nToolIndex].sName then
Mortising.sMessage = 'Chainsaw not found'
Mortising.bIsApplicable = false
EgtOutLog( Mortising.sMessage)
return Mortising
end
-- verifica dimensioni tasca compatibili
-- se tasca meno spessa della sega a catena la strategia non è applicabile
if TOOLS[Mortising.nToolIndex].dThickness > dPocketHeight + 10 * GEO.EPS_SMALL then
Mortising.sMessage = 'Pocket too narrow for chainsaw thickness'
Mortising.bIsApplicable = false
EgtOutLog( Mortising.sMessage)
return Mortising
end
if #( Proc.MainFaces.SideFaces) > 1 then
-- se tasca più stretta della sega a catena la strategia non è applicabile
if TOOLS[Mortising.nToolIndex].dWidth > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then
Mortising.sMessage = 'Pocket too narrow for chainsaw width'
Mortising.bIsApplicable = false
EgtOutLog( Mortising.sMessage)
return Mortising
end
end
-- parametri della lavorazione
-- TODO gestire ToolInvert per rispettare direzione migliore di lavorazione
-- profondità (parametro DEPTH) non usata
Mortising.sDepth = 'TH'
-- inizio e fine aperti o chiusi
Mortising.bIsStartClosed = not EdgeToMachine.bIsStartOpen
Mortising.bIsEndClosed = not EdgeToMachine.bIsEndOpen
-- lato di lavoro e inversioni
Mortising.bInvert = false
if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then
Mortising.nWorkside = MCH_MILL_WS.RIGHT
Mortising.bToolInvert = false
else
Mortising.nWorkside = MCH_MILL_WS.LEFT
Mortising.bToolInvert = true
end
-- profondità e offset longitudinale
if bExtendWithCornerRadius then
Mortising.dDepthToMachine = Mortising.dDepthToMachine + TOOLS[Mortising.nToolIndex].dCornerRadius
end
if TOOLS[Mortising.nToolIndex].dMaxMaterial > Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then
Mortising.dResidualDepth = 0
if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then
Mortising.dLongitudinalOffset = 0
else
Mortising.dLongitudinalOffset = abs( EdgeToMachine.dElevation) - Mortising.dDepthToMachine
end
else
Mortising.dDepthToMachine = TOOLS[Mortising.nToolIndex].dMaxMaterial - 1
Mortising.dResidualDepth = abs( EdgeToMachine.dElevation) - Mortising.dDepthToMachine
if EdgeToMachine.dElevation > -10 * GEO.EPS_SMALL then
Mortising.dLongitudinalOffset = EdgeToMachine.dElevation - Mortising.dDepthToMachine
else
Mortising.dLongitudinalOffset = 0
end
Mortising.sMessage = 'Feature '.. Proc.idFeature .. ' : chainsaw elevation (' .. EgtNumToString( EdgeToMachine.dElevation, 1) .. ') bigger than max tool depth (' .. EgtNumToString( Mortising.dDepthToMachine, 1) .. ')'
EgtOutLog( Mortising.sMessage)
end
-- completamento
Mortising.dCompletionPercentage = 100 - Mortising.dResidualDepth / Mortising.dDepthToMachine
-- massima elevazione
if dCustomMaxElev < Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then
Mortising.dMaxElev = dCustomMaxElev
end
-- offset radiale
Mortising.dRadialOffset = 0
-- distanza di sicurezza
Mortising.dStartSafetyLength = max( EdgeToMachine.dElevation, 10)
-- overlap
Mortising.dOverlap = 0
-- step
Mortising.Steps = {}
if bUseZigZagMortising then
Mortising.Steps.nStepType = MCH_MILL_ST.ZIGZAG
else
Mortising.Steps.nStepType = MCH_MILL_ST.ONEWAY
end
Mortising.Steps.dStep = TOOLS[Mortising.nToolIndex].dStep
-- faceuse
if EdgeToMachine.dElevation > - 10 * GEO.EPS_SMALL then
Mortising.nFaceuse = BeamLib.GetNearestParalOpposite( EdgeToMachine.vtToolDirection)
else
Mortising.nFaceuse = BeamLib.GetNearestParalOpposite( -EdgeToMachine.vtToolDirection)
end
-- SCC
Mortising.SCC = MCH_SCC.NONE
-- asse bloccato e angoli suggeriti
local vtRes = FaceToMachine.vtN ^ EdgeToMachine.vtToolDirection
if abs( vtRes:getZ()) < 10 * GEO.EPS_SMALL then
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN)
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtToolDirection, 1)
elseif EdgeToMachine.vtToolDirection:getZ() < 10 * GEO.EPS_SMALL then
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN)
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtToolDirection, 2)
end
-- approccio e retrazione
Mortising.LeadIn, Mortising.LeadOut = CalculateLeadInOut( Mortising, EdgeToMachine, sSideToMachine, dLengthToMachine)
-- eventuale step verticale
Mortising.VerticalSteps = MachiningLib.GetMachiningSteps( dPocketHeight, TOOLS[Mortising.nToolIndex].dThickness)
-- geometria
Mortising.Geometry = {{Proc.id, FaceToMachine.id}}
-- nome operazione
Mortising.sOperationName = 'Chainsaw_' .. ( EgtGetName( Mortising.idProc) or tostring( Mortising.idProc)) .. '_' .. tostring( FaceToMachine.id + 1)
-- eventuale avviso di danneggiamento pezzo successivo
-- TODO da sostituire con check se si riesce a separare e il grezzo dietro è lungo a sufficienza
-- local dOffsideLength = max( Mortising.LeadIn.dStartAddLength, Mortising.LeadOut.dEndAddLength) + TOOLS[Mortising.nToolIndex].dWidth / 2 + 10 * GEO.EPS_SMALL
-- if ( not Proc.bTail or Proc.bAdvTail) and Proc.AffectedFaces.bLeft and ( Proc.dDistanceToNextPart < dOffsideLength) then
-- local sDamageNextPieceMessage = 'Feature '.. Proc.idFeature .. ' : chainsaw can damage next piece.'
-- if #Mortising.sMessage > 0 then
-- Mortising.sMessage = Mortising.sMessage .. '\n' .. sDamageNextPieceMessage
-- else
-- Mortising.sMessage = sDamageNextPieceMessage
-- end
-- EgtOutLog( sDamageNextPieceMessage)
-- end
return Mortising
end
-------------------------------------------------------------------------------------------------------------
return SLOTBYCHAINSAW
+24
View File
@@ -0,0 +1,24 @@
-- Strategia: STR0001
-- Descrizione
-- Lama + fresa CodaDiRondine per tenone
-- Feature: 55,1
-- carico librerie
local BeamLib = require( 'BeamLib')
-- Tabella per definizione modulo
local STR0001 = {}
-------------------------------------------------------------------------------------------------------------
function STR0001.Make( AddMachining, Proc, Part, CustomParameters)
-- carico parametri de default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti)
local StrategyLib = {}
StrategyLib.Config = require( 'STR0001\\STR0001Config')
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
StrategyParameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
end
-------------------------------------------------------------------------------------------------------------
return STR0001
@@ -0,0 +1,13 @@
-- Parametri configurabili da cliente per strategia: STR0001
local STR0001Data = {
sStrategyId = 'STR0001',
Parameters = {
{ sName = 'dOverMatOnLenght', sValue = '0', sDescription = 'Sovramateriale lunghezza tenone', sType = 'd'},
{ sName = 'dOverMatOnRadius', sValue = '0', sDescription = 'Sovramateriale larghezza tenone', sType = 'd'},
{ sName = 'nMaxMillingPaths', sValue = '3', sDescription = 'Numero massimo di passaggi di fresatura. Se richiesti più passaggi, si fa svuotatura', sType = 'd'},
{ sName = 'bUseDTToolOnPocketing', sValue = 'true', sDescription = 'Utilizza utensile a coda di rondimne per fare svuotatura', sType = 'b'}
}
}
return STR0001Data
+570
View File
@@ -0,0 +1,570 @@
-- Strategia: STR0002
-- Descrizione
-- Svuotatura tasca
-- Feature tipo LapJpint
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
-- TODO
-- 1 - Controllare lavorazioni in caso di feature lunga spezzata
-- 2 - Inserire antischeggia (fresa o lama)
-- 3 - Modalità svuotatura con fresa grande e spigoli con fresa piccola
-- 4 - Smusso a V
-- 5 - Finitura con motosega (se la fresa non completa)
-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
local FeatureData = require( 'FeatureData')
-- Tabella per definizione modulo
local STR0002 = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function IsTopologyOk( Proc)
if Proc.Topology.sName == 'Pocket-5-Blind' or
Proc.Topology.sName == 'Tunnel-4-Through' or
Proc.Topology.sName == 'Groove-4-Blind' or
Proc.Topology.sName == 'Groove-3-Through' or
Proc.Topology.sName == 'Groove-3-Blind' or
Proc.Topology.sName == 'Rabbet-2-Through' then
return true
else
return false
end
end
-------------------------------------------------------------------------------------------------------------
local function CalcMachinedPercentage( Proc, Machining)
-- se non ci sono lavorazioni esco subito
if Machining.sTypeMachining == 'None' then
return 0
end
local dTotalPercentage = 0
local dPercentageBottom = 0
if Machining[1].bIsApplicable then
dTotalPercentage = ( Machining[1].dElevation - Machining[1].ToolInfo.dResidualDepth) / Machining[1].dElevation
dPercentageBottom = dTotalPercentage
end
if Machining[2].bIsApplicable then
local dAbsPercentage = ( Machining[2].dElevation - Machining[2].ToolInfo.dResidualDepth) / Machining[2].dElevation
dTotalPercentage = dTotalPercentage + ( 1 - dTotalPercentage) * dAbsPercentage
end
if Machining[3].bIsApplicable then
local dAbsPercentage
if Machining[3].bMachAppliedToTunnelFace then
dAbsPercentage = ( Machining[3].dElevation - Machining[3].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation) / Machining[3].dElevation
else
dAbsPercentage = ( Machining[3].dElevation - Machining[3].ToolInfo.dResidualDepth) / Machining[3].dElevation
end
dTotalPercentage = dTotalPercentage + ( 1 - dPercentageBottom) * dAbsPercentage
end
if Machining[4].bIsApplicable then
local dAbsPercentage
if Machining[3].bMachAppliedToTunnelFace then
dAbsPercentage = ( Machining[4].dElevation - Machining[4].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation) / Machining[4].dElevation
else
dAbsPercentage = ( Machining[4].dElevation - Machining[4].ToolInfo.dResidualDepth) / Machining[4].dElevation
end
dTotalPercentage = dTotalPercentage + ( 1 - dPercentageBottom) * dAbsPercentage
end
return dTotalPercentage * 100
end
-------------------------------------------------------------------------------------------------------------
local function GetBestPocketingStrategy( Proc)
-- imposto paraemtri di ricerca utensile in base a topologia
local Machining = {}
local Milling = {}
local ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
Machining.sTypeMachining = 'None' -- Bottom-Side1-Side2\ Bottom-Side1\ Bottom-Side2\ Side1-Side2\ Bottom\ Side1 \ Side2 \ None
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Mill')
-- caso speciale Tunnel che non ha faccia bottom
if Proc.Topology.sName == 'Tunnel-4-Through' then
local dFaceHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
local dFaceWidth = Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength
ToolSearchParameters.sType = 'MILL_STD'
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, dFaceHeight, dFaceWidth)
-- imposto dati per cercare la fresa migliore
elseif Proc.Topology.sName == 'Pocket-5-Blind' then
local dFaceWidth = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength
local dFaceHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
ToolSearchParameters.sType = 'MILL_STD'
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, dFaceHeight, dFaceWidth)
-- cerco fresa che può anche non lavorare di testa
elseif Proc.Topology.sName == 'Groove-4-Blind' then
local dFaceWidth = Proc.MainFaces.BottomFaces[2].MainEdges.BottomEdge.dLength
ToolSearchParameters.sType = 'MILL_NOTIP'
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, dFaceWidth)
elseif Proc.Topology.sName == 'Groove-3-Through' then
local dFaceWidth = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
ToolSearchParameters.sType = 'MILL_NOTIP'
ToolSearchParameters.dMaxToolDiameter = dFaceWidth
elseif Proc.Topology.sName == 'Groove-3-Blind' then
ToolSearchParameters.sType = 'MILL_NOTIP'
ToolSearchParameters.dMaxToolDiameter = Strategy.Parameters.dMaxCornerRadius * 2
elseif Proc.Topology.sName == 'Rabbet-2-Through' then
ToolSearchParameters.sType = 'MILL_NOTIP'
ToolSearchParameters.dMaxToolDiameter = 9999
else
return nil
end
-- ===== RICERCA UTENSILE =====
-- cerco utensile per lavorare faccia Bottom
Milling.bIsApplicable = false
if Proc.Topology.sName ~= 'Tunnel-4-Through' then
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[1].vtN
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[1].id
Milling.idProc = Proc.id
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[1].vtN
Milling.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Milling.ToolInfo.nToolIndex then
Milling.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
end
table.insert( Machining, Milling)
-- caso speciale 'Rabbet-2-Through' seconda faccia principale
Milling = {}
Milling.bIsApplicable = false
if Proc.Topology.sName == 'Rabbet-2-Through' then
ToolSearchParameters.dElevation = Proc.MainFaces.LongFaces[1].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.LongFaces[1].vtN
Milling.vtFaceNormal = Proc.MainFaces.LongFaces[1].vtN
Milling.idFaceToMachine = Proc.MainFaces.LongFaces[1].id
Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.LongFaces[1].dElevation
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Milling.ToolInfo.nToolIndex then
Milling.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
end
table.insert( Machining, Milling)
-- cerco utensile per lavorare di fianco 1
Milling = {}
Milling.bIsApplicable = false
if Proc.Topology.sName ~= 'Pocket-5-Blind' then
if Proc.Topology.sName == 'Groove-4-Blind' then
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id
Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
elseif Proc.Topology.sName == 'Groove-3-Blind' then
ToolSearchParameters.dElevation = Proc.MainFaces.LongFaces[1].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.LongFaces[1].vtN
Milling.vtFaceNormal = Proc.MainFaces.LongFaces[1].vtN
Milling.idFaceToMachine = Proc.MainFaces.LongFaces[1].id
Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.LongFaces[1].dElevation
else -- 'Tunnel-4-Through', 'Groove-3-Through', 'Rabbet-2-Through'
-- se lavoro di fianco, devo comunque rispettare il raggio massimo
ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2)
ToolSearchParameters.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
ToolSearchParameters.vtToolDirection = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
Milling.vtFaceNormal = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
Milling.idFaceToMachine = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].id
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
Milling.bMachAppliedToTunnelFace = true
end
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Milling.ToolInfo.nToolIndex then
Milling.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
end
table.insert( Machining, Milling)
-- cerco utensile per lavorare di fianco 2
Milling = {}
Milling.bIsApplicable = false
if Proc.Topology.sName ~= 'Pocket-5-Blind' and Proc.Topology.sName ~= 'Groove-4-Blind' then
if Proc.MainFaces.TunnelAddedFaces then -- Tunnel-4-Through, Groove-3-Through, Rabbet-2-Through
-- se lavoro di fianco, devo comunque rispettare il raggio massimo
ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2)
ToolSearchParameters.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
ToolSearchParameters.vtToolDirection = -Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
Milling.vtFaceNormal = -Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].vtN
Milling.idFaceToMachine = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].id
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
Milling.bToolInvert = true
Milling.bMachAppliedToTunnelFace = true
else -- 'Groove-3-Blind'
ToolSearchParameters.dElevation = Proc.MainFaces.SideFaces[1].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.SideFaces[1].vtN
Milling.vtFaceNormal = Proc.MainFaces.SideFaces[1].vtN
Milling.idFaceToMachine = Proc.MainFaces.SideFaces[1].id
Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.SideFaces[1].dElevation
end
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if Milling.ToolInfo.nToolIndex then
Milling.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
end
table.insert( Machining, Milling)
-- ===== SCELTA LAVORAZIONI =====
-- se bottom completa tutto
if Machining[1].bIsApplicable and Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Machining.sTypeMachining = 'Bottom'
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = Machining[1].dMRR
Machining[1].ToolInfo.dResidualDepth = 0
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- caso speciale 'Rabbet-2-Through' che ha la sweconda faccia come se fosse una seconda bottom
elseif Proc.Topology.sName == 'Rabbet-2-Through' and Machining[2].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Machining.sTypeMachining = 'Bottom2'
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = Machining[2].dMRR
Machining[2].ToolInfo.dResidualDepth = 0
Machining[1].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- se la 3 completa tutto
elseif Machining[3].bIsApplicable and Machining[3].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Machining.sTypeMachining = 'Side1'
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = Machining[3].dMRR
if Proc.MainFaces.TunnelAddedFaces then
Machining[3].ToolInfo.dResidualDepth = -( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP)
else
Machining[3].ToolInfo.dResidualDepth = 0
end
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- se la 4 completa tutto
elseif Machining[4].bIsApplicable and Machining[4].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Machining.sTypeMachining = 'Side2'
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = Machining[4].dMRR
if Proc.MainFaces.TunnelAddedFaces then
Machining[4].ToolInfo.dResidualDepth = -( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP)
else
Machining[4].ToolInfo.dResidualDepth = 0
end
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
return Machining
-- se tunnel 2+3 completa tutto
elseif Proc.MainFaces.TunnelAddedFaces and Machining[3].bIsApplicable and Machining[4].bIsApplicable and
Machining[3].ToolInfo.dResidualDepth + Machining[4].ToolInfo.dResidualDepth < (Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP then
Machining.sTypeMachining = 'Side1-Side2'
Strategy.Result.sStatus = 'Completed'
Machining[3].ToolInfo.dResidualDepth = Machining[3].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation
Machining[4].ToolInfo.dResidualDepth = -Machining[3].ToolInfo.dResidualDepth - BeamData.MILL_OVERLAP
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = ( Machining[3].dMRR + Machining[4].dMRR) / 2
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
return Machining
end
Strategy.Result.sStatus = 'Not-Completed'
Strategy.Result.dMRR = 0
if Machining[1].bIsApplicable then
Machining.sTypeMachining = 'Bottom'
Strategy.Result.dMRR = Machining[1].dMRR
end
if Machining[2].bIsApplicable then
Machining.sTypeMachining = EgtIf( Machining.sTypeMachining == 'None', 'Bottom2', Machining.sTypeMachining .. '-Bottom2')
Strategy.Result.dMRR = ( Strategy.Result.dMRR + Machining[2].dMRR) / EgtIf( Strategy.Result.dMRR == 0, 1, 2)
end
if Machining[3].bIsApplicable then
if Proc.MainFaces.TunnelAddedFaces then
Machining[3].ToolInfo.dResidualDepth = Machining[3].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP
end
Machining.sTypeMachining = EgtIf( Machining.sTypeMachining == 'None', 'Side1', Machining.sTypeMachining .. '-Side1')
Strategy.Result.dMRR = ( Strategy.Result.dMRR + Machining[3].dMRR) / EgtIf( Strategy.Result.dMRR == 0, 1, 2)
end
if Machining[4].bIsApplicable then
if Proc.MainFaces.TunnelAddedFaces then
Machining[4].ToolInfo.dResidualDepth = Machining[4].ToolInfo.dResidualDepth - Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation + BeamData.MILL_OVERLAP
end
Machining.sTypeMachining = EgtIf( Machining.sTypeMachining == 'None', 'Side2', Machining.sTypeMachining .. '-Side2')
Strategy.Result.dMRR = ( Strategy.Result.dMRR + Machining[4].dMRR) / EgtIf( Strategy.Result.dMRR == 0, 1, 2)
end
local dMachinedPrercentage = CalcMachinedPercentage( Proc, Machining)
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dMachinedPrercentage)
Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
-- se non ho trovato neanche una lavorazione
if Machining.sTypeMachining == 'None' then
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.nCompletionIndex = 0
Strategy.Result.dMRR = 0
Strategy.Result.nQuality = 0
Strategy.Result.sInfo = 'Mill not found'
end
return Machining
end
-------------------------------------------------------------------------------------------------------------
local function VerifySplitMachiningNeeded( Proc, Part)
local vAddId = {}
local vAddIdTunnel = {}
local bSplit
-- la lunghezza richiede spezzatura
if Proc.b3Box:getDimX() > BeamData.LONGCUT_MAXLEN or Proc.b3Box:getDimX() > 0.7 * Part.b3Solid:getDimX() then
bSplit = true
else
bSplit = false
end
-- la lunghezza richiede spezzatura
if ( bSplit) then
-- recupero gruppo per geometria aggiuntiva
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
local bStartLeft, bStartRight
local nIdTunnel = nil
if Proc.MainFaces.TunnelAddedFaces then
nIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
end
-- se feature inizia al di sotto del limite sinistro (coda)
if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN then
bStartLeft = true
end
-- se feature inizia al di sotto del limite destro (testa)
if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN then
bStartRight = true
end
-- recupero utensile con massimo diametro
local dMaxDiam = 30
for t = 1, #Strategy.Machining do
if Strategy.Machining[t].bIsApplicable then
dMaxDiam = min( dMaxDiam, TOOLS[Strategy.Machining[t].ToolInfo.nToolIndex].dDiameter)
end
end
-- salvo valori
local dNewMinX = Proc.b3Box:getMin():getX()
local dNewMaxX = Proc.b3Box:getMax():getX()
local dNewRest = Proc.b3Box:getDimX()
-- creo primo spezzone sulla sinistra
if bStartLeft then
local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
-- copio faccia tunnel
local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL
-- decido punto spezzatura verso la coda
if Proc.b3Box:getDimX() > BeamData.LONGCUT_ENDLEN * 2 then
dNewMinX = max( Part.b3Solid:getMin():getX() + BeamData.LONGCUT_ENDLEN, Proc.b3Box:getMin():getX() + dMaxDiam * 3)
else
-- se pezzo abbastanza piccolo, spezzo in mezzo al 'pezzo + grezzo restante'
if Part.dRestLength + Part.b3Solid:getDimX() < BeamData.dMinRaw * 1.5 then
dNewMinX = Part.b3Solid:getMax():getX() - ( ( Part.dRestLength + Part.b3Solid:getDimX()) / 2)
else
dNewMinX = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN)
end
end
local ptOn = Point3d( dNewMinX, 0, 0)
dNewRest = abs( dNewMaxX - dNewMinX)
-- taglio della superficie lato sinistro
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB)
-- eseguo inserimento
table.insert( vAddId, AddId)
table.insert( vAddIdTunnel, AddIdTunnel)
end
-- creo spezzone sulla destra
if bStartRight then
local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
-- copio faccia tunnel
local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL
dNewMaxX = min( ( Proc.b3Box:getMax():getX() - dMaxDiam * 3), Part.b3Solid:getMax():getX() - BeamData.LONGCUT_ENDLEN)
if dNewMaxX - dNewMinX < 500 * GEO.EPS_SMALL then
dNewMaxX = dNewMinX - BeamData.MILL_OVERLAP
dNewRest = 0
else
dNewRest = dNewMaxX - dNewMinX
end
local ptOn = Point3d( dNewMaxX, 0, 0)
-- taglio della superficie lato destro
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB)
-- eseguo inserimento
table.insert( vAddId, 1, AddId)
table.insert( vAddIdTunnel, AddIdTunnel)
end
-- lavoro il restante
if dNewRest > 0 then
local nSplitParts = max( ceil( dNewRest / BeamData.LONGCUT_MAXLEN + 10 * GEO.EPS_SMALL), 1)
local dSplitPartsLen = dNewRest / nSplitParts
for i = 1, nSplitParts do
local AddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
-- copio faccia tunnel
local AddIdTunnel = EgtCopyGlob( nIdTunnel, nAddGrpId) or GDB_ID.NULL
local ptOn
-- se un solo spezzone, prendo punto massimo e minimo
if nSplitParts == 1 then
ptOn = Point3d( dNewMinX, 0, 0)
-- taglio della superficie lato sinistro
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB)
ptOn = Point3d( dNewMaxX, 0, 0)
-- taglio della superficie lato destro
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB)
else
-- eseguo trim sinistro
if i ~= 1 or bStartLeft then
ptOn = Point3d( dNewMinX, 0, 0)
-- taglio della superficie lato sinistro
EgtCutSurfTmPlane( AddId, ptOn, -X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( AddIdTunnel, ptOn, -X_AX(), true, GDB_RT.GLOB)
end
-- eseguo trim destro
dNewMaxX = dNewMinX + dSplitPartsLen
if i ~= nSplitParts or bStartRight then
ptOn = Point3d( dNewMaxX, 0, 0)
-- taglio della superficie lato destro
EgtCutSurfTmPlane( AddId, ptOn, X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( AddIdTunnel, ptOn, X_AX(), true, GDB_RT.GLOB)
end
-- il nuovo minimo è il punto massimo del precedente
dNewMinX = dNewMaxX
end
-- eseguo inserimento in modo da ordinare da X- a X+
table.insert( vAddId, EgtIf( #vAddId == 0 or not bStartRight, 1, 2), AddId)
table.insert( vAddIdTunnel, EgtIf( #vAddIdTunnel == 0 or not bStartRight, 1, 2), AddIdTunnel)
end
end
else
-- TODO se è sulla coda, messaggio che posso rovinare
table.insert( vAddId, Proc.id)
end
return vAddId, vAddIdTunnel
end
-------------------------------------------------------------------------------------------------------------
function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
-- carico parametri de default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti)
local StrategyLib = {}
StrategyLib.Config = require( 'STR0002\\STR0002Config')
Strategy.sName = StrategyLib.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.Machining = {}
Strategy.Result = {}
if not IsTopologyOk( Proc) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not implemented'
EgtOutLog( sErr)
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.nCompletionIndex = 0
Strategy.Result.dMRR = 0
Strategy.Result.nQuality = 0
Strategy.Result.sInfo = sErr
return false, Strategy.Result
end
local bAreAllApplyOk = true
local ToolInfo = {}
local Pocketing = {}
Strategy.Machining = GetBestPocketingStrategy( Proc)
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
local vAddId, vAddIdTunnel = VerifySplitMachiningNeeded( Proc, Part)
-- si applicano le lavorazioni
for i = 1, #vAddId do
for j = 1, #Strategy.Machining do
if Strategy.Machining[j].bIsApplicable then
Pocketing = {}
Pocketing.Steps = {}
Pocketing.LeadIn = {}
Pocketing.nType = MCH_OY.POCKETING
Pocketing.nSubType = EgtIf( Proc.Topology.sName == 'Pocket-5-Blind', MCH_POCK_SUB.SPIRALOUT, MCH_POCK_SUB.SPIRALIN)
Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG
Pocketing.Steps.dStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dStep
Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dSideStep
Pocketing.nToolIndex = Strategy.Machining[j].ToolInfo.nToolIndex
Pocketing.LeadIn.dTangentDistance = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter/2
Pocketing.LeadIn.dElevation = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter/2
Pocketing.sDepth = -Strategy.Machining[j].ToolInfo.dResidualDepth
-- il quarto ciclo è la lavorazione opposta sulla faccia Tunnel
if Strategy.Machining[j].bToolInvert then
Pocketing.bToolInvert = true
end
-- se ho una sola trimesh, sto lavorando la Proc direttamente e non ho spezzato. Applico direttamente alla geometria calcolata prima
if #vAddId == 1 then
Pocketing.Geometry = {{ Strategy.Machining[j].idProc, Strategy.Machining[j].idFaceToMachine}}
bAreAllApplyOk = MachiningLib.AddNewMachining( Proc, Pocketing)
else
-- TODO settare parametro per indicare qual è lo spezzone che deve essere fatto dopo il taglio di separazione
for k = 1, Proc.nFct do
local vtNSplitFace
local dIdTm = EgtIf( Strategy.Machining[j].bMachAppliedToTunnelFace, vAddIdTunnel[i], vAddId[i])
_, vtNSplitFace = EgtSurfTmFacetCenter( dIdTm, k - 1, GDB_ID.ROOT)
if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then
Pocketing.Geometry = {{ dIdTm, k - 1}}
bAreAllApplyOk = bAreAllApplyOk and MachiningLib.AddNewMachining( Proc, Pocketing)
break
end
end
end
end
end
end
else
bAreAllApplyOk = false
end
return bAreAllApplyOk, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
return STR0002
@@ -0,0 +1,11 @@
-- Parametri configurabili da cliente per strategia: STR0002
local STR0002Data = {
sStrategyId = 'STR0002',
Parameters = {
{ sName = 'dMaxCornerRadius', sValue = '15', sDescriptionShort = 'Max radius left on corners', sDescriptionLong = 'Radius-limit left by the tool at each corner of the feature', sType = 'd', sMinUserLevel = '1', sMessageId = ''},
{ sName = 'bAntiSplint', sValue = 'false', sDescriptionShort = 'Use Anti-Splint strategy', sDescriptionLong = 'The strategy will apply blade cuts on corner to avoid wood splint', sType = 'b', sMinUserLevel = '1', sMessageId = ''}
}
}
return STR0002Data
+494
View File
@@ -0,0 +1,494 @@
-- Strategia: STR0003
-- Descrizione
-- Lama + motosega per slot
-- Feature: tipo lapjoint
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
local FeatureData = require( 'FeatureData')
-- strategie di base
local SlotByBlade = require( 'SLOTBYBLADE')
local SlotByChainSaw = require( 'SLOTBYCHAINSAW')
-- Tabella per definizione modulo
local STR0003 = {}
local Strategy = {}
local Blade = {}
local Chainsaw = {}
Blade.Result = {}
Chainsaw.Result = {}
-------------------------------------------------------------------------------------------------------------
local function IsTopologyOk( Proc)
if Proc.Topology.bAllRightAngles and
( Proc.Topology.sName == 'Pocket-5-Blind' or
Proc.Topology.sName == 'Groove-3-Through' or
Proc.Topology.sName == 'Groove-4-Blind' or
Proc.Topology.sName == 'Tunnel-4-Through') then
return true
else
return false
end
end
local function GetCompletionPercentage( Proc, Result)
local dNotMachinedArea = 0
local dCompletionPercentage = 0
if Proc.Topology.sFamily == 'Tunnel' then
dNotMachinedArea = Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
if #Result == 2 then
dNotMachinedArea = dNotMachinedArea - Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[2].dDepthMachined)
end
else
if #Result == 1 then
dNotMachinedArea = Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
elseif #Result == 2 then
dNotMachinedArea = ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength - Result[2].dDepthMachined) * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
elseif #Result == 3 then
dNotMachinedArea = ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength - Result[2].dDepthMachined - Result[3].dDepthMachined) * ( Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength - Result[1].dDepthMachined)
end
end
dCompletionPercentage = 100 - dNotMachinedArea / Proc.MainFaces.LongFaces[1].dArea * 100
return dCompletionPercentage
end
local function AddResult( Machining, Result)
table.insert( Result, {})
if not Result.Bottom then
Result.Bottom = {}
end
if not Result.Side then
Result.Side = {}
end
if not Result.Opposite then
Result.Opposite = {}
end
if Machining.sEdgeType == 'Bottom' then
table.insert( Result.Bottom, Machining)
elseif Machining.sEdgeType == 'Side' then
table.insert( Result.Side, Machining)
elseif Machining.sEdgeType == 'Opposite' then
table.insert( Result.Opposite, Machining)
else
error('AddResult : unknown edge type')
end
return Result
end
function Blade.AddResult( Cutting)
AddResult( Cutting, Blade.Result)
end
function Blade.AddMachiningAllSteps( Proc, Cutting, AuxiliaryData)
local bMachiningAdded = false
if not AuxiliaryData then
AuxiliaryData = {}
end
AuxiliaryData.Clones = {}
local dOriginalRadialOffset = Cutting.dRadialOffset
local dOriginalLeadInPerpDistance = Cutting.LeadIn.dPerpDistance
local dOriginalLeadOutPerpDistance = Cutting.LeadOut.dPerpDistance
for i = Cutting.HorizontalSteps.nCount, 1, -1 do
AuxiliaryData.Clones[i] = {}
AuxiliaryData.Clones[i].LeadIn = {}
AuxiliaryData.Clones[i].LeadOut = {}
AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffset + Cutting.HorizontalSteps.dStep * ( i - 1)
-- update distanza perpendicolare attacco per contemplare l'offset applicato
AuxiliaryData.Clones[i].LeadIn.dPerpDistance = dOriginalLeadInPerpDistance - Cutting.dRadialOffset
AuxiliaryData.Clones[i].LeadOut.dPerpDistance = dOriginalLeadOutPerpDistance - Cutting.dRadialOffset
end
bMachiningAdded = MachiningLib.AddNewMachining( Proc, Cutting, AuxiliaryData)
return bMachiningAdded
end
function Chainsaw.AddResult( Mortising)
AddResult( Mortising, Chainsaw.Result)
end
function Chainsaw.AddMachiningAllSteps( Proc, Mortising, AuxiliaryData)
local bMachiningAdded = false
if not AuxiliaryData then
AuxiliaryData = {}
end
AuxiliaryData.Clones = {}
local dOriginalRadialOffsetMortising = Mortising.dRadialOffset
for i = Mortising.VerticalSteps.nCount, 1, -1 do
AuxiliaryData.Clones[i] = {}
AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffsetMortising + Mortising.VerticalSteps.dStep * ( i - 1)
end
bMachiningAdded = MachiningLib.AddNewMachining( Proc, Mortising, AuxiliaryData)
return bMachiningAdded
end
function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
-- TODO da implementare gestione feature lunghe e spezzatura
-- carico parametri da default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti)
local StrategyLib = {}
StrategyLib.Config = require( 'STR0003\\STR0003Config')
Strategy.sName = StrategyLib.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.Result = {}
Strategy.Result.sInfo = ''
Blade.Result = {}
Chainsaw.Result = {}
if not IsTopologyOk( Proc) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
EgtOutLog( sErr)
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.sInfo = 'Topology'
return false, Strategy.Result
end
-- se tasca su faccia sotto la strategia non è applicabile (la sega a catena in generale non può lavorare da sotto)
-- TODO se OnlySaw questo test è da rimuovere ma bisogna considerare anche la lama da sotto
if Proc.AffectedFaces.bBottom and ( Proc.nFct > 3 or not Proc.AffectedFaces.bTop) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket on bottom face'
EgtOutLog( sErr)
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Result.sInfo = 'Direction'
return false, Strategy.Result
end
-- lama
-- lavorazione di lama - fondo della tasca o fino a massimo materiale se tunnel
local Cutting = {}
local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade}
if Proc.Topology.sFamily == 'Tunnel' then
Cutting = SlotByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
else
Cutting = SlotByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
end
Blade.AddResult( Cutting)
-- lato opposto del tunnel
if Proc.Topology.sFamily == 'Tunnel' then
Cutting = SlotByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
Blade.AddResult( Cutting)
else
-- se la lama non è arrivata sul fondo e c'è almeno un lato aperto va lavorato
if Blade.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then
-- eventuale lavorazione di lama - lato della tasca da cui inizia la lavorazione
if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then
Cutting = SlotByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
Blade.AddResult( Cutting)
end
-- eventuale lavorazione di lama - lato della tasca in cui finisce la lavorazione
if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then
Cutting = SlotByBlade.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
Blade.AddResult( Cutting)
end
-- la lama è arrivata sul fondo e tasca passante, non servono ulteriori lavorazioni
elseif #( Proc.MainFaces.SideFaces) == 0 then
Strategy.Parameters.bFinishWithChainSaw = false
Strategy.Parameters.bNotCompleteWithBladeRadius = false
end
end
local nIsApplicableCount = 0
local dFinalCompletionPercentage = 100
local bAreAllMachiningsAdded = true
for i = 1, #Blade.Result.Bottom do
if Blade.Result.Bottom[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded = Blade.AddMachiningAllSteps( Proc, Blade.Result.Bottom[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Bottom[i].sMessage
end
end
for i = 1, #Blade.Result.Side do
if Blade.Result.Side[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded = Blade.AddMachiningAllSteps( Proc, Blade.Result.Side[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Side[i].sMessage
end
end
for i = 1, #Blade.Result.Opposite do
if Blade.Result.Opposite[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded = Blade.AddMachiningAllSteps( Proc, Blade.Result.Opposite[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Blade.Result.Opposite[i].sMessage
end
end
if nIsApplicableCount > 0 then
-- TODO sistemare il calcolo completamento - implementare calcolo area lavorata
if not Strategy.Parameters.bNotCompleteWithBladeRadius and Cutting.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
Strategy.Result.sStatus = 'Completed'
else
Strategy.Result.sStatus = 'Not-Completed'
-- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante
dFinalCompletionPercentage = Cutting.dCompletionPercentage
end
else
Strategy.Result.sStatus = 'Not-Applicable'
Strategy.Parameters.bFinishWithChainSaw = false
end
if not Strategy.Parameters.bFinishWithChainSaw then
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dFinalCompletionPercentage)
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Blade')
local MRRParametersBlade = {
dStep = TOOLS[Cutting.nToolIndex].dThickness,
dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength),
dFeed = TOOLS[Cutting.nToolIndex].Feeds.dFeed}
local dMRRBlade = MachiningLib.GetToolMRR( MRRParametersBlade)
Strategy.Result.dMRR = dMRRBlade
return bAreAllMachiningsAdded, Strategy.Result
end
-- sega a catena
local Mortising = {}
OptionalParameters = {}
if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then
-- si lavora solamente l'impronta lama sui lati chiusi
if ( Blade.Result.Bottom[1].dResidualDepth < 10 * GEO.EPS_SMALL) and
( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.dLength > 3 * Blade.Result.Bottom[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
if not Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
end
if not Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Bottom[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
end
-- si lavora tutto il fondo
else
local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
end
-- ancora materiale residuo - se possibile si lavora dal lato
if Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].dResidualDepth > 10 * GEO.EPS_SMALL and #Proc.MainFaces.SideFaces == 1 then
-- si lavora solamente l'impronta lama sul fondo
if ( #Blade.Result.Side > 0) and Blade.Result.Side[1].dResidualDepth < 10 * GEO.EPS_SMALL then
if ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
elseif ( Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
end
-- si lavora tutto il lato
else
local dBladeResidualDepth
if #Blade.Result.Side > 0 then
dBladeResidualDepth = Blade.Result.Side[1].dResidualDepth
else
dBladeResidualDepth = Blade.Result.Bottom[1].dResidualDepth
end
if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then
local OptionalParameters = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
elseif Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsEndOpen then
local OptionalParameters = { dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
end
end
Chainsaw.AddResult( Mortising)
end
elseif Proc.Topology.sName == 'Groove-3-Through' then
if Blade.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then
-- si lavora tutto il fondo
local OptionalParameters = { dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
-- ancora materiale residuo - si lavorano i lati
if Chainsaw.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then
-- si lavora solamente l'impronta lama sul fondo
if ( Blade.Result.Side[1].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength > 3 * Blade.Result.Side[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) and
( Blade.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2].dLength > 3 * Blade.Result.Side[2].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
local OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
-- ancora materiale residuo - si lavora da entrambi i lati
if Chainsaw.Result.Side[1].dResidualDepth > 10 * GEO.EPS_SMALL then
local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Side[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Side[2].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
Chainsaw.AddResult( Mortising)
-- lavorando dai due lati non c'è materiale residuo - si può eliminare la lavorazione del fondo
if Chainsaw.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL then
Chainsaw.Result.Bottom[1].bIsApplicable = false
end
end
-- si lavora tutto il lato
else
local OptionalParameters = { dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
-- ancora materiale residuo - si lavora da entrambi i lati
if Chainsaw.Result.Side[1].dResidualDepth > 10 * GEO.EPS_SMALL then
Chainsaw.Result.Side[1].bIsApplicable = false
local OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Side[2].dResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
Chainsaw.AddResult( Mortising)
-- lavorando dai due lati non c'è materiale residuo - si può disabilitare la lavorazione del fondo
if Chainsaw.Result.Side[2].dResidualDepth < 10 * GEO.EPS_SMALL then
Chainsaw.Result.Bottom[1].bIsApplicable = false
end
end
end
end
end
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
-- si lavora solamente l'impronta lama sul lato opposto
if ( Blade.Result.Opposite[1].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1].dLength > 3 * Blade.Result.Opposite[1].dBladeMarkLength - 10 * GEO.EPS_SMALL) and
( Blade.Result.Opposite[2].dResidualDepth < 10 * GEO.EPS_SMALL and Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2].dLength > 3 * Blade.Result.Opposite[2].dBladeMarkLength - 10 * GEO.EPS_SMALL) then
local OptionalParameters = { sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
if Chainsaw.Result.Opposite[1].dResidualDepth > GEO.EPS_SMALL or Chainsaw.Result.Opposite[2].dResidualDepth > GEO.EPS_SMALL then
Chainsaw.Result.Opposite[1].bIsApplicable = false
Chainsaw.Result.Opposite[2].bIsApplicable = false
local OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[1].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'Start', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, sSideToMachine = 'End', dLengthToMachine = Blade.Result.Opposite[2].dBladeMarkLength, dMaxElev = 0}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
Chainsaw.AddResult( Mortising)
end
else
local OptionalParameters = { dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
if Chainsaw.Result.Opposite[1].dResidualDepth > GEO.EPS_SMALL then
Chainsaw.Result.Opposite[1].bIsApplicable = false
local OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA}
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[2].dResidualDepth + BeamData.CUT_EXTRA}
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
Chainsaw.AddResult( Mortising)
end
end
end
local nIsApplicableCount = 0
local dFinalCompletionPercentage = 100
local bAreAllMachiningsAdded = true
for i = 1, #Chainsaw.Result.Bottom do
if Chainsaw.Result.Bottom[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Bottom[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Bottom[i].sMessage
end
end
for i = 1, #Chainsaw.Result.Side do
if Chainsaw.Result.Side[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Side[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Side[i].sMessage
end
end
for i = 1, #Chainsaw.Result.Opposite do
if Chainsaw.Result.Opposite[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Opposite[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Opposite[i].sMessage
end
end
if nIsApplicableCount > 0 then
if Mortising.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
Strategy.Result.sStatus = 'Completed'
else
Strategy.Result.sStatus = 'Not-Completed'
-- TODO al momento si assume che la percentuale di completamento dell'ultima lavorazione sia quella rilevante
dFinalCompletionPercentage = Mortising.dCompletionPercentage
end
else
Strategy.Result.sStatus = 'Not-Applicable'
end
Strategy.Result.nCompletionIndex = FeatureData.GetFeatureCompletionIndex( dFinalCompletionPercentage)
Strategy.Result.nQuality = FeatureData.GetFeatureQuality( 'Chainsaw')
local MRRParametersBlade = {
dStep = TOOLS[Cutting.nToolIndex].dThickness,
dSideStep = min( TOOLS[Cutting.nToolIndex].dSideStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength),
dFeed = TOOLS[Cutting.nToolIndex].Feeds.dFeed}
local MRRParametersChainsaw = {
dStep = min( TOOLS[Mortising.nToolIndex].dStep, Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1].dLength),
dSideStep = TOOLS[Mortising.nToolIndex].dThickness,
dFeed = TOOLS[Mortising.nToolIndex].Feeds.dFeed}
local dMRRBlade = MachiningLib.GetToolMRR( MRRParametersBlade)
local dMRRChainsaw = MachiningLib.GetToolMRR( MRRParametersChainsaw)
Strategy.Result.dMRR = ( dMRRBlade + dMRRChainsaw) / 2
return bAreAllMachiningsAdded, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
return STR0003
@@ -0,0 +1,13 @@
-- Parametri configurabili da cliente per strategia: STR0001
local STR0003Data = {
sStrategyId = 'STR0003',
Parameters = {
{ sName = 'bFinishWithChainSaw', sValue = 'true', sDescriptionShort = 'Finish with chainsaw if needed', sDescriptionLong = 'Finish with chainsaw if needed', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bForceLongcutBlade', sValue = 'false', sDescriptionShort = 'Force ripping blade', sDescriptionLong = 'Force the use of ripping blade, designed for cuts parallel to the grain', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bNotCompleteWithBladeRadius', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bUseZigZagMortising', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
}
}
return STR0003Data
+143
View File
@@ -0,0 +1,143 @@
; Commento per evitare BOM con UTF-8
[Comments]
STR0001 = Tenone a coda di rondine. Lama + fresa a coda di rondine
STR0002 = Topologia tipo LapJoint. Svuotatura con fresa
STR0003 = Topologia tipo LapJoint. Lama + motosega
[Strategies]
; Processing , Gruppo , Topologia , Strategie
;Feature : Cut
10,1,Feature,
;Feature : Longitudinal Cut
10,0,Feature,
;Feature : Double Cut
11,1,Feature,
; Feature : Ridge or Valley Cut
12,0,Feature,
; Feature : Saw Cut
13,0,Feature,
; Feature : Slot
16,0,Pocket-5-Blind,STR0002,STR0003
16,0,Groove-4-Blind,STR0002,STR0003
16,0,Groove-3-Through,STR0002,STR0003
16,0,Groove-3-Blind,STR0002
16,0,Rabbet-2-Through,STR0002
16,0,Tunnel-4-Through,STR0003
; Feature : Front Slot
17,0,Pocket-5-Blind,STR0002,STR0003
17,0,Groove-4-Blind,STR0002,STR0003
17,0,Groove-3-Blind,STR0002
17,0,Groove-3-Through,STR0002,STR0003
17,0,Rabbet-2-Through,STR0002
17,0,Tunnel-4-Through,STR0003
; Feature : Birds Mouth
20,0,Feature,
; Feature : Hip or Valley Rafter Notch
25,0,Feature,
; Feature : Ridge Lap
30,1,Pocket-5-Blind,STR0002,STR0003
30,1,Groove-4-Blind,STR0002,STR0003
30,1,Groove-3-Blind,STR0002
30,1,Groove-3-Through,STR0002,STR0003
30,1,Rabbet-2-Through,STR0002
30,1,Tunnel-4-Through,STR0003
; Feature : Lap Joint
30,0,Pocket-5-Blind,STR0002,STR0003
30,0,Groove-4-Blind,STR0002,STR0003
30,0,Groove-3-Blind,STR0002
30,0,Groove-3-Through,STR0002,STR0003
30,0,Rabbet-2-Through,STR0002
30,0,Tunnel-4-Through,STR0003
; Feature : Notch/Rabbet
32,0,Pocket-5-Blind,STR0002,STR0003
32,0,Groove-4-Blind,STR0002,STR0003
32,0,Groove-3-Blind,STR0002
32,0,Groove-3-Through,STR0002,STR0003
32,0,Rabbet-2-Through,STR0002
32,0,Tunnel-4-Through,STR0003
; Feature : Block Haus
33,0,Feature,
; Feature : Notch
34,0,Pocket-5-Blind,STR0002,STR0003
34,0,Groove-4-Blind,STR0002,STR0003
34,0,Groove-3-Blind,STR0002
34,0,Groove-3-Through,STR0002,STR0003
34,0,Rabbet-2-Through,STR0002
34,0,Tunnel-4-Through,STR0003
; Feature : French Ridge Lap
35,1,Feature,
; Feature : Chamfer
36,0,Feature,
; Feature : Block Haus Half Lap
37,0,Feature,
; Feature : Block Haus Front
38,0,Feature,
; Feature : Pocket
39,0,Pocket-5-Blind,STR0002,STR0003
39,0,Groove-4-Blind,STR0002,STR0003
39,0,Groove-3-Blind,STR0002
39,0,Groove-3-Through,STR0002,STR0003
39,0,Rabbet-2-Through,STR0002
39,0,Tunnel-4-Through,STR0003
; Feature : Drilling
40,0,Feature,
; Feature : Tenon
50,1,Feature,
; Feature : Mortise
50,0,Feature,
; Feature : Front Mortise
51,0,Feature,
; Feature : House
52,1,Feature,
; Feature : House Mortise
53,0,Feature,
; Feature : Dovetail Tenon
55,1,Feature,STR0001
; Feature : Dovetail Mortise
55,0,Feature,
; Feature : Dovetail Mortise Front
56,0,Feature,
; Feature : Marking
60,0,Feature,
; Feature : Text
61,0,Feature,
; Feature : Scarf Simple
70,1,Feature,
; Feature : Scarf Joint
71,1,Feature,
; Feature : Step Joint
80,1,Feature,
; Feature : Step Joint Notch
80,0,Feature,
; Feature : Planing
90,0,Feature,
; Feature : Front Profile
100,0,Feature,
; Feature : Head Concave Profile
101,0,Feature,
; Feature : Head Convex Profile
102,0,Feature,
; Feature : Head Cambered Profile
103,0,Feature,
; Feature : Round Arch
104,0,Feature,
; Feature : Head Profile
106,0,Feature,
; Feature : Sphere
107,0,Feature,
; Feature : Triangle Cut
120,0,Feature,
; Feature : TyroleanDovetail
136,0,Feature,
; Feature : Dovetail
138,0,Feature,
; Feature : Free Contour
250,0,Feature,
; Feature : Outline
251,0,Feature,
; Feature : Aperture
252,0,Feature,
; Feature : Variant
900,0,Feature,
; Feature Decor
959,0,Feature,
+31
View File
@@ -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
+4
View File
@@ -0,0 +1,4 @@
==== Beam Update Log ====
Versione 2.6-- (--/--/2024)
- Primo commit creazione nuovo automatismo BEAM con strategie
+6
View File
@@ -0,0 +1,6 @@
-- Version.lua by EgalWare s.r.l. 2024/04/02
-- Gestione della versione di Beam
NAME = 'Beam'
VERSION = '2.6d1'
MIN_EXE = '2.6g1'