169 Commits

Author SHA1 Message Date
luca.mazzoleni 9fcd805ed5 - in FeatureLib -> GetFeatureSplittingPoints correzioni e migliorie
- in MachiningLib -> GetSplitMachinings correzione all'assegnazione del segmento per gli edge non lavorati completamente
- in STR0003 gestito ordinamento lavorazioni lama + sega a catena
- altre piccole migliorie
2024-12-06 16:29:34 +01:00
luca.mazzoleni eccfb96c22 - in STR0003 aggiunto splitting lavorazioni lama e sega a catena e refactoring
- da testare
2024-12-05 17:54:30 +01:00
luca.mazzoleni a6ddaa8bbd - alcune correzioni nel calcolo approccio retrazione per lavorazioni di coda e split
- in STR0003 aggiunta gestione lavorazioni di coda per sega a catena
2024-12-03 16:47:47 +01:00
luca.mazzoleni bb82dcb724 - in MachiningLib -> StartsLeftSide contemplato ToolInvert
- in SLOTBYBLADE aggiunta gestione lavorazioni di coda
- in STR0003 > lama aggiunta gestione lavorazioni di coda
- in Config STR0003 e STR0004 aggiunto parametro dExtendAfterTail per decidere di quanto estendere una lavorazione oltre la coda
2024-12-03 14:55:46 +01:00
andrea.villa d58be78868 - Prima bozza separazione con doppia lavorazione lama e lama da sotto.
- HEADCUT derivata da SPLITCUT. Da verificare se mantenere separate o fondere in un'unica strategia
2024-12-02 14:46:08 +01:00
luca.mazzoleni 1cb9104404 Merge branch 'MachiningsOnTailManagement' into develop 2024-11-28 18:00:07 +01:00
luca.mazzoleni 19a47115ea - in BeamExec corretto calcolo della distanza dal pezzo successivo in caso di ultimo pezzo per tenere conto di grezzo scaricabile o meno 2024-11-28 17:59:50 +01:00
luca.mazzoleni 6da682dfed - in MachiningLib corretta CanMoveAfterSplit
- in SLOTBYCHAINSAW e STR0004 modifiche alla gestione delle lavorazioni in coda
2024-11-27 11:51:21 +01:00
luca.mazzoleni 08d3f7ff6d aggiunta la gestione delle lavorazioni in coda, per decidere se spostare dopo separazione o accorciarle:
- in MachiningLib aggiunte funzioni StartsLeftSide e CanExtendAfterTail; modificata GetSplitMachinings
- Machining.nPart rinominato nSegment
- in SLOTBYCHAINSAW.Make aggiunta sezione per gestire lavorazioni di coda
-  STR0004 adeguata per passare alla strategia di base le informazioni sulle lavorazioni di coda
2024-11-26 13:33:36 +01:00
luca.mazzoleni 229e98cf9d Merge branch 'NewParametersManagement' into develop 2024-11-22 17:56:01 +01:00
luca.mazzoleni d7096a8a68 - migliorie al tipo di parametro 'combo'
- aggiunto parametro sCanDamageNextPiece
2024-11-22 17:55:32 +01:00
andrea.villa b0f26bdea2 BOZZA sviluppo nuove tipologie di parametri
- tipo di parametro "Combo"
- nuovo campo sNameNge che verrà scritto nelle info nel Processing
2024-11-22 12:56:12 +01:00
luca.mazzoleni 2586407ec9 Merge branch 'STR0004_Splitting' into develop 2024-11-21 18:12:14 +01:00
luca.mazzoleni a34a62d635 Merge remote-tracking branch 'origin/develop' into STR0004_Splitting 2024-11-21 18:07:37 +01:00
luca.mazzoleni 44215b3b4e - in MachiningLib -> GetSplitMachinings correzione a inversione start/end 2024-11-21 18:04:18 +01:00
luca.mazzoleni a2b49fdf3e - in MachiningLib aggiunta la scrittura dello spezzone nella lavorazione
- in STR0004 aggiunto ordinamento lavorazioni
- piccole aggiunte varie
2024-11-21 17:53:24 +01:00
luca.mazzoleni 21b73e0031 - in MachiningLib aggiunta funzione GetSplitMachinings, estrapolata da STR0004 (modificata di conseguenza) 2024-11-20 14:58:04 +01:00
andrea.villa 54c86774b7 - Corretta creazione barra in caso di più pezzi
- Libreria specifica per Log
- Nuovo log feature con tutte le strategie disponibili
- Nel log della matrice rotazioni si indica se la strategia scelta è completa (C), parziale (P) o non applicabile (N)
2024-11-20 14:28:20 +01:00
luca.mazzoleni 80c5a5a393 - piccola correzione in SLOTBYCHAINSAW 2024-11-19 09:21:41 +01:00
luca.mazzoleni 13ae86b6a7 - in STR0004 miglioramenti a spezzatura 2024-11-18 18:29:18 +01:00
luca.mazzoleni 8119643221 Merge branch 'develop' into STR0004_Splitting 2024-11-18 17:32:26 +01:00
luca.mazzoleni 941954825d - in BeamLib aggiunta funzione TableCopyDeep per copiare una tabella mantenendo senza riferimenti le sottotabelle
- in STR0004 primo implemento di spezzatura lavorazioni, da completare
- in SLOTBYCHAINSAW scritti alcuni parametri realtivi al lato nel Machining
2024-11-18 17:32:10 +01:00
andrea.villa 8d1286dd71 Calcolo rotazione scritto in modo più comprensibile 2024-11-18 16:03:53 +01:00
andrea.villa 4abc2c01af Piccola modifica al nome delle variabili 2024-11-18 15:36:11 +01:00
andrea.villa 7e6d8f4172 Corretta gestione rotazione pezzo nel DISP in caso che la soluzione scelta sia una prerotazione 2024-11-18 15:29:32 +01:00
luca.mazzoleni 5aa2b5ac4d Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2024-11-14 10:52:36 +01:00
luca.mazzoleni ae4c3f9156 - in FeatureLib e STR0002 invertito ordine dei punti di spezzatura, ora è da testa a coda 2024-11-14 10:52:32 +01:00
andrea.villa a4f6e10dc3 Merge branch 'CollectBasedOnCombinations' into develop 2024-11-14 10:25:24 +01:00
andrea.villa fc047c2350 Ottimizzazione collect. Si calcola solo se la rotazione è abilitata, in base alle combinazioni disponibili 2024-11-14 10:23:58 +01:00
luca.mazzoleni 28946a0291 - in FaceData, nella trimesh generata TunnelAddedFaces.MiddleFaceTm, aggiunte le facce di contenimento laterali per garantire lati chiusi in svuotatura splittata 2024-11-13 18:42:01 +01:00
luca.mazzoleni 9375cd0868 Merge branch 'GetSplittingPoints' into develop 2024-11-11 14:50:50 +01:00
luca.mazzoleni 8bd772c96d - in STR0002 -> GetSplitSurfaces correzione a taglio superfici 2024-11-11 14:48:18 +01:00
luca.mazzoleni 2fff4438c0 - in STR0002 overlap tra le passate portato a 1/2 MILL_OVERLAP
- in FaceData in ogni Edge si scrive ora la lunghezza proiettata lungo X dLengthOnX
- in FeatureLib aggiunta la funzione MachiningNeedsSplitting per unificare il check di necessità spezzatura
2024-11-11 11:52:21 +01:00
luca.mazzoleni a17c62c15f - GetSplittedSurfaces convertita in GetSplitSurfaces 2024-11-11 08:59:49 +01:00
luca.mazzoleni 20c8518f1d - in STR0002 -> GetSplittedSurfaces aggiunto overlap tra le superfici 2024-11-08 18:32:40 +01:00
luca.mazzoleni 730d37c917 - in STR0002 miglioramenti vari 2024-11-08 18:00:28 +01:00
luca.mazzoleni 184a78d34c - in FeatureLib aggiunta funzione GetFeatureSplittingPoints che restituisce i punti di spezzatura di una feature, estrapolata da STR0002
- in STR0002 aggiunta funzione GetSplittedSurfaces per contemplare nuova funzione di restituzione punti e restituire direttamente le superfici trimmate alla Make
- piccole correzioni varie
2024-11-08 16:37:10 +01:00
luca.mazzoleni a33e794b1e Merge branch 'STR0004_SlotByChainsaw' into develop 2024-11-07 16:54:54 +01:00
luca.mazzoleni f212c0cede Merge branch 'develop' into STR0004_SlotByChainsaw 2024-11-07 16:53:38 +01:00
luca.mazzoleni 38fdaca7bf - FeatureData rinominata FeatureLib
- piccole migliorie stilistiche
2024-11-07 16:53:06 +01:00
andrea.villa 7b580b24bb Merge branch 'MachiningInRotation' into develop 2024-11-06 17:31:58 +01:00
andrea.villa 23bbd938fc Prima versione funzionante scelta soluzioni che contempla le pre-rotazioni 2024-11-06 17:31:38 +01:00
andrea.villa 21dd75b4a6 Migliorata identificazione combinazione disponibile. Ora 3 modi: Basic, NoRotation,Advanced 2024-11-06 12:17:56 +01:00
luca.mazzoleni a8ec76f451 Merge branch 'develop' into STR0004_SlotByChainsaw 2024-11-06 11:33:39 +01:00
luca.mazzoleni 9b5bb25c76 - implementata STR0004, strategia SlotByChainSaw 2024-11-06 11:32:51 +01:00
andrea.villa b9c492fe5a Merge branch 'develop' into MachiningInRotation 2024-11-06 10:12:36 +01:00
andrea.villa fdcb428002 Merge branch 'MachiningInRotation' into develop 2024-11-06 10:11:57 +01:00
andrea.villa 91c883b87c Completata funzione applicazione lavorazione in fase appropriata. MANCA prerotazione 2024-11-06 10:11:40 +01:00
luca.mazzoleni 8e151758b1 - creata STR0004 copiando do STR0003. Da implementare 2024-11-05 18:30:11 +01:00
luca.mazzoleni 1132369f1e - in STR0003 SawPlusChain corretto ordine passate orizzontali lama 2024-11-05 18:09:07 +01:00
luca.mazzoleni b9bb1aefdd - in BeamExec > GetToolsFromDB, in lettura parametri con EgtGetValInNotes, aggiunta 'd' se valori numerici
- in SPLITCUT > GetSplitStrategy gestito caso in cui GetMaxMatReductionBladeCut non è presente in BeamData anche per il Machining[2]
2024-11-05 17:20:44 +01:00
andrea.villa 2b9113347a Prima bozza (non funzionante) applicazione lavorazioni nella relativa rotazione 2024-11-05 16:37:50 +01:00
andrea.villa 7c80c4d3d8 Merge branch 'GetBestCombination' into develop 2024-11-05 13:27:48 +01:00
andrea.villa 69fc865452 Completata funzione scelta miglior combinazione 2024-11-05 13:27:36 +01:00
andrea.villa 88bc848966 Merge branch 'AvailableCombinations' into develop 2024-11-05 12:06:17 +01:00
andrea.villa 81a274563f Completata funzione identificazione combinazioni disponibili in base a configurazione 2024-11-05 12:06:06 +01:00
andrea.villa 32fa372012 Prima bozza scelta combinazioni disponibili in base a configurazione 2024-11-05 09:36:46 +01:00
andrea.villa 21da5f633d - Prima bozza gestione matrice delle rotazioni
- Adeguamento strategia 0002 e SPLITCUT a nuovo metodo gestione matrice
2024-11-04 16:52:42 +01:00
andrea.villa c24fef22a7 Merge branch 'ProcessAgainOnError' into develop 2024-10-09 13:16:22 +02:00
andrea.villa 35e8ef2482 - ProcessFeature divisa in GetProcessings(collect e raccolta strategie) e ProcessMachinings (scelta strategia migliore e applicazione lavorazioni)
- in ProcessMachinings predisposto ciclo per ricalcolare in caso di errore su Apply
- Nuova lista globale PROCESSINGS
- Calcolo tempi commentato, da riposizionare in base alle misure che si vogliono effettuare
- Predisposizione funzione per calcolo della matrice delle combinazioni (completamente da fare)
2024-10-09 13:16:11 +02:00
luca.mazzoleni 23d5f82403 Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2024-10-08 16:15:49 +02:00
luca.mazzoleni ec734ca99d - in MachiningLib aggiunta scrittura cloni geometria
- in STR0003 sistemati commenti
2024-10-08 16:11:54 +02:00
andrea.villa 34c5ecc5ec Merge branch 'SplitCut' into develop 2024-10-08 16:09:18 +02:00
andrea.villa 362f3fd2b0 - Prima implementazione creazioni fasi
- Piccole migliorie varie
- Corretta lettura info utensile profilato
- Su Proc, aggiunte alcune note pezzo
2024-08-09 16:46:51 +02:00
andrea.villa 9acd52ea10 - Prima versione strategia standard SPLITCUT e aggiunta chiamata della strategia
- Prima versione strategia core FACEBYBLADE
- Aggiunte altre UserNotes e corretto append se più note
2024-08-09 09:46:01 +02:00
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
35 changed files with 8113 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

+574
View File
@@ -0,0 +1,574 @@
--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')
-- TODO tabella da compleatare man mano che si inseriscono le varie strategie
-- ESEMPIO SCRITTURA TABELLA CON STRATEGIE DISPONIBILI
---------------------------------------------------------------------
-- Feature : Cut
-- if ID.TipoFeature( Proc) then
-- if Proc.Topology.sName == 'QQQQQQQQQ' then
-- Strategies = {
-- { sStrategyId = 'STR9999',
-- Parameters = {
-- { sName = 'Val_1', sValue = '15', sType = 'd'},
-- { sName = 'Val_2', sValue = 'false', sType = 'b'}
-- }
-- }
-- { sStrategyId = 'STR9998'}
-- }
-- end
-- end
----------------------------------------------------------------------------------
-- *** EGALWARE ***
----------------------------------------------------------------------------------
local function GetStrategies_Egalware( Proc)
local Strategies = {}
---------------------------------------------------------------------
-- Feature : Cut
if ID.IsHeadCut( Proc) then
Strategies = { { sStrategyId = 'HEADCUT'}}
---------------------------------------------------------------------
-- Feature : Cut
elseif ID.IsSplitCut( Proc) then
Strategies = { { sStrategyId = 'SPLITCUT'}}
---------------------------------------------------------------------
-- 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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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 = {}
---------------------------------------------------------------------
-- Feature : Cut
if ID.IsHeadCut( Proc) then
Strategies = { { sStrategyId = 'HEADCUT'}}
---------------------------------------------------------------------
-- Feature : Cut
elseif ID.IsSplitCut( Proc) then
Strategies = { { sStrategyId = 'SPLITCUT'}}
---------------------------------------------------------------------
-- 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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-4-Blind' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Groove-3-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0003'}, { sStrategyId = 'STR0004'}}
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
+1460
View File
File diff suppressed because it is too large Load Diff
+477
View File
@@ -0,0 +1,477 @@
-- 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( nRawId, OriXR, PosXR, dDeltaSucc)
EgtAddPhase()
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
-------------------------------------------------------------------------------------------------------------
--- funzione che ruota il pezzo, da lanciare per creare la disposizione corretta
function BeamLib.RotatePart( Part, nPosition)
-- primo posizionamento
if nPosition == 1 then
; -- il pezzo è già in posizione
-- rotazione 90°
elseif nPosition == 2 then
local dDeltaYZ = EgtGetRawPartBBox( Part.idRaw):getDimY() - EgtGetRawPartBBox( Part.idRaw):getDimZ()
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
local bPreMove = dDeltaYZ < 0
-- ruoto le travi della fase corrente
local nRId = Part.idRaw
while nRId do
if bPreMove then EgtMoveRawPart( nRId, vtMove) end
EgtRotateRawPart( nRId, X_AX(), EgtIf( BeamData.RIGHT_LOAD, -90, 90))
if not bPreMove then EgtMoveRawPart( nRId, vtMove) end
nRId = EgtGetNextRawPart( nRId)
end
-- rotazione 180°
elseif nPosition == 3 then
-- ribalto le travi della fase corrente
local nRId = Part.idRaw
while nRId do
EgtRotateRawPart( nRId, X_AX(), 180)
nRId = EgtGetNextRawPart( nRId)
end
-- rotazione 270°
elseif nPosition == 4 then
local dDeltaYZ = EgtGetRawPartBBox( Part.idRaw):getDimY() - EgtGetRawPartBBox( Part.idRaw):getDimZ()
local vtMove = Vector3d( 0, dDeltaYZ / 2 * EgtIf( BeamData.RIGHT_LOAD, -1, 1), dDeltaYZ / 2)
local bPreMove = dDeltaYZ < 0
-- ruoto le travi della fase corrente
local nRId = Part.idRaw
while nRId do
if bPreMove then EgtMoveRawPart( nRId, vtMove) end
EgtRotateRawPart( nRId, X_AX(), EgtIf( BeamData.RIGHT_LOAD, 90, -90))
if not bPreMove then EgtMoveRawPart( nRId, vtMove) end
nRId = EgtGetNextRawPart( nRId)
end
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].sType == 'd' then
Parameters[CustomParameters[i].sName] = tonumber( CustomParameters[i].sValue)
else --CustomParameters[i].sType == 's' or CustomParameters[i].sType == 'combo'
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
---------------------------------------------------------------------
function BeamLib.BinaryToDecimal( dNumber)
local sNumberToConvert = tostring( dNumber)
local dResult = 0
local k = 0
for i = #sNumberToConvert, 1, -1 do
k = k + 1
local n = string.sub(sNumberToConvert, k, k)
dResult = dResult + n*(2^(i-1))
end
return dResult
end
---------------------------------------------------------------------
function BeamLib.DecimalToBinary( dNumber)
local sNumberToConvert = tostring( dNumber)
local n = sNumberToConvert
local tmp = {}
local sResult = ""
for i = sNumberToConvert, 0, -1 do
local q = math.modf(n)
n = n/2
local b = q%2
table.insert(tmp, b)
if (q == 1) then
break
end
end
for i = #tmp, 1, -1 do
sResult = sResult..tmp[i]
end
return tonumber( sResult)
end
---------------------------------------------------------------------
function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
local NumberString = tostring( dNumber)
while #NumberString < CharNumber do
NumberString = '0' .. NumberString
end
return NumberString
end
---------------------------------------------------------------------
--- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle
--- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs
function BeamLib.TableCopyDeep( OriginalTable)
local CopiedTable = {}
for key, value in pairs( OriginalTable) do
if type( value) == "table" then
if isBBox3d( value) then
CopiedTable[ key] = BBox3d( value)
elseif isColor3d( value) then
CopiedTable[ key] = Color3d( value)
elseif isFrame3d( value) then
CopiedTable[ key] = Frame3d( value)
elseif isPoint3d( value) then
CopiedTable[ key] = Point3d( value)
elseif isQuaternion( value) then
CopiedTable[ key] = Quaternion( value)
elseif isVector3d( value) then
CopiedTable[ key] = Vector3d( value)
else
CopiedTable[ key] = BeamLib.TableCopyDeep( value)
end
else
CopiedTable[ key] = value
end
end
return CopiedTable
end
-------------------------------------------------------------------------------------------------------------
return BeamLib
+506
View File
@@ -0,0 +1,506 @@
-- 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')
local Logs = require( 'Logs')
---------------------------------------------------------------------
-- 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
local nMiddleTmId = 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( nMiddleTmId, Proc.Faces[i].ptCenter, -Proc.Faces[i].vtN, false, GDB_ID.ROOT)
end
-- facce laterali
local nLateralTmId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
EgtCutSurfTmPlane( nLateralTmId, ptTunnelCenter, -vtTunnelDirection, false, GDB_ID.ROOT)
-- unione facce
-- TODO cambiare nome alla trimesh?? non contiene più solamente la faccia di mezzo
TunnelAddedFaces.MiddleFaceTm = {}
TunnelAddedFaces.MiddleFaceTm.id = EgtSurfTmBySewing( nAddGrpId, { nMiddleTmId, nLateralTmId}, true)
-- TODO c'è un modo più elegante per raccogliere le informazioni delle facce aggiunte
TunnelAddedFaces.MiddleFaceTm.sType = 'Tunnel'
TunnelAddedFaces.MiddleFaceTm.nFct = Proc.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.dLengthOnX = CurrentEdge.dLength * CurrentEdge.vtToolDirection:getY()
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.dLengthOnX = CurrentEdge.dLength * CurrentEdge.vtToolDirection:getY()
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.dLengthOnX = CurrentEdge.dLength * CurrentEdge.vtToolDirection:getY()
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)
-- scrivo informazioni delle facce nel log
if EgtGetDebugLevel() >= 3 then
Logs.WriteMainFacesLog( Proc, MainFaces)
end
else
EgtOutLog( '---MainFaces NOT NEEDED---')
end
EgtOutLog( '---MainFaces END---')
return MainFaces
end
-------------------------------------------------------------------------------------------------------------
return FaceData
+400
View File
@@ -0,0 +1,400 @@
-- FeatureLib.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 FeatureLib = {}
-- 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 FeatureLib.NeedTopologyFeature( Proc)
-- features tipo taglio
if ID.IsCut( Proc) then
return true
elseif ID.IsHeadCut( Proc) then
return true
elseif ID.IsSplitCut( 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 FeatureLib.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 FeatureLib.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 FeatureLib.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 FeatureLib.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 = max( nQuality - 1, 0.5)
end
return nQuality
end
-------------------------------------------------------------------------------------------------------------
-- funzione che calcola il 'CompositeRating' di ogni strategia
function FeatureLib.CalculateCompositeRating( StrategyResult)
-- se ho tutti i dati che mi servono calcolo il rating della strategia applicato alla feature
if StrategyResult and StrategyResult.nQuality and StrategyResult.nCompletionIndex and StrategyResult.dMRR then
StrategyResult.dCompositeRating = ceil( StrategyResult.nQuality * StrategyResult.nCompletionIndex * StrategyResult.dMRR)
else
StrategyResult.dCompositeRating = 0
end
return StrategyResult
end
-------------------------------------------------------------------------------------------------------------
function FeatureLib.MachiningNeedsSplitting( dMachiningLengthOnX, Part, OptionalParameters)
local bMachiningNeedsSplitting
-- parametri opzionali
if not OptionalParameters then
OptionalParameters = {}
end
local dMaxSegmentLength = OptionalParameters.dMaxSegmentLength or BeamData.LONGCUT_MAXLEN
bMachiningNeedsSplitting = ( dMachiningLengthOnX > dMaxSegmentLength + 10 * GEO.EPS_SMALL)
or ( dMachiningLengthOnX > 0.7 * Part.b3Solid:getDimX() + 10 * GEO.EPS_SMALL)
return bMachiningNeedsSplitting
end
-------------------------------------------------------------------------------------------------------------
function FeatureLib.GetFeatureSplittingPoints( Proc, Part, OptionalParameters)
local vFeatureSplittingPoints = {}
local bFeatureStartsOnEdgeLeft = false
local bFeatureStartsOnEdgeRight = false
local dSplitXLeft = Proc.b3Box:getMin():getX()
local dSplitXRight = Proc.b3Box:getMax():getX()
local dFeatureCentralLength = Proc.b3Box:getDimX()
-- parametri opzionali
if not OptionalParameters then
OptionalParameters = {}
end
local dMaxSegmentLength = OptionalParameters.dMaxSegmentLength or BeamData.LONGCUT_MAXLEN
local dMaxSegmentLengthOnEdges = OptionalParameters.dMaxSegmentLengthOnEdges or BeamData.LONGCUT_ENDLEN
local dMinSegmentLength = OptionalParameters.dMinSegmentLength or dMaxSegmentLengthOnEdges / 2
local dToolOverlapBetweenSegments = OptionalParameters.dToolOverlapBetweenSegments or BeamData.MILL_OVERLAP
-- verifica spezzatura necessaria
if not FeatureLib.MachiningNeedsSplitting( Proc.b3Box:getDimX(), Part) then
return {}
end
-- verifica se necessari spezzoni differenti sugli estremi
if Proc.b3Box:getMin():getX() < Part.b3Solid:getMin():getX() + dMaxSegmentLengthOnEdges - 10 * GEO.EPS_SMALL then
bFeatureStartsOnEdgeLeft = true
end
if Proc.b3Box:getMax():getX() > Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges + 10 * GEO.EPS_SMALL then
bFeatureStartsOnEdgeRight = true
end
-- calcolo punto estremo sinistro
local ptSplitXLeft
if bFeatureStartsOnEdgeLeft then
-- decido punto spezzatura verso la coda
if Proc.b3Box:getDimX() > dMaxSegmentLengthOnEdges * 2 then
dSplitXLeft = max( Part.b3Solid:getMin():getX() + dMaxSegmentLengthOnEdges, Proc.b3Box:getMin():getX() + dMinSegmentLength)
else
-- se pezzo abbastanza piccolo, spezzo in mezzo al 'pezzo + grezzo restante'
if Part.dRestLength + Part.b3Solid:getDimX() < BeamData.dMinRaw * 1.5 then
dSplitXLeft = Part.b3Solid:getMax():getX() - ( ( Part.dRestLength + Part.b3Solid:getDimX()) / 2)
else
dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges)
end
end
dFeatureCentralLength = abs( dSplitXRight - dSplitXLeft)
ptSplitXLeft = Point3d( dSplitXLeft, 0, 0)
end
-- calcolo punto estremo destro
local ptSplitXRight
if bFeatureStartsOnEdgeRight then
dSplitXRight = min( ( Proc.b3Box:getMax():getX() - dMinSegmentLength), Part.b3Solid:getMax():getX() - dMaxSegmentLengthOnEdges)
if dSplitXRight - dSplitXLeft < 500 * GEO.EPS_SMALL then
dSplitXRight = dSplitXLeft - dToolOverlapBetweenSegments
dFeatureCentralLength = 0
else
dFeatureCentralLength = dSplitXRight - dSplitXLeft
end
ptSplitXRight = Point3d( dSplitXRight, 0, 0)
end
-- aggiungo eventuale punto estremo destro
if bFeatureStartsOnEdgeRight then
table.insert( vFeatureSplittingPoints, ptSplitXRight)
end
-- aggiungo punti centrali della feature
if dFeatureCentralLength > 0 then
local nSplitParts = max( ceil( dFeatureCentralLength / dMaxSegmentLength + 10 * GEO.EPS_SMALL), 1)
local dSplitPartsLen = dFeatureCentralLength / nSplitParts
for i = 1, ( nSplitParts - 1) do
local ptOn
local dCurrentPointX = dSplitXRight - i * dSplitPartsLen
ptOn = Point3d( dCurrentPointX, 0, 0)
table.insert( vFeatureSplittingPoints, ptOn)
end
end
-- aggiungo eventuale punto estemo sinistro
if bFeatureStartsOnEdgeLeft then
table.insert( vFeatureSplittingPoints, ptSplitXLeft)
end
return vFeatureSplittingPoints
end
-------------------------------------------------------------------------------------------------------------
return FeatureLib
+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
+213
View File
@@ -0,0 +1,213 @@
-- Logs.lua by Egalware s.r.l. 2024/11/20
-- Libreria per logs vari
-- Tabella per definizione modulo
local Logs = {}
-------------------------------------------------------------------------------------------------------------
function Logs.WriteFeaturesLog( ProcessingsOnPart, PartInfo)
EgtOutLog( ' === === === === === === === === === === FEATURES STRATEGIES === === === === === === === === === === === ===')
EgtOutLog( ' Feature ID | BTL POSITION | 90 ROTATION | 180 ROTATION | 270 ROTATION |')
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
local nProcessingsNumber
local nFirstAvailableRotation
-- ricerco prima rotazione effettivamente calcolata. In genere è sempre la prima
for i = 1, 4 do
if PartInfo.CombinationList.Rotations[i] == 1 then
nProcessingsNumber = #ProcessingsOnPart.Rotation[i]
nFirstAvailableRotation = i
break
end
end
-- per ogni feature
for ProcLog = 1, nProcessingsNumber do
-- ricavo il massimo numero di strategie per feature
local nMaxStrategiesPerFeature = 0
for nRotLog = 1, 4 do
if PartInfo.CombinationList.Rotations[nRotLog] == 1 and ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies then
nMaxStrategiesPerFeature = max( nMaxStrategiesPerFeature, #ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies)
end
end
-- ciclo su tutte le strategie
for nCountStrategies = 1, nMaxStrategiesPerFeature do
local sLogLine = ''
-- al primo ciclo scrivo ID feature
if nCountStrategies == 1 then
sLogLine = ' ' .. tostring( ProcessingsOnPart.Rotation[nFirstAvailableRotation][ProcLog].id)
while string.len( sLogLine) <= 20 do
sLogLine = sLogLine .. ' '
end
sLogLine = sLogLine .. '|'
else
sLogLine = ' |'
end
for nRotLog = 1, 4 do
-- se rotazione abilitata
if PartInfo.CombinationList.Rotations[nRotLog] == 1 then
-- se ci sono strategie
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies and ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies] then
-- se la strategia è stat processata e ha un risultato
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result then
-- leggo lo stato della strategia per aggiungere un suffisso
local sStatusStrategy = ' '
if not ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus or
ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Not-Applicable' then
sStatusStrategy = 'N'
elseif ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Completed' then
sStatusStrategy = 'C'
elseif ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.sStatus == 'Not-Completed' then
sStatusStrategy = 'P'
end
-- se c'è una chosen strategy, si aggiunge prefisso '*' per indicare nel log qual è la strategia che è stata scelta
local nIndexBestStrategy = ProcessingsOnPart.Rotation[nRotLog][ProcLog].nIndexBestStrategy or 0
local sLogLineProc = EgtIf( nIndexBestStrategy == nCountStrategies, '*', '') ..
tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].Result.dCompositeRating) ..' (' ..
tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].AvailableStrategies[nCountStrategies].sStrategyId) .. ')' ..
sStatusStrategy .. ' |'
while string.len( sLogLineProc) <= 20 do
sLogLineProc = ' ' .. sLogLineProc
end
sLogLine = sLogLine .. sLogLineProc
else
sLogLine = sLogLine .. ' 0 (STR----)- |'
end
else
sLogLine = sLogLine .. ' |'
end
-- rotazione non presa in considerazione
else
if nCountStrategies == 1 then
sLogLine = sLogLine .. ' ---------- |'
else
sLogLine = sLogLine .. ' |'
end
end
end
EgtOutLog( sLogLine)
end
end
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
end
-------------------------------------------------------------------------------------------------------------
function Logs.WriteMatrixLog( ProcessingsOnPart, PartInfo)
EgtOutLog( ' === === === === === === === === === === ROTATION MATRIX === === === === === === === === === === === === ===')
EgtOutLog( ' Feature ID | BTL POSITION | 90 ROTATION | 180 ROTATION | 270 ROTATION |')
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
local nProcessingsNumber
local nFirstAvailableRotation
-- ricerco prima rotazione effettivamente calcolata. In genere è sempre la prima
for i = 1, 4 do
if PartInfo.CombinationList.Rotations[i] == 1 then
nProcessingsNumber = #ProcessingsOnPart.Rotation[i]
nFirstAvailableRotation = i
break
end
end
for ProcLog = 1, nProcessingsNumber do
local sLogLine = ' ' .. tostring( ProcessingsOnPart.Rotation[nFirstAvailableRotation][ProcLog].id)
while string.len( sLogLine) <= 20 do
sLogLine = sLogLine .. ' '
end
sLogLine = sLogLine .. '|'
for nRotLog = 1, 4 do
if PartInfo.CombinationList.Rotations[nRotLog] == 1 then
if ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy then
local sStatusStrategy = EgtIf( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.Result.sStatus == 'Completed', 'C', 'P')
local sLogLineProc = tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.Result.dCompositeRating) ..
' (' .. tostring( ProcessingsOnPart.Rotation[nRotLog][ProcLog].ChosenStrategy.sStrategyId) .. ')' .. sStatusStrategy .. ' |'
while string.len( sLogLineProc) <= 20 do
sLogLineProc = ' ' .. sLogLineProc
end
sLogLine = sLogLine .. sLogLineProc
else
sLogLine = sLogLine .. ' 0 (STR----)- |'
end
else
sLogLine = sLogLine .. ' ---------- |'
end
end
EgtOutLog( sLogLine)
end
EgtOutLog( '----------------------------------------------------------------------------------------------------------')
end
-------------------------------------------------------------------------------------------------------------
function Logs.WriteCombinationLog( CombinationsList, BestCombination)
EgtOutLog( ' === === === === === === === === === === COMBINATIONS === === === === === === ')
EgtOutLog( ' COMBI (UNL) | RATING | COMPLETE | NO COMPL | NO EXEC | ROTATE |')
EgtOutLog( '---------------------------------------------------------------------------')
for CombiLog = 1, #CombinationsList do
local sLogLine = ' ' .. CombinationsList[CombiLog].sBitIndexCombination .. ' (' .. CombinationsList[CombiLog].nUnloadPos .. ') |'
-- rating
local sOtherField = tostring( CombinationsList[CombiLog].dTotalRating) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- completed
sOtherField = tostring( CombinationsList[CombiLog].nComplete) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- not completed
sOtherField = tostring( CombinationsList[CombiLog].nNotComplete) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- not executed
sOtherField = tostring( CombinationsList[CombiLog].nNotExecute) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
-- rotations
sOtherField = tostring( CombinationsList[CombiLog].nRotations) .. ' |'
while string.len( sOtherField) <= 11 do
sOtherField = ' ' .. sOtherField
end
sLogLine = sLogLine .. sOtherField
EgtOutLog( sLogLine)
end
EgtOutLog( '---------------------------------------------------------------------------')
EgtOutLog( ' BEST ROTATION : ' .. BestCombination.sBitIndexCombination .. ' (' .. BestCombination.nUnloadPos .. ')')
EgtOutLog( '---------------------------')
end
-------------------------------------------------------------------------------------------------------------
function Logs.WriteMainFacesLog( Proc, MainFaces)
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
---------------------------------------------------------------------
return Logs
+715
View File
@@ -0,0 +1,715 @@
-- 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')
local BeamLib = require( 'BeamLib')
local FeatureLib = require( 'FeatureLib')
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.StartsLeftSide( Machining)
local bStartsLeftSide = ( Machining.vtEdgeDirection:getX() > 10 * GEO.EPS_SMALL and not Machining.bInvert)
or ( not( Machining.vtEdgeDirection:getX() > 10 * GEO.EPS_SMALL) and Machining.bInvert)
return bStartsLeftSide
end
-------------------------------------------------------------------------------------------------------------
-- TODO valutare se c'è un modo più preciso di prevedere i casi in cui le lavorazioni dopo separazione sono da saltare
function MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part)
local bCanMoveAfterSplitcut = ( Part.dLength > BeamData.dMinRaw + 10 * GEO.EPS_SMALL)
and ( dLengthOnX < 0.7 * Part.dLength - 10 * GEO.EPS_SMALL)
return bCanMoveAfterSplitcut
end
-------------------------------------------------------------------------------------------------------------
function MachiningLib.CanExtendAfterTail( sCanDamageNextPiece, Part)
local bCanExtendAfterTail = false
if sCanDamageNextPiece == 'ALWAYS' then
bCanExtendAfterTail = true
elseif sCanDamageNextPiece == 'ONLY_IF_RAWPART' then
bCanExtendAfterTail = Part.bIsLastPart
end
return bCanExtendAfterTail
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
-------------------------------------------------------------------------------------------------------------
function MachiningLib.GetSplitMachinings( Machinings, vSplittingPoints, Part )
for i = #Machinings, 1, -1 do
local nParts = #vSplittingPoints + 1
local dEdgeMaxX = Machinings[i].ptEdge1:getX()
local dEdgeMinX = Machinings[i].ptEdge2:getX()
if Machinings[i].ptEdge1:getX() < Machinings[i].ptEdge2:getX() - 10 * GEO.EPS_SMALL then
dEdgeMaxX = Machinings[i].ptEdge2:getX()
dEdgeMinX = Machinings[i].ptEdge1:getX()
end
local dOriginalStartAddLength = Machinings[i].LeadIn.dStartAddLength
local dOriginalEndAddLength = Machinings[i].LeadOut.dEndAddLength
if FeatureLib.MachiningNeedsSplitting( Machinings[i].dLengthOnX, Part) then
local nCurrentMachiningIndex = i
-- lo spezzone attivo è quello precedente al punto di spezzatura corrente
for j = 1, nParts do
-- check ultimo segmento della lavorazione (NON della feature)
local bIsLastSegment = ( nParts == 1)
or ( ( ( j ~= 1) and vSplittingPoints[j - 1]:getX() > dEdgeMinX + 10 * GEO.EPS_SMALL)
and ( j == nParts or vSplittingPoints[j]:getX() < dEdgeMinX + 10 * GEO.EPS_SMALL))
-- se non è l'ultimo segmento della lavorazione, il punto di spezzatura deve essere all'interno del lato che si sta lavorando
if ( j ~= nParts and ( vSplittingPoints[j]:getX() > dEdgeMinX + 10 * GEO.EPS_SMALL and vSplittingPoints[j]:getX() < dEdgeMaxX - 10 * GEO.EPS_SMALL))
or bIsLastSegment then
if j > 1 then
nCurrentMachiningIndex = nCurrentMachiningIndex + 1
table.insert( Machinings, nCurrentMachiningIndex, BeamLib.TableCopyDeep( Machinings[i]))
end
local dStartAddLength = dOriginalStartAddLength
local dEndAddLength = dOriginalEndAddLength
if MachiningLib.StartsLeftSide( Machinings[i]) then
dStartAddLength, dEndAddLength = dEndAddLength, dStartAddLength
end
if j == 1 then
dEndAddLength = - ( vSplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP
elseif j == nParts then
dStartAddLength = - ( dEdgeMaxX - vSplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP
else
dStartAddLength = - ( dEdgeMaxX - vSplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP
dEndAddLength = - ( vSplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP
end
if MachiningLib.StartsLeftSide( Machinings[nCurrentMachiningIndex]) then
dStartAddLength, dEndAddLength = dEndAddLength, dStartAddLength
end
Machinings[nCurrentMachiningIndex].LeadIn.dStartAddLength = dStartAddLength
Machinings[nCurrentMachiningIndex].LeadOut.dEndAddLength = dEndAddLength
end
if not bIsLastSegment then
Machinings[nCurrentMachiningIndex].bMoveAfterSplitcut = false
end
Machinings[nCurrentMachiningIndex].nSegment = j
end
-- anche le lavorazioni non splittate necessitano del segmento assegnato
else
local dRightAddLength = dOriginalStartAddLength
local dLeftAddLength = dOriginalEndAddLength
if MachiningLib.StartsLeftSide( Machinings[i]) then
dRightAddLength, dLeftAddLength = dLeftAddLength, dRightAddLength
end
for j = 1, nParts do
local dNextSplitX = dEdgeMinX
local dPreviousSplitX = dEdgeMaxX
if j ~= 1 then
dPreviousSplitX = vSplittingPoints[j - 1]:getX()
elseif j ~= nParts then
dNextSplitX = vSplittingPoints[j]:getX()
end
if ( dEdgeMinX - dLeftAddLength) > dNextSplitX - 10 * GEO.EPS_SMALL and ( dEdgeMaxX + dRightAddLength) < dPreviousSplitX + 10 * GEO.EPS_SMALL then
Machinings[i].nSegment = j
end
end
end
end
return Machinings
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
if not nBestToolIndex then
nBestToolIndex = i
else
-- prediligo utensile per tagli lunghi, se richiesto
if ToolSearchParameters.bForceLongcutBlade and not TOOLS[nBestToolIndex].bIsUsedForLongCut and TOOLS[i].bIsUsedForLongCut then
nBestToolIndex = i
end
end
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
-- se nome non definito, assegno alla lavorazioen un nome standard
if not MachiningToAdd.sOperationName then
-- 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
MachiningToAdd.sOperationName = MachiningToAdd.sTypeName .. ( EgtGetName( ProcToAdd.id) or tostring( ProcToAdd.id)) -- .. '_' .. tostring( MachiningToAdd.Geometry)
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, sRotation)
local nErr
local sErr = ''
local bAreAllMachiningApplyOk = true
local bSplitExecuted = false
-- 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'},
{ sName = 'dOpenMinSafe', sMchParam = 'OpenMinSafe'},
{ sName = 'nVMRS', sMchParam = 'VMRS'},
{ sName = 'dStartZmax', sMchParam = 'StartZmax'},
{ sName = 'nOutRaw', sMchParam = 'OutRaw'},
{ sName = 'nOpenOutRaw', sMchParam = 'OpenOutRaw'},
{ sName = 'nPlunge', sMchParam = 'Plunge'}
}
-- parametri da scrivere nelle note di sistema
local SystemNotes = {
}
for i = 1, #MACHININGS do
-- si aggiungono solo quelle della fase richiesta
if ( sRotation == 'STD' and not MACHININGS[i].Proc.bDown and not MACHININGS[i].Proc.bSide) or
( MACHININGS[i].Proc.bDown and sRotation == 'DOWN') or
( MACHININGS[i].Proc.bSide and sRotation == 'SIDE') then
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
local Geometry
if MACHININGS[i].AuxiliaryData.Clones and MACHININGS[i].AuxiliaryData.Clones[j].Geometry then
Geometry = MACHININGS[i].AuxiliaryData.Clones[j].Geometry
elseif MACHININGS[i].Machining.Geometry then
Geometry = MACHININGS[i].Machining.Geometry
end
EgtSetMachiningGeometry( 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 = EgtGetMachiningParam( MCH_MP.USERNOTES)
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 = EgtGetMachiningParam( MCH_MP.SYSNOTES)
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
-- TODO è giusto inserire queste info alla fine della lavorazione? oppure conviene creare un record in MACHININGS apposito per la disposizione?
-- se era taglio di separazione, aggiungo nuova fase
if MACHININGS[i].AuxiliaryData.bAddNewPhase then
bSplitExecuted = true
BeamLib.AddPhaseWithRawParts( MACHININGS[i].Proc.idRaw, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
-- se grezzo successivo senza pezzi e finale, va tolto
local nNextRawId = EgtGetNextRawPart( MACHININGS[i].Proc.idRaw)
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BeamData.dMinRaw then
EgtRemoveRawPartFromCurrPhase( nNextRawId)
end
local nPhase = EgtGetCurrPhase()
local nDispId = EgtGetPhaseDisposition( nPhase)
if sRotation == 'DOWN' then
local nRotation = EgtIf( Part.nInitialPosition + 2 > 4, Part.nInitialPosition + 2 - 4, Part.nInitialPosition + 2)
BeamLib.RotatePart( Part, nRotation)
EgtSetInfo( nDispId, 'ROT', -2)
EgtSetInfo( nDispId, 'TYPE', 'MID2')
elseif sRotation == 'SIDE' then
local nRotation = EgtIf( Part.nInitialPosition + 1 > 4, Part.nInitialPosition + 1 - 4, Part.nInitialPosition + 1)
BeamLib.RotatePart( Part, nRotation)
EgtSetInfo( nDispId, 'ROT', -1)
EgtSetInfo( nDispId, 'TYPE', 'MID2')
else
local nRotation = Part.nInitialPosition
BeamLib.RotatePart( Part, nRotation)
EgtSetInfo( nDispId, 'TYPE', 'END')
end
EgtSetInfo( nDispId, 'ORD', MACHININGS[i].Proc.nIndexPartInParts)
end
else
return false, 'UNEXPECTED ERROR: Error on creating machining', bSplitExecuted
end
end
end
end
return bAreAllMachiningApplyOk, sErr, bSplitExecuted
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
+352
View File
@@ -0,0 +1,352 @@
-- 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( true)
-- 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.FeatureLib = nil
_G.package.loaded.FaceData = nil
_G.package.loaded.MachiningLib = nil
_G.package.loaded.Logs = nil
-- strategie di base sempre presenti
_G.package.loaded['SPLITCUT\\SPLITCUT'] = nil
_G.package.loaded['SPLITCUT\\SPLITCUTConfig'] = nil
_G.package.loaded['HEADCUT\\HEADCUT'] = nil
_G.package.loaded['HEADCUT\\HEADCUTConfig'] = 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 = {} -- tabella contenente tutte le informazioni di ogni pezzo
PROCESSINGS = {} -- tabella contenente tutte le informazioni di ogni feature, processate per ogni rotazione
-- 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 PROCESSINGS = BeamExec.GetProcessings( PROCESSINGS, PARTS)
local bOk, Stats = BeamExec.ProcessMachinings( PROCESSINGS, 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
+118
View File
@@ -0,0 +1,118 @@
-- Strategia: FACEBYBLADE
-- Descrizione
-- Strategia di base per la lavorazione di una faccia con lama
-- Feature: tutte
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
-- Tabella per definizione modulo
local FACEBYBLADE = {}
-------------------------------------------------------------------------------------------------------------
local function CalculateLeadInOut( EdgeToMachine)
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
-- elevazione sempre in negativo
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
else
LeadIn.dPerpDistance = BeamData.CUT_SIC
LeadOut.dPerpDistance = BeamData.CUT_SIC
end
LeadIn.dElevation = 0
LeadOut.dElevation = 0
LeadIn.dCompLength = 0
LeadOut.dCompLength = 0
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
return LeadIn, LeadOut
end
-------------------------------------------------------------------------------------------------------------
-- TODO da sistemare
local function GetSCC( vtMachiningDirection)
local nSCC = MCH_SCC.NONE
if vtMachiningDirection:getZ() < -0.9 then
nSCC = MCH_SCC.ADIR_ZM
elseif vtMachiningDirection:getZ() > 0.9 then
nSCC = MCH_SCC.ADIR_ZP
elseif vtMachiningDirection:getY() < -0.707 then
nSCC = MCH_SCC.ADIR_YM
elseif vtMachiningDirection:getY() > 0.707 then
nSCC = MCH_SCC.ADIR_YP
elseif vtMachiningDirection:getX() < -0.707 then
nSCC = MCH_SCC.ADIR_XM
elseif vtMachiningDirection:getX() > 0.707 then
nSCC = MCH_SCC.ADIR_XP
end
return nSCC
end
-------------------------------------------------------------------------------------------------------------
-- TODO da sistemare
function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalParameters)
local Cutting = {}
local vtMachiningDirection = EdgeToMachine.Norm
local vtN = Proc.Faces[FaceToMachine+1].vtN
Cutting.sDepth = OptionalParameters.sDepth or 0
Cutting.dRadialOffset = OptionalParameters.dRadialOffset or 0
Cutting.nType = MCH_MY.MILLING
Cutting.nToolIndex = OptionalParameters.nToolIndex
Cutting.Geometry = {{ Proc.id, FaceToMachine}}
Cutting.id = Proc.id
-- ===== calcolo LeadIn/out =====
if OptionalParameters.LeadIn and OptionalParameters.LeadOut then
Cutting.LeadIn, Cutting.LeadOut = OptionalParameters.LeadIn, OptionalParameters.LeadOut
else
Cutting.LeadIn, Cutting.LeadOut = CalculateLeadInOut( EdgeToMachine)
end
-- ===== scelta soluzione braccio C del motore =====
Cutting.nSCC = GetSCC( vtMachiningDirection)
-- ===== parametri da settare in UserNotes =====
Cutting.nFaceuse = OptionalParameters.nFaceuse
Cutting.sUserNotes = EgtSetValInNotes( Cutting.sUserNotes, 'VtFaceUse', vtMachiningDirection)
if OptionalParameters.sUserNotes then
Cutting.sUserNotes = Cutting.sUserNotes .. OptionalParameters.sUserNotes
end
-- ===== scelta senso di lavorazione =====
local bIsSawCCW = TOOLS[Cutting.nToolIndex].bIsCCW
local bInvert
-- se la lama ruota in senso antiorario inverto la direzione di lavorazione, per avere rotazione lama opposta a avanzamento
if bInvert == nil then
bInvert = ( not bIsSawCCW)
if bIsSawCCW then
bInvert = (( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_FRONT and vtN:getX() < 0) or ( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_BACK and vtN:getX() > 0))
else
bInvert = (( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_FRONT and vtN:getX() > 0) or ( Cutting.nFaceuse == MCH_MILL_FU.ORTHO_BACK and vtN:getX() < 0))
end
end
Cutting.bInvert = bInvert
Cutting.nWorkside = EgtIf( bInvert, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
return Cutting
end
-------------------------------------------------------------------------------------------------------------
return FACEBYBLADE
+283
View File
@@ -0,0 +1,283 @@
-- 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 = 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
Cutting. nSegment = 1
-- parametri opzionali
if not OptionalParameters then
OptionalParameters = {}
end
local bForceLongcutBlade = OptionalParameters.bForceLongcutBlade or false
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
Cutting.dLengthToMachine = EdgeToMachine.dLength
Cutting.dLengthOnX = abs( EdgeToMachine.dLength * EdgeToMachine.vtToolDirection:getY())
Cutting.dEdgeLength = EdgeToMachine.dLength
Cutting.ptEdge1, _, Cutting.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -EdgeToMachine.vtToolDirection, GDB_ID.ROOT)
Cutting.vtEdgeDirection = EdgeToMachine.vtToolDirection ^ FaceToMachine.vtN
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)
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
-- TODO valutare se fare funzione a parte
if Proc.AffectedFaces.bLeft then
local bStartLeft = MachiningLib.StartsLeftSide( Cutting)
local dAddLengthLeftSide = Cutting.LeadOut.dEndAddLength
local dAddLengthToReduce = sqrt( Cutting.dDepthToMachine * TOOLS[Cutting.nToolIndex].dDiameter - Cutting.dDepthToMachine * Cutting.dDepthToMachine)
if bStartLeft then
dAddLengthLeftSide = Cutting.LeadIn.dStartAddLength
end
if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtToolDirection, Y_AX()) then
if MachiningLib.CanMoveAfterSplitcut( Cutting.dLengthOnX, Part) then
Cutting.bMoveAfterSplitcut = true
else
Cutting.bIsApplicable = false
end
elseif dAddLengthLeftSide + dAddLengthToReduce > dExtendAfterTail then
if MachiningLib.CanMoveAfterSplitcut( Cutting.dLengthOnX, Part) then
Cutting.bMoveAfterSplitcut = true
else
if bStartLeft then
Cutting.LeadIn.dStartAddLength = - dAddLengthToReduce + dExtendAfterTail
else
Cutting.LeadOut.dEndAddLength = - dAddLengthToReduce + dExtendAfterTail
end
end
end
end
return Cutting
end
-------------------------------------------------------------------------------------------------------------
return SLOTBYBLADE
+257
View File
@@ -0,0 +1,257 @@
-- 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
Mortising.nSegment = 1
-- parametri opzionali
if not OptionalParameters then
OptionalParameters = {}
end
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
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
Mortising.dLengthToMachine = dLengthToMachine
Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtToolDirection:getY())
Mortising.dEdgeLength = EdgeToMachine.dLength
Mortising.ptEdge1, _, Mortising.ptEdge2 = EgtSurfTmFacetOppositeSide( Proc.id, FaceToMachine.id, -EdgeToMachine.vtToolDirection, GDB_ID.ROOT)
Mortising.vtEdgeDirection = EdgeToMachine.vtToolDirection ^ FaceToMachine.vtN
-- 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 = max( dCustomMaxElev, dCustomMaxElev - Mortising.dLongitudinalOffset)
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)
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
-- TODO valutare se fare funzione a parte
if Proc.AffectedFaces.bLeft then
local bStartLeft = MachiningLib.StartsLeftSide( Mortising)
local dAddLengthLeftSide = Mortising.LeadOut.dEndAddLength
if bStartLeft then
dAddLengthLeftSide = Mortising.LeadIn.dStartAddLength
end
if not AreSameOrOppositeVectorApprox( EdgeToMachine.vtToolDirection, Y_AX()) then
if MachiningLib.CanMoveAfterSplitcut( Mortising.dLengthOnX, Part) then
Mortising.bMoveAfterSplitcut = true
else
Mortising.bIsApplicable = false
end
elseif dAddLengthLeftSide + TOOLS[Mortising.nToolIndex].dDiameter / 2 > dExtendAfterTail then
if MachiningLib.CanMoveAfterSplitcut( Mortising.dLengthOnX, Part) then
Mortising.bMoveAfterSplitcut = true
else
if bStartLeft then
Mortising.LeadIn.dStartAddLength = - TOOLS[Mortising.nToolIndex].dDiameter / 2 + dExtendAfterTail
else
Mortising.LeadOut.dEndAddLength = - TOOLS[Mortising.nToolIndex].dDiameter / 2 + dExtendAfterTail
end
end
end
end
return Mortising
end
-------------------------------------------------------------------------------------------------------------
return SLOTBYCHAINSAW
+391
View File
@@ -0,0 +1,391 @@
-- Strategia: HEADCUT
-- Descrizione
-- HeadCut
-- Feature: HeadCut
---------------------------------------------------------------------------------------------------------
-- TODO: HEADCUT copiata da SPLITCUT. Da sistemare e capire se fare solo una strategia oppure due divise.
---------------------------------------------------------------------------------------------------------
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
-- Tabella per definizione modulo
local HEADCUT = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function LoadStrategyParameters( CustomParameters)
local StrategyLib = {}
StrategyLib.Config = require( 'HEADCUT\\HEADCUTConfig')
Strategy.sName = StrategyLib.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.Result = {}
Strategy.Machining = {}
Strategy.Result.sInfo = ''
return Strategy
end
-------------------------------------------------------------------------------------------------------------
local function CalculateLeadInOut( Machining, EdgeToMachine)
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
-- elevazione sempre in negativo
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
else
LeadIn.dPerpDistance = BeamData.CUT_SIC
LeadOut.dPerpDistance = BeamData.CUT_SIC
end
LeadIn.dElevation = 0
LeadOut.dElevation = 0
LeadIn.dCompLength = 0
LeadOut.dCompLength = 0
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
return LeadIn, LeadOut
end
-------------------------------------------------------------------------------------------------------------
local function MakeChamfer()
-- TODO funzionalit da aggiungere
end
-------------------------------------------------------------------------------------------------------------
local function GetEdgeToMachine( Proc, vtEdge)
local Edge
for i = 1, #Proc.Faces[1].Edges do
if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then
Edge = Proc.Faces[1].Edges[i]
end
end
return Edge
end
-------------------------------------------------------------------------------------------------------------
local function GetSplitStrategy( Proc, Part)
-- se non sono stati caricati i parametri, si ricaricano
if not Strategy.Parameters then
Strategy = LoadStrategyParameters()
end
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
Strategy.bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BeamData.dMinRaw))
-- imposto paraemtri di ricerca utensile in base a topologia
local Machining = {}
-- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None
Machining.sTypeMachining = 'None'
local Splitting = {}
local ToolSearchParameters = {}
ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN
-- ===== RICERCA UTENSILE =====
-- cerco lama sopra
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = false
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco lama sotto
Splitting = {}
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = false
ToolSearchParameters.bAllowBottomHead = true
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco motosega
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- cerco fresa
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- ===== SCELTA LAVORAZIONI =====
-- forzature da parametri
if Strategy.Parameters.bForceChainSaw then
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
end
-- setto valori di default. Impossibile che taglio di separazione sia incompleto
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = 1
-- correzioni sul massimo materiale lama, considerando ingombri vari
local dMaxMatBladeSideSingle
local dMaxMatBladeSideDouble
local dMaxMatBladeHorizontalSingle
local dMaxMatBladeHorizontalDouble
if Machining[1].bIsApplicable then
local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2
local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead
-- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni.
if Part.dHeight < BeamData.MIN_DIM_HBEAM then
dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT)
dMaxMatBladeSideSingle = dMaxMat
dMaxMatBladeSideDouble = dMaxMat * 2
else
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())),
TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial)
dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())
else
dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM)
dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2
end
end
-- se taglio orizzontale
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX()))
else
dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
end
end
if Machining[2].bIsApplicable then
if BeamData.GetMaxMatReductionBladeCut then
local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2
dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX()))
else
dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial
end
end
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideSingle (taglio di lama singolo di fianco)
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeSideSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideDouble (taglio di lama doppio di fianco)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeSideDouble'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeHorizontalSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeHorizontalDouble'
Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle
Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- TODO : casi con motosega da completare
-- ChainSawHorizontal (motosega)
-- ChainSawSideSingle (motosega)
-- ChainSawSideDouble (motosega)
-- ChainSawPlusBlade (motosega pi lama orizzontale)
-- Mill (svuotatura)
end
-- se non ho trovato neanche una lavorazione completa, non posso separare
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 = 'Split not possible'
end
return Machining
end
-------------------------------------------------------------------------------------------------------------
function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy = LoadStrategyParameters( CustomParameters)
local bAreAllMachiningsAdded = true
local Splitting = {}
local AuxiliaryData = {}
Strategy.sSplitStrategy = GetSplitStrategy( Proc, Part)
if bAddMachining then
-- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then
MakeChamfer()
end
local OptionalParameters = {}
-- applico le lavorazioni
----------------------------------------------------------------------------------
if Strategy.sSplitStrategy.sTypeMachining == 'BladeSideSingle' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
-- TODO gestire lavorazione a cubetti
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeSideDouble' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
-- TODO gestire lavorazione a cubetti
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
-- Taglio lato dietro
OptionalParameters = {}
Splitting = {}
AuxiliaryData = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
-- TODO gestire lavorazione a cubetti
EdgeToMachine = GetEdgeToMachine( Proc, Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA
-- TODO gestire lavorazione a cubetti
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
local dExtraMaxMat = ( Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat
-- TODO gestire lavorazione a cubetti
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
-- Taglio lato dietro
OptionalParameters = {}
Splitting = {}
AuxiliaryData = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[2].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat
-- TODO gestire lavorazione a cubetti
EdgeToMachine = GetEdgeToMachine( Proc, -Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawHorizontal' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideSingle' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideDouble' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'Mill' then
; -- TODO
----------------------------------------------------------------------------------
end
return bAreAllMachiningsAdded, Strategy.Result
else
return nil, Strategy.Result
end
end
-------------------------------------------------------------------------------------------------------------
return HEADCUT
@@ -0,0 +1,12 @@
-- Parametri configurabili da cliente per strategia: HEADCUT
local HEADCUTData = {
sStrategyId = 'HEADCUT',
Parameters = {
{ sName = 'bMakeChamfer', sValue = 'false', sDescriptionShort = 'Execute Chamfer', sDescriptionLong = 'Use the V-Mill to execute chamfers on cut-edges', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bForceChainSaw', sValue = 'false', sDescriptionShort = 'Force to use chain saw', sDescriptionLong = 'Force to use chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bFinishWithMill', sValue = 'true', sDescriptionShort = 'Finish with mill', sDescriptionLong = 'Use a mill to finish the surface if split with chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
}
}
return HEADCUTData
+425
View File
@@ -0,0 +1,425 @@
-- Strategia: SPLITCUT
-- Descrizione
-- Taglio di separazione
-- Feature: SplitCut
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
-- Tabella per definizione modulo
local SPLITCUT = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function LoadStrategyParameters( CustomParameters)
local StrategyLib = {}
StrategyLib.Config = require( 'SPLITCUT\\SPLITCUTConfig')
Strategy.sName = StrategyLib.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.Result = {}
Strategy.Machining = {}
Strategy.Result.sInfo = ''
return Strategy
end
-------------------------------------------------------------------------------------------------------------
local function CalculateLeadInOut( Machining, EdgeToMachine)
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
-- elevazione sempre in negativo
if EdgeToMachine.Elev < 10 * GEO.EPS_SMALL then
LeadIn.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
LeadOut.dPerpDistance = BeamData.CUT_SIC - EdgeToMachine.Elev
else
LeadIn.dPerpDistance = BeamData.CUT_SIC
LeadOut.dPerpDistance = BeamData.CUT_SIC
end
LeadIn.dElevation = 0
LeadOut.dElevation = 0
LeadIn.dCompLength = 0
LeadOut.dCompLength = 0
LeadIn.dStartAddLength = BeamData.CUT_EXTRA
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
return LeadIn, LeadOut
end
-------------------------------------------------------------------------------------------------------------
local function MakeChamfer()
-- TODO funzionalità da aggiungere
end
-------------------------------------------------------------------------------------------------------------
local function GetEdgeToMachine( Proc, vtEdge)
local Edge
for i = 1, #Proc.Faces[1].Edges do
if AreSameVectorApprox( Proc.Faces[1].Edges[i].Norm, vtEdge) then
Edge = Proc.Faces[1].Edges[i]
end
end
return Edge
end
-------------------------------------------------------------------------------------------------------------
local function GetSplitStrategy( Proc, Part)
-- se non sono stati caricati i parametri, si ricaricano
if not Strategy.Parameters then
Strategy = LoadStrategyParameters()
end
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
Strategy.bSplit = ( nNextRawId and ( EgtGetPartInRawPartCount( nNextRawId) > 0 or EgtGetRawPartBBox( nNextRawId):getDimX() >= BeamData.dMinRaw))
-- imposto paraemtri di ricerca utensile in base a topologia
local Machining = {}
-- sTypeMachining = BladeSideSingle\ BladeSideDouble\ BladeHorizontalSingle\ BladeHorizontalDouble\ ChainSawHorizontal\ ChainSawSideSingle\ ChainSawSideDouble\ ChainSawPlusBlade\ Mill\ None
Machining.sTypeMachining = 'None'
local Splitting = {}
local ToolSearchParameters = {}
ToolSearchParameters.vtToolDirection = Proc.Faces[1].vtN
-- ===== RICERCA UTENSILE =====
-- cerco lama sopra
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = false
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco lama sotto
Splitting = {}
Splitting.bIsApplicable = false
ToolSearchParameters.bAllowTopHead = false
ToolSearchParameters.bAllowBottomHead = true
Splitting.ToolInfo = {}
Splitting.ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
if Splitting.ToolInfo.nToolIndex then
Splitting.bIsApplicable = true
local ParametersMRR = {}
ParametersMRR.nToolIndex = Splitting.ToolInfo.nToolIndex
Splitting.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
end
table.insert( Machining, Splitting)
-- cerco motosega
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- cerco fresa
Splitting = {}
Splitting.bIsApplicable = false
table.insert( Machining, Splitting)
-- ===== SCELTA LAVORAZIONI =====
-- forzature da parametri
if Strategy.Parameters.bForceChainSaw then
Machining[1].bIsApplicable = false
Machining[2].bIsApplicable = false
end
-- setto valori di default. Impossibile che taglio di separazione sia incompleto
Strategy.Result.sStatus = 'Completed'
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = 1
-- correzioni sul massimo materiale lama, considerando ingombri vari
local dMaxMatBladeSideSingle
local dMaxMatBladeSideDouble
local dMaxMatBladeHorizontalSingle
local dMaxMatBladeHorizontalDouble
if Machining[1].bIsApplicable then
local dMaxMat = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
local dRadius = TOOLS[Machining[1].ToolInfo.nToolIndex].dDiameter / 2
local sHead = TOOLS[Machining[1].ToolInfo.nToolIndex].sHead
-- se taglio di fianco disponibile, si controlla il massimo materiale reale. Per pezzi alti, bisogna controllare anche l'ingombro asse Z nelle 4 direzioni.
if Part.dHeight < BeamData.MIN_DIM_HBEAM then
dMaxMat = min( dMaxMat, BeamData.MAX_DIM_HTCUT)
dMaxMatBladeSideSingle = dMaxMat
dMaxMatBladeSideDouble = dMaxMat * 2
else
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeSideSingle = min( max( dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()), dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())),
TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial)
dMaxMatBladeSideDouble = dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, Y_AX()) + dRadius - BeamData.GetMaxMatReductionBladeCut( sHead, -Y_AX())
else
dMaxMatBladeSideSingle = abs( BeamData.MAX_DIM_HTCUT_HBEAM)
dMaxMatBladeSideDouble = abs( BeamData.MAX_DIM_HTCUT_HBEAM) * 2
end
end
-- se taglio orizzontale
if BeamData.GetMaxMatReductionBladeCut then
dMaxMatBladeHorizontalSingle = min( TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[1].ToolInfo.nToolIndex].sHead, -Z_AX()))
else
dMaxMatBladeHorizontalSingle = TOOLS[Machining[1].ToolInfo.nToolIndex].dMaxMaterial
end
end
if Machining[2].bIsApplicable then
if BeamData.GetMaxMatReductionBladeCut then
local dRadius = TOOLS[Machining[2].ToolInfo.nToolIndex].dDiameter / 2
dMaxMatBladeHorizontalDouble = min( TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial, dRadius - BeamData.GetMaxMatReductionBladeCut( TOOLS[Machining[2].ToolInfo.nToolIndex].sHead, Z_AX()))
else
dMaxMatBladeHorizontalDouble = TOOLS[Machining[2].ToolInfo.nToolIndex].dMaxMaterial
end
end
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideSingle (taglio di lama singolo di fianco)
if Machining[1].bIsApplicable and ( dMaxMatBladeSideSingle - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeSideSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- TODO considerare di tagliare con il massimo materiale possibile per non salire troppo in Z (macchine tipo PF), oppure non scendere troppo (tipo Kairos)
-- BladeSideDouble (taglio di lama doppio di fianco)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeSideDouble - BeamData.CUT_EXTRA) > Part.dWidth + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeSideDouble'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- BladeHorizontalSingle (taglio di lama singolo orizzontale)
elseif Machining[1].bIsApplicable and ( dMaxMatBladeHorizontalSingle - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Machining.sTypeMachining = 'BladeHorizontalSingle'
Machining[2].bIsApplicable = false
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- BladeHorizontalDouble (taglio di lama doppio orizzontale)
elseif Machining[1].bIsApplicable and Machining[2].bIsApplicable and
( dMaxMatBladeHorizontalSingle + dMaxMatBladeHorizontalDouble - BeamData.CUT_EXTRA) > Part.dHeight + 10 * GEO.EPS_SMALL then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Blade')
Strategy.Result.dMRR = Strategy.Result.dMRR/2
Machining.sTypeMachining = 'BladeHorizontalDouble'
Machining[1].ToolInfo.dMaxMatBladeFromTop = dMaxMatBladeHorizontalSingle
Machining[2].ToolInfo.dMaxMatBladeFromDown = dMaxMatBladeHorizontalDouble
Machining[3].bIsApplicable = false
Machining[4].bIsApplicable = false
return Machining
-- TODO : casi con motosega da completare
-- ChainSawHorizontal (motosega)
-- ChainSawSideSingle (motosega)
-- ChainSawSideDouble (motosega)
-- ChainSawPlusBlade (motosega più lama orizzontale)
-- Mill (svuotatura)
end
-- se non ho trovato neanche una lavorazione completa, non posso separare
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 = 'Split not possible'
end
return Machining
end
-------------------------------------------------------------------------------------------------------------
function SPLITCUT.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy = LoadStrategyParameters( CustomParameters)
local bAreAllMachiningsAdded = true
local Splitting = {}
local AuxiliaryData = {}
Strategy.sSplitStrategy = GetSplitStrategy( Proc, Part)
if bAddMachining then
-- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then
MakeChamfer()
end
local OptionalParameters = {}
-- applico le lavorazioni
----------------------------------------------------------------------------------
if Strategy.sSplitStrategy.sTypeMachining == 'BladeSideSingle' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeSideDouble' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_BACK
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'PreSplit;'
else
OptionalParameters.sUserNotes = 'PreCut;'
end
local EdgeToMachine = GetEdgeToMachine( Proc, -Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
-- Taglio lato dietro
OptionalParameters = {}
Splitting = {}
AuxiliaryData = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_FRONT
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = ( Part.dWidth - BeamData.CUT_EXTRA) / 2
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
EdgeToMachine = GetEdgeToMachine( Proc, Y_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalSingle' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = -BeamData.CUT_EXTRA
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'BladeHorizontalDouble' then
OptionalParameters = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[1].ToolInfo.nToolIndex
-- Taglio lato frontale
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_DOWN
OptionalParameters.sDepth = 0
local dExtraMaxMat = ( Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown - Part.dHeight - BeamData.CUT_EXTRA) / 2
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[1].ToolInfo.dMaxMatBladeFromTop + dExtraMaxMat
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'PreSplit;'
else
OptionalParameters.sUserNotes = 'PreCut;'
end
local EdgeToMachine = GetEdgeToMachine( Proc, Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
-- Taglio lato dietro
OptionalParameters = {}
Splitting = {}
AuxiliaryData = {}
OptionalParameters.nToolIndex = Strategy.sSplitStrategy[2].ToolInfo.nToolIndex
OptionalParameters.nFaceuse = MCH_MILL_FU.ORTHO_TOP
OptionalParameters.sDepth = 0
OptionalParameters.dRadialOffset = Part.dHeight - Strategy.sSplitStrategy[2].ToolInfo.dMaxMatBladeFromDown + dExtraMaxMat
-- TODO gestire lavorazione a cubetti
if Strategy.bSplit then
OptionalParameters.sUserNotes = 'Split;'
else
OptionalParameters.sUserNotes = 'Cut;'
end
AuxiliaryData.bAddNewPhase = true
EdgeToMachine = GetEdgeToMachine( Proc, -Z_AX())
-- approccio e retrazione
OptionalParameters.LeadIn, OptionalParameters.LeadOut = CalculateLeadInOut( Splitting, EdgeToMachine)
Splitting = FaceByBlade.Make( Proc, Part, Proc.Faces[1].id, EdgeToMachine, OptionalParameters)
MachiningLib.AddNewMachining( Proc, Splitting, AuxiliaryData)
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawHorizontal' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideSingle' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawSideDouble' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'ChainSawPlusBlade' then
; -- TODO
----------------------------------------------------------------------------------
elseif Strategy.sSplitStrategy.sTypeMachining == 'Mill' then
; -- TODO
----------------------------------------------------------------------------------
end
return bAreAllMachiningsAdded, Strategy.Result
else
return nil, Strategy.Result
end
end
-------------------------------------------------------------------------------------------------------------
return SPLITCUT
@@ -0,0 +1,12 @@
-- Parametri configurabili da cliente per strategia: SPLITCUT
local SPLITCUTData = {
sStrategyId = 'SPLITCUT',
Parameters = {
{ sName = 'bMakeChamfer', sValue = 'false', sDescriptionShort = 'Execute Chamfer', sDescriptionLong = 'Use the V-Mill to execute chamfers on cut-edges', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bForceChainSaw', sValue = 'false', sDescriptionShort = 'Force to use chain saw', sDescriptionLong = 'Force to use chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bFinishWithMill', sValue = 'true', sDescriptionShort = 'Finish with mill', sDescriptionLong = 'Use a mill to finish the surface if split with chain saw', sType = 'b', sMessageId = '', sMinUserLevel = '1'}
}
}
return SPLITCUTData
+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', sNameNge = 'OVM_LENGTH', sValue = '0', sDescription = 'Sovramateriale lunghezza tenone', sType = 'd'},
{ sName = 'dOverMatOnRadius', sNameNge = 'OVM_RADIUS', sValue = '0', sDescription = 'Sovramateriale larghezza tenone', sType = 'd'},
{ sName = 'nMaxMillingPaths', sNameNge = 'MAX_PATHS', sValue = '3', sDescription = 'Numero massimo di passaggi di fresatura. Se richiesti più passaggi, si fa svuotatura', sType = 'd'},
{ sName = 'bUseDTToolOnPocketing', sNameNge = 'ALLOW_DT_POCKET', sValue = 'true', sDescription = 'Utilizza utensile a coda di rondine per fare svuotatura', sType = 'b'}
}
}
return STR0001Data
+489
View File
@@ -0,0 +1,489 @@
-- 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 FeatureLib = require( 'FeatureLib')
-- 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 parametri 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 = FeatureLib.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
-- se utensile scelto è su aggregato, ricalcolo la qualità
if TOOLS[Milling.ToolInfo.nToolIndex].SetupInfo.bToolOnAggregate then
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'MillOnAggregate')
end
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 = FeatureLib.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 = FeatureLib.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 = FeatureLib.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 = FeatureLib.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 = FeatureLib.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 = FeatureLib.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 GetSplitSurfaces( Proc, Part)
local vAddId = {}
local vAddIdTunnel = {}
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
local nOriginalTmIdTunnel = GDB_ID.NULL
if Proc.MainFaces.TunnelAddedFaces then
nOriginalTmIdTunnel = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
end
-- recupero punti di spezzatura - da destra a sinistra
local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
if #vFeatureSplittingPoints == 0 then
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
table.insert( vAddId, nAddId)
table.insert( vAddIdTunnel, nAddIdTunnel)
else
for i = 1, #vFeatureSplittingPoints do
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
if i == 1 then
-- prima superficie, va tagliata solo a sinistra
local ptSplit = vFeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
EgtCutSurfTmPlane( nAddId, ptSplit, -X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, -X_AX(), true, GDB_RT.GLOB)
else
-- taglio della superficie corrente - lato sinistro
local ptSplit = vFeatureSplittingPoints[i] + Vector3d( -BeamData.MILL_OVERLAP / 2, 0, 0)
EgtCutSurfTmPlane( nAddId, ptSplit, -X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, -X_AX(), true, GDB_RT.GLOB)
-- taglio della superficie corrente - lato destro
ptSplit = vFeatureSplittingPoints[i - 1] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0)
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
end
table.insert( vAddId, nAddId)
table.insert( vAddIdTunnel, nAddIdTunnel)
end
-- taglio ultima superficie, va tagliata solo a destra
local nAddId = EgtCopyGlob( Proc.id, nAddGrpId) or GDB_ID.NULL
local nAddIdTunnel = EgtCopyGlob( nOriginalTmIdTunnel, nAddGrpId) or GDB_ID.NULL
local ptSplit = vFeatureSplittingPoints[#vFeatureSplittingPoints] + Vector3d( BeamData.MILL_OVERLAP / 2, 0, 0)
EgtCutSurfTmPlane( nAddId, ptSplit, X_AX(), true, GDB_RT.GLOB)
EgtCutSurfTmPlane( nAddIdTunnel, ptSplit, X_AX(), true, GDB_RT.GLOB)
table.insert( vAddId, nAddId)
table.insert( vAddIdTunnel, nAddIdTunnel)
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 bAreAllMachiningsAdded = true
local ToolInfo = {}
local Pocketing = {}
Strategy.Machining = GetBestPocketingStrategy( Proc)
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
local vAddId = {}
local vAddIdTunnel = {}
-- recupero superficie, se necessario trimmata sugli spezzoni
vAddId, vAddIdTunnel = GetSplitSurfaces( 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}}
bAreAllMachiningsAdded = 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 nIdTm = EgtIf( Strategy.Machining[j].bMachAppliedToTunnelFace, vAddIdTunnel[i], vAddId[i])
vtNSplitFace = EgtSurfTmFacetNormVersor( nIdTm, k - 1, GDB_ID.ROOT)
if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then
Pocketing.Geometry = {{ nIdTm, k - 1}}
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddNewMachining( Proc, Pocketing)
break
end
end
end
end
end
end
else
bAreAllMachiningsAdded = false
end
return bAreAllMachiningsAdded, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
return STR0002
@@ -0,0 +1,11 @@
-- Parametri configurabili da cliente per strategia: STR0002
local STR0002Data = {
sStrategyId = 'STR0002',
Parameters = {
{ sName = 'dMaxCornerRadius', sNameNge = 'MAX_CORNER_RADIUS', 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', sNameNge = 'ANTISPLINT', 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
+557
View File
@@ -0,0 +1,557 @@
-- 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 FeatureLib = require( 'FeatureLib')
-- 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
-- TODO si può unificare con eguale funzione in STR0004
local function SortMachiningsBySegment( MachiningA, MachiningB)
if MachiningA.nSegment > MachiningB.nSegment then
return false
elseif MachiningB.nSegment > MachiningA.nSegment then
return true
else
if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then
return true
elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then
return false
else
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
return true
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
return false
end
end
end
end
local function SortMachiningsByTool( MachiningA, MachiningB)
if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then
return true
elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then
return false
else
if MachiningA.nSegment > MachiningB.nSegment then
return false
elseif MachiningB.nSegment > MachiningA.nSegment then
return true
else
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
return true
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
return false
end
end
end
end
local function MergeResults( Result)
local SortedResult = {}
for i = 1, #Result.Side do
if Result.Side[i].bIsApplicable then
table.insert( SortedResult, Result.Side[i])
end
end
for i = 1, #Result.Bottom do
if Result.Bottom[i].bIsApplicable then
table.insert( SortedResult, Result.Bottom[i])
end
end
for i = 1, #Result.Opposite do
if Result.Opposite[i].bIsApplicable then
table.insert( SortedResult, Result.Opposite[i])
end
end
return SortedResult
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
local function AddMachinings( Proc, Machinings, bAddMachining)
local nIsApplicableCount = 0
local bAreAllMachiningsAdded = true
for i = 1, #Machinings do
if Machinings[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded
if TOOLS[ Machinings[i].nToolIndex].sFamily == 'SAWBLADE' then
Blade.AddMachiningAllSteps( Proc, Machinings[i])
elseif TOOLS[ Machinings[i].nToolIndex].sFamily == 'MORTISE' then
Chainsaw.AddMachiningAllSteps( Proc, Machinings[i])
else
error( 'AddMachinings : tool type not supported')
end
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Machinings[i].sMessage
end
end
return bAreAllMachiningsAdded, nIsApplicableCount
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 = 1, Cutting.HorizontalSteps.nCount do
AuxiliaryData.Clones[i] = {}
AuxiliaryData.Clones[i].LeadIn = {}
AuxiliaryData.Clones[i].LeadOut = {}
AuxiliaryData.Clones[i].dRadialOffset = dOriginalRadialOffset + Cutting.HorizontalSteps.dStep * ( Cutting.HorizontalSteps.nCount - i)
-- 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
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then
dExtendAfterTail = 10000
end
-- lama - calcolo lavorazioni
local Cutting = {}
local OptionalParameters = { bForceLongcutBlade = Strategy.Parameters.bForceLongcutBlade, dExtendAfterTail = dExtendAfterTail}
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
-- lama - lavorazioni raggruppate in unica lista
Blade.Result.Sorted = MergeResults( Blade.Result)
-- lama - aggiunta eventuali lavorazioni splittate
local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
if #vFeatureSplittingPoints > 0 then
Blade.Result.Sorted = MachiningLib.GetSplitMachinings( Blade.Result.Sorted, vFeatureSplittingPoints, Part)
end
-- lama - nessuna lavorazione successiva - aggiunta lavorazioni e calcolo risultati
if not Strategy.Parameters.bFinishWithChainSaw then
-- ordinamento
if Strategy.Parameters.bSortBySegment then
table.sort( Blade.Result.Sorted, SortMachiningsBySegment)
else
table.sort( Blade.Result.Sorted, SortMachiningsByTool)
end
-- aggiunta lavorazioni
local nIsApplicableCount = 0
local bAreAllMachiningsAdded = true
local dFinalCompletionPercentage = 100
bAreAllMachiningsAdded, nIsApplicableCount = AddMachinings( Proc, Blade.Result.Sorted, bAddMachining)
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
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage)
Strategy.Result.nQuality = FeatureLib.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 - calcolo lavorazioni
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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 > 10 * GEO.EPS_SMALL or Chainsaw.Result.Opposite[2].dResidualDepth > 10 * 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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
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 > 10 * GEO.EPS_SMALL then
Chainsaw.Result.Opposite[1].bIsApplicable = false
local OptionalParameters = { bStopAtHalfElevation = true, dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA, dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
Chainsaw.AddResult( Mortising)
end
end
end
-- sega a catena - lavorazioni raggruppate in unica lista
Chainsaw.Result.Sorted = MergeResults( Chainsaw.Result)
-- sega a catena - aggiunta eventuali lavorazioni splittate
if #vFeatureSplittingPoints > 0 then
Chainsaw.Result.Sorted = MachiningLib.GetSplitMachinings( Chainsaw.Result.Sorted, vFeatureSplittingPoints, Part)
end
-- tutte le lavorazioni di tutti gli utensili in unica lista
local Result = {}
for i = 1, #Blade.Result.Sorted do
table.insert( Result, Blade.Result.Sorted[i])
end
for i = 1, #Chainsaw.Result.Sorted do
table.insert( Result, Chainsaw.Result.Sorted[i])
end
-- ordinamento
if Strategy.Parameters.bSortBySegment then
table.sort( Result, SortMachiningsBySegment)
else
table.sort( Result, SortMachiningsByTool)
end
-- aggiunta lavorazioni per tutti gli utensili
local nIsApplicableCount = 0
local bAreAllMachiningsAdded = true
local dFinalCompletionPercentage = 100
bAreAllMachiningsAdded, nIsApplicableCount = AddMachinings( Proc, Result, bAddMachining)
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
-- calcolo risultati
Strategy.Result.nCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage)
Strategy.Result.nQuality = FeatureLib.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,19 @@
-- Parametri configurabili da cliente per strategia: STR0003
local STR0003Data = {
sStrategyId = 'STR0003',
Parameters = {
{ sName = 'bFinishWithChainSaw', sNameNge = 'ALLOW_FINISH_CHAINSAW', sValue = 'true', sDescriptionShort = 'Finish with chainsaw if needed', sDescriptionLong = 'Finish with chainsaw if needed', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'dExtendAfterTail', sNameNge = 'EXTEND_AFTER_TAIL', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bForceLongcutBlade', sNameNge = 'USE_LONGCUT_BLADE', 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', sNameNge = 'NOT_COMPLETE_WITH_BLADE_RADIUS', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bUseZigZagMortising', sNameNge = 'USE_ZIGZAG_CHAINSAW', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'bSortBySegment', sNameNge = 'SORT_BY_SEGMENT', sValue = 'true', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'sCanDamageNextPiece', sNameNge = 'DAMAGE_NEXT_PIECE', sValue = 'NEVER', sType = 'combo', sMinUserLevel = '1',
Choices = { sValue = 'NEVER', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
{ sValue = 'ONLY_IF_RAWPART', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
{ sValue = 'ALWAYS', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}}
}
}
return STR0003Data
+287
View File
@@ -0,0 +1,287 @@
-- Strategia: STR0004
-- Descrizione
-- motosega per slot
-- Feature: tipo lapjoint
-- carico librerie
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamData')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
-- strategie di base
local SlotByChainSaw = require( 'SLOTBYCHAINSAW')
-- Tabella per definizione modulo
local STR0004 = {}
local Strategy = {}
local Chainsaw = {}
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 SortMachiningsBySegment( MachiningA, MachiningB)
if MachiningA.nSegment > MachiningB.nSegment then
return false
elseif MachiningB.nSegment > MachiningA.nSegment then
return true
else
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
return true
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
return false
end
end
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 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 STR0004.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( 'STR0004\\STR0004Config')
Strategy.sName = StrategyLib.Config.sStrategyId
CustomParameters = BeamLib.GetUpdateCustomParameters( CustomParameters, StrategyLib.Config.Parameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( CustomParameters)
Strategy.Result = {}
Strategy.Result.sInfo = ''
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)
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
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
if MachiningLib.CanExtendAfterTail( Strategy.Parameters.sCanDamageNextPiece, Part) then
dExtendAfterTail = 10000
end
-- calcolo lavorazioni
local Mortising = {}
OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then
-- si lavora tutto il fondo
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
-- materiale residuo - se possibile si lavora dal lato
if ( Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].dResidualDepth > 10 * GEO.EPS_SMALL or not Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].bIsApplicable) and #Proc.MainFaces.SideFaces == 1 then
if Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge.bIsStartOpen then
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
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 = { dExtendAfterTail = dExtendAfterTail}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[2], OptionalParameters)
end
Chainsaw.AddResult( Mortising)
end
elseif Proc.Topology.sName == 'Groove-3-Through' then
-- si lavora tutto il fondo
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
-- materiale residuo - si lavorano i lati
if ( Chainsaw.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL or not Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].bIsApplicable) then
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
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, dExtendAfterTail = dExtendAfterTail}
Mortising = SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.SideEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail}
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
elseif Proc.Topology.sName == 'Tunnel-4-Through' then
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail}
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 > 10 * GEO.EPS_SMALL then
Chainsaw.Result.Opposite[1].bIsApplicable = false
local OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail}
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[1], OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters = {}
OptionalParameters = { bStopAtHalfElevation = true, dExtendAfterTail = dExtendAfterTail}
SlotByChainSaw.Make( Proc, Part, Proc.MainFaces.LongFaces[1], Proc.MainFaces.LongFaces[1].MainEdges.OppositeEdges[2], OptionalParameters)
Chainsaw.AddResult( Mortising)
end
end
-- lavorazioni raggruppate in unica lista
Chainsaw.Result.Sorted = {}
for i = 1, #Chainsaw.Result.Side do
if Chainsaw.Result.Side[i].bIsApplicable then
table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Side[i])
end
end
for i = 1, #Chainsaw.Result.Bottom do
if Chainsaw.Result.Bottom[i].bIsApplicable then
table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Bottom[i])
end
end
for i = 1, #Chainsaw.Result.Opposite do
if Chainsaw.Result.Opposite[i].bIsApplicable then
table.insert( Chainsaw.Result.Sorted, Chainsaw.Result.Opposite[i])
end
end
-- aggiunta eventuali lavorazioni splittate
local vFeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
if #vFeatureSplittingPoints > 0 then
Chainsaw.Result.Sorted = MachiningLib.GetSplitMachinings( Chainsaw.Result.Sorted, vFeatureSplittingPoints, Part)
end
-- ordinamento
-- TODO aggiungere ordinamento per utensile
table.sort( Chainsaw.Result.Sorted, SortMachiningsBySegment)
-- aggiunta lavorazioni
local nIsApplicableCount = 0
local dFinalCompletionPercentage = 100
local bAreAllMachiningsAdded = true
for i = 1, #Chainsaw.Result.Sorted do
if Chainsaw.Result.Sorted[i].bIsApplicable then
nIsApplicableCount = nIsApplicableCount + 1
if bAddMachining then
local bIsMachiningAdded = Chainsaw.AddMachiningAllSteps( Proc, Chainsaw.Result.Sorted[i])
if not bIsMachiningAdded then
bAreAllMachiningsAdded = false
end
end
Strategy.Result.sInfo = Strategy.Result.sInfo .. '\n' .. Chainsaw.Result.Sorted[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 = FeatureLib.GetFeatureCompletionIndex( dFinalCompletionPercentage)
Strategy.Result.nQuality = FeatureLib.GetFeatureQuality( 'Chainsaw')
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 dMRRChainsaw = MachiningLib.GetToolMRR( MRRParametersChainsaw)
Strategy.Result.dMRR = dMRRChainsaw
return bAreAllMachiningsAdded, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
return STR0004
@@ -0,0 +1,15 @@
-- Parametri configurabili da cliente per strategia: STR0004
local STR0004Data = {
sStrategyId = 'STR0004',
Parameters = {
{ sName = 'bUseZigZagMortising', sNameNge = 'USE_ZIGZAG_CHAINSAW', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'b', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'dExtendAfterTail', sNameNge = 'EXTEND_AFTER_TAIL', sValue = 'false', sDescriptionShort = '', sDescriptionLong = '', sType = 'd', sMessageId = '', sMinUserLevel = '1'},
{ sName = 'sCanDamageNextPiece', sNameNge = 'DAMAGE_NEXT_PIECE', sValue = 'NEVER', sType = 'combo', sMinUserLevel = '1',
Choices = { sValue = 'NEVER', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
{ sValue = 'ONLY_IF_RAWPART', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''},
{ sValue = 'ALWAYS', sDescriptionShort = '', sDescriptionLong = '', sMessageId = ''}}
}
}
return STR0004Data
+147
View File
@@ -0,0 +1,147 @@
; 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,STR0004
16,0,Groove-4-Blind,STR0002,STR0003,STR0004
16,0,Groove-3-Through,STR0002,STR0003,STR0004
16,0,Groove-3-Blind,STR0002
16,0,Rabbet-2-Through,STR0002
16,0,Tunnel-4-Through,STR0003,STR0004
; Feature : Front Slot
17,0,Pocket-5-Blind,STR0002,STR0003,STR0004
17,0,Groove-4-Blind,STR0002,STR0003,STR0004
17,0,Groove-3-Blind,STR0002
17,0,Groove-3-Through,STR0002,STR0003,STR0004
17,0,Rabbet-2-Through,STR0002
17,0,Tunnel-4-Through,STR0003,STR0004
; 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,STR0004
30,1,Groove-4-Blind,STR0002,STR0003,STR0004
30,1,Groove-3-Blind,STR0002
30,1,Groove-3-Through,STR0002,STR0003,STR0004
30,1,Rabbet-2-Through,STR0002
30,1,Tunnel-4-Through,STR0003,STR0004
; Feature : Lap Joint
30,0,Pocket-5-Blind,STR0002,STR0003,STR0004
30,0,Groove-4-Blind,STR0002,STR0003,STR0004
30,0,Groove-3-Blind,STR0002
30,0,Groove-3-Through,STR0002,STR0003,STR0004
30,0,Rabbet-2-Through,STR0002
30,0,Tunnel-4-Through,STR0003,STR0004
; Feature : Notch/Rabbet
32,0,Pocket-5-Blind,STR0002,STR0003,STR0004
32,0,Groove-4-Blind,STR0002,STR0003,STR0004
32,0,Groove-3-Blind,STR0002
32,0,Groove-3-Through,STR0002,STR0003,STR0004
32,0,Rabbet-2-Through,STR0002
32,0,Tunnel-4-Through,STR0003,STR0004
; Feature : Block Haus
33,0,Feature,
; Feature : Notch
34,0,Pocket-5-Blind,STR0002,STR0003,STR0004
34,0,Groove-4-Blind,STR0002,STR0003,STR0004
34,0,Groove-3-Blind,STR0002
34,0,Groove-3-Through,STR0002,STR0003,STR0004
34,0,Rabbet-2-Through,STR0002
34,0,Tunnel-4-Through,STR0003,STR0004
; 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,STR0004
39,0,Groove-4-Blind,STR0002,STR0003,STR0004
39,0,Groove-3-Blind,STR0002
39,0,Groove-3-Through,STR0002,STR0003,STR0004
39,0,Rabbet-2-Through,STR0002
39,0,Tunnel-4-Through,STR0003,STR0004
; 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 : HEADCUT
340,0,Feature,HEADCUT
; Feature : SPLITCUT
350,0,Feature,SPLITCUT
; 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'