Compare commits

..

151 Commits

Author SHA1 Message Date
luca.mazzoleni dc02047db8 - aggiunti i messaggi da accodare ai messaggi generali 2026-06-23 13:03:35 +02:00
luca.mazzoleni 168c72af9e - in tutti i Json strategia aggiunti i campi "idDescriptionShortMsg" e "idDescriptionLongMsg" per la traduzione dei messaggi interni dell'automatismo 2026-06-23 11:46:07 +02:00
luca.mazzoleni a0ba2fb535 - correzione in BeamExec 2026-06-23 10:45:03 +02:00
luca.mazzoleni 43e2c61820 - in FaceData si usa la funzione GetAdjacentIndices dove possibile
- in FaceData si accettano, solo per le groove-3, i MainEdges per LongFaces a 5 lati
- in FACEBYCHAINSAW modifiche per rispecchiare la direzione utensile calcolata dal Cam5 e MaxElev impostata di conseguenza; invece di usare formule si provano sempre entrambe le soluzioni BlockedAxis, per contemplare tutti i casi
2026-06-22 18:29:59 +02:00
luca.mazzoleni fca53e5c4c - gestita feature Chamfer (stesse strategie di Longitudinal Cut)
- aggiunta topologia PseudoPocket 4 facce (faccia di fondo con numero indefinito di lati e facce laterali attaccate), es Birdsmouth di forme strane
- in STR0015 si gestisce SCC per minimizzare problemi di pinzaggio
- in BLADEKEEPWASTE piccola correzione
- in MachiningLib.GetSpliMachinings il sormonto tra le lavorazioni ora è corretto (MILL_OVERLAP); valutare parametro generale invece di costante macchina
2026-06-19 16:05:18 +02:00
luca.mazzoleni 987ffd30d6 - in PreSimulationLib aggiunto controllo collisione con flangia lama 2026-06-19 09:41:55 +02:00
luca.mazzoleni 30d29add83 - varie correzioni per il caso FIRST_IN_LIST
- in STR0008 se la mortasa è aperta su almeno un lato si forza lo SPIRALIN
2026-06-18 10:02:58 +02:00
luca.mazzoleni b73adc5092 Merge branch 'ObliqueNesting' into develop 2026-06-15 12:23:19 +02:00
luca.mazzoleni ab6380c1c5 - in STR0011 e 13 aggiunto SCC
- in BeamExec il clamp del MaxReprocess è portato a 5
2026-06-15 12:23:10 +02:00
luca.mazzoleni 38f834c421 Merge branch 'develop' into ObliqueNesting 2026-06-15 10:21:19 +02:00
luca.mazzoleni b0827ad72d - in BALDEKEEPWASTE piccola correzione 2026-06-15 10:21:11 +02:00
luca.mazzoleni d2669b0af9 Merge branch 'develop' into ObliqueNesting 2026-06-12 18:18:53 +02:00
luca.mazzoleni cc9a2314eb - in FACEBYCHAINSAW corretti punti di attacco per verifica finecorsa; corretto calcolo safeZ
- in MachiningLib piccola correzione alla stima lunghezza percorso sega a catena
- in STR0003 si gestisce il cambio di orientamento sega a catena in caso di lavorazione fallita (es: finecorsa); se raggio lama non finito si abbassa la qualità (SEMI)
2026-06-12 18:18:44 +02:00
luca.mazzoleni 08856faba2 - in BeamExec.GetAvailableCombinations se FlipRot e Nesting2D si disattivano le combinazioni con rotazioni; i tagli di testa ottimizzati (inclinati) si usano solo se FlipRot e Nesing2D 2026-06-12 14:23:35 +02:00
luca.mazzoleni cc949b5dd1 Merge branch 'develop' into ObliqueNesting 2026-06-11 17:41:28 +02:00
luca.mazzoleni 2cee0831d0 Merge branch 'DicingPresimDynamicRaw' into develop 2026-06-11 17:40:53 +02:00
luca.mazzoleni 4ff1405c8e - ora i tagli di testa obliqui e le informazioni per nesting obliquo sono scritte solo se il parametro GEN_bGetAlternativesNesting2D è attivo 2026-06-11 17:22:16 +02:00
luca.mazzoleni b90ef91edb Merge branch 'DicingPreSimDynamicRaw' into ObliqueNesting 2026-06-11 14:48:13 +02:00
luca.mazzoleni b8d3cd461b Merge branch 'develop' into DicingPreSimDynamicRaw 2026-06-11 14:39:52 +02:00
luca.mazzoleni c506486585 - in BLADETOWASTE.UpdateDiceRaw correzione 2026-06-11 13:08:02 +02:00
luca.mazzoleni a73c0c85ac - in PreSimulationLib si usa il grezzo dinamico per i cubetti. Modificate funzioni correlate
- in BLADETOWASTE.UpdateDiceRaw alcune correzioni
2026-06-11 13:05:06 +02:00
luca.mazzoleni fb3a5ec0be - in Process e BatchProcessNew piccola correzione 2026-06-10 18:21:08 +02:00
luca.mazzoleni e3e7537f8f Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2026-06-10 18:15:24 +02:00
luca.mazzoleni eec6b50985 - in BLADETOWASTE.CalculateDiceMachinings si calcola il grezzo dinamico per la presimulazione. Da completare e gestire in presimulazione 2026-06-10 18:15:17 +02:00
andrea.villa b5cb706ad5 Aggiunto controllo su massima lunghezza pezzo processabile 2026-06-10 15:02:29 +02:00
andrea.villa 053755e583 Merge remote-tracking branch 'origin/main' into develop 2026-06-10 14:54:41 +02:00
luca.mazzoleni beedbc71f1 - in BLADETOWASTE.CalculateDiceMachinings grezzo dinamico per evitare collisioni in presimulazione, da completare 2026-06-10 09:20:37 +02:00
luca.mazzoleni 8da693817d - in BeamExec.GetFeatureInfoAndDependency correzione importante 2026-06-08 13:27:40 +02:00
luca.mazzoleni 19f35ccd61 - in BeamExec.ProcessBeams modifiche minori 2026-06-08 11:58:15 +02:00
luca.mazzoleni 0806e1bab8 Merge branch 'main' into ObliqueNesting 2026-06-08 11:17:04 +02:00
luca.mazzoleni 387eda8b4a - in BeamExec corretta ProcessBeams per i casi in cui dPosX non è definito 2026-06-08 11:16:50 +02:00
andrea.villa c7045499f4 Merge remote-tracking branch 'origin/develop' 2026-05-29 11:15:28 +02:00
andrea.villa 44478b91f0 Aggiornato log e versione 2026-05-29 11:15:09 +02:00
andrea.villa 1f4aa15af4 Aggiunto tipo fresa da cercare 2026-05-29 11:10:41 +02:00
luca.mazzoleni 476f214b99 Merge remote-tracking branch 'origin/develop' into ObliqueNesting 2026-05-21 18:53:12 +02:00
luca.mazzoleni eacabb5af7 - in BeamExec.ProcessBeams correzioni. Sembra funzionare correttamente in tutti i casi 2026-05-21 18:53:02 +02:00
luca.mazzoleni 5c7751aebd - in BeamLib aggiunta GetNewMachGroupName per avere il prossimo numero MachGroup intero libero
- in NestProcess i nomi MachGroup sono sempre interi; si mantiene sempre un BEAM_SAFETY_BUFFER nel riempimento delle barre
- in BeamExec.GetCombinationListFromMatrix corretti indici taglio di testa e coda
2026-05-21 15:02:23 +02:00
luca.mazzoleni 6649842c70 - in NestProcess modifiche per nestare pezzi senza alternative 2026-05-21 10:49:28 +02:00
luca.mazzoleni 27475763a2 - in BeamExec correzioni per il caso di taglio standard che diventa taglio di testa
- in MachiningLib.FindBlade e relativi non si testa più la normale della faccia in caso di informazioni lato mancanti (portava erroneamente a non trovare la lama nei casi solo downUp)
2026-05-21 09:29:55 +02:00
luca.mazzoleni 3fcca044ed - in BeamExec si ritornano stati per l'interfaccia anche per tagli che sono diventati Headcut e TailCut 2026-05-20 16:14:54 +02:00
luca.mazzoleni 630d28bf5b - in BeamExec se un taglio è diventato Headcut o Tailcut viene comunque considerato nel punteggio delle combinazioni 2026-05-20 16:00:15 +02:00
luca.mazzoleni 5e5f3d08c4 - in BeamExec se non è stato trovato nessun taglio di testa o di coda si usa quello settato in precedenza 2026-05-20 14:42:59 +02:00
luca.mazzoleni a773e0156a - in BeamLib.AddPhaseWithRawParts e correlati correzioni in caso di scarico ultimo grezzo 2026-05-19 17:03:21 +02:00
luca.mazzoleni 72e3b7dc8f - in BeamLib.AddPhaseWithRawParts correzioni 2026-05-19 15:53:53 +02:00
luca.mazzoleni 10592ac612 - in BeamLib.AddPhaseWithRawParts correzioni, ma ancora non funziona correttamente 2026-05-19 14:29:16 +02:00
andrea.villa a5d606b225 Prima versione gestione utensile flottante. Per ora solo su marcature.
Gestione da migliorare.
2026-05-19 13:05:15 +02:00
luca.mazzoleni 3ba456f72f - in BeamLib e correlate modificata AddPhaseWithRawParts per funzionare con overlap dei pezzi per nesting obliquo 2026-05-19 12:47:21 +02:00
luca.mazzoleni 608f8da033 - in NestProcess si fanno correttamente inversioni e rotazioni 2026-05-19 09:50:58 +02:00
luca.mazzoleni 08397ae102 - in NestProcess aggiunte eventuali rotazioni/inversioni duplo nella barra 2026-05-18 18:28:57 +02:00
luca.mazzoleni b7dbc7422c - in BeamExec.ProcessAlternatives si passa all'interfaccia da scrivere anche la posizione iniziale del pezzo 2026-05-18 17:26:05 +02:00
luca.mazzoleni 974d1abb41 - in NestProcess correzione bug 2026-05-18 16:40:58 +02:00
andrea.villa c4697fbd6f In STR0014:
- se utensile PEN, si riduce il percorso per evitare di attaccare fuori dal grezzo
- gestione parametro SCC bloccato letto dalla macchina
2026-05-18 16:38:02 +02:00
luca.mazzoleni b79617fbe4 - in NestProcess primo abbozzo della creazione MachGroup 2026-05-18 15:53:18 +02:00
luca.mazzoleni e5f1abc47d - in NestProcess aggiunto lo spostamento delle travi verso la testa della trave (vedere se poi integrare in creazione MachGroup) 2026-05-18 14:45:57 +02:00
luca.mazzoleni 965c6e8f9e - in NestProcess aggiunta MIN_FILLER_LIMITin CONFIG per pulizia codice 2026-05-18 12:40:06 +02:00
luca.mazzoleni d59039eae0 - in NestProcess correzioni in PrintDiagnosticReport 2026-05-18 12:28:36 +02:00
luca.mazzoleni a404bf2f9e - in NestProcess si provano barre nuove solo se non si trovano soluzioni con quelle già attive 2026-05-18 12:03:46 +02:00
luca.mazzoleni 1cde1c94d9 - in NestProcess aggiunta PrintDiagnosticReport per stimare la bontà del nesting; in CalculateMove modificato calcolo efficienza nel caso di barra nuova; correzioni minori 2026-05-18 11:32:15 +02:00
luca.mazzoleni a66054a6c8 - in NestProcess correzioni e modifiche per migliorare l'efficienza. Sembra funzionare, da verificare bontà nesting. Manca creazione MachGroup veri e propri 2026-05-18 10:16:20 +02:00
luca.mazzoleni b77e79d0d0 - in NestProcess loop completo, alcune migliorie possibili per prestazioni; manca la parte che effettivamente crea i MachGroup 2026-05-15 18:33:15 +02:00
luca.mazzoleni cad57b2fd5 - in NestProcess piccole correzioni 2026-05-15 10:37:58 +02:00
luca.mazzoleni 5e503762e5 - in NestProcess agiunto sorting della JobPool 2026-05-15 10:26:30 +02:00
luca.mazzoleni f27000b7bc - in NestProcess.PartTemplates:AddPart si salvano i MaxHeadRecess testa e coda; creata funzione FindBestPartForBeam, da completare 2026-05-15 10:10:25 +02:00
luca.mazzoleni f90dd95880 - in NestProcess creato il loop di base dello script. Mancano funzioni accessorie 2026-05-14 16:44:12 +02:00
luca.mazzoleni 0497877abb - in NestProcess ora si compilano correttamente le tabelle di grezzi e pezzi da nestare, in preparazione al neting 2026-05-14 15:39:29 +02:00
luca.mazzoleni b8299df247 - in BeamExec.ProcessAlternatives si passano correttamente le info a interfaccia da scrivere sul pezzo
- in BeamLib aggiunta funzione ConvertBitIndexToRotationIndex per convertire da BitIndex a RotationIndex
2026-05-13 18:42:01 +02:00
luca.mazzoleni 4a99f2bdf6 - in BeamExec.GetProcessings per HeadcutInfo e TailcutInfo si usano gli indici di rotazione canonici (1,2,3,4 per std e 5,6,7,8 per invertiti) 2026-05-13 16:28:04 +02:00
luca.mazzoleni 1e86180723 - in BeamExec si scrivono HeadcutInfo e TailcutInfo nel PARTS che serviranno per nesting; da completare output alternative 2026-05-13 16:00:20 +02:00
luca.mazzoleni f6d6043c0e - piccole modifiche per test nesting 2026-05-13 12:40:45 +02:00
luca.mazzoleni b048e2ebe2 - in BeamLib.GetSortedVertices piccola correzione 2026-05-13 11:58:28 +02:00
luca.mazzoleni fc47bca0f1 - in NestProcess prime modifiche per nesting obliquo (da completare)
- in BeamExec test BEAM.INFONGEPART per scrittura note pezzo in nge tramite Aedifica
- in BeamLib aggiunta funzione RotateTableFromIndex per reindicizzare una tabella passata
2026-05-13 11:47:25 +02:00
luca.mazzoleni 0274096f57 - in BeamExec.GetFeatureInfoAndDependency si salvano le info necessarie per nesting (offset X dei vertici dei tagli rispetto al box, normali delle facce) 2026-05-12 11:59:26 +02:00
luca.mazzoleni 983609397e - in BeamLib funzione GetSurfTmSortedVertices diventa GetSortedVertices e si passa la Proc direttamente
- in BeamLib aggiunta funzione GetAdjacentIndices per la ricerca degli indici precedente e successivo con circular indexing
2026-05-12 10:45:26 +02:00
luca.mazzoleni 05a8d23f6a - in BeamExec.GetFeatureInfoAndDependency si calcolano i punti ai vertici dei tagli di testa e coda
- in BeamLib aggiunta funzione GetSurfTmSortedVertices per restituire i punti ai vertici già ordinati; da correggere perchè i vertici non arrivano ordinati dalla funzione EgtSurfTmGetAllVertInFacet
2026-05-12 09:06:43 +02:00
luca.mazzoleni 40580cdc69 - NestProcess attuale rinominata Old per test nesting obliqui, con NestProcess ripulita 2026-05-11 12:42:34 +02:00
luca.mazzoleni f6b2477f2b - in BeamExec.GetFeatureInfoAndDependency correzione 2026-05-08 12:29:46 +02:00
luca.mazzoleni 69db74e30e - in BeamExec.ProcessBeams modifiche per accettare grezzi compenetranti
- in BeamExec.GetFeatureInfoAndDependency si scelgono taglio di testa e coda anche obliqui, quelli più verso il centro della trave. Gli altri tagli si disattivano
- da completare
2026-05-08 12:00:58 +02:00
luca.mazzoleni f58004dfeb - in PreSimulationLIb correzioni importanti in test collisione 2026-05-08 11:54:16 +02:00
luca.mazzoleni 7c485360de Merge branch 'ScarfJoint' into develop 2026-04-27 18:18:19 +02:00
luca.mazzoleni 967117cc23 - in FeatureLib, per ScarfJoint e ScarfSimple, si scrivono sempre AdjacencyMatrix e Faces
- in STR0009 aggiunto antischeggia di lama e, nel caso sia disattivato, lavorazione con lama dell'eventuale faccia inclinata
2026-04-27 18:18:07 +02:00
andrea.villa 64b2e86a2d Abbozzata gestione (non funzionante) passaggio supplementare in caso di angolo > 90° che necessita di passata extra 2026-04-24 16:47:40 +02:00
andrea.villa 89b342a564 Prima versione Scarf Joint. Manca:
- lavorazioni di antischeggia con fresa e lama
 - Il primo taglio de ve essere calcolato con 2 facce se il piano di taglio attraversa faccia 1
 - gestione caso con facce 4 e 5 mancanti
2026-04-24 14:45:31 +02:00
andrea.villa 117e475de5 STR0009 riutilizzata per ScarfJoint. Primo commit, da sviluppare completamente. 2026-04-24 08:52:56 +02:00
andrea.villa a7b817b211 STR0014 corretta lavorazione cloni 2026-04-24 08:41:25 +02:00
andrea.villa d8c6a8ad55 In STR0008 si aggiunge svuotatura con paraemtri di default 2026-04-23 10:35:03 +02:00
andrea.villa 9026acd9ca In STR0007 la faccia di taglio deve essere messa sul gruppo aggiuntivo. Prima era su quello temporaneo che però viene poi cancellato 2026-04-21 10:03:05 +02:00
andrea.villa 204346326f In STR0003 controllo delle MainFaces spostato a prima del controllo topologia 2026-04-21 08:13:41 +02:00
luca.mazzoleni 5d6e4c397d - in MachiningLib.FindMill si evita di lavorare troppo sotto con la fresa, a meno che sia in testa o coda; temporaneo in attesa di test collisione anche per fresa e attacco corretto dal lato 2026-04-20 18:09:22 +02:00
luca.mazzoleni 64bde8924d - in STR0002 si evita di lavorare la faccia tunnel se troppo piccola 2026-04-20 16:27:59 +02:00
luca.mazzoleni cb6115d23f - in STR0010 (fresatura) migliorata qualità se no lati chiusi 2026-04-20 15:25:19 +02:00
luca.mazzoleni 771c1367b1 - in PreSimulationLib, se taglio perpendicolare a cubetti, non si verifica l'elevazione reale del taglio 2026-04-20 10:47:41 +02:00
luca.mazzoleni 6092063daa - in BLADETOWASTE piccola correzione 2026-04-20 09:21:52 +02:00
luca.mazzoleni 44650c303c Merge branch 'test' into develop 2026-04-17 18:31:27 +02:00
luca.mazzoleni 69fa0d741d - piccole correzioni ai cubetti nel caso di due facce molto aperte 2026-04-17 18:31:22 +02:00
luca.mazzoleni 8e55ddda1f - in PreSimulationLib aggiunto check collisione anche per punti di attacco perpendicolare 2026-04-17 17:25:06 +02:00
andrea.villa 7a8fb04ebe In STR0013 (foro con fresa) si controlla che abbia trovato fresa prima di verificare se foro completo. Se non trovava fresa andava in crash 2026-04-17 12:36:26 +02:00
luca.mazzoleni 77c27d911c Merge branch 'PreSimulationV2' into develop 2026-04-16 17:02:43 +02:00
luca.mazzoleni 3a29f273c9 - in PreSimulationLib alcune correzioni 2026-04-16 17:02:39 +02:00
luca.mazzoleni bab5b07bd1 Merge remote-tracking branch 'origin/develop' into PreSimulationV2 2026-04-15 17:45:20 +02:00
luca.mazzoleni 683ae78c65 - in PreSimulationLib si usano le funzioni MachineCalc per la precollisione 2026-04-15 17:45:15 +02:00
andrea.villa 06d9529b7b Per ruotare il pezzo non lo si toglie più dalla barra, ma lo si gira in "Draw" 2026-04-14 09:05:46 +02:00
andrea.villa 922a7ac846 Correzioni varie in strategie per gestire casi strani dove non vengono calcolate le MainFaces 2026-04-14 07:57:59 +02:00
andrea.villa a21a3979f1 Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2026-04-13 13:02:10 +02:00
andrea.villa fcbed252e1 Merge branch 'PreRotationInterface' into develop 2026-04-13 13:02:06 +02:00
andrea.villa b68bbb2c48 - Report TXT ora gestisce bene le prerotazioni
- Corretta info indice rotazione su Proc
2026-04-13 13:01:56 +02:00
andrea.villa 6fe6b41e87 Migliorie calcolo prerotazioni 2026-04-13 12:28:09 +02:00
andrea.villa 78189631c1 Aggiunto inversione 2026-04-13 09:43:47 +02:00
andrea.villa 1a6433d5f8 Prima versione che sistema il pezzo in interfaccia come è stato preruotato 2026-04-13 08:08:14 +02:00
luca.mazzoleni 28026358b9 - aggiunto GetBeamData per lettura parametri macchina da interfaccia 2026-04-10 11:19:27 +02:00
luca.mazzoleni b73fb86be9 - in BatchProcessNew si sposta cancellazione gruppo temporaneo a dopo la ProcessAlternatives
- in BLADETOWASTE CalculateDiceMachinings commentata inversione facce per normale non raggiungibile (ci pensa già la FaceByBlade)
2026-04-09 15:59:30 +02:00
luca.mazzoleni 1032557782 Merge branch 'FlipRotInBatchProcessNew' into develop 2026-04-08 13:33:17 +02:00
andrea.villa 0ca5f92b96 - tolto paraemtro generale GEN_bTestAlternative, sostituito da GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION'. Se utente abilita ricerca delle prerotazioni anche a 90°, significa che accetta anche ottimizzazioni nel nesting ruotando pezzo a 90°, probabilmente fibra non importante
- In BatchProcessNew, quando si crea la barra, il paraemtro FlipRot dipende dal BEAM.FLAG == 10
2026-04-03 16:13:15 +02:00
luca.mazzoleni 0f58c026d0 - in BatchProcessNew gestito Flag 10 per FlipRot 2026-04-03 15:05:15 +02:00
luca.mazzoleni 70d170b2a3 Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2026-04-02 18:13:38 +02:00
luca.mazzoleni 06bc0f77df Merge branch 'AntiSplintOnSTR0002' into develop 2026-04-02 18:13:34 +02:00
luca.mazzoleni a40cc026c9 - in STR0002 implementato AntiSplint
- in ANTISPLINTONFACE piccole modifiche
2026-04-02 18:13:25 +02:00
andrea.villa 34fb38ac00 Piccola correzione sul nome della feature StartCut e EndCut 2026-04-01 16:31:15 +02:00
andrea.villa aaa06c1af5 Corretto indice rotazione da verificare in caso di soluzione invertita. Si aggiunge un offset di 4, l'indice nella tabella delle rotazioni sono 5-6-7-8 2026-04-01 13:17:28 +02:00
luca.mazzoleni 98a48522ee Merge branch 'FlipRot' into develop 2026-04-01 11:41:42 +02:00
andrea.villa 6fd356f757 - Aggiunta tolleranza nella scelta della migliore combinazione di lavorazione. Se voto uguale non era chiaro quale avrebbe scelto prima
- Quando si processano alternative, si resetta flag bPartInCombiIsInverted
2026-04-01 11:06:15 +02:00
andrea.villa 83895cc3bf In STR0002 migliorata gestione topologia 'DoubleBevel-2-Through' 2026-03-31 17:44:49 +02:00
luca.mazzoleni d001273704 - in FlipRot e ProcessAlternatives si scrivono le variabili globali nella tabella Beam per l'interfaccia 2026-03-31 16:11:54 +02:00
luca.mazzoleni 621c9149b5 Merge branch 'ChainsawVerifyOutStroke' into develop 2026-03-26 17:44:22 +01:00
luca.mazzoleni f6f625c7cc - in FACEBYCHAINSAW si escludono casi in cui l'asse bloccato non è calcolato 2026-03-26 17:43:09 +01:00
luca.mazzoleni 9d8985093d - in PreSimulationLib.CheckOutStrokePoint modifiche per contemplare terzo asse rotativo 2026-03-26 17:25:56 +01:00
luca.mazzoleni fe8275f05a - in PreSimulationLib.CheckOutOfStrokeFromPoints e altri si contemplano vettore ausiliario e asse bloccato per verificare finecorsa sega a catena
- in STR0004 se non applicabile si cambia lato, se possibile
- in FACEBYCHAINSAW si verifica finecorsa
2026-03-24 14:36:52 +01:00
andrea.villa d32403f546 Il parametro GEN_nMaxReProcessCycles viene letto ora dal pezzo e non dalla lista dei parametri generali (la quale potrebbe avere quelli -sbagliati- di default). 2026-03-18 10:27:29 +01:00
luca.mazzoleni 63d4ca7176 - in PreSimulationLib correzione al calcolo vtC, vettore asse C 2026-03-17 17:07:42 +01:00
luca.mazzoleni 0889ae5c7a - in STR0002 corretti casi in cui non ci sono le LongFaces
- in STR0003 e STR0004 se non ci sono MainFaces e MainEdges necessari si esce
2026-03-17 16:37:00 +01:00
andrea.villa 0fc9e1dd09 - Se la lavorazione non ha percorso, la si disattiva
- Se rotazione impostata su "IF_NECESSARY", prima del numero rotazioni, si controllano il numero di feature non eseguite
2026-03-13 13:26:20 +01:00
luca.mazzoleni 63308c0349 - correzione in BLADEKEEPWASTE 2026-03-12 17:24:25 +01:00
luca.mazzoleni 7e5ab8ecd3 Merge branch 'BLADEKEEPWASTEImprovement' into develop 2026-03-12 17:08:19 +01:00
luca.mazzoleni bddaf91fb7 - in STR0003 si evita caso con Groove-3 passante e pareti oblique
- in STR0010 migliorie
- in BLADEKEEPWASTE aggiunta pulizia lati chiusi con sistema nuovo
2026-03-12 17:08:07 +01:00
luca.mazzoleni 2c77277c85 - alle StrategyLibs aggiunta ANTISPLINTONFACE per calcolare le lavorazioni antischeggia passando una faccia; STR0010 e BLADEKEEPWASTE modificate di conseguenza
- in BLADEKEEPWASTE migliorie e correzioni; manca ancora la pulitura con fresa
- in FACEBYBLADE rimossa dimensione minima lato maggiore del diametro lama. Si può avere un accorciamento massimo pari alla lunghezza lato
2026-03-06 18:23:24 +01:00
luca.mazzoleni 38a6ac237e Merge branch 'develop' into BLADEKEEPWASTEImprovement 2026-03-06 12:43:28 +01:00
luca.mazzoleni ed4d97ba51 Merge branch 'STR0010Improvement' into develop 2026-03-06 12:43:13 +01:00
luca.mazzoleni 7b12eaf331 - in BatchProcessNew -> GET_TOPOLOGY si legge anche nParts (serve nel Classify Topology)
- in STR0005 si ammettono feature a più di 3 lati se la topologia è DoubleBevel
- in BLADEKEEPWASTE si gestisce topologia DoubleBevel e migliorie varie
2026-03-06 12:42:53 +01:00
luca.mazzoleni 3e55af917e - in BLADETOWASTE gestito caso in cui arrivano due facce separate 2026-03-04 18:02:43 +01:00
luca.mazzoleni 73b6d80510 - in FeatureLib->ClassifyTopology correzione al riconoscimento DoubleBevel su più parti
- in FaceData correzioni per i casi DoubleBevel su più parti
- in BeamExec->CollectFeatures si scrive il numero di parti di cui è composta la trimesh
2026-03-04 16:13:31 +01:00
luca.mazzoleni 65c2c244d6 in STR0010 aggiunto antischeggia facce di chiusura 2026-03-04 12:19:29 +01:00
luca.mazzoleni 2ae547a24e - in FeatureLib correzioni a classificazione topologia DoubleBevel
- in STR0010 aggiunte passate di finitura con fresa e piccole correzioni
2026-03-04 09:26:47 +01:00
luca.mazzoleni aff61f1daa Merge remote-tracking branch 'origin/develop' into STR0010Improvement 2026-03-03 09:45:20 +01:00
luca.mazzoleni 0db6a74f8c - in FaceData e FeatureLib modifiche per gestire DoubleBevel
- in STR0010 modifiche per gestire casi non contemplati
2026-03-03 09:45:11 +01:00
andrea.villa f68533944c Merge branch 'NewRotationMng' into develop 2026-03-02 13:26:56 +01:00
andrea.villa 37e08e3f42 - Aggiunto tempo di calcolo delle alternative
- Di default la ricerca delle alternative è disattiva
- Piccole migliorie varie
2026-03-02 13:23:28 +01:00
andrea.villa c6ced91b14 - Aggiunti parametri configurabili GEN_bTestAlternative e GEN_bGetAlternativesNesting2D per testare altre alternative valide
- Aggiunta funzione dedicata alla creazione del gruppo ausiliario al MachGroup
- Alla funzione BeamExec.GetCombinationListFromMatrix si può passare una lista con le sole combinazioni da provare
- Nella BeamExec aggiunta funzione ProcessAlternatives solo per provare le alternative (simile alla ProcessFeatures, ma completamente slegata). La ProcessFeature decide il posizionamento iniziale, la ProcessAlternatives verifica solamente le alternative.
- FlipRot adeguata a nuovo funzionamento
- Altre piccole migliorie varie
- TODO :
   1) manca la parte per settare nelle info pezzo la rotazione iniziale (per vista in Aedifica) e le altre alternative (per ottimizzazione in nesting)
   2) In FlipRot gestire interazione con Aedifica, dato che verrà lanciato direttamente dal programma (per ora funziona lanciato come la Process)
2026-03-02 12:35:12 +01:00
luca.mazzoleni 8efb64810a - in FaceData si raccolgono informazioni sulle facce fino a 6 lati compresi 2026-02-26 17:56:12 +01:00
andrea.villa 02390c2e9b - Tolte pre-rotazioni dalla Process
- FlipRot modificata, ora ereditata dalla Process
2026-02-24 16:50:48 +01:00
andrea.villa 7f7d75c113 - BatchProcess non calcola più le prerotazioni
- Modifiche varie per nuova gestione pre-rotazioni
- Nuovo script FlipRot (per ora copiata da BatchProcess, poi dovrà ruotare i pezzi e posizionarli in base alla migliore posizione di lavoro)
2026-02-23 16:24:43 +01:00
andrea.villa ecd50c0fea Piccola correzione gestione ricalcolo lavorazioni dopo applicazione 2026-02-10 13:33:05 +01:00
andrea.villa 6f195e7fac Merge branch 'ReprocessOnApplyError' into develop 2026-02-10 09:45:49 +01:00
59 changed files with 5551 additions and 1606 deletions
+39 -14
View File
@@ -214,9 +214,6 @@ end
local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. ( BEAM.MACHINE or EgtGetCurrMachineName()) .. ', ' .. sFlag
EgtOutLog( sLog)
-- TODO forzatura calcolo con prerotazioni. Cancellare dopo che è stata aggiunta la gestione corretta
local bCalcBestPieceUnloadPosition = true or BEAM.FLAG == 10
-- Dati dei file
-- TODO spostare a quando flag ~= 6 e 9
local sDir, sTitle = EgtSplitPath( BEAM.FILE)
@@ -253,6 +250,7 @@ elseif BEAM.FLAG == 9 then
local Proc = FeatureLib.GetProcFromTrimesh( BEAM.FEATUREID, Part)
Proc.nGrp = EgtGetInfo( Proc.id, 'GRP', 'i')
Proc.nPrc = EgtGetInfo( Proc.id, 'PRC', 'i')
Proc.nParts = EgtSurfTmPartCount( Proc.id) or 1
Proc.Topology = {}
if FeatureLib.NeedTopologyFeature( Proc, Part) then
@@ -390,6 +388,15 @@ if bToProcess then
else
PARTS[i].b3PartOriginal = b3Solid
end
if BeamData.MAX_LENGTH and BeamData.MAX_LENGTH > 10 and b3Solid:getDimX() > BeamData.MAX_LENGTH then
local sOut = 'Piece-Length (' .. EgtNumToString( b3Solid:getDimX(), 2) .. ') ' ..
'out of machine limits (' .. EgtNumToString( BeamData.MAX_LENGTH, 2) .. ') '
BEAM.ERR = 17
BEAM.MSG = sOut
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
PostErrView( BEAM.ERR, BEAM.MSG)
return
end
end
-- Assegno lunghezza della barra
dBarLen = PARTS[1].b3PartOriginal:getDimX() + 10
@@ -449,6 +456,15 @@ if bToProcess then
else
PARTS[i].b3PartOriginal = b3Solid
end
if BeamData.MAX_LENGTH and BeamData.MAX_LENGTH > 10 and b3Solid:getDimX() > BeamData.MAX_LENGTH then
local sOut = 'Piece-Length (' .. EgtNumToString( b3Solid:getDimX(), 2) .. ') ' ..
'out of machine limits (' .. EgtNumToString( BeamData.MAX_LENGTH, 2) .. ') '
BEAM.ERR = 17
BEAM.MSG = sOut
WriteErrToLogFile( BEAM.ERR, BEAM.MSG)
PostErrView( BEAM.ERR, BEAM.MSG)
return
end
end
end
@@ -494,6 +510,7 @@ if bToProcess then
return
end
-- TODO in caso di "GEN_sPiecesLoadingPosition = FULL_PRE_ROTATION" bisogna controllare anche sezione ribaltata di 90°
-- 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
@@ -551,7 +568,7 @@ if bToProcess then
end
-- Sistemo le travi nel grezzo
local bPbOk, sPbErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, nil, PARTS, BEAM.FLAG ~= 6, bCalcBestPieceUnloadPosition)
local bPbOk, sPbErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, nil, PARTS, BEAM.FLAG ~= 6, BEAM.FLAG == 10)
if not bPbOk then
BEAM.ERR = 18
BEAM.MSG = sPbErr
@@ -640,7 +657,8 @@ if bToProcess then
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
TIMER:stopElapsed('Json')
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bCalcBestPieceUnloadPosition)
-- parametro FlipRot sempre a false perchè a barra già creata non si possono più ruotare i pezzi
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], false)
-- sovramateriale in testa al pezzo
local dDeltaS = max( PARTS[i].dPosX - ( dBarLen - dLen), 0)
@@ -693,12 +711,9 @@ if bToProcess then
-- TODO gestire errori e messaggi di ritorno in questo caso
if not GetDataConfig() then return end
BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
BeamExec.ProcessMachinings( PARTS)
-- si cancella gruppo temporaneo contenente entità da cancellare
EgtErase( idTempGroup)
BeamExec.GetProcessings( PARTS, BEAM.FLAG == 10)
BeamExec.GetCombinationMatrix( PARTS, BEAM.FLAG == 10)
BeamExec.ProcessMachinings( PARTS, BEAM.FLAG == 10)
local sOutput = ''
@@ -725,7 +740,7 @@ if bToProcess then
BEAM.ERR = 0
BEAM.MSG = '---'
end
BEAM.ROT = -( RESULT[i].nRotation or 1) + 1
BEAM.ROT = -( ( RESULT[i].nRotation - ( BEAM.PREROTATE90 or 0)) or 1) + 1
BEAM.CUTID = RESULT[i].idCut
BEAM.TASKID = RESULT[i].idTask
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
@@ -741,7 +756,7 @@ if bToProcess then
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
BEAM.ERR = 19
BEAM.MSG = sMsg
BEAM.ROT = -( RESULT[i].nRotation or 1) + 1
BEAM.ROT = -( ( RESULT[i].nRotation - ( BEAM.PREROTATE90 or 0)) or 1) + 1
BEAM.CUTID = RESULT[i].idCut
BEAM.TASKID = RESULT[i].idTask
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
@@ -767,7 +782,7 @@ if bToProcess then
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
BEAM.ERR = -19
BEAM.MSG = 'Incomplete : Completion index ' .. RESULT[i].ChosenStrategy.dCompletionIndex .. '/5\n' .. sMsg
BEAM.ROT = -( RESULT[i].nRotation or 1) + 1
BEAM.ROT = -( ( RESULT[i].nRotation - ( BEAM.PREROTATE90 or 0)) or 1) + 1
BEAM.CUTID = RESULT[i].idCut
BEAM.TASKID = RESULT[i].idTask
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
@@ -775,6 +790,16 @@ if bToProcess then
end
end
-- calcolo alternative (scrive già le variabili globali per interfaccia)
if BEAM.FLAG == 10 then
TIMER:startElapsed('Alternatives')
BeamExec.ProcessAlternatives( PARTS)
TIMER:stopElapsed('Alternatives')
end
-- si cancella gruppo temporaneo contenente entità da cancellare
EgtErase( idTempGroup)
-- TODO: se scarico a caduta (-101, -102) le lavorazioni dopo separazione vanno disattivate. Scrivere info feature incompleta su quelle feature
-- Salvo il progetto
+247
View File
@@ -0,0 +1,247 @@
-- Process.lua by Egalware s.r.l. 2024/04/02
-- Gestione calcolo disposizione e lavorazioni per Travi
-- Si opera sulla macchina corrente
-- 2024/04/02 PRIMA VERSIONE
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
-- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua')
EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.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\\BeamDataNew.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.BasicCustomerStrategies = nil
_G.package.loaded.BeamExec = nil
_G.package.loaded.BeamLib = nil
_G.package.loaded.DiceCut = nil
_G.package.loaded.FaceData = nil
_G.package.loaded.FeatureLib = nil
_G.package.loaded.Identity = nil
_G.package.loaded.Logs = nil
_G.package.loaded.MachiningLib = nil
_G.package.loaded.PreSimulationLib = nil
_G.package.loaded.LeadInOutLib = nil
-- strategie di base sempre presenti
_G.package.loaded['HEADCUT\\HEADCUT'] = nil
_G.package.loaded['TAILCUT\\TAILCUT'] = nil
-- libreria macchina
_G.package.loaded.BeamDataNew = nil
-- libreria calcolo tempo esecuzione
_G.package.loaded.TimeLib = 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( EgtNumToString( i/10000, -4), '0.', '')
local sLibraryToReload = "STR" .. idSTRTemp .. "\\STR" .. idSTRTemp
if _G.package.loaded[sLibraryToReload] then
_G.package.loaded[sLibraryToReload] = nil
end
end
local vtCoreStrategiesNames = EgtFindAllFiles( BEAM.BASEDIR .. '\\StrategyLibs\\*.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
-- Variabili globali
PARTS = {} -- tabella contenente tutte le informazioni di ogni pezzo
-- Carico i dati globali
local BeamData = require( 'BeamDataNew')
-- carico librerie
local BeamExec = require( 'BeamExec')
local BeamLib = require( 'BeamLib')
-------------------------------------------------------------------------------------------------------------
-- *** Recupero trave (E' SEMPRE E SOLO UNA) ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessInputData()
-- Recupero il pezzo e i suoi dati
local nId = EgtGetFirstPart()
if nId then
table.insert( PARTS, { nInd = #PARTS + 1, id = nId, sName = ( EgtGetName( nId) or ( 'Id=' .. tonumber( nId)))})
local Ls = EgtGetFirstNameInGroup( PARTS[1].id, 'Box')
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
if not b3Solid then
return false
end
PARTS[1].b3PartOriginal = b3Solid
else
return false
end
return true
end
-------------------------------------------------------------------------------------------------------------
local function GetDataConfig()
-- recupero utensili dal magazzino
BeamExec.GetToolsFromDB()
-- TODO da gestire eventuali errori bloccanti
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle travi nel grezzo ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessBeams()
-- Lunghezza totale delle travi
local dLen = PARTS[1].b3PartOriginal:getDimX()
local dRawW = PARTS[1].b3PartOriginal:getDimY()
local dRawH = PARTS[1].b3PartOriginal:getDimZ()
-- Determinazione minimo grezzo scaricabile
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
local dOvmHead = BeamData.OVM_HEAD or 10
local dOvmMid = BeamData.OVM_MID or 10
local dRawL = max( dLen + dOvmHead + dOvmMid, BeamData.dMinRaw)
-- Recupero info pezzi
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, true)
if not bOk then
EgtOutLog( sErr)
return false
end
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle lavorazioni nelle travi ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessFeatures()
BeamExec.GetProcessings( PARTS, true)
BeamExec.GetCombinationMatrix( PARTS, true)
BeamExec.ProcessMachinings( PARTS, true)
-- scrittura variabili globali per interfaccia
BEAM.PREROTATE90 = PARTS[1].nInitialPosition - 1
BEAM.PREINVERT = EgtIf( PARTS[1].bPartInCombiIsInverted, 1, 0)
local nErrCnt = 0
local nWarnCnt = 0
local sOutput = ''
for i = 1, #RESULT do
local sMsg = ''
if RESULT[i].sType == 'Feature' then
sMsg = RESULT[i].ChosenStrategy.sInfo
elseif RESULT[i].sType == 'Part' then
sMsg = RESULT[i].sMsg
end
sMsg = string.gsub( sMsg or '', '\n', ' ', 10)
sMsg = string.gsub( sMsg or '', '\r', ' ', 10)
-- trovata almeno una strategia e feature lavorata completamente
if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg or '')
-- trovata almeno una strategia ma nessuna applicabile oppure non trovata alcuna strategia
elseif RESULT[i].sType == 'Feature'
and ( ( RESULT[i].ChosenStrategy.sStatus == 'Not-Applicable')
or ( not RESULT[i].ChosenStrategy.sStrategyName)) then
nErrCnt = nErrCnt + 1
if #sMsg == 0 then
sMsg = 'No applicable strategy found'
end
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
else
-- segnalazione scarico pezzo standard, incompleto o a caduta
if RESULT[i].sType == 'Part' and ( RESULT[i].nErr == -100 or RESULT[i].nErr == -101 or RESULT[i].nErr == -102) then
-- nulla da segnalare
-- feature incompleta e altro
elseif RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Not-Completed' then
nWarnCnt = nWarnCnt + 1
sMsg = 'Incomplete : Completion index ' .. RESULT[i].ChosenStrategy.dCompletionIndex .. '/5\n' .. sMsg
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
end
end
end
-- si calcolano alternative
TIMER:startElapsed('Alternatives')
BeamExec.ProcessAlternatives( PARTS)
TIMER:stopElapsed('Alternatives')
-- cancello gruppo temporaneo
local idTempGroup = BeamLib.GetTempGroup()
EgtErase( idTempGroup)
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 ***
-------------------------------------------------------------------------------------------------------------
-- calcolo tempo esecuzione
TIMER:start()
EgtOutLog( ' Execution timer started')
-- script principale
if not MyProcessInputData() then return end
-- recupero parametri generali da progetto
BeamExec.GetGeneralParameters()
-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella
BeamLib.CreateTempGroup()
if not MyProcessBeams() then return end
if not GetDataConfig() then return end
-- Abilito Vmill
EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1')
MyProcessFeatures()
-- log tempi di esecuzione
if EgtGetDebugLevel() >= 3 then
TIMER:logAllElapsed()
end
+44
View File
@@ -0,0 +1,44 @@
-- GetWallData.lua by Egaltech s.r.l. 2022/06/28
-- Recupero dati da file WallData.lua di macchina
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Per test
--GWD = {}
--GWD.MACHINE = 'Essetre-90480019_MW'
local sLog = 'GetBeamData : ' .. GWD.MACHINE
EgtOutLog( sLog)
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( GWD.BASEDIR .. '\\LuaLibs\\?.lua')
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
local sMachDir = EgtGetCurrMachineDir()
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
GWD.ERR = 12
GWD.MSG = 'Error not configured for beam machine : ' .. GWD.MACHINE
WriteErrToLogFile( GWD.ERR, GWD.MSG)
PostErrView( GWD.ERR, GWD.MSG)
return
end
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
EgtRemoveBaseMachineDirFromPackagePath()
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
-- Carico i dati globali
_G.package.loaded.BeamData = nil
local BD = require( 'BeamDataNew')
-- Assegno valori di interesse
GWD.SIMUL_VIEW_DIR = BD.SIMUL_VIEW_DIR
GWD.OVM_MID = BD.OVM_MID
-- Tutto ok
GWD.ERR = 0
EgtOutLog( ' +++ GetBeamData completed')
+1
View File
@@ -252,6 +252,7 @@ local function GetStrategies_Essetre( Proc)
---------------------------------------------------------------------
-- Feature : Chamfer (0-36)
elseif ID.IsChamfer( Proc) then
Strategies = { { sStrategyId = 'STR0002'}, { sStrategyId = 'STR0005'}, { sStrategyId = 'STR0010'}}
---------------------------------------------------------------------
-- Feature : Block Haus Half Lap (0-37)
elseif ID.IsHalfBlockHaus( Proc) then
+965 -311
View File
File diff suppressed because it is too large Load Diff
+176 -22
View File
@@ -161,17 +161,45 @@ function BeamLib.GetPartSplittingPoints( Part)
end
-------------------------------------------------------------------------------------------------------------
function BeamLib.AddPhaseWithRawParts( idRaw, OriXR, PosXR, dDeltaSucc)
function BeamLib.AddPhaseWithRawParts( PARTS, nPartIndex, OriXR, PosXR, dDeltaSucc)
local nPhase = EgtAddPhase()
local Part
local idRaw
-- se l'indice è oltre significa che è l'ultimo grezzo senza pezzi
if nPartIndex > #PARTS then
idRaw = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
else
Part = PARTS[nPartIndex]
idRaw = Part.idRaw
end
-- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola
EgtSetTableAreaOffset( 2000, 2000, 2000, 2000)
local dRawMove = 0
local bIsFirstRaw = true
local dPosXFirst = 0
while idRaw do
local dPosX
for i = 1, #PARTS do
local CurrentPart = PARTS[i]
if CurrentPart.idRaw == idRaw then
dPosX = CurrentPart.dPosX
if bIsFirstRaw then
dPosXFirst = dPosX
end
break
end
if i == #PARTS then
dPosX = PARTS[i].dPosX + PARTS[i].b3Raw:getDimX()
end
end
if bIsFirstRaw then
bIsFirstRaw = false
else
dRawMove = dDeltaSucc + dPosX - dPosXFirst
end
EgtKeepRawPart( idRaw)
EgtMoveToCornerRawPart( idRaw, OriXR, PosXR)
EgtMoveRawPart( idRaw, Vector3d( - dRawMove, 0, 0))
if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end
dRawMove = dRawMove + EgtGetRawPartBBox( idRaw):getDimX()
idRaw = EgtGetNextRawPart( idRaw)
end
-- salvo info nuova fase aggiunta
@@ -328,6 +356,18 @@ function BeamLib.RotateRawPart( Part, nNumberOfRotations)
end
end
-------------------------------------------------------------------------------------------------------------
function BeamLib.CreateAddGroup( PartId, sGroupName)
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, sGroupName)
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 25))
end
-------------------------------------------------------------------------------------------------------------
function BeamLib.CreateOrEmptyAddGroup( PartId)
-- recupero i dati del gruppo aggiuntivo
@@ -341,15 +381,9 @@ function BeamLib.CreateOrEmptyAddGroup( PartId)
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, 25))
BeamLib.CreateAddGroup( PartId, sMchGrp)
return true
end
@@ -389,6 +423,24 @@ function BeamLib.GetAddGroup( PartId)
return AddGrpId, sMchGrp
end
-------------------------------------------------------------------------------------------------------------
-- Funzione prossimo nome MachGroup libero (numero intero)
function BeamLib.GetNewMachGroupName()
local idMachGroup = EgtGetFirstMachGroup()
if not idMachGroup then return 1 end
local nMaxMachGroup = 0
while idMachGroup do
local sMachGroupName = EgtGetMachGroupName( idMachGroup)
local nMachGroupName = tonumber( sMachGroupName)
if nMachGroupName > nMaxMachGroup then
nMaxMachGroup = nMachGroupName
end
idMachGroup = EgtGetNextMachGroup( idMachGroup)
end
return nMaxMachGroup + 1
end
-------------------------------------------------------------------------------------------------------------
-- restituisce le facce della parte interessate dalla feature Proc
-- TODO da spostare in FeatureLib???
@@ -506,10 +558,69 @@ function BeamLib.GetDirectionFromSCC( nSCC)
elseif nSCC == MCH_SCC.ADIR_ZM then
vtSCC = -Z_AX()
end
return vtSCC
end
-------------------------------------------------------------------------------------------------------------
-- Restituisce una tabella con i punti ai vertici della faccia, in globale
-- ordinati partendo da quello ai valori minimi degli assi e i successivi secondo rotazione destrorsa X+;
-- solo per Proc a 1 faccia
function BeamLib.GetSortedVertices( Proc)
local PtVerticesSorted = {}
-- se più di una faccia si esce subito
if Proc.nFct > 1 then
return
end
local PtVertices = {}
local nFirstIndex
local dMinYZ = GEO.INFINITO
for i = 1, #Proc.Faces[1].Edges do
local Edge = Proc.Faces[1].Edges[i]
table.insert( PtVertices, Edge.ptStart)
if ( Edge.ptStart:getY() + Edge.ptStart:getZ() < dMinYZ) then
nFirstIndex = i
dMinYZ = Edge.ptStart:getY() + Edge.ptStart:getZ()
end
end
table.insert( PtVerticesSorted, PtVertices[nFirstIndex])
local nCurrentIndex = nFirstIndex
-- faccia che guarda verso X+, ordine ok
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL then
for _ = 1, #PtVertices - 1 do
_, nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
end
-- faccia che guarda verso X-, ordine da invertire
else
for _ = 1, #PtVertices - 1 do
nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
end
end
return PtVerticesSorted
end
-------------------------------------------------------------------------------------------------------------
-- restituisce il precedente e prossimo indice 1-based, tenendo conto del massimo indice
function BeamLib.GetAdjacentIndices( nCurrentIndex, nMaxIndex)
local nPreviousIndex, nNextIndex
if ( nCurrentIndex < 1) or ( nCurrentIndex > nMaxIndex) then
return
end
-- circular indexing 1-based
nPreviousIndex = ( ( nCurrentIndex - 2 + nMaxIndex) % nMaxIndex) + 1
nNextIndex = ( nCurrentIndex % nMaxIndex) + 1
return nPreviousIndex, nNextIndex
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)
@@ -769,22 +880,28 @@ function BeamLib.GetBlockedAxis( nToolIndex, sBlockedAxis, b3Raw, vtTool, vtOut)
return ''
end
-------------------------------------------------------------------------------------------------------------
function BeamLib.StringReplaceChar( sOriginal, nPosition, sChar)
return sOriginal:sub( 1, nPosition-1) .. sChar .. sOriginal:sub( nPosition+1)
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))
local n = string.sub( sNumberToConvert, k, k)
dResult = dResult + n * ( 2^( i-1))
end
return dResult
end
-------------------------------------------------------------------------------------------------------------
-- TODO si può sostituire con funzione EgtNumToBitString
function BeamLib.DecimalToBinary( dNumber)
local sNumberToConvert = tostring( dNumber)
local n = sNumberToConvert
@@ -792,12 +909,12 @@ function BeamLib.DecimalToBinary( dNumber)
local sResult = ""
for i = sNumberToConvert, 0, -1 do
local q = math.modf(n)
n = n/2
local b = q%2
table.insert(tmp, b)
local q = math.modf( n)
n = n / 2
local b = q % 2
table.insert( tmp, b)
if (q == 1) then
if ( q == 1) then
break
end
end
@@ -805,7 +922,7 @@ function BeamLib.DecimalToBinary( dNumber)
for i = #tmp, 1, -1 do
sResult = sResult..tmp[i]
end
return tonumber( sResult)
end
@@ -819,6 +936,43 @@ function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
return NumberString
end
-------------------------------------------------------------------------------------------------------------
function BeamLib.ConvertBitIndexToRotationIndex( sBitIndexCombination)
local nRotationIndex
if sBitIndexCombination == '1000' then
return 1
elseif sBitIndexCombination == '0100' then
return 2
elseif sBitIndexCombination == '0010' then
return 3
elseif sBitIndexCombination == '0001' then
return 4
elseif sBitIndexCombination == '1000_INV' then
return 5
elseif sBitIndexCombination == '0100_INV' then
return 6
elseif sBitIndexCombination == '0010_INV' then
return 7
elseif sBitIndexCombination == '0001_INV' then
return 8
end
return nRotationIndex
end
-------------------------------------------------------------------------------------------------------------
-- reindicizza una tabella passata ripartendo dall'indice nStartIndex e mantenendo l'ordine
function BeamLib.RotateTableFromIndex( Table, nStartIndex)
local RotatedTable = {}
for i = 1, #Table do
RotatedTable[#RotatedTable + 1] = Table[((RotatedTable + i - 2) % #Table) + 1]
end
return RotatedTable
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
+1 -1
View File
@@ -453,7 +453,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- se piani non ortogonali, diminuisco la distanza di offset opportunamente
local dOffsetParallelOriginal = dOffsetParallel
if not bGetOrtoPlanes then
local dCoeff = ( vtNMainFace ^ vtNSubordinateFace):len()
local dCoeff = max( ( vtNMainFace ^ vtNSubordinateFace):len(), 0.5)
dOffsetParallel = dOffsetParallel * dCoeff
dOffsetOrthogonal = dOffsetOrthogonal * dCoeff
end
+59 -45
View File
@@ -91,7 +91,9 @@ function FaceData.GetFacesByAdjacencyNumber( Proc)
FacesByAdjacencyNumber[i] = {}
end
for i = 1, Proc.nFct do
table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i])
if #Proc.Faces[i].Adjacencies > 0 then
table.insert( FacesByAdjacencyNumber[#Proc.Faces[i].Adjacencies], Proc.Faces[i])
end
end
return FacesByAdjacencyNumber
@@ -114,14 +116,8 @@ function FaceData.GetEdgesInfo( ProcOrId, idFace )
local nFaceType, EdgesEgt = EgtSurfTmGetFacetOutlineInfo( Proc.id, idFace, GDB_ID.ROOT)
for i = 1, #EdgesEgt do
local nPreviousEdgeIndex = i - 1
if i == 1 then
nPreviousEdgeIndex = #EdgesEgt
end
local nNextEdgeIndex = i + 1
if i == #EdgesEgt then
nNextEdgeIndex = 1
end
local nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( i, #EdgesEgt)
-- l'elevazione si tiene sempre positiva e la normale sempre diretta verso l'interno della faccia
-- per sapere se il lato è aperto c'è la proprietà apposita bIsOpen
@@ -141,6 +137,8 @@ function FaceData.GetEdgesInfo( ProcOrId, idFace )
CurrentEdge.vtEdge = CurrentEdge.ptEnd - CurrentEdge.ptStart ; CurrentEdge.vtEdge:normalize()
CurrentEdge.sType = 'Standard'
CurrentEdge.id = i - 1
CurrentEdge.nPreviousEdgeIndex = nPreviousEdgeIndex
CurrentEdge.nNextEdgeIndex = nNextEdgeIndex
-- se nella Proc ci sono le adiacenze e il lato ha adiacenza, si salva l'angolo con la faccia adiacente
if Proc.AdjacencyMatrix then
@@ -186,7 +184,7 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
Faces[i].id = i - 1
Faces[i].idTrimesh = Proc.id
Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT)
if Proc.nFct < 6 or FaceIsToGet( i) then
if Proc.nFct < 7 or FaceIsToGet( i) then
-- frame OCS faccia
Faces[i].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
-- elevazione calcolata rispetto al box della parte
@@ -367,7 +365,8 @@ local function GetBottomFaces( Proc)
if Proc.Topology.sFamily == 'Tunnel' then
return nil
elseif not ( Proc.Topology.sFamily == 'Rabbet'
elseif not ( Proc.Topology.sFamily == 'PseudoPocket'
or Proc.Topology.sFamily == 'Rabbet'
or Proc.Topology.sFamily == 'VGroove'
or Proc.Topology.sFamily == 'Groove'
or Proc.Topology.sFamily == 'Pocket'
@@ -383,10 +382,28 @@ local function GetBottomFaces( Proc)
return { Proc.Faces[1]}
end
-- la faccia di fondo ha sempre Fct - 1 adiacenze
-- la faccia di fondo ha sempre Fct - 1 adiacenze, tranne caso speciale DoubleBevel con facce di chiusura triangolari
local FacesByAdjacencyNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
if FacesByAdjacencyNumber then
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct - 1]
-- caso speciale DoubleBevel
if #BottomFaces == 0 then
if Proc.nParts == 1 then
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct / 2]
-- DoubleBevel composto da più parti
else
for i = #FacesByAdjacencyNumber, 1, -1 do
if #FacesByAdjacencyNumber[i] > 0 then
BottomFaces = FacesByAdjacencyNumber[i]
break
end
end
-- se non sono state trovate facce di fondo significa che nessuna faccia ha adiacenze -> DoubleBevel-2
if #BottomFaces == 0 then
BottomFaces = Proc.Faces
end
end
end
-- si rimuovono le facce non adatte ad essere lavorate
local nBottomFaces = #BottomFaces
local nCurrentFace = 1
@@ -430,14 +447,7 @@ local function GetBottomFaces( Proc)
end
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 nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( i, #BottomFaces[1].Edges)
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = BottomFaces[1].Edges[i].idAdjacentFace
@@ -451,6 +461,8 @@ local function GetBottomFaces( Proc)
CurrentEdge.ptEnd = BottomFaces[1].Edges[i].ptEnd
CurrentEdge.vtEdge = BottomFaces[1].Edges[i].vtEdge
CurrentEdge.id = BottomFaces[1].Edges[i].id
CurrentEdge.nPreviousEdgeIndex = BottomFaces[1].Edges[i].nPreviousEdgeIndex
CurrentEdge.nNextEdgeIndex = BottomFaces[1].Edges[i].nNextEdgeIndex
if nFirstLongEdgeIndex then
if i == nFirstLongEdgeIndex then
@@ -476,7 +488,7 @@ end
local function GetLongFaces( Proc, MainFaces)
local LongFaces = {}
if Proc.nFct > 5 then
if Proc.nFct > 6 then
error( 'GetLongFaces : Topology not implemented')
elseif Proc.nFct == 1 then
return {}
@@ -519,8 +531,8 @@ local function GetLongFaces( Proc, MainFaces)
for i = 1, #LongFaces do
LongFaces[i].sType = 'Long'
-- calcolo MainEdges possibile solo se 4 lati esatti
if #LongFaces[i].Edges ~= 4 then
-- calcolo MainEdges possibile solo se 4 lati esatti e caso speciale lato opposto groove tagliato
if #LongFaces[i].Edges ~= 4 and not ( #LongFaces[i].Edges == 5 and Proc.Topology.sName == 'Groove-3-Through') then
break
end
@@ -529,14 +541,7 @@ local function GetLongFaces( Proc, MainFaces)
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 nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( j, #LongFaces[i].Edges)
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = LongFaces[i].Edges[j].idAdjacentFace
@@ -550,6 +555,8 @@ local function GetLongFaces( Proc, MainFaces)
CurrentEdge.ptEnd = LongFaces[i].Edges[j].ptEnd
CurrentEdge.vtEdge = LongFaces[i].Edges[j].vtEdge
CurrentEdge.id = LongFaces[i].Edges[j].id
CurrentEdge.nPreviousEdgeIndex = LongFaces[i].Edges[j].nPreviousEdgeIndex
CurrentEdge.nNextEdgeIndex = LongFaces[i].Edges[j].nNextEdgeIndex
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
@@ -575,6 +582,12 @@ local function GetLongFaces( Proc, MainFaces)
end
end
end
-- il primo OppositeEdge deve essere sempre il più lungo, se più di uno
if #LongFaces[i].MainEdges.OppositeEdges > 1 then
if LongFaces[i].MainEdges.OppositeEdges[1].dLength < LongFaces[i].MainEdges.OppositeEdges[2].dLength - 10 * GEO.EPS_SMALL then
LongFaces[i].MainEdges.OppositeEdges[1], LongFaces[i].MainEdges.OppositeEdges[2] = LongFaces[i].MainEdges.OppositeEdges[2], LongFaces[i].MainEdges.OppositeEdges[1]
end
end
end
return LongFaces
@@ -584,7 +597,7 @@ end
local function GetSideFaces( Proc, MainFaces)
local SideFaces = {}
if Proc.nFct > 5 then
if Proc.nFct > 6 then
error( 'GetSideFaces : Topology not implemented')
elseif Proc.nFct == 1 then
return {}
@@ -629,14 +642,7 @@ local function GetSideFaces( Proc, MainFaces)
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 nPreviousEdgeIndex, nNextEdgeIndex = BeamLib.GetAdjacentIndices( j, #SideFaces[i].Edges)
local CurrentEdge = {}
CurrentEdge.idAdjacentFace = SideFaces[i].Edges[j].idAdjacentFace
@@ -650,6 +656,8 @@ local function GetSideFaces( Proc, MainFaces)
CurrentEdge.ptEnd = SideFaces[i].Edges[j].ptEnd
CurrentEdge.vtEdge = SideFaces[i].Edges[j].vtEdge
CurrentEdge.id = SideFaces[i].Edges[j].id
CurrentEdge.nPreviousEdgeIndex = SideFaces[i].Edges[j].nPreviousEdgeIndex
CurrentEdge.nNextEdgeIndex = SideFaces[i].Edges[j].nNextEdgeIndex
if Proc.Topology.sFamily == 'Tunnel' then
if CurrentEdge.idAdjacentFace > -1 then
@@ -686,19 +694,25 @@ function FaceData.GetMainFaces( Proc, Part)
local MainFaces = {}
-- CASO 1 : Feature tipo LapJoint
if Proc.Topology.sFamily == 'Rabbet' or Proc.Topology.sFamily == 'VGroove' or Proc.Topology.sFamily == 'Groove' or
if Proc.Topology.sFamily == 'PseudoPocket' or Proc.Topology.sFamily == 'Rabbet' or Proc.Topology.sFamily == 'VGroove' or Proc.Topology.sFamily == 'Groove' or
Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Bevel' or
Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sFamily == 'Cut' or Proc.Topology.sFamily == 'HeadCut' or Proc.Topology.sFamily == 'TailCut' then
if ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5)
or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind' then
if Proc.nParts == 1 and ( ( Proc.Topology.bIsThrough and Proc.Topology.bAllRightAngles and Proc.nFct < 5)
or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind') then
MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc, Part)
end
MainFaces.BottomFaces = GetBottomFaces( Proc)
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
if Proc.nParts == 1 then
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
-- caso tipo DoubleBevel con facce separate
else
MainFaces.LongFaces = {}
MainFaces.SideFaces = {}
end
else
MainFaces = nil
+21 -8
View File
@@ -43,7 +43,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra
local function IsFeatureCuttingEntireSection( b3Proc, Part)
function FeatureLib.IsFeatureCuttingEntireSection( b3Proc, Part)
return ( b3Proc:getDimY() > ( Part.b3Part:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Part:getDimZ() - 500 * GEO.EPS_SMALL))
end
@@ -198,7 +198,7 @@ function FeatureLib.ClassifyTopology( Proc, Part)
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part)
local bIsFeatureCuttingEntireSection = FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part)
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part)
local vAdj = Proc.AdjacencyMatrix
@@ -226,13 +226,13 @@ function FeatureLib.ClassifyTopology( Proc, Part)
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
elseif Proc.nFct == 2 and bAllAnglesConcave and Proc.nParts == 1 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
elseif Proc.nFct == 2 and bAllAnglesConcave and Proc.nParts == 1 then
sFamily = 'VGroove'
bIsThrough = true
elseif Proc.nFct == 2 and not bAllAnglesConcave and bIsAnyDimensionLongAsPart then
elseif Proc.nFct == 2 and ( not bAllAnglesConcave or Proc.nParts == 2) and bIsAnyDimensionLongAsPart then
sFamily = 'DoubleBevel'
bIsThrough = true
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and #vTriangularFaces == 2 then
@@ -244,7 +244,9 @@ function FeatureLib.ClassifyTopology( Proc, Part)
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
elseif Proc.nFct == 4
and ( ( not bAllAnglesConcave and ( ( #vFacesByAdjNumber[2] == 2 and #vTriangularFaces == 2) or ( #vFacesByAdjNumber[3] == 2)))
or ( #vTriangularFaces == 2 and Proc.nParts == 2)) then
sFamily = 'DoubleBevel'
bIsThrough = false
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then
@@ -253,13 +255,18 @@ function FeatureLib.ClassifyTopology( Proc, Part)
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 4 and bIsAnyDimensionLongAsPart then
sFamily = 'Tunnel'
bIsThrough = true
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 1 then
sFamily = 'PseudoPocket'
bIsThrough = false
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
elseif Proc.nFct == 6
and ( ( #vFacesByAdjNumber[1] == 4 and #vFacesByAdjNumber[3] == 2 and #vTriangularFaces == 4 and not bAllAnglesConcave)
or ( #vFacesByAdjNumber[1] == 4 and #vTriangularFaces == 4 and Proc.nParts == 2)) then
sFamily = 'DoubleBevel'
bIsThrough = false
end
@@ -333,6 +340,9 @@ function FeatureLib.GetAdditionalInfo( Proc, Part)
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
Proc.FeatureInfo, Proc.MainFaces = FeatureLib.GetRafterNotchData( Proc)
elseif ( ID.IsScarfJoint( Proc) or ID.IsScarfSimple( Proc)) then
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
end
return Proc
@@ -757,6 +767,9 @@ function FeatureLib.CalculateStrategiesCompositeRating( AvailableStrategies, sMa
AvailableStrategies[n].Result.dCompositeRating = dQuality + dCompletion + dTime -- TODO da verificare se meglio sommare o moltiplicare gli indici
else
if not AvailableStrategies[n].Result then
AvailableStrategies[n].Result = {}
end
AvailableStrategies[n].Result.dCompositeRating = 0
end
end
@@ -850,7 +863,7 @@ function FeatureLib.GetFeatureSplittingPoints( Proc, Part, OptionalParameters)
if Part.dRestLength + Part.b3Part:getDimX() < BeamData.dMinRaw * 1.5 then
dSplitXLeft = Part.b3Part:getMax():getX() - ( ( Part.dRestLength + Part.b3Part:getDimX()) / 2)
else
dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw)/2 + 150, Part.b3Part:getMax():getX() - dMaxSegmentLengthOnEdges)
dSplitXLeft = max( Proc.b3Box:getMin():getX() + ( BeamData.dMinRaw) / 2 + 150, Part.b3Part:getMax():getX() - dMaxSegmentLengthOnEdges)
end
end
dFeatureCentralLength = abs( dSplitXRight - dSplitXLeft)
+99 -72
View File
@@ -169,20 +169,20 @@ function MachiningLib.GetSplitMachinings( Machinings, SplittingPoints, Part)
dStartAddLength, dEndAddLength = dEndAddLength, dStartAddLength
end
if j == 1 then
dEndAddLength = - ( SplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP
dEndAddLength = - ( SplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP / 2
if LeadOutForSplit then
Machinings[nCurrentMachiningIndex].LeadOut = BeamLib.TableCopyDeep( LeadOutForSplit)
end
Machinings[nCurrentMachiningIndex].ptCenter = Point3d( SplittingPoints[j]:getX() + ( dEdgeMaxX - SplittingPoints[j]:getX()) / 2, 0, 0)
elseif j == nParts then
dStartAddLength = - ( dEdgeMaxX - SplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP
dStartAddLength = - ( dEdgeMaxX - SplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP / 2
if LeadInForSplit then
Machinings[nCurrentMachiningIndex].LeadIn = BeamLib.TableCopyDeep( LeadInForSplit)
end
Machinings[nCurrentMachiningIndex].ptCenter = Point3d( dEdgeMinX + ( SplittingPoints[j - 1]:getX() - dEdgeMinX) / 2, 0, 0)
else
dStartAddLength = - ( dEdgeMaxX - SplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP
dEndAddLength = - ( SplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP
dStartAddLength = - ( dEdgeMaxX - SplittingPoints[j - 1]:getX()) + BeamData.MILL_OVERLAP / 2
dEndAddLength = - ( SplittingPoints[j]:getX() - dEdgeMinX) + BeamData.MILL_OVERLAP / 2
if LeadInForSplit then
Machinings[nCurrentMachiningIndex].LeadIn = BeamLib.TableCopyDeep( LeadInForSplit)
end
@@ -347,7 +347,7 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters)
return false
end
-- lavorazione in collisione con il pezzo: non fattibile
local bCollisionFound, bMoveAfterSplit = PreSimulationLib.CheckCollision( sBladeEngagement, CheckCollisionParameters, CheckCollisionOptionalParameters)
local bCollisionFound, bMoveAfterSplit = PreSimulationLib.CheckCollision( CheckCollisionParameters, CheckCollisionOptionalParameters)
if bCollisionFound then
return false
end
@@ -363,16 +363,22 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters)
-- attacco perpendicolare
local PerpendicularLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Perpendicular', Parameters, LeadInOutOptionalParameters)
-- check extracorsa nei punti di attacco
PointsOnToolTipCenter = {
PreSimulationLib.GetPointOnToolTipCenter( PerpendicularLeadInOut.LeadIn.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool),
PreSimulationLib.GetPointOnToolTipCenter( PerpendicularLeadInOut.LeadOut.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool)
}
local bOutOfStrokePerpendicular = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
-- se non è in extracorsa si aggiunge come attacco possibile
-- attacco perpendicolare non in extracorsa: si verifica se è in collisione
if not bOutOfStrokePerpendicular then
LeadInOut.Perpendicular = PerpendicularLeadInOut
LeadInOut.Perpendicular.bMoveAfterSplit = bMoveAfterSplit
CheckCollisionOptionalParameters.PointsToCheck = {}
table.insert( CheckCollisionOptionalParameters.PointsToCheck, PerpendicularLeadInOut.LeadIn.ptPoint)
table.insert( CheckCollisionOptionalParameters.PointsToCheck, PerpendicularLeadInOut.LeadOut.ptPoint)
local bCollisionFoundPerpendicular, bMoveAfterSplitPerpendicular = PreSimulationLib.CheckCollision( CheckCollisionParameters, CheckCollisionOptionalParameters)
-- attacco perpendicolare possibile
if not bCollisionFoundPerpendicular then
LeadInOut.Perpendicular = PerpendicularLeadInOut
LeadInOut.Perpendicular.bMoveAfterSplit = bMoveAfterSplitPerpendicular
end
end
-- se c'è almeno un lato chiuso l'unico attacco possibile è il perpendicolare
if not ( Edge.bIsStartOpen and Edge.bIsEndOpen) then
@@ -397,7 +403,7 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters)
CheckCollisionOptionalParameters.PointsToCheck = {}
table.insert( CheckCollisionOptionalParameters.PointsToCheck, TangentLeadInOut.LeadIn.ptPoint)
table.insert( CheckCollisionOptionalParameters.PointsToCheck, TangentLeadInOut.LeadOut.ptPoint)
local bCollisionFoundTangent, bMoveAfterSplitTangent = PreSimulationLib.CheckCollision( sBladeEngagement, CheckCollisionParameters, CheckCollisionOptionalParameters)
local bCollisionFoundTangent, bMoveAfterSplitTangent = PreSimulationLib.CheckCollision( CheckCollisionParameters, CheckCollisionOptionalParameters)
-- attacco tangenziale possibile
if not bCollisionFoundTangent then
LeadInOut.Tangent = TangentLeadInOut
@@ -468,6 +474,11 @@ end
function MachiningLib.FindMill( Proc, ToolSearchParameters)
local ToolInfo = {}
-- direzione utensile e fipo fresa obbligatori, altrimenti si esce
if not ToolSearchParameters.vtToolDirection or not ToolSearchParameters.sMillShape then
return ToolInfo
end
local nBestToolIndex
local dBestToolResidualDepth = 0
for i = 1, #TOOLS do
@@ -511,6 +522,18 @@ function MachiningLib.FindMill( Proc, ToolSearchParameters)
bIsToolCompatible = false
end
end
-- TODO da sostituire con test collisione come lama
local bIsFromBottom = ToolSearchParameters.vtToolDirection:getZ() < - 10 * GEO.EPS_SMALL
local bIsFromTop = ToolSearchParameters.vtToolDirection:getZ() > 10 * GEO.EPS_SMALL
local bIsSlanted = abs( ToolSearchParameters.vtToolDirection:getY()) > 0.707
local bIsOnHeadOrTail = Proc.AffectedFaces.bLeft or Proc.AffectedFaces.bRight
if ( ( bIsFromBottom and TOOLS[i].SetupInfo.HeadType.bTop) or ( bIsFromTop and TOOLS[i].SetupInfo.HeadType.bBottom))
and ( not bIsSlanted)
and ( not bIsOnHeadOrTail) then
bIsToolCompatible = false
end
-- scelgo il migliore
if bIsToolCompatible then
@@ -579,13 +602,11 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo LAMA con certe caratteristiche
-- TODO da rivedere/completare
-- TODO per Engagement serviranno (opzionali) sBlockedAxis e vtAux
function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local ToolInfo = {}
-- parametri obbligatori
if type( ToolSearchParameters.FaceToMachine) ~= 'table' then
error( 'FindBlade : missing face info')
end
if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then
error( 'FindBlade : missing top head info')
end
@@ -604,9 +625,10 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local bForceLongcutBlade = ToolSearchParameters.bForceLongcutBlade or false
local EdgeToMachine = ToolSearchParameters.EdgeToMachine
local Part = ToolSearchParameters.Part
local bIsDicing = ToolSearchParameters.bIsDicing or false
local idCheckCollisionTm = ToolSearchParameters.idCheckCollisionTm
local sRestLengthSideForPreSimulation = ToolSearchParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = ToolSearchParameters.bCannotSplitRestLength or false
local bDisableRealElevationCheck = ToolSearchParameters.bDisableRealElevationCheck or false
local nBestToolIndex
local dBestToolResidualDepth = 0
@@ -638,9 +660,10 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
dDepthToMachine = min( dElevation, TOOLS[i].dMaxDepth)
}
local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
}
TIMER:startElapsed( 'GetBladeEngagement')
bIsBladeOk, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
@@ -649,12 +672,6 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
if not bIsBladeOk then
bIsToolCompatible = false
end
-- se si ha solo la faccia si può verificare se questa è orientata correttamente
elseif FaceToMachine then
if MachiningLib.IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then
bIsToolCompatible = false
end
end
end
@@ -1158,7 +1175,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione per aggiungere una nuova lavorazione
function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
function MachiningLib.AddOperations( MACHININGS, PARTS, Part, sRotation)
local nErr
local sErr = ''
local bAreAllMachiningApplyOk = true
@@ -1355,13 +1372,19 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
MachStartAxesPos = EgtGetMachiningStartAxes(),
MachEndAxesPos = EgtGetMachiningEndAxes()}
table.insert( DB_MACH_APPLIED, MachExtraInfo)
-- se non esistono punto iniziale o finale, si disattiva operazione
if not MachExtraInfo.MachStartAxesPos or not MachExtraInfo.MachEndAxesPos then
EgtSetOperationMode( nOperationId, false)
end
-- se errore in applicazione
if not bIsApplyOk then
bAreAllMachiningApplyOk = false
nErr, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nOperationId, false)
local CurrProc = PROCESSINGS[MACHININGS[i].Proc.nIndexPartInParts].Rotation[MACHININGS[i].Proc.nIndexRotation][MACHININGS[i].Proc.nIndexInVProc]
local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
local CurrProc = PROCESSINGS[MACHININGS[i].Proc.nIndexPartInParts].Rotation[MACHININGS[i].Proc.nIndexRotation+nOffsetIndex][MACHININGS[i].Proc.nIndexInVProc]
-- si annulla la feature scelta, in modo che un successivo ricalcolo non la tenga in considerazione
CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sStatus = 'Not-Applicable'
CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sInfo = 'REJECTED (' .. sErr .. ')'
@@ -1378,7 +1401,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
-- se applicazione andata a buon fine
else
-- se non deve essere igniorato, si salva ingombro lavorazione attuale e fasi successive
-- se non deve essere ignorato, si salva ingombro lavorazione attuale e fasi successive
if not MACHININGS[i].AuxiliaryData.bIgnoreNotClampableLength then
-- salvo ingombro non pinzabile testa/coda
local nCurrRotation = MACHININGS[i].Proc.nIndexRotation
@@ -1420,9 +1443,9 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
bSplitExecuted = true
MACHININGS.Info.bSplitExecuted = true
BeamLib.AddPhaseWithRawParts( MACHININGS[i].Proc.idRaw, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
BeamLib.AddPhaseWithRawParts( PARTS, Part.nIndexInParts, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
-- se grezzo successivo senza pezzi e finale, va tolto
local nNextRawId = EgtGetNextRawPart( MACHININGS[i].Proc.idRaw)
local nNextRawId = EgtGetNextRawPart( Part.idRaw)
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BeamData.dMinRaw then
EgtRemoveRawPartFromCurrPhase( nNextRawId)
end
@@ -1436,18 +1459,20 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase)
-- posizione iniziale considerando eventuiali prerotazioni
local nRealInitialPosition = Part.nInitialPosition
if sRotation == 'DOWN' then
local nRotation = EgtIf( Part.nInitialPosition + 2 > 4, Part.nInitialPosition + 2 - 4, Part.nInitialPosition + 2) - 1
local nRotation = EgtIf( nRealInitialPosition + 2 > 4, nRealInitialPosition + 2 - 4, nRealInitialPosition + 2) - 1
BeamLib.RotateRawPart( Part, nRotation)
EgtSetInfo( idDisp, 'ROT', -2)
EgtSetInfo( idDisp, 'TYPE', 'MID2')
elseif sRotation == 'SIDE' then
local nRotation = EgtIf( Part.nInitialPosition + 1 > 4, Part.nInitialPosition + 1 - 4, Part.nInitialPosition + 1) - 1
local nRotation = EgtIf( nRealInitialPosition + 1 > 4, nRealInitialPosition + 1 - 4, nRealInitialPosition + 1) - 1
BeamLib.RotateRawPart( Part, nRotation)
EgtSetInfo( idDisp, 'ROT', -1)
EgtSetInfo( idDisp, 'TYPE', 'MID2')
else
local nRotation = Part.nInitialPosition - 1
local nRotation = nRealInitialPosition - 1
BeamLib.RotateRawPart( Part, nRotation)
EgtSetInfo( idDisp, 'TYPE', 'END')
end
@@ -1516,14 +1541,14 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
if Machining.nType == MCH_MY.DRILLING then
local function fact(n) return n == 0 and 1 or n * fact(n - 1) end
local nSteps = ceil( Machining.sDepth / Machining.dStep)
local dLenghtEachStep = Machining.sDepth / nSteps
local dLengthEachStep = Machining.sDepth / nSteps
-- numero dei movimenti a step, compresi andata e ritorno per scarico truciolo
local nTotStepMovement = 2 * fact( nSteps)
-- in feed si lavorano solo gli step
local dFeedTime = ( ( dLenghtEachStep + Machining.dStartSafetyLength) * nSteps) / dToolFeed
-- ritorno per scaricare e approccio al prossimo step seno in feed finale
local dEndFeedTime = ( dLenghtEachStep * ( nTotStepMovement - nSteps) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ) * 2) / dToolEndFeed
dLengthToMachineAllStepsWithLeadInOut = dLenghtEachStep * nTotStepMovement
local dFeedTime = ( ( dLengthEachStep + Machining.dStartSafetyLength) * nSteps) / dToolFeed
-- ritorno per scaricare e approccio al prossimo step sono in feed finale
local dEndFeedTime = ( dLengthEachStep * ( nTotStepMovement - nSteps) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ) * 2) / dToolEndFeed
dLengthToMachineAllStepsWithLeadInOut = dLengthEachStep * nTotStepMovement
dTimeToMachineTotal = dFeedTime + dEndFeedTime
elseif Machining.nType == MCH_MY.MILLING then
-- stima LeadIn e LeadOut; se non settati si impostano a valori di default
@@ -1559,8 +1584,8 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
Machining.CloneStepsLongitudinal.nCount = 1
end
-- stima tempi di lavorazione per i diversi tratti
local dTimeToMachineLeadIn = ( Machining.dDepthToMachine + ( TOOLS[Machining.nToolIndex].SetupInfo.dZSafeDelta or 60) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ)) / dToolStartFeed
local dTimeToMachineLeadOut = ( Machining.dDepthToMachine + ( TOOLS[Machining.nToolIndex].SetupInfo.dZSafeDelta or 60) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ)) / dToolEndFeed
local dTimeToMachineLeadIn = ( Machining.dDepthToMachine + ( TOOLS[Machining.nToolIndex].SetupInfo.dZSafeDelta or 0) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ)) / dToolStartFeed
local dTimeToMachineLeadOut = ( Machining.dDepthToMachine + ( TOOLS[Machining.nToolIndex].SetupInfo.dZSafeDelta or 0) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ)) / dToolEndFeed
local dTimeToMachineEdge = Machining.dLengthToMachine / dToolFeed
-- calcolo lunghezze e tempi
if Machining.Steps.nStepType == MCH_MILL_ST.ZIGZAG then
@@ -1780,44 +1805,46 @@ function MachiningLib.ShortestPathSorting()
-- se è una lavorazione
while DB_MACH_APPLIED[i] and DB_MACH_APPLIED[i].sType ~= 'DISP' do
-- se lavorazione non attiva non va considerata
local nOperationId = DB_MACH_APPLIED[i].nOperationId
if EgtGetOperationMode( nOperationId) then
local ptMinX, ptMaxX
-- aggiungo lavorazioni
local nToolIndex = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nToolIndex
EgtOptMachAddTool( nToolIndex, 2, 2) -- , [ num dTC_X, num dTC_Y, num dTC_Z, num dTC_A, num dTC_B, num dTC_C])
-- viene eseguito prima il gruppo con indice più alto, quindi si inverte indice dato che lo stage è dal più piccolo al più grande
local nGroup = 10 - MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage
local MachStartAxesPos = DB_MACH_APPLIED[i].MachStartAxesPos
local MachEndAxesPos = DB_MACH_APPLIED[i].MachEndAxesPos
EgtOptMachAddMachining( i, nToolIndex, nGroup, MachStartAxesPos, MachEndAxesPos)
table.insert( MachiningOptList, i)
if DB_MACH_APPLIED[i].MachStartAxesPos and DB_MACH_APPLIED[i].MachEndAxesPos then
-- se lavorazione non attiva non va considerata
local nOperationId = DB_MACH_APPLIED[i].nOperationId
if EgtGetOperationMode( nOperationId) then
local ptMinX, ptMaxX
-- aggiungo lavorazioni
local nToolIndex = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nToolIndex
EgtOptMachAddTool( nToolIndex, 2, 2) -- , [ num dTC_X, num dTC_Y, num dTC_Z, num dTC_A, num dTC_B, num dTC_C])
-- viene eseguito prima il gruppo con indice più alto, quindi si inverte indice dato che lo stage è dal più piccolo al più grande
local nGroup = 10 - MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage
local MachStartAxesPos = DB_MACH_APPLIED[i].MachStartAxesPos
local MachEndAxesPos = DB_MACH_APPLIED[i].MachEndAxesPos
EgtOptMachAddMachining( i, nToolIndex, nGroup, MachStartAxesPos, MachEndAxesPos)
table.insert( MachiningOptList, i)
-- si salvano i punti minimi e massimi tra tutte le lavorazioni di ogni gruppo
if MachStartAxesPos[1] < MachEndAxesPos[1] then
ptMinX = MachStartAxesPos
ptMaxX = MachEndAxesPos
else
ptMinX = MachEndAxesPos
ptMaxX = MachStartAxesPos
end
-- si aggiungono le info di gruppo
local bFound = false
for t = 1, #GroupInfo do
if GroupInfo[t].nGroup == nGroup then
if GroupInfo[t].ptMin[1] > ptMinX[1] then GroupInfo[t].ptMin = ptMinX end
if GroupInfo[t].ptMax[1] < ptMaxX[1] then GroupInfo[t].ptMax = ptMaxX end
bFound = true
-- si salvano i punti minimi e massimi tra tutte le lavorazioni di ogni gruppo
if MachStartAxesPos[1] < MachEndAxesPos[1] then
ptMinX = MachStartAxesPos
ptMaxX = MachEndAxesPos
else
ptMinX = MachEndAxesPos
ptMaxX = MachStartAxesPos
end
end
-- se non ho trovato, si aggiunge in lista
if not bFound then
table.insert( GroupInfo, { nGroup = nGroup, nStage = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage, ptMin = ptMinX, ptMax = ptMaxX})
end
nMachInDisp = nMachInDisp + 1
-- si aggiungono le info di gruppo
local bFound = false
for t = 1, #GroupInfo do
if GroupInfo[t].nGroup == nGroup then
if GroupInfo[t].ptMin[1] > ptMinX[1] then GroupInfo[t].ptMin = ptMinX end
if GroupInfo[t].ptMax[1] < ptMaxX[1] then GroupInfo[t].ptMax = ptMaxX end
bFound = true
end
end
-- se non ho trovato, si aggiunge in lista
if not bFound then
table.insert( GroupInfo, { nGroup = nGroup, nStage = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage, ptMin = ptMinX, ptMax = ptMaxX})
end
nMachInDisp = nMachInDisp + 1
end
end
i = i + 1
end
+189 -121
View File
@@ -34,12 +34,12 @@ local function GetMachineAxes()
end
-------------------------------------------------------------------------------------------------------------
local function LogOutstroke( ptOnToolTipCenter, vtHead, OptionalParameters)
local function LogOutstroke( sToolName, ptOnToolTipCenter, vtHead, OptionalParameters)
-- parametri opzionali
OptionalParameters = OptionalParameters or {}
local LinearAxes = OptionalParameters.LinearAxes
local RotativeAxes = OptionalParameters.RotativeAxes
local LinearAxesValues = OptionalParameters.LinearAxesValues
local RotativeAxesValues = OptionalParameters.RotativeAxesValues
-- gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup()
@@ -50,15 +50,18 @@ local function LogOutstroke( ptOnToolTipCenter, vtHead, OptionalParameters)
EgtSetColor( idPoint, RED())
EgtSetColor( idVector, RED())
-- nome utensile
EgtOutLog( 'Tool ' .. sToolName)
-- si loggano valori di punto e vettore
EgtOutLog( ' Presimulation : OutStroke, Tip Point = ' .. tostring( ptOnToolTipCenter) .. ', id = ' .. idPoint .. ', vtHead = ' .. tostring( vtHead) .. ', id = ' .. idVector)
-- se disponibili, si loggano anche i valori calcolati degli assi
if LinearAxes then
EgtOutLog( ' ' .. LinearAxes[1].sName .. ' = ' .. tostring( LinearAxes[1].dValue) .. ', ' .. LinearAxes[2].sName .. ' = ' .. tostring( LinearAxes[2].dValue) .. ', ' .. LinearAxes[3].sName .. ' = ' .. tostring( LinearAxes[3].dValue))
if LinearAxesValues then
EgtOutLog( ' ' .. 'Lin1' .. ' = ' .. tostring( LinearAxesValues[1]) .. ', ' .. 'Lin2' .. ' = ' .. tostring( LinearAxesValues[2]) .. ', ' .. 'Lin3' .. ' = ' .. tostring( LinearAxesValues[3]))
end
if RotativeAxes then
EgtOutLog( ' ' .. RotativeAxes[1].sName .. ' = ' .. tostring( RotativeAxes[1].dValue) .. ', ' .. RotativeAxes[2].sName .. ' = ' .. tostring( RotativeAxes[2].dValue))
if RotativeAxesValues then
EgtOutLog( ' ' .. 'Rot1' .. ' = ' .. tostring( RotativeAxesValues[1]) .. ', ' .. 'Rot2' .. ' = ' .. tostring( RotativeAxesValues[2]) .. ', ' .. 'Rot3' .. ' = ' .. tostring( RotativeAxesValues[3]))
end
return
@@ -110,7 +113,7 @@ local function GetToolExitPoint( ptMachining, vtNEdge, vtHead, Tool, bIsDownUp)
end
-------------------------------------------------------------------------------------------------------------
-- calcolo pivot in riferimento globale, datipunto sull'uscita utensile e direzioni
-- calcolo pivot in riferimento globale, dati punto sull'uscita utensile e direzioni
local function GetGlobalPivot( ptToolExit, vtC, vtHead, vtMovePivot)
-- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito)
@@ -150,27 +153,28 @@ local function GetCollisionPointsToCheck( Edge, dDepthToMachine)
end
-------------------------------------------------------------------------------------------------------------
local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool)
local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
-- impostazione utensile
EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
local bOkTool = EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
if not bOkTool then
error( 'CheckOutOfStrokePoint : cannot set calc tool')
end
-- settaggio SCC per discriminare soluzioni multiple
EgtSetCalcSolCh( nSCC)
-- assi macchina da calcolare
local LinearAxes, RotativeAxes = GetMachineAxes()
-- se più di 3 assi lineari e 2 assi rotativi, macchina non supportata
if #LinearAxes > 3 or #RotativeAxes > 2 then
error(' CheckOutOfStrokePoint : too many axes')
-- se presente, settaggio asse bloccato
if sBlockedAxis and type( sBlockedAxis) == "string" then
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
end
-- calcolo assi rotativi
local bOkAngles, nSolutionsAngles, dRot1, dRot2 = EgtGetCalcAngles( vtHead)
RotativeAxes[1].dValue = dRot1
RotativeAxes[2].dValue = dRot2
local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
local dRotative1 = RotativeAxesValues[1]
local dRotative2 = RotativeAxesValues[2]
local dRotative3 = RotativeAxesValues[3]
if not bOkAngles then
error( ' CheckOutOfStrokePoint : error')
@@ -180,61 +184,42 @@ local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool)
if nSolutionsAngles == 0 then
if EgtGetDebugLevel() >= 3 then
LogOutstroke( ptOnToolTipCenter, vtHead)
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
end
return true
end
-- calcolo assi lineari
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, RotativeAxes[1].dValue, RotativeAxes[2].dValue)
LinearAxes[1].dValue = dLinear1
LinearAxes[2].dValue = dLinear2
LinearAxes[3].dValue = dLinear3
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
if not bOkPositions then
error( ' CheckOutOfStrokePoint : error')
end
-- verifica finecorsa per tutti gli assi
-- siccome non si sa a priori il numero di assi lineari e rotativi, si aggiungono tutti a Args in ordine
-- Args viene poi esplosa in modo da passare a EgtVerifyOutstroke i valori separati
local Args = {}
for i = 1, #LinearAxes do
Args[#Args+1] = LinearAxes[i].dValue
end
for i = 1, #RotativeAxes do
Args[#Args+1] = RotativeAxes[i].dValue
end
local bAllAxesInStroke = EgtVerifyOutstroke( table.unpack( Args))
-- verifica finecorsa per assi lineari (assi rotativi già verificati)
local bAllAxesInStroke = EgtVerifyOutstroke( dLinear1, dLinear2, dLinear3)
-- extracorsa
if not bAllAxesInStroke then
if EgtGetDebugLevel() >= 3 then
LogOutstroke( ptOnToolTipCenter, vtHead, { LinearAxes = LinearAxes, RotativeAxes = RotativeAxes})
LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { LinearAxesValues = { dLinear1, dLinear2, dLinear3}, RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
end
return true
end
-- EgtSetAxisPos( 'T', dT)
-- EgtSetAxisPos( 'Y', dY)
-- EgtSetAxisPos( 'Z', dZ)
-- EgtSetAxisPos( 'C', dC1)
-- EgtSetAxisPos( 'A', dA1)
-- se si arriva qui, il punto non è in finecorsa
return false
end
-------------------------------------------------------------------------------------------------------------
-- check extracorsa da punti sul tip dell'utensile
function PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
function PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
for i = 1, #PointsOnToolTipCenter do
local bOutOfStroke = CheckOutOfStrokePoint( PointsOnToolTipCenter[i], vtHead, nSCC, Tool)
local bOutOfStroke = CheckOutOfStrokePoint( PointsOnToolTipCenter[i], vtHead, nSCC, Tool, vtAux, sBlockedAxis)
-- se trovato extracorsa inutile procedere con gli altri punti
if bOutOfStroke then
@@ -249,7 +234,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- check extracorsa da geometria
-- TODO da considerare anche gli attacchi
function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC, Tool)
function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
local b3GeomMaxOffset = EgtGetBBoxGlob( idGeometry, GDB_BB.STANDARD)
local ptBoxCenter = b3GeomMaxOffset:getCenter()
@@ -272,74 +257,127 @@ function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC
-- Z-
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimZ / 2 * Z_AX()))
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
return bOutOfStroke
end
-------------------------------------------------------------------------------------------------------------
local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollisionData, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
local function MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
local ptPivot = GetGlobalPivot( ptToolExitToCheck, vtC, vtHead, PreCollisionData.vtMovePivot)
-- calcolo assi rotativi
local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
local dRotative1 = RotativeAxesValues[1]
local dRotative2 = RotativeAxesValues[2]
local dRotative3 = RotativeAxesValues[3]
-- orientamento del riferimento locale
local vtDirectionX = PreCollisionData.Directions.vtDirectionX
local vtDirectionY = PreCollisionData.Directions.vtDirectionY
local vtDirectionZ = PreCollisionData.Directions.vtDirectionZ
if not bOkAngles then
error( ' MoveMachineAxesToPosition : error')
end
-- costruzione trimesh a partire dalla curva di collisione
-- recupero punti da macchina per costruire trimesh
local CollisionCurvePoints = PreCollisionData.Points
-- curva di collisione in riferimento locale
local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints)
-- curva in riferimento globale
local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX)
EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB)
-- trimesh di collisione
local idCollisionSurfTm
if PreCollisionData.bSurfTmByRevolve then
idCollisionSurfTm = EgtSurfTmByRevolve( Part.idTempGroup, idCollisionCurve, ptPivot, vtDirectionY, true, 0.05, GDB_RT.GLOB)
else
local vtPreMove = -vtDirectionZ * ( PreCollisionData.dExtrusionDepth / 2)
EgtMove( idCollisionCurve, vtPreMove, GDB_RT.GLOB)
local vtExtrusion = vtDirectionZ * PreCollisionData.dExtrusionDepth
idCollisionSurfTm = EgtSurfTmByRegionExtrusion( Part.idTempGroup, idCollisionCurve, vtExtrusion, 0.05, GDB_RT.GLOB)
-- calcolo assi lineari
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
if not bOkPositions then
error( ' MoveMachineAxesToPosition : error')
end
local AxesNames = EgtGetAllCurrAxesNames()
local dTHome = EgtGetAxisHomePos( AxesNames[1])
-- spostamento assi in posizione (la T non si sposta perchè si sposta direttamente la testa)
EgtSetAxisPos( AxesNames[2], dLinear2)
EgtSetAxisPos( AxesNames[3], dLinear3)
EgtSetAxisPos( AxesNames[4], dRotative1)
EgtSetAxisPos( AxesNames[5], dRotative2)
if dRotative3 then
EgtSetAxisPos( AxesNames[6], dRotative3)
end
return dLinear1 - dTHome
end
-------------------------------------------------------------------------------------------------------------
local function CheckCollisionPoint( sAxis, ptOnToolTipCenter, vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, idCheckCollisionTm, idAddedCollisionSurfTm)
-- spostamento assi macchina in posizione
local dDeltaXHeadOffset = MoveMachineAxesToPosition( ptOnToolTipCenter, vtHead, vtAux)
-- si recuperano gli id delle geometrie dell'asse con cui controllare la collisione
local idCollisionGroup = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'COLLISION')
local idCollisionGroupOther = EgtGetFirstNameInGroup( EgtGetAxisId( sAxis), 'OTHER_COLLISION') or GDB_ID.NULL
local CollisionGroupEntitiesId = EgtGetAllInGroup( idCollisionGroup)
local CollisionGroupOtherEntitiesId = EgtGetAllInGroup( idCollisionGroupOther)
-- si tengono solo gli elementi trimesh
local CollisionSurfTmId = {}
for i = 1, #CollisionGroupEntitiesId do
if EgtGetType( CollisionGroupEntitiesId[i]) == GDB_TY.SRF_MESH then
local idCollisionSurfTmCopy = EgtCopyGlob( CollisionGroupEntitiesId[i], Part.idTempGroup)
EgtMove( idCollisionSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
table.insert( CollisionSurfTmId, idCollisionSurfTmCopy)
end
end
-- se presenti geometrie nel gruppo other si aggiungono anche quelle
if CollisionGroupOtherEntitiesId and #CollisionGroupOtherEntitiesId > 0 then
for i = 1, #CollisionGroupOtherEntitiesId do
if EgtGetType( CollisionGroupOtherEntitiesId[i]) == GDB_TY.SRF_MESH then
local idCollisionOtherSurfTmCopy = EgtCopyGlob( CollisionGroupOtherEntitiesId[i], Part.idTempGroup)
EgtMove( idCollisionOtherSurfTmCopy, Vector3d( dDeltaXHeadOffset, 0, 0), GDB_RT.GLOB)
table.insert( CollisionSurfTmId, idCollisionOtherSurfTmCopy)
end
end
end
-- se presente si aggiunge la geometria opzionale (es: flangia lama)
if idAddedCollisionSurfTm then
table.insert( CollisionSurfTmId, idAddedCollisionSurfTm)
end
-- check collisione con pezzo
local bCollisionFoundPiece = false
if not bCheckOnlyRestlength then
local idCheckCollisionTm = Part.idBoxTm
if not idCheckCollisionTm then
idCheckCollisionTm = Part.idBoxTm
-- se testa o coda attaccate, si considerano nella superficie di collisione
if bCannotSplitRestLength then
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
end
bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, idCollisionSurfTm, BeamData.COLL_SIC)
end
for i = 1, #CollisionSurfTmId do
bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, CollisionSurfTmId[i], BeamData.COLL_SIC)
if not type( bCollisionFoundPiece) == "boolean" then
error( 'Presimulation fail')
end
if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then
EgtSetColor( idCollisionSurfTm, RED())
EgtSetColor( CollisionSurfTmId[i], RED())
end
if bCollisionFoundPiece then
break
end
end
-- se trovata collisione con pezzo è inutile procedere con il grezzo
if bCollisionFoundPiece then
return true
end
end
-- check collisione con grezzo restante, se con il pezzo non c'è collisione e non è un taglio di testa o coda
local bCollisionFoundRestLength = false
if not ( bCollisionFoundPiece or bCannotSplitRestLength) then
local idRestLengthSurfFr = GetRestlengthSurfTm( Part, sRestLengthSideForPreSimulation)
if idRestLengthSurfFr then
bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC)
if not type( bCollisionFoundRestLength) == "boolean" then
error( 'Presimulation fail')
end
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
EgtSetColor( idCollisionSurfTm, ORANGE())
for i = 1, #CollisionSurfTmId do
bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, CollisionSurfTmId[i], BeamData.COLL_SIC)
if not type( bCollisionFoundRestLength) == "boolean" then
error( 'Presimulation fail')
end
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
EgtSetColor( CollisionSurfTmId[i], ORANGE())
end
if bCollisionFoundRestLength then
break
end
end
end
end
@@ -361,46 +399,50 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
-- parametri opzionali
OptionalParameters = OptionalParameters or {}
local bCheckOnlyRestlength = OptionalParameters.bCheckOnlyRestlength or false
local idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
local vtAux = OptionalParameters.vtAux
-- se normale faccia non parallela a direzione testa c'è qualcosa che non va
if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then
error( 'CheckCollisionWithAxis : invalid directions')
end
-- punti notevoli della lavorazione in cui fare il check
local PointsToCheck = OptionalParameters.PointsToCheck or GetCollisionPointsToCheck( Edge, dDepthToMachine)
-- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto
local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead)
local ToolExitPoints = {}
-- punti sul tip dell'utensile, in centro
local PointsOnToolTipCenter = {}
for i = 1, #PointsToCheck do
ToolExitPoints[i] = GetToolExitPoint( PointsToCheck[i], Edge.vtN, vtHead, Tool, bIsDownUp)
PointsOnToolTipCenter[i] = PreSimulationLib.GetPointOnToolTipCenter( PointsToCheck[i], vtHead, vtNFace, Edge.vtN, Tool)
end
-- vtC punta sempre verso il corpo dell'asse C o verso l'aggregato
local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.vtEdge, vtNFace)
local vtSCC = BeamLib.GetDirectionFromSCC( nSCC)
local vtC = vtHead ^ Tool.SetupInfo.vtRotationAxisC
vtC:normalize()
if vtC:isZero() then
vtC = vtSCC
elseif vtC * vtSCC < GEO.EPS_SMALL then
vtC = -vtC
end
-- punti curva collisione e direzioni check da macchina
local PreCollisionData = Tool.SetupInfo.GetPreCollisionData( sAxis, vtC, vtHead)
local bMoveAfterSplit = false
-- se almeno in un punto c'è collisione con il pezzo si ritorna collisione
-- se non si trova collisione si ritorna se è necessario separare prima di effettuare la lavorazione (ossia non c'è collisione con il pezzo ma c'è con il grezzo restante)
for i = 1, #ToolExitPoints do
for i = 1, #PointsOnToolTipCenter do
local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( ToolExitPoints[i], vtC, vtHead, PreCollisionData, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
-- se lama con flangia si aggiunge quest'ultima ai solidi di collisione, ipotizzandola grande fino al dMaxDepth + sicurezza
local idAddedCollisionSurfTm
if Tool.sType == 'SAW_FLAT' then
local ptCenterFlange = PointsOnToolTipCenter[i] + vtHead * Tool.dThickness
local frHead = Frame3d( ptCenterFlange, vtHead)
local dExtraSafety = 2 -- valore empirico che serve nei casi molto inclinati, ci potrebbero essere casi in cui va aumentato
local idFlangeCurve = EgtCircle( Part.idTempGroup, ORIG(), dExtraSafety + Tool.dDiameter / 2 - Tool.dMaxDepth, GDB_RT.GLOB)
EgtTransform( idFlangeCurve, frHead, GDB_RT.GLOB)
-- TODO verificare se questo controllo serve
if AreOppositeVectorApprox( vtHead, EgtCurveExtrusion( idFlangeCurve)) then
EgtInvertCurve( idFlangeCurve)
end
local vtExtrusion = 15 * vtHead
idAddedCollisionSurfTm = EgtSurfTmByRegionExtrusion( Part.idTempGroup, idFlangeCurve, vtExtrusion, 0.05, GDB_RT.GLOB)
end
local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( sAxis, PointsOnToolTipCenter[i], vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, idCheckCollisionTm, idAddedCollisionSurfTm)
-- se trovata collisione con pezzo è inutile controllare gli altri punti
if bCollisionFoundPiece then
@@ -419,29 +461,33 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
end
-------------------------------------------------------------------------------------------------------------
function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, OptionalParameters)
function PreSimulationLib.CheckCollision( Parameters, OptionalParameters)
local bCollisionFound
local bMoveAfterSplitZ, bMoveAfterSplitC, bMoveAfterSplitAB
local bMoveAfterSplitL3, bMoveAfterSplitR3, bMoveAfterSplitR2, bMoveAfterSplitR1
-- parametri obbligatori
local Edge = Parameters.Edge
local vtNFace = Parameters.vtNFace
local Tool = Parameters.Tool
-- parametri opzionali, in parte da far transitare
OptionalParameters = OptionalParameters or {}
local OptionalParametersCheckCollisionWithAxis = {}
OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = false
OptionalParametersCheckCollisionWithAxis.PointsToCheck = OptionalParameters.PointsToCheck or nil
OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
OptionalParametersCheckCollisionWithAxis.sBlockedAxis = OptionalParameters.sBlockedAxis
OptionalParametersCheckCollisionWithAxis.vtAux = OptionalParameters.vtAux
OptionalParametersCheckCollisionWithAxis.idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
local bIsDicing = OptionalParameters.bIsDicing or false
local bCheckOnlyRestlengthForAxisABC = false
local sBlockedAxis = OptionalParameters.sBlockedAxis
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
-- se cubetti in modalità standard (no DownUp) gli assi AB e C si controllano solo con grezzo (ci sarebbe collisione con il materiale già rimosso controllando AB e C con pezzo)
if bIsDicing and ( sBladeEngagement == 'Standard') then
bCheckOnlyRestlengthForAxisABC = true
-- se l'elevazione reale (rispetto al pezzo + eventuale materiale in testa/coda) è maggiore del massimo materiale è sempre collisione
-- TODO rifare con funzione
else
if not bDisableRealElevationCheck then
local Edge = Parameters.Edge
local vtNFace = Parameters.vtNFace
local dDepthToMachine = Parameters.dDepthToMachine
@@ -464,21 +510,43 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional
end
end
-- asse Z si controlla sempre
bCollisionFound, bMoveAfterSplitZ = CheckCollisionWithAxis( 'Z', Parameters, OptionalParametersCheckCollisionWithAxis)
-- SCC
local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.vtEdge, vtNFace)
-- assi AB e C: se richiesto si controlla la collisione solo col grezzo
OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = bCheckOnlyRestlengthForAxisABC
-- si settano utensile, SCC e asse bloccato per il controllo collisione
local bOkTool = EgtSetCalcTool( Tool.sName, Tool.sHead, Tool.nExit)
if not bOkTool then
error( 'CheckCollisionWithAxis : cannot set calc tool')
end
EgtSetCalcSolCh( nSCC)
if sBlockedAxis and type( sBlockedAxis) == "string" then
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
end
if not bCollisionFound then
bCollisionFound, bMoveAfterSplitAB = CheckCollisionWithAxis( 'AB', Parameters, OptionalParametersCheckCollisionWithAxis)
-- nomi degli assi con cui controllare la collisione
local AxesNames = EgtGetAllCurrAxesNames()
local sL3 = AxesNames[3]
local sR3 = AxesNames[6]
local sR2 = AxesNames[5]
local sR1 = AxesNames[4]
-- ultimo asse lineare prima dei rotativi (solitamente Z) si controlla sempre
bCollisionFound, bMoveAfterSplitL3 = CheckCollisionWithAxis( sL3, Parameters, OptionalParametersCheckCollisionWithAxis)
if sR3 and not bCollisionFound then
bCollisionFound, bMoveAfterSplitR3 = CheckCollisionWithAxis( sR3, Parameters, OptionalParametersCheckCollisionWithAxis)
end
if not bCollisionFound then
bCollisionFound, bMoveAfterSplitC = CheckCollisionWithAxis( 'C', Parameters, OptionalParametersCheckCollisionWithAxis)
bCollisionFound, bMoveAfterSplitR2 = CheckCollisionWithAxis( sR2, Parameters, OptionalParametersCheckCollisionWithAxis)
end
local bMoveAfterSplit = bMoveAfterSplitZ or bMoveAfterSplitC or bMoveAfterSplitAB
if not bCollisionFound then
bCollisionFound, bMoveAfterSplitR1 = CheckCollisionWithAxis( sR1, Parameters, OptionalParametersCheckCollisionWithAxis)
end
local bMoveAfterSplit = bMoveAfterSplitL3 or bMoveAfterSplitR3 or bMoveAfterSplitR2 or bMoveAfterSplitR1
return bCollisionFound, bMoveAfterSplit
end
+322
View File
@@ -0,0 +1,322 @@
// Message File EgalTech English 2026/06/23
0=ENG
// ----- BeamNew -----
1000001=Part loading position
1000002=Part loading position
1000003=Loading position from BTL, no pre-rotation
1000004=Loading position from BTL, no pre-rotation
1000005=Get Best loading position from 0° and 180°
1000006=Get Best loading position from 0° and 180°
1000007=Get Best loading position in each piece rotation
1000008=Get Best loading position in each piece rotation
1000009=Allow piece inversion
1000010=Allow piece inversion
1000011=Enable material optimization function in nesting (part rotation disabled)
1000012=Enable material optimization function in nesting (part rotation disabled)
1000013=Part rotating acceptability
1000014=Acceptability of rotating the part between machining steps
1000015=Rotation not allowed
1000016=Rotation not allowed
1000017=Rotation allowed only if strictly necessary
1000018=Rotation allowed only if strictly necessary
1000019=Rotation easily acceptable / no constraint
1000020=Rotation easily acceptable / no constraint
1000021=Machining Strategy
1000022=Machining Strategy
1000023=Quality and time equally prioritized
1000024=Quality and time equally prioritized
1000025=Fastest
1000026=Prefer fastest strategies
1000027=High quality
1000028=Prefer high-quality strategies
1000029=Ordering rules
1000030=The first complete strategy in list is the one chosen; no intelligent choosing
1000031=Max number of reprocessing cycles
1000032=Max number of reprocessing cycles
1000033=Use entire blade diameter to shorten path
1000034=Use entire blade diameter to shorten path
1000035=Maximum length for dropped waste
1000036=Maximum length for dropped waste
1000037=Maximum volume for dropped waste
1000038=Maximum volume for dropped waste
1000039=Maximum dice dimension
1000040=Maximum dice dimension
1000041=Overmaterial on tenon length
1000042=Overmaterial on tenon length
1000043=Overmaterial on tenon width
1000044=Overmaterial on tenon width
1000045=Maximum number of milling passes
1000046=Maximum number of milling passes. If more passes are required, pocketing is performed
1000047=Use DoveTail tool to pocket
1000048=Use DoveTail tool to pocket
1000049=Cutting Strategy
1000050=Cutting Strategy
1000051=Automatic
1000052=Automatic
1000053=Blade only
1000054=Blade only
1000055=Mill only
1000056=Mill only
1000057=ChainSaw only
1000058=ChainSaw only
1000059=Available mill to machine the tenon cut surface
1000060=Available mill to machine the tenon cut surface
1000061=Available mill to machine the dovetail tenon
1000062=Available mill to machine the dovetail tenon
1000063=Max radius left on corners
1000064=Radius-limit left by the tool at each corner of the feature
1000065=Use Anti-Splint strategy
1000066=The strategy will apply blade cuts on corner to avoid wood splint
1000067=Extend after tail
1000068=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
1000069=Minimum approach distance on open sides
1000070=Minimum approach distance on open sides
1000071=Available mill to pocket the feature
1000072=Available mill to pocket the feature
1000073=Finish with chainsaw if needed
1000074=Finish with chainsaw if needed
1000075=Extend after tail
1000076=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
1000077=Force ripping blade
1000078=Force the use of ripping blade, designed for cuts parallel to the grain
1000079=Not complete with Blade radius imprint left
1000080=If the parameter is active, the automatism considers the feature as - not complete - if the blade radius imprint is left
1000081=Use Zig-Zag ChainSaw
1000082=Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.
1000083=Sort by segment
1000084=Sort the machinings according to the piece-segment where the machining has inserted
1000085=Damage next piece
1000086=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
1000087=Never damage
1000088=Never damage
1000089=Damage only if raw
1000090=Damage only if raw
1000091=Can damage
1000092=Can damage
1000093=Use Zig-Zag ChainSaw
1000094=Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.
1000095=Extend after tail
1000096=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
1000097=Damage next piece
1000098=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
1000099=Never damage
1000100=Never damage
1000101=Damage only if raw
1000102=Damage only if raw
1000103=Can damage
1000104=Can damage
1000105=Force ripping blade
1000106=Force the use of ripping blade, designed for cuts parallel to the grain
1000107=Extend after tail
1000108=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
1000109=Damage next piece
1000110=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
1000111=Never damage
1000112=Never damage
1000113=Damage only if raw
1000114=Damage only if raw
1000115=Can damage
1000116=Can damage
1000117=Cutting strategy
1000118=Cutting strategy
1000119=Automatic
1000120=Automatic
1000121=Drop waste
1000122=Drop waste
1000123=Keep waste attached
1000124=Keep waste attached
1000125=Disable dicing
1000126=Disable dicing
1000127=Prioritize machining speed over quality
1000128=Prioritize machining speed over quality
1000129=Strip width
1000130=In case the waste is still kept attached, this is the wigth dimension of the strip
1000131=Clean blade radius with mill
1000132=Clean blade radius with mill
1000133=Milling offset from side
1000134=Milling offset from side
1000135=Overmaterial on tenon length
1000136=Overmaterial on tenon length
1000137=Overmaterial on tenon width
1000138=Overmaterial on tenon width
1000139=Maximum number of milling passes
1000140=Maximum number of milling passes. If more passes are required, pocketing is performed
1000141=Cutting Strategy
1000142=Cutting Strategy
1000143=Automatic
1000144=Automatic
1000145=Blade only
1000146=Blade only
1000147=Mill only
1000148=Mill only
1000149=ChainSaw only
1000150=ChainSaw only
1000151=Available mill to machine the tenon
1000152=Available mill to machine the tenon
1000153=Overmaterial on Mortise length
1000154=Overmaterial on Mortise length
1000155=Overmaterial on Mortise width
1000156=Overmaterial on Mortise width
1000157=Maximum number of milling passes
1000158=Maximum number of milling passes. If more passes are required, pocketing is performed
1000159=Use DoveTail tool in case of pocketing
1000160=Use DoveTail tool in case of pocketing
1000161=Add Anti-Splint
1000162=Add Anti-Splint
1000163=Cutting Strategy
1000164=Cutting Strategy
1000165=Automatic
1000166=Automatic
1000167=Blade only
1000168=Blade only
1000169=Mill only
1000170=Mill only
1000171=ChainSaw only
1000172=ChainSaw only
1000173=Available mill to machine the mortise cut surface
1000174=Available mill to machine the mortise cut surface
1000175=Available mill to machine the dovetail mortise
1000176=Available mill to machine the dovetail mortise
1000177=Overmaterial on mortise length
1000178=Overmaterial on mortise length
1000179=Overmaterial on mortise width
1000180=Overmaterial on mortise width
1000181=Cutting Strategy
1000182=Cutting Strategy
1000183=Automatic
1000184=Automatic
1000185=Blade only
1000186=Blade only
1000187=Mill only
1000188=Mill only
1000189=ChainSaw only
1000190=ChainSaw only
1000191=Available mill to machine the mortise cut surface
1000192=Available mill to machine the mortise cut surface
1000193=Available mill to machine the mortise
1000194=Available mill to machine the mortise
1000195=Depth Chamfer
1000196=Depth of the V-Mill to execute chamfers on cut-edges
1000197=Use Anti-Splint strategy
1000198=The strategy will apply blade cuts on corner to avoid wood splint
1000199=Available mill to machine the profile
1000200=Available mill to machine the profile
1000201=Antisplint with blade
1000202=Use the blade as antisplint in case the geometry is not through
1000203=Extend after tail
1000204=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
1000205=Clean radius with mill
1000206=Clean radius with mill
1000207=Milling offset from side
1000208=Milling offset from side
1000209=Damage next piece
1000210=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
1000211=Never damage
1000212=Never damage
1000213=Damage only if raw
1000214=Damage only if raw
1000215=Can damage
1000216=Can damage
1000217=Tolerance on Diameter
1000218=Tolerance on Diameter
1000219=Depth PreHole
1000220=Depth PreHole
1000221=Drilling Mode
1000222=Drilling Mode
1000223=Automatic
1000224=Automatic
1000225=Preferred machining from one side only
1000226=Preferred machining from one side only
1000227=Force machining from two sides
1000228=Force machining from two sides
1000229=Available Drillbit list
1000230=Available Drillbit list
1000231=Extend after tail
1000232=The automatism considers this length as machinable. This means you accept to damage the next piece in the bar
1000233=Damage next piece
1000234=This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time
1000235=Never damage
1000236=Never damage
1000237=Damage only if raw
1000238=Damage only if raw
1000239=Can damage
1000240=Can damage
1000241=Ridge Lap strategy
1000242=Ridge Lap strategy
1000243=Automatic
1000244=Automatic
1000245=Use blade
1000246=Use blade
1000247=Use mill
1000248=Use mill
1000249=Tolerance on Diameter
1000250=Tolerance on Diameter
1000251=Use mill as a drillbit
1000252=Admit to use the mill as a drillbit
1000253=Execute contour only
1000254=Execute the contour anyway, even the hole is bigger than the tool diameter
1000255=Drilling mode
1000256=Drilling mode
1000257=Automatic
1000258=Automatic
1000259=Preferred machining from one side only
1000260=Preferred machining from one side only
1000261=Force machining from two sides
1000262=Force machining from two sides
1000263=Available mill to machine drills
1000264=Available mill to machine drills
1000265=Machining Depth
1000266=Machining Depth
1000267=Available mill to machine mark and text
1000268=Available mill to machine mark and text
1000269=Marking Strategy
1000270=Marking Strategy
1000271=Automatic
1000272=Automatic
1000273=Pen only
1000274=Pen only
1000275=V-Mill only
1000276=V-Mill only
1000277=Depth Chamfer
1000278=Depth of the V-Mill to execute chamfers on cut-edges
1000279=Only Chamfer
1000280=Execute the chamfer only, no other machining
1000281=Overmaterial
1000282=Overmaterial
1000283=Max radius left on corners
1000284=Radius-limit left by the tool at each corner of the feature
1000285=Execute cut to remove material
1000286=Execute cut to remove material
1000287=Force strip
1000288=Enable the parameter to force the software to leave a strip to sustain the piece
1000289=Strip width
1000290=Width of the strip in case if foreseen from the machining
1000291=Cutting Strategy
1000292=Cutting Strategy
1000293=Automatic
1000294=Automatic
1000295=No machining
1000296=No machining
1000297=Blade forced
1000298=Blade forced
1000299=Mill forced
1000300=Mill forced
1000301=Available mill to machine the profile
1000302=Available mill to machine the profile
1000303=Depth Chamfer
1000304=Depth of the V-Mill to execute chamfers on cut-edges
1000305=Force to use chain saw
1000306=Force to use chain saw
1000307=Force to add PreCuts
1000308=Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length
1000309=Finish with mill
1000310=Use a mill to finish the surface if split with chain saw
1000311=Depth Chamfer
1000312=Depth of the V-Mill to execute chamfers on cut-edges
1000313=Force to use chain saw
1000314=Force to use chain saw
1000315=Force to add PreCuts
1000316=Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length
1000317=Finish with mill
1000318=Use a mill to finish the surface if split with chain saw
// ----- End -----
+322
View File
@@ -0,0 +1,322 @@
// File dei messaggi EgalTech Italiano 2026/06/23
0=ITA
// ----- BeamNew -----
1000001=Posizione di caricamento pezzo
1000002=Posizione di caricamento pezzo
1000003=Posizione di caricamento da BTL, senza pre-rotazione
1000004=Posizione di caricamento da BTL, senza pre-rotazione
1000005=Ottieni la migliore posizione di caricamento tra 0° e 180°
1000006=Ottieni la migliore posizione di caricamento tra 0° e 180°
1000007=Ottieni la migliore posizione di caricamento per ogni rotazione del pezzo
1000008=Ottieni la migliore posizione di caricamento per ogni rotazione del pezzo
1000009=Consenti inversione pezzo
1000010=Consenti inversione pezzo
1000011=Abilita funzione di ottimizzazione materiale nel nesting (rotazione pezzo disabilitata)
1000012=Abilita funzione di ottimizzazione materiale nel nesting (rotazione pezzo disabilitata)
1000013=Accettabilità rotazione pezzo
1000014=Accettabilità della rotazione del pezzo tra le fasi di lavorazione
1000015=Rotazione non consentita
1000016=Rotazione non consentita
1000017=Rotazione consentita solo se strettamente necessaria
1000018=Rotazione consentita solo se strettamente necessaria
1000019=Rotazione facilmente accettabile / nessun vincolo
1000020=Rotazione facilmente accettabile / nessun vincolo
1000021=Strategia di lavorazione
1000022=Strategia di lavorazione
1000023=Qualità e tempo considerati con la stessa priorità
1000024=Qualità e tempo considerati con la stessa priorità
1000025=Più veloce
1000026=Preferisci le strategie più veloci
1000027=Alta qualità
1000028=Preferisci le strategie ad alta qualità
1000029=Regole di ordinamento
1000030=La prima strategia completa in lista è quella scelta; nessuna scelta intelligente
1000031=Numero massimo di cicli di rilavorazione
1000032=Numero massimo di cicli di rilavorazione
1000033=Usa l'intero diametro della lama per accorciare il percorso
1000034=Usa l'intero diametro della lama per accorciare il percorso
1000035=Massima lunghezza per lo scarto caduto
1000036=Massima lunghezza per lo scarto caduto
1000037=Massimo volume per lo scarto caduto
1000038=Massimo volume per lo scarto caduto
1000039=Dimensione massima dei cubetti
1000040=Dimensione massima dei cubetti
1000041=Sovramateriale sulla lunghezza del tenone
1000042=Sovramateriale sulla lunghezza del tenone
1000043=Sovramateriale sulla larghezza del tenone
1000044=Sovramateriale sulla larghezza del tenone
1000045=Numero massimo di passate di fresatura
1000046=Numero massimo di passate di fresatura. Se sono necessarie più passate, viene eseguita la svuotatura
1000047=Utilizza l'utensile a coda di rondine per svuotare
1000048=Utilizza l'utensile a coda di rondine per svuotare
1000049=Strategia di taglio
1000050=Strategia di taglio
1000051=Automatico
1000052=Automatico
1000053=Solo lama
1000054=Solo lama
1000055=Solo fresa
1000056=Solo fresa
1000057=Solo sega a catena
1000058=Solo sega a catena
1000059=Fresa disponibile per lavorare la superficie di taglio del tenone
1000060=Fresa disponibile per lavorare la superficie di taglio del tenone
1000061=Fresa disponibile per lavorare il tenone a coda di rondine
1000062=Fresa disponibile per lavorare il tenone a coda di rondine
1000063=Raggio massimo rimasto sugli spigoli
1000064=Limite del raggio lasciato dall'utensile ad ogni spigolo della feature
1000065=Utilizza la strategia antischeggia
1000066=La strategia applicherà tagli di lama sullo spigolo per evitare scheggiature del legno
1000067=Estendi dopo la coda
1000068=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
1000069=Distanza minima di approccio sui lati aperti
1000070=Distanza minima di approccio sui lati aperti
1000071=Fresa disponibile per svuotare la feature
1000072=Fresa disponibile per svuotare la feature
1000073=Finisci con sega a catena se necessario
1000074=Finisci con sega a catena se necessario
1000075=Estendi dopo la coda
1000076=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
1000077=Forza lama da scasso
1000078=Forza l'uso della lama da scasso, progettata per tagli paralleli alla venatura
1000079=Non completare se rimane l'impronta del raggio della lama
1000080=Se il parametro è attivo, l'automatismo considera la feature come - non completa - se rimane l'impronta del raggio della lama
1000081=Utilizza sega a catena in Zig-Zag
1000082=Abilita il parametro per impostare il movimento Zig-Zag sulla lavorazione della sega a catena. Disattivarlo per utilizzare il movimento One-Way.
1000083=Ordina per segmento
1000084=Ordina le lavorazioni in base al segmento del pezzo in cui la lavorazione è inserita
1000085=Danneggia il pezzo successivo
1000086=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
1000087=Non danneggiare mai
1000088=Non danneggiare mai
1000089=Danneggia solo se grezzo
1000090=Danneggia solo se grezzo
1000091=Può danneggiare
1000092=Può danneggiare
1000093=Utilizza sega a catena in Zig-Zag
1000094=Abilita il parametro per impostare il movimento Zig-Zag sulla lavorazione della sega a catena. Disattivarlo per utilizzare il movimento One-Way.
1000095=Estendi dopo la coda
1000096=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
1000097=Danneggia il pezzo successivo
1000098=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
1000099=Non danneggiare mai
1000100=Non danneggiare mai
1000101=Danneggia solo se grezzo
1000102=Danneggia solo se grezzo
1000103=Può danneggiare
1000104=Può danneggiare
1000105=Forza lama da scasso
1000106=Forza l'uso della lama da scasso, progettata per tagli paralleli alla venatura
1000107=Estendi dopo la coda
1000108=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
1000109=Danneggia il pezzo successivo
1000110=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
1000111=Non danneggiare mai
1000112=Non danneggiare mai
1000113=Danneggia solo se grezzo
1000114=Danneggia solo se grezzo
1000115=Può danneggiare
1000116=Può danneggiare
1000117=Strategia di taglio
1000118=Strategia di taglio
1000119=Automatico
1000120=Automatico
1000121=Scarica lo scarto
1000122=Scarica lo scarto
1000123=Mantieni lo scarto attaccato
1000124=Mantieni lo scarto attaccato
1000125=Disabilita la tassellatura
1000126=Disabilita la tassellatura
1000127=Dai priorità alla velocità di lavorazione rispetto alla qualità
1000128=Dai priorità alla velocità di lavorazione rispetto alla qualità
1000129=Larghezza del testimone
1000130=Nel caso in cui lo scarto venga mantenuto attaccato, questa è la dimensione della larghezza del testimone
1000131=Pulisci il raggio della lama con la fresa
1000132=Pulisci il raggio della lama con la fresa
1000133=Offset di fresatura dal lato
1000134=Offset di fresatura dal lato
1000135=Sovramateriale sulla lunghezza del tenone
1000136=Sovramateriale sulla lunghezza del tenone
1000137=Sovramateriale sulla larghezza del tenone
1000138=Sovramateriale sulla larghezza del tenone
1000139=Numero massimo di passate di fresatura
1000140=Numero massimo di passate di fresatura. Se sono necessarie più passate, viene eseguita la svuotatura
1000141=Strategia di taglio
1000142=Strategia di taglio
1000143=Automatico
1000144=Automatico
1000145=Solo lama
1000146=Solo lama
1000147=Solo fresa
1000148=Solo fresa
1000149=Solo sega a catena
1000150=Solo sega a catena
1000151=Fresa disponibile per lavorare il tenone
1000152=Fresa disponibile per lavorare il tenone
1000153=Sovramateriale sulla lunghezza della mortasa
1000154=Sovramateriale sulla lunghezza della mortasa
1000155=Sovramateriale sulla larghezza della mortasa
1000156=Sovramateriale sulla larghezza della mortasa
1000157=Numero massimo di passate di fresatura
1000158=Numero massimo di passate di fresatura. Se sono necessarie più passate, viene eseguita la svuotatura
1000159=Utilizza l'utensile a coda di rondine in caso di svuotatura
1000160=Utilizza l'utensile a coda di rondine in caso di svuotatura
1000161=Aggiungi antischeggia
1000162=Aggiungi antischeggia
1000163=Strategia di taglio
1000164=Strategia di taglio
1000165=Automatico
1000166=Automatico
1000167=Solo lama
1000168=Solo lama
1000169=Solo fresa
1000170=Solo fresa
1000171=Solo sega a catena
1000172=Solo sega a catena
1000173=Fresa disponibile per lavorare la superficie di taglio della mortasa
1000174=Fresa disponibile per lavorare la superficie di taglio della mortasa
1000175=Fresa disponibile per lavorare la mortasa a coda di rondine
1000176=Fresa disponibile per lavorare la mortasa a coda di rondine
1000177=Sovramateriale sulla lunghezza della mortasa
1000178=Sovramateriale sulla lunghezza della mortasa
1000179=Sovramateriale sulla larghezza della mortasa
1000180=Sovramateriale sulla larghezza della mortasa
1000181=Strategia di taglio
1000182=Strategia di taglio
1000183=Automatico
1000184=Automatico
1000185=Solo lama
1000186=Solo lama
1000187=Solo fresa
1000188=Solo fresa
1000189=Solo sega a catena
1000190=Solo sega a catena
1000191=Fresa disponibile per lavorare la superficie di taglio della mortasa
1000192=Fresa disponibile per lavorare la superficie di taglio della mortasa
1000193=Fresa disponibile per lavorare la mortasa
1000194=Fresa disponibile per lavorare la mortasa
1000195=Profondità dello smusso
1000196=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
1000197=Utilizza la strategia antischeggia
1000198=La strategia applicherà tagli di lama sullo spigolo per evitare scheggiature del legno
1000199=Fresa disponibile per lavorare il profilo
1000200=Fresa disponibile per lavorare il profilo
1000201=Antischeggia con lama
1000202=Utilizza la lama come antischeggia nel caso in cui la geometria non sia passante
1000203=Estendi dopo la coda
1000204=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
1000205=Pulisci il raggio con la fresa
1000206=Pulisci il raggio con la fresa
1000207=Offset di fresatura dal lato
1000208=Offset di fresatura dal lato
1000209=Danneggia il pezzo successivo
1000210=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
1000211=Non danneggiare mai
1000212=Non danneggiare mai
1000213=Danneggia solo se grezzo
1000214=Danneggia solo se grezzo
1000215=Può danneggiare
1000216=Può danneggiare
1000217=Tolleranza sul diametro
1000218=Tolleranza sul diametro
1000219=Profondità del preforo
1000220=Profondità del preforo
1000221=Modalità di foratura
1000222=Modalità di foratura
1000223=Automatico
1000224=Automatico
1000225=Lavorazione preferita da un solo lato
1000226=Lavorazione preferita da un solo lato
1000227=Forza la lavorazione da due lati
1000228=Forza la lavorazione da due lati
1000229=Lista delle punte disponibili
1000230=Lista delle punte disponibili
1000231=Estendi dopo la coda
1000232=L'automatismo considera questa lunghezza come lavorabile. Questo significa che si accetta di danneggiare il pezzo successivo nella barra
1000233=Danneggia il pezzo successivo
1000234=Questa opzione consente di decidere come considerare il pezzo successivo nella barra. Il software calcola specifici ingressi/uscite per rispettare il parametro. Questo parametro può variare il tempo di lavorazione
1000235=Non danneggiare mai
1000236=Non danneggiare mai
1000237=Danneggia solo se grezzo
1000238=Danneggia solo se grezzo
1000239=Può danneggiare
1000240=Può danneggiare
1000241=Strategia del mezzolegno di colmo
1000242=Strategia del mezzolegno di colmo
1000243=Automatico
1000244=Automatico
1000245=Utilizza la lama
1000246=Utilizza la lama
1000247=Utilizza la fresa
1000248=Utilizza la fresa
1000249=Tolleranza sul diametro
1000250=Tolleranza sul diametro
1000251=Utilizza la fresa come una punta
1000252=Ammetti l'uso della fresa come una punta da foratura
1000253=Esegui solo il contorno
1000254=Esegui comunque il contorno, anche se il foro è più grande del diametro dell'utensile
1000255=Modalità di foratura
1000256=Modalità di foratura
1000257=Automatico
1000258=Automatico
1000259=Lavorazione preferita da un solo lato
1000260=Lavorazione preferita da un solo lato
1000261=Forza la lavorazione da due lati
1000262=Forza la lavorazione da due lati
1000263=Fresa disponibile per lavorare i fori
1000264=Fresa disponibile per lavorare i fori
1000265=Profondità di lavorazione
1000266=Profondità di lavorazione
1000267=Fresa disponibile per lavorare marcature e testi
1000268=Fresa disponibile per lavorare marcature e testi
1000269=Strategia di marcatura
1000270=Strategia di marcatura
1000271=Automatico
1000272=Automatico
1000273=Solo penna
1000274=Solo penna
1000275=Solo fresa a V
1000276=Solo fresa a V
1000277=Profondità dello smusso
1000278=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
1000279=Solo smusso
1000280=Esegui solo lo smusso, nessuna altra lavorazione
1000281=Sovramateriale
1000282=Sovramateriale
1000283=Raggio massimo rimasto sugli spigoli
1000284=Limite del raggio lasciato dall'utensile ad ogni spigolo della feature
1000285=Esegui il taglio per rimuovere materiale
1000286=Esegui il taglio per rimuovere materiale
1000287=Forza il testimone
1000288=Abilita il parametro per forzare il software a lasciare un testimone per sostenere il pezzo
1000289=Larghezza del testimone
1000290=Larghezza del testimone nel caso in cui sia previsto dalla lavorazione
1000291=Strategia di taglio
1000292=Strategia di taglio
1000293=Automatico
1000294=Automatico
1000295=Nessuna lavorazione
1000296=Nessuna lavorazione
1000297=Forza lama
1000298=Forza lama
1000299=Forza fresa
1000300=Forza fresa
1000301=Fresa disponibile per lavorare il profilo
1000302=Fresa disponibile per lavorare il profilo
1000303=Profondità dello smusso
1000304=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
1000305=Forza l'uso della sega a catena
1000306=Forza l'uso della sega a catena
1000307=Forza l'aggiunta di pretagli
1000308=Autocam applicherà una lavorazione sullo zero teorico per evitare collisioni se la lunghezza teorica del pezzo non corrisponde alla lunghezza reale
1000309=Finisci con la fresa
1000310=Utilizza una fresa per rifinire la superficie se tagliata con la sega a catena
1000311=Profondità dello smusso
1000312=Profondità della fresa a V per eseguire smussi sugli spigoli di taglio
1000313=Forza l'uso della sega a catena
1000314=Forza l'uso della sega a catena
1000315=Forza l'aggiunta di pretagli
1000316=Autocam applicherà una lavorazione sullo zero teorico per evitare collisioni se la lunghezza teorica del pezzo non corrisponde alla lunghezza reale
1000317=Finisci con la fresa
1000318=Utilizza una fresa per rifinire la superficie se tagliata con la sega a catena
// ----- End -----
+322
View File
@@ -0,0 +1,322 @@
// Message File EgalTech Dutch 2026/06/23
0=NLD
// ----- BeamNew -----
1000001=Ladevolgorde van het onderdeel
1000002=Ladevolgorde van het onderdeel
1000003=Laadpositie vanaf BTL, geen voorrotatie
1000004=Laadpositie vanaf BTL, geen voorrotatie
1000005=Bepaal de beste laadpositie uit 0° en 180°
1000006=Bepaal de beste laadpositie uit 0° en 180°
1000007=Bepaal de beste laadpositie bij elke rotatie van het onderdeel
1000008=Bepaal de beste laadpositie bij elke rotatie van het onderdeel
1000009=Omkeren van het onderdeel toestaan
1000010=Omkeren van het onderdeel toestaan
1000011=Materiaaloptimalisatie in nesting inschakelen (rotatie van onderdeel uitgeschakeld)
1000012=Materiaaloptimalisatie in nesting inschakelen (rotatie van onderdeel uitgeschakeld)
1000013=Acceptatie van rotatie van het onderdeel
1000014=Acceptatie van het roteren van het onderdeel tussen bewerkingsstappen
1000015=Rotatie niet toegestaan
1000016=Rotatie niet toegestaan
1000017=Rotatie alleen toegestaan indien strikt noodzakelijk
1000018=Rotatie alleen toegestaan indien strikt noodzakelijk
1000019=Rotatie eenvoudig acceptabel / geen beperking
1000020=Rotatie eenvoudig acceptabel / geen beperking
1000021=Bewerkingsstrategie
1000022=Bewerkingsstrategie
1000023=Kwaliteit en tijd hebben gelijke prioriteit
1000024=Kwaliteit en tijd hebben gelijke prioriteit
1000025=Snelste
1000026=Voorkeur geven aan de snelste strategieën
1000027=Hoge kwaliteit
1000028=Voorkeur geven aan hoogwaardige strategieën
1000029=Ordeningsregels
1000030=De eerste complete strategie in de lijst wordt gekozen; geen intelligente selectie
1000031=Max. aantal herbewerkingscycli
1000032=Max. aantal herbewerkingscycli
1000033=Gebruik de volledige bladdiameter om het pad te verkorten
1000034=Gebruik de volledige bladdiameter om het pad te verkorten
1000035=Maximale lengte voor vallend afval
1000036=Maximale lengte voor vallend afval
1000037=Maximaal volume voor vallend afval
1000038=Maximaal volume voor vallend afval
1000039=Maximale afmeting van de blokjes
1000040=Maximale afmeting van de blokjes
1000041=Overmaat op de penlengte
1000042=Overmaat op de penlengte
1000043=Overmaat op de penbreedte
1000044=Overmaat op de penbreedte
1000045=Maximaal aantal freesgangen
1000046=Maximaal aantal freesgangen. Als er meer gangen vereist zijn, wordt er uitkameren/uitfrezen uitgevoerd
1000047=Zwaluwstaartgereedschap gebruiken voor uitfrezen
1000048=Zwaluwstaartgereedschap gebruiken voor uitfrezen
1000049=Snijstrategie
1000050=Snijstrategie
1000051=Automatisch
1000052=Automatisch
1000053=Alleen zaagblad
1000054=Alleen zaagblad
1000055=Alleen frees
1000056=Alleen frees
1000057=Alleen kettingzaag
1000058=Alleen kettingzaag
1000059=Beschikbare frees om het snijvlak van de pen te bewerken
1000060=Beschikbare frees om het snijvlak van the pen te bewerken
1000061=Beschikbare frees om de zwaluwstaartpen te bewerken
1000062=Beschikbare frees om de zwaluwstaartpen te bewerken
1000063=Maximale hoekradius achtergelaten op hoeken
1000064=Radiuslimiet achtergelaten door het gereedschap bij elke binnenhoek van de feature
1000065=Anti-splinterstrategie gebruiken
1000066=De strategie past zaagsneden toe op de hoek om houtsplinters te voorkomen
1000067=Verlengen na de staart
1000068=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
1000069=Minimale benaderingsafstand op open zijden
1000070=Minimale benaderingsafstand op open zijden
1000071=Beschikbare frees voor het uitdiepen/uitfrezen van de feature
1000072=Beschikbare frees voor het uitdiepen/uitfrezen van de feature
1000073=Afwerken met kettingzaag indien nodig
1000074=Afwerken met kettingzaag indien nodig
1000075=Verlengen na de staart
1000076=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
1000077=Schulpzaagblad forceren
1000078=Forceer het gebruik van een schulpzaagblad, ontworpen voor zaagsneden parallel aan de houtnerf
1000079=Niet voltooien als de uitloopradius van het zaagblad achterblijft
1000080=Als de parameter actief is, beschouwt het automatisme de feature als - niet voltooid - als de uitloopradius van het zaagblad achterblijft
1000081=Kettingzaag in zig-zag-modus gebruiken
1000082=Schakel deze parameter in om de zig-zag-beweging voor de kettingzaagbewerking in te stellen. Deactiveer deze om de one-way-beweging te gebruiken.
1000083=Sorteren per segment
1000084=Sorteer de bewerkingen op basis van het onderdeelsegment waarin de bewerking is ingevoegd
1000085=Volgend onderdeel beschadigen
1000086=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
1000087=Nooit beschadigen
1000088=Nooit beschadigen
1000089=Alleen beschadigen als het onbewerkt hout betreft
1000090=Alleen beschadigen als het onbewerkt hout betreft
1000091=Mag beschadigen
1000092=Mag beschadigen
1000093=Kettingzaag in zig-zag-modus gebruiken
1000094=Schakel deze parameter in om de zig-zag-beweging voor de kettingzaagbewerking in te stellen. Deactiveer deze om de one-way-beweging te gebruiken.
1000095=Verlengen na de staart
1000096=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
1000097=Volgend onderdeel beschadigen
1000098=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
1000099=Nooit beschadigen
1000100=Nooit beschadigen
1000101=Alleen beschadigen als het onbewerkt hout betreft
1000102=Alleen beschadigen als het onbewerkt hout betreft
1000103=Mag beschadigen
1000104=Mag beschadigen
1000105=Schulpzaagblad forceren
1000106=Forceer het gebruik van een schulpzaagblad, ontworpen voor zaagsneden parallel aan de houtnerf
1000107=Verlengen na de staart
1000108=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
1000109=Volgend onderdeel beschadigen
1000110=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
1000111=Nooit beschadigen
1000112=Nooit beschadigen
1000113=Alleen beschadigen als het onbewerkt hout betreft
1000114=Alleen beschadigen als het onbewerkt hout betreft
1000115=Mag beschadigen
1000116=Mag beschadigen
1000117=Zaagstrategie
1000118=Zaagstrategie
1000119=Automatisch
1000120=Automatisch
1000121=Kortafval afvoeren
1000122=Kortafval afvoeren
1000123=Kortafval verbonden houden
1000124=Kortafval verbonden houden
1000125=Opdelen in blokjes uitschakelen
1000126=Opdelen in blokjes uitschakelen
1000127=Prioriteit geven aan bewerkingssnelheid boven kwaliteit
1000128=Prioriteit geven aan bewerkingssnelheid boven kwaliteit
1000129=Breedte van de verbindingsstrip
1000130=In het geval dat het afval vastgehecht blijft, is dit de breedteafmeting van de verbindingsstrip
1000131=Uitloopradius van zaagblad reinigen met frees
1000132=Uitloopradius van zaagblad reinigen met frees
1000133=Freesoffset vanaf de zijde
1000134=Freesoffset vanaf de zijde
1000135=Overmaat op de penlengte
1000136=Overmaat op de penlengte
1000137=Overmaat op de penbreedte
1000138=Overmaat op de penbreedte
1000139=Maximum aantal freesgangen
1000140=Maximum aantal freesgangen. Als er meer gangen vereist zijn, wordt er uitfrezen/uitkameren uitgevoerd
1000141=Snijstrategie
1000142=Snijstrategie
1000143=Automatisch
1000144=Automatisch
1000145=Alleen zaagblad
1000146=Alleen zaagblad
1000147=Alleen frees
1000148=Alleen frees
1000149=Alleen kettingzaag
1000150=Alleen kettingzaag
1000151=Beschikbare frees om de pen te bewerken
1000152=Beschikbare frees om de pen te bewerken
1000153=Overmaat op de gatlengte
1000154=Overmaat op de gatlengte
1000155=Overmaat op de gatbreedte
1000156=Overmaat op de gatbreedte
1000157=Maximum aantal freesgangen
1000158=Maximum aantal freesgangen. Als er meer gangen vereist zijn, wordt er uitfrezen/uitkameren uitgevoerd
1000159=Zwaluwstaartgereedschap gebruiken bij uitfrezen
1000160=Zwaluwstaartgereedschap gebruiken bij uitfrezen
1000161=Anti-splintertoevoeging toepassen
1000162=Anti-splintertoevoeging toepassen
1000163=Snijstrategie
1000164=Snijstrategie
1000165=Automatisch
1000166=Automatisch
1000167=Alleen zaagblad
1000168=Alleen zaagblad
1000169=Alleen frees
1000170=Alleen frees
1000171=Alleen kettingzaag
1000172=Alleen kettingzaag
1000173=Beschikbare frees om het snijvlak van het gat te bewerken
1000174=Beschikbare frees om het snijvlak van het gat te bewerken
1000175=Beschikbare frees om het zwaluwstaartgat te frezen
1000176=Beschikbare frees om het zwaluwstaartgat te frezen
1000177=Overmaat op de gatlengte
1000178=Overmaat op de gatlengte
1000179=Overmaat op de gatbreedte
1000180=Overmaat op de gatbreedte
1000181=Snijstrategie
1000182=Snijstrategie
1000183=Automatisch
1000184=Automatisch
1000185=Alleen zaagblad
1000186=Alleen zaagblad
1000187=Alleen frees
1000188=Alleen frees
1000189=Alleen kettingzaag
1000190=Alleen kettingzaag
1000191=Beschikbare frees om het snijvlak van het gat te bewerken
1000192=Beschikbare frees om het snijvlak van het gat te bewerken
1000193=Beschikbare frees om het gat te frezen
1000194=Beschikbare frees om het gat te frezen
1000195=Diepte van de afschuining
1000196=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
1000197=Anti-splinterstrategie gebruiken
1000198=De strategie past zaagsneden toe op de hoek om houtsplinters te voorkomen
1000199=Beschikbare frees om het profiel te bewerken
1000200=Beschikbare frees om het profiel te bewerken
1000201=Anti-splinterfunctie via zaagblad
1000202=Gebruik het zaagblad als anti-splintervoorziening indien de geometrie niet doorgaand is
1000203=Verlengen na de staart
1000204=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
1000205=Uitloopradius reinigen met frees
1000206=Uitloopradius reinigen met frees
1000207=Freesoffset vanaf de zijde
1000208=Freesoffset vanaf de zijde
1000209=Volgend onderdeel beschadigen
1000210=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
1000211=Nooit beschadigen
1000212=Nooit beschadigen
1000213=Alleen beschadigen als het onbewerkt hout betreft
1000214=Alleen beschadigen als het onbewerkt hout betreft
1000215=Mag beschadigen
1000216=Mag beschadigen
1000217=Tolerantie op diameter
1000218=Tolerantie op diameter
1000219=Diepte van het voorgat
1000220=Diepte van het voorgat
1000221=Boormodus
1000222=Boormodus
1000223=Automatisch
1000224=Automatisch
1000225=Voorkeursbewerking vanaf slechts één zijde
1000226=Voorkeursbewerking vanaf slechts één zijde
1000227=Bewerking vanaf beide zijden forceren
1000228=Bewerking vanaf beide zijden forceren
1000229=Lijst met beschikbare boren
1000230=Lijst met beschikbare boren
1000231=Verlengen na de staart
1000232=Het automatisme beschouwt deze lengte als bewerkbaar. Dit betekent dat u accepteert dat het volgende onderdeel in de balk beschadigd kan raken
1000233=Volgend onderdeel beschadigen
1000234=Met deze optie kunt u beslissen hoe u het volgende onderdeel in de balk beschouwt. De software berekent specifieke in- en uitlopen om de parameter te respecteren. Deze parameter kan de bewerkingstijd beïnvloeden
1000235=Nooit beschadigen
1000236=Nooit beschadigen
1000237=Alleen beschadigen als het onbewerkt hout betreft
1000238=Alleen beschadigen als het onbewerkt hout betreft
1000239=Mag beschadigen
1000240=Mag beschadigen
1000241=Borstverjonging zaag- en freesstrategie
1000242=Borstverjonging zaag- en freesstrategie
1000243=Automatisch
1000244=Automatisch
1000245=Zaagblad gebruiken
1000246=Zaagblad gebruiken
1000247=Frees gebruiken
1000248=Frees gebruiken
1000249=Tolerantie op diameter
1000250=Tolerantie op diameter
1000251=Frees gebruiken als boor
1000252=Toestaan dat de frees axiaal als boor wordt ingezet
1000253=Alleen contour frezen
1000254=Contour sowieso frezen, zelfs wanneer het gat groter is dan de gereedschapsdiameter
1000255=Boormodus via frezen
1000256=Boormodus via frezen
1000257=Automatisch
1000258=Automatisch
1000259=Voorkeursbewerking vanaf slechts één zijde
1000260=Voorkeursbewerking vanaf slechts één zijde
1000261=Bewerking vanaf beide zijden forceren
1000262=Bewerking vanaf beide zijden forceren
1000263=Beschikbare frezen om gaten te bewerken
1000264=Beschikbare frezen om gaten te bewerken
1000265=Bewerkingsdiepte
1000266=Bewerkingsdiepte
1000267=Beschikbare frees voor markeringen en tekst
1000268=Beschikbare frees voor markeringen en tekst
1000269=Markeerstrategie
1000270=Markeerstrategie
1000271=Automatisch
1000272=Automatisch
1000273=Alleen markeerpen
1000274=Alleen markeerpen
1000275=Alleen V-frees
1000276=Alleen V-frees
1000277=Diepte van de afschuining
1000278=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
1000279=Alleen afschuining frezen
1000280=Alleen de afschuining uitvoeren, geen andere bewerkingen
1000281=Overmaat
1000282=Overmaat
1000283=Maximale hoekradius achtergelaten op hoeken
1000284=Radiuslimiet achtergelaten door het gereedschap bij elke binnenhoek van de feature
1000285=Zaagsnede uitvoeren om materiaal te verwijderen
1000286=Zaagsnede uitvoeren om materiaal te verwijderen
1000287=Snoei- / steunstrip forceren
1000288=Activeer deze parameter om de software te verplichten een reststrip te laten staan om het onderdeel te ondersteunen
1000289=Breedte van de steunstrip
1000290=Breedte van de strip in het geval dat deze door de bewerking is voorzien
1000291=Kopsnijstrategie
1000292=Kopsnijstrategie
1000293=Automatisch
1000294=Automatisch
1000295=Geen bewerking
1000296=Geen bewerking
1000297=Zaagblad geforceerd
1000298=Zaagblad geforceerd
1000299=Frees geforceerd
1000300=Frees geforceerd
1000301=Beschikbare frees om het kops profiel te bewerken
1000302=Beschikbare frees om het kops profiel te bewerken
1000303=Diepte van de afschuining
1000304=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
1000305=Gebruik van kettingzaag forceren
1000306=Gebruik van kettingzaag forceren
1000307=PreCuts (Voorsneden) forceren
1000308=Autocam past een bewerking toe op het theoretische nulpunt om botsingen te voorkomen als de theoretische lengte niet overeenkomt met de werkelijke lengte
1000309=Afwerken met frees
1000310=Gebruik een frees om het oppervlak na te bewerken als dit met de kettingzaag is gespleten
1000311=Diepte van de afschuining
1000312=Diepte van de V-frees om afschuiningen op snijkanten uit te voeren
1000313=Gebruik van kettingzaag forceren
1000314=Gebruik van kettingzaag forceren
1000315=PreCuts (Voorsneden) forceren
1000316=Autocam past een bewerking toe op het theoretische nulpunt om botsingen te voorkomen als de theoretische lengte niet overeenkomt met de werkelijke lengte
1000317=Afwerken met frees
1000318=Gebruik een frees om het oppervlak na te bewerken als dit met de kettingzaag is gespleten
// ----- End -----
+623 -404
View File
File diff suppressed because it is too large Load Diff
+477
View File
@@ -0,0 +1,477 @@
-- BeamNestProcess.lua by Egaltech s.r.l. 2023/01/15
-- Gestione nesting automatico travi
-- 2022/10/05 Piccole modifiche per far funzionare correttamente i compilati.
-- 2022/10/06 Corretto bug che moltiplicava i pezzi se erano presenti più grezzi della stessa sezione.
-- 2023/01/15 Piccole correzioni.
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Per test
--NEST = {}
--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl'
--NEST.MACHINE = 'Essetre-90480019_MW'
--NEST.FLAG = 3
local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN[1]
EgtOutLog( sLog)
-- flag per abilitare statistiche in log
local bLogStat = false
-- Cancello file di log specifico
local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt')
EgtEraseFile( sLogFile)
-- Funzioni per scrittura su file di log specifico
local function WriteErrToLogFile( nErr, sMsg, nRot, nCutId, nTaskId)
local hFile = io.open( sLogFile, 'a')
hFile:write( 'ERR=' .. tostring( nErr) .. '\n')
hFile:write( sMsg .. '\n')
hFile:write( 'ROT=' .. tostring( nRot or 0) .. '\n')
hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n')
hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n')
hFile:close()
end
local function WriteTimeToLogFile( dTime)
local hFile = io.open( sLogFile, 'a')
hFile:write( 'TIME=' .. EgtNumToString( dTime) .. '\n')
hFile:close()
end
-- Funzione per gestire visualizzazione dopo errore
local function PostErrView( nErr, sMsg)
if nErr ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
EgtSetView( SCE_VD.ISO_SW, false)
EgtZoom( SCE_ZM.ALL)
EgtOutBox( sMsg, 'BatchProcess (err=' .. tostring( nErr) .. ')', 'ERRORS')
end
end
-- Funzione per gestire visualizzazione dopo warning
local function PostWarnView( nWarn, sMsg)
if nWarn ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
EgtSetView( SCE_VD.ISO_SW, false)
EgtZoom( SCE_ZM.ALL)
EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS')
end
end
-- Funzione per aggiornare dati ausiliari
local function UpdateAuxData( sAuxFile)
local bModif = false
-- Se definito LOAD90, aggiorno
local sLoad90 = EgtGetStringFromIni( 'AuxData', 'LOAD90', '', sAuxFile)
if sLoad90 ~= '' then
local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL
EgtSetInfo( BtlInfoId, 'LOAD90', sLoad90)
bModif = true
end
return bModif
end
local function PartsToFill( Parts)
local nToFill = 0
for i = 1, #Parts do
if Parts[i].Cnt > 0 then
nToFill = nToFill + Parts[i].Cnt
end
end
return nToFill
end
local function ExecMaximumFilling( Raw, Parts)
-- Inizializzo maximum filler
EgtMaxFillerStart()
-- Inserisco i pezzi
for i = 1, #Parts do
EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1)
end
-- Eseguo l'ottimizzazione
EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType)
-- Recupero i risultati
local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults()
local OneRes = {}
for i = 0, nDiffParts - 1 do
local nPartId, nCount = EgtMaxFillerGetOneResult( i)
table.insert( OneRes, { Id=nPartId, Count=nCount})
end
--return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes}
return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Data=OneRes}
end
-- Funzione per trovare nome MachGroup
local function NewMachGroupName()
local nMachGroupId = EgtGetFirstMachGroup()
if not nMachGroupId then return 1 end
local nMaxMachGroup = 0
while nMachGroupId do
sMachGroupName = EgtGetMachGroupName(nMachGroupId)
local nMachGroupName = tonumber(sMachGroupName)
if nMachGroupName > nMaxMachGroup then
nMaxMachGroup = nMachGroupName
end
nMachGroupId = EgtGetNextMachGroup(nMachGroupId)
end
return nMaxMachGroup + 1
end
local function TotRawCount(Raws)
local nTotRaws = 0
for RawIndex = 1, #Raws do
nTotRaws = nTotRaws + Raws[RawIndex].Count
end
return nTotRaws
end
local function TotPartLen(Parts)
local nTotPartLen = 0
for PartIndex = 1, #Parts do
nTotPartLen = nTotPartLen + ( Parts[PartIndex].Len * Parts[PartIndex].Cnt)
end
return nTotPartLen
end
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( NEST.BASEDIR .. '\\LuaLibs\\?.lua')
-- Imposto la macchina corrente e verifico sia abilitata per la lavorazione delle Travi
EgtSetCurrMachine( NEST.MACHINE)
local sMachDir = EgtGetCurrMachineDir()
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
NEST.ERR = 12
NEST.MSG = 'Error not configured for beam machine : ' .. sMachine
WriteErrToLogFile( NEST.ERR, NEST.MSG)
PostErrView( NEST.ERR, NEST.MSG)
return
end
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
EgtRemoveBaseMachineDirFromPackagePath()
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
-- Inizializzo contatori errori e avvisi
local nErrCnt = 0
local nWarnCnt = 0
-- Grezzi
local Raws = {}
-- creo tabella dei grezzi
for nIndex, nLen in pairs( LEN) do
Raws[tonumber(nIndex)] = {LenToFill = nLen, StartGap = NEST.STARTOFFSET, MidGap = NEST.OFFSET, EndGap = 0, SortType = -1}
end
for nIndex, nQty in pairs( QTY) do
Raws[tonumber(nIndex)].Count = nQty
end
-- cerco il grezzo con la lunghezza maggiore, epurata dello start gap
local maxRawLenToFillNoStartGap = 0
for RawIndex = 1, #Raws do
if Raws[RawIndex].Count > 0 then
maxRawLenToFillNoStartGap = max( maxRawLenToFillNoStartGap, Raws[RawIndex].LenToFill - Raws[RawIndex].StartGap)
end
end
-- Pezzi
local Parts = {}
-- ciclo su pezzi per aggiungerli al nesting
local dTotLen = 0
for nPartId, nCount in pairs( PART) do
-- recupero lunghezza pezzo
local Len = EgtGetInfo( nPartId, "L", 'd')
local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0)
-- aggiungo il pezzo solo se ci sta nel grezzo più lungo a disposizione
if Len < maxRawLenToFillNoStartGap then
for nCntIndex = 1 , nCount do
table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = 1})
dTotLen = dTotLen + Len
end
end
end
-- lunghezza totale pezzi
local dTotPartLen = TotPartLen( Parts)
-- calcolo media delle barre necessarie
local NeededRawsForType = {}
for RawIndex = 1, #Raws do
NeededRawsForType[RawIndex] = min( ceil( dTotPartLen / Raws[RawIndex].LenToFill), Raws[RawIndex].Count)
end
local RawQtySum = 0
for NeededRawIndex = 1, #NeededRawsForType do
RawQtySum = RawQtySum + NeededRawsForType[NeededRawIndex]
end
local MediumRawQty = ceil( RawQtySum / #NeededRawsForType)
if MediumRawQty > 1 then
MediumRawQty = MediumRawQty - 1
end
-- lista dei risultati
local ResultList = {}
local BestResult = nil
local BestResultIndex = nil
-- riordino lista pezzi per lunghezza
table.sort( Parts, function( B1, B2) return B1.Len < B2.Len end)
local function NestSolutionByIndex( Index)
-- creo copia lista raw
local TempRaws = {}
for TempRawIndex = 1, #Raws do
table.insert(TempRaws, {LenToFill = Raws[TempRawIndex].LenToFill, StartGap = Raws[TempRawIndex].StartGap, MidGap = Raws[TempRawIndex].MidGap, EndGap = Raws[TempRawIndex].EndGap, SortType = Raws[TempRawIndex].SortType, Count = Raws[TempRawIndex].Count})
end
-- recupero pezzi corti
local ShortList = {}
local LongList = {}
for PartIndex = 1, #Parts do
if PartIndex <= Index then
table.insert( ShortList, Parts[PartIndex])
else
table.insert( LongList, Parts[PartIndex])
end
Parts[PartIndex].Cnt = 1
end
-- numero di pezzi piccoli per barra
local ShortCount = Index
local ShortForRaw = floor( ShortCount / MediumRawQty)
local ExtraShortForRaw = 0
if MediumRawQty > 0 then
ExtraShortForRaw = fmod( ShortCount, MediumRawQty)
end
-- creo lista pezzi corti singoli
local SingleShortList = {}
for ShortIndex = 1, #ShortList do
for ShortCount = 1, ShortList[ShortIndex].Cnt do
table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1})
end
end
-- li divido per le barre previste
local RawsShortList = {}
local RawIndex = 0
local ShortRawIndex = 0
for ShortIndex = 1, #SingleShortList do
if ShortRawIndex > 0 then
table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex])
ShortRawIndex = ShortRawIndex - 1
else
table.insert( RawsShortList, {SingleShortList[ShortIndex]})
RawIndex = RawIndex + 1
ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1
end
end
-- Ciclo fino ad esaurimento pezzi o barre
local dTotPartInRawLen = 0
local nRawTot = 0
local dRawTotLen = 0
local dTime = 0
local nCycle = 1
local CurrResult = {}
while TotRawCount( TempRaws) > 0 and PartsToFill( Parts) > 0 do
-- creo lista con pezzi lunghi e pezzi corti di questo Cycle
local PartsToNest = {}
for PartIndex = 1, #LongList do
table.insert( PartsToNest, LongList[PartIndex])
end
for CycleIndex = 1, #RawsShortList do
if CycleIndex <= nCycle then
for PartIndex = 1, #RawsShortList[CycleIndex] do
table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex])
end
end
end
-- se non ci sono pezzi da nestare, esco
if PartsToFill( PartsToNest) <= 0 then
break
end
-- Eseguo ottimizzazione per ogni lunghezza di barra
local Results = {}
for RawIndex = 1, #TempRaws do
if TempRaws[RawIndex].Count > 0 then
Results[RawIndex] = ExecMaximumFilling( TempRaws[RawIndex], PartsToNest)
else
Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000, DiffParts = 0}
end
end
-- verifico quale e' quella con meno scarto
local nMinWasteRawIndex = GDB_ID.NULL
local dMinWaste = 100000
for ResultIndex = 1, #Results do
if Results[ResultIndex] then
local dWaste = (1 - Results[ResultIndex].FillRatio) * TempRaws[ResultIndex].LenToFill
if Results[ResultIndex].DiffParts > 0 and dWaste < dMinWaste then
dMinWaste = dWaste
nMinWasteRawIndex = ResultIndex
end
end
end
-- verifico se ci sono pezzi
if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then
-- riporto barra e pezzi nel risultato corrente
local CurrBar = { BarLen = TempRaws[nMinWasteRawIndex].LenToFill, Parts = {}}
local CurrX = TempRaws[nMinWasteRawIndex].StartGap
local nInfoIndex = 1
for i = 1, Results[nMinWasteRawIndex].DiffParts do
local PartIndex = Results[nMinWasteRawIndex].Data[i].Id
local PartId = PartsToNest[PartIndex].Id
local dLen = PartsToNest[PartIndex].Len
for j = 1, Results[nMinWasteRawIndex].Data[i].Count do
-- creo pezzo copia
CurrPart = { Index = nInfoIndex, PartId = PartId, PosX = CurrX}
table.insert( CurrBar.Parts, CurrPart)
CurrX = CurrX + dLen + TempRaws[nMinWasteRawIndex].MidGap
nInfoIndex = nInfoIndex + 1
end
end
table.insert( CurrResult, CurrBar)
dTotPartInRawLen = dTotPartInRawLen + ( Results[nMinWasteRawIndex].FillRatio * TempRaws[nMinWasteRawIndex].LenToFill)
nRawTot = nRawTot + 1
dRawTotLen = dRawTotLen + TempRaws[nMinWasteRawIndex].LenToFill
-- Aggiorno per prossima iterazione
TempRaws[nMinWasteRawIndex].Count = TempRaws[nMinWasteRawIndex].Count - 1
for i = 1, Results[nMinWasteRawIndex].DiffParts do
local PartId = Results[nMinWasteRawIndex].Data[i].Id
PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count
end
else
-- se non sono riuscito ad inserire alcun pezzo esco dal ciclo perche' non ci sono pezzi inseribili
break
end
nCycle = nCycle + 1
end
-- riporto risultato in lista
ResultList[Index] = dTotPartInRawLen
if not BestResult or not BestResultIndex or
( dTotPartInRawLen > ResultList[BestResultIndex] + 0.02 or ( abs( dTotPartInRawLen - ResultList[BestResultIndex]) < 0.02 and dRawTotLen < BestResult.RawTotLen - 0.02)) then
BestResult = CurrResult
BestResult.RawTotLen = dRawTotLen
BestResultIndex = Index
end
end
local CycleCount = 0
local MinTime = 10 + pow( 3, ceil( log10( #Parts)) - 1)
if bLogStat then EgtOutLog('MinTime: ' .. MinTime ) end
local MaxTime = 30 + pow( 7, ceil( log10( #Parts)) - 1)
if bLogStat then EgtOutLog('MaxTime: ' .. MaxTime ) end
local TargetRatio = 0.98
local dTargetRatioLen = TargetRatio * dTotLen
if bLogStat then EgtOutLog('TargetRatioLen: ' .. dTargetRatioLen ) end
local CurrTime = 0
local function NestSolutionFromSP( StartingPoint, OscillationStep)
-- ciclo sulle possibilita' da un punto di origine con uno step fisso
local CurrResultIndex = StartingPoint
NestSolutionByIndex( StartingPoint)
if OscillationStep == 0 then return end
local CycleIndex = 1
local nOutOfBoundary = 0
while nOutOfBoundary ~= 3 do
CurrTime = EgtStopCounter() / 1000
if bLogStat then EgtOutLog('CurrTime: ' .. CurrTime ) end
if bLogStat then EgtOutLog('BestRatio: ' .. dTotLen / BestResult.RawTotLen ) end
-- se e' passato il tempo massimo, o e' passato il tempo minimo, ha inserito tutti i pezzi e la percentuale di utilizzo del materiale e' maggiore della soglia
if CurrTime > MaxTime or ( CurrTime > MinTime and ResultList[BestResultIndex] > dTotLen - 0.1 and ( dTotLen / BestResult.RawTotLen ) >= TargetRatio) then
if bLogStat then EgtOutLog('Brake') end
break
end
local bCurrOutOfBoundary = false
if CurrResultIndex < 0 then
bCurrOutOfBoundary = true
if nOutOfBoundary == 2 then
nOutOfBoundary = 3
else
nOutOfBoundary = 1
end
end
if CurrResultIndex > #Parts then
bCurrOutOfBoundary = true
if nOutOfBoundary == 1 then
nOutOfBoundary = 3
else
nOutOfBoundary = 2
end
end
if not bCurrOutOfBoundary and not ResultList[CurrResultIndex] then
NestSolutionByIndex( CurrResultIndex)
if bLogStat then EgtOutLog('CurrResultIndex: ' .. CurrResultIndex ) end
if bLogStat then EgtOutLog('Result: ' .. ResultList[CurrResultIndex]) end
CycleCount = CycleCount + 1
end
CurrResultIndex = StartingPoint + EgtIf( CycleIndex % 2 == 0, (CycleIndex / 2) * OscillationStep, -( ( CycleIndex + 1) / 2) * OscillationStep )
CycleIndex = CycleIndex + 1
end
end
-- lancio calcolo
EgtStartCounter()
local StartingResult = floor( #Parts * 0.3)
if bLogStat then EgtOutLog('StartingResult: ' .. StartingResult ) end
--local Step = floor( #Parts / 10) * floor( log10( #Parts))
local nDividendo = pow( 10, floor( log10( #Parts)) - 1)
nDividendo = EgtIf( nDividendo ~= 1, nDividendo, 10)
local Step = floor( #Parts / nDividendo) * floor( log10( #Parts))
if bLogStat then EgtOutLog('Step: ' .. Step ) end
NestSolutionFromSP( StartingResult, Step)
if Step > 1 then
NestSolutionFromSP( StartingResult, 1)
end
-- creo gruppi di lavorazione per risultato
for MachGroupIndex = 1, #BestResult do
local CurrMachGroup = BestResult[ MachGroupIndex]
-- creo gruppo di lavorazione
local MachGroupName = NewMachGroupName()
nMachGroup = EgtAddMachGroup( MachGroupName)
EgtSetInfo( nMachGroup, "BARLEN", CurrMachGroup.BarLen)
EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL)
EgtSetInfo( nMachGroup, "AUTONEST", 1)
-- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID)
EgtSetInfo( nMachGroup, "PATTID", nMachGroup)
-- Disegno i pezzi
for i = 1, #CurrMachGroup.Parts do
local CurrPart = CurrMachGroup.Parts[ i]
-- creo pezzo copia
local nPartDuploId = EgtDuploNew( CurrPart.PartId)
EgtSetInfo( nMachGroup, "PART" .. CurrPart.Index, nPartDuploId .. "," .. CurrPart.PosX)
end
end
-- creo grezzi per ogni gruppo di lavorazione
local nRawCnt = 0
local nRawTot = ResultList[BestResultIndex]
_G.BEAM = {}
BEAM.FILE = NEST.FILE
BEAM.MACHINE = NEST.MACHINE
BEAM.FLAG = 6 -- CREATE_PANEL
BEAM.BASEDIR = NEST.BASEDIR
nMachGroup = EgtGetFirstMachGroup()
while nMachGroup do
local nNextMachGroup = EgtGetNextMachGroup( nMachGroup)
EgtSetCurrMachGroup( nMachGroup)
if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then
EgtRemoveInfo( nMachGroup, "AUTONEST")
EgtSetInfo( nMachGroup, "UPDATEUI", 1)
local bOk, sErr = pcall( dofile, BEAM.BASEDIR .. "\\BatchProcessNew.lua")
if not bOk then
EgtOutLog( 'Error in BatchProcessNew.lua call (' .. ( sErr or '') ..')')
end
nRawCnt = nRawCnt + 1
-- aggiorno interfaccia
EgtProcessEvents( 200 + ( nRawCnt / nRawTot * 100), 0)
end
nMachGroup = nNextMachGroup
end
EgtResetCurrMachGroup()
NEST.ERR = 0
EgtOutLog( ' +++ BeamNestProcess completed')
+12 -7
View File
@@ -15,9 +15,6 @@ EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua')
EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.lua')
-- TODO forzatura calcolo con prerotazioni. Cancellare dopo che è stata aggiunta la gestione corretta
local bCalcBestPieceUnloadPosition = true
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
local sMachDir = EgtGetCurrMachineDir()
if not sMachDir then
@@ -134,6 +131,14 @@ local function MyProcessInputData()
else
PARTS[i].b3PartOriginal = b3Solid
end
if BeamData.MAX_LENGTH and BeamData.MAX_LENGTH > 10 and b3Solid:getDimX() > BeamData.MAX_LENGTH then
local sOut = 'Lunghezza (' .. EgtNumToString( b3Solid:getDimX(), 2) .. ') ' ..
'oltre i limiti della macchina (' .. EgtNumToString( BeamData.MAX_LENGTH, 2) .. ') '
EgtOutLog( sOut)
EgtOutBox( sOut, 'Lavora Travi', 'WARNING')
EgtDraw()
return false
end
end
dRawW = PARTS[1].b3PartOriginal:getDimY()
dRawH = PARTS[1].b3PartOriginal:getDimZ()
@@ -290,7 +295,7 @@ local function MyProcessBeams()
end
-- Sistemo le travi nel grezzo
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, bCalcBestPieceUnloadPosition)
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, false)
if not bOk then
EgtOutLog( sErr)
EgtOutBox( sErr, 'Lavora Travi', 'ERROR')
@@ -305,9 +310,9 @@ end
-------------------------------------------------------------------------------------------------------------
local function MyProcessFeatures()
BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
BeamExec.ProcessMachinings( PARTS)
BeamExec.GetProcessings( PARTS, false)
BeamExec.GetCombinationMatrix( PARTS, false)
BeamExec.ProcessMachinings( PARTS, false)
local nErrCnt = 0
local nWarnCnt = 0
local sOutput = ''
+2 -2
View File
@@ -392,7 +392,7 @@
"TopologyList" : [
{ "sName": "Feature",
"sImage": "ConfigStrategy\\Chamfer.png",
"StrategyList" : [ ]
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010" } ]
}
]
},
@@ -688,7 +688,7 @@
"TopologyList" : [
{ "sName": "Feature",
"sImage": "ConfigStrategy\\ScarfJoint.png",
"StrategyList" : [ ]
"StrategyList" : [ { "sStrategyId": "STR0009" }]
}
]
},
+76 -9
View File
@@ -1,35 +1,68 @@
[
{
"nGroup": "MACHINE",
"nGroup": "PIECE LOADING",
"sName": "GEN_sPiecesLoadingPosition",
"sNameNge": "GEN_PIECES_LOADING",
"sValue": "BEST_POSITION",
"sValue": "BTL_POSITION",
"sDescriptionShort": "Part loading position",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000001,
"idDescriptionLongMsg": 1000002,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
{
"sValue": "BTL_POSITION",
"sDescriptionShort": "Last piece position as BTL",
"sDescriptionShort": "Loading position from BTL, no pre-rotation",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000003,
"idDescriptionLongMsg": 1000004,
"sMessageId": ""
},
{
"sValue": "BEST_ROTATION",
"sDescriptionShort": "Allow piece rotations",
"sValue": "STD_PRE_ROTATION",
"sDescriptionShort": "Get Best loading position from 0° and 180°",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000005,
"idDescriptionLongMsg": 1000006,
"sMessageId": ""
},
{
"sValue": "BEST_POSITION",
"sDescriptionShort": "Allow piece rotation and inversion",
"sValue": "FULL_PRE_ROTATION",
"sDescriptionShort": "Get Best loading position in each piece rotation",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000007,
"idDescriptionLongMsg": 1000008,
"sMessageId": ""
}
]
},
{
"nGroup": "PIECE LOADING",
"sName": "GEN_bAllowPieceInversion",
"sNameNge": "ADMIT_INVERSION",
"sValue": "false",
"sDescriptionShort": "Allow piece inversion",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000009,
"idDescriptionLongMsg": 1000010,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"nGroup": "PIECE LOADING",
"sName": "GEN_bGetAlternativesNesting2D",
"sNameNge": "GET_ALTERNATIVES_NEST2D",
"sValue": "false",
"sDescriptionShort": "Enable material optimization function in nesting (part rotation disabled)",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000011,
"idDescriptionLongMsg": 1000012,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"nGroup": "MACHINE",
"sName": "GEN_sPieceRotation",
@@ -37,6 +70,8 @@
"sValue": "IF_NECESSARY",
"sDescriptionShort": "Part rotating acceptability",
"sDescriptionLong": "Acceptability of rotating the part between machining steps",
"idDescriptionShortMsg": 1000013,
"idDescriptionLongMsg": 1000014,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -44,18 +79,24 @@
"sValue": "NOT_ALLOWED",
"sDescriptionShort": "Rotation not allowed",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000015,
"idDescriptionLongMsg": 1000016,
"sMessageId": ""
},
{
"sValue": "IF_NECESSARY",
"sDescriptionShort": "Rotation allowed only if strictly necessary",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000017,
"idDescriptionLongMsg": 1000018,
"sMessageId": ""
},
{
"sValue": "NO_CONSTRAINT",
"sDescriptionShort": "Rotation easily acceptable / no constraint",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000019,
"idDescriptionLongMsg": 1000020,
"sMessageId": ""
}
]
@@ -67,6 +108,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Machining Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000021,
"idDescriptionLongMsg": 1000022,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -74,18 +117,32 @@
"sValue": "AUTO",
"sDescriptionShort": "Quality and time equally prioritized",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000023,
"idDescriptionLongMsg": 1000024,
"sMessageId": ""
},
{
"sValue": "FASTEST",
"sDescriptionShort": "Fastest",
"sDescriptionLong": "Prefer fastest strategies",
"idDescriptionShortMsg": 1000025,
"idDescriptionLongMsg": 1000026,
"sMessageId": ""
},
{
"sValue": "HIGH_QUALITY",
"sDescriptionShort": "High quality",
"sDescriptionLong": "Prefer high-quality strategies",
"idDescriptionShortMsg": 1000027,
"idDescriptionLongMsg": 1000028,
"sMessageId": ""
},
{
"sValue": "FIRST_IN_LIST",
"sDescriptionShort": "Ordering rules",
"sDescriptionLong": "The first complete strategy in list is the one chosen; no intelligent choosing",
"idDescriptionShortMsg": 1000029,
"idDescriptionLongMsg": 1000030,
"sMessageId": ""
}
]
@@ -97,6 +154,8 @@
"sValue": "1",
"sDescriptionShort": "Max number of reprocessing cycles",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000031,
"idDescriptionLongMsg": 1000032,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "10"
@@ -108,6 +167,8 @@
"sValue": "true",
"sDescriptionShort": "Use entire blade diameter to shorten path",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000033,
"idDescriptionLongMsg": 1000034,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "5"
@@ -119,6 +180,8 @@
"sValue": "300",
"sDescriptionShort": "Maximum length for dropped waste",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000035,
"idDescriptionLongMsg": 1000036,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "5"
@@ -130,6 +193,8 @@
"sValue": "6000000",
"sDescriptionShort": "Maximum volume for dropped waste",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000037,
"idDescriptionLongMsg": 1000038,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "5"
@@ -141,8 +206,10 @@
"sValue": "150",
"sDescriptionShort": "Maximum dice dimension",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000039,
"idDescriptionLongMsg": 1000040,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "5"
}
]
]
+9 -2
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Depth Chamfer",
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
"idDescriptionShortMsg": 1000301,
"idDescriptionLongMsg": 1000302,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "false",
"sDescriptionShort": "Force to use chain saw",
"sDescriptionLong": "Force to use chain saw",
"idDescriptionShortMsg": 1000303,
"idDescriptionLongMsg": 1000304,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "false",
"sDescriptionShort": "Force to add PreCuts",
"sDescriptionLong": "Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length",
"idDescriptionShortMsg": 1000305,
"idDescriptionLongMsg": 1000306,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "true",
"sDescriptionShort": "Finish with mill",
"sDescriptionLong": "Use a mill to finish the surface if split with chain saw",
"idDescriptionShortMsg": 1000307,
"idDescriptionLongMsg": 1000308,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -58,5 +66,4 @@
"sMinUserLevel": "5"
}
]
}
}
+5 -3
View File
@@ -40,6 +40,11 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- si setta che è taglio di testa
Strategy.bIsHeadCut = true
-- quando si aggiunge la lavorazione, si cambia il nome della feature
if bAddMachining then
-- si forza il nome della feature
EgtSetName( Proc.id, 'StartCut')
end
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then
@@ -67,9 +72,6 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- se devo applicare le lavorazioni
if bAddMachining then
-- si forza il nome della feature
EgtSetName( Proc.id, 'StartCut')
-- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then
MakeChamfer()
+22
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on tenon length",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000041,
"idDescriptionLongMsg": 1000042,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on tenon width",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000043,
"idDescriptionLongMsg": 1000044,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "3",
"sDescriptionShort": "Maximum number of milling passes",
"sDescriptionLong": "Maximum number of milling passes. If more passes are required, pocketing is performed",
"idDescriptionShortMsg": 1000045,
"idDescriptionLongMsg": 1000046,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "true",
"sDescriptionShort": "Use DoveTail tool to pocket",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000047,
"idDescriptionLongMsg": 1000048,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -48,6 +56,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Cutting Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000049,
"idDescriptionLongMsg": 1000050,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -55,24 +65,32 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000051,
"idDescriptionLongMsg": 1000052,
"sMessageId": ""
},
{
"sValue": "BLADE_FORCED",
"sDescriptionShort": "Blade only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000053,
"idDescriptionLongMsg": 1000054,
"sMessageId": ""
},
{
"sValue": "MILL_FORCED",
"sDescriptionShort": "Mill only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000055,
"idDescriptionLongMsg": 1000056,
"sMessageId": ""
},
{
"sValue": "CHAINSAW_FORCED",
"sDescriptionShort": "ChainSaw only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000057,
"idDescriptionLongMsg": 1000058,
"sMessageId": ""
}
]
@@ -83,6 +101,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the tenon cut surface",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000059,
"idDescriptionLongMsg": 1000060,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
@@ -94,6 +114,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the dovetail tenon",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000061,
"idDescriptionLongMsg": 1000062,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
+1
View File
@@ -87,6 +87,7 @@ local function GetTenonStrategy( Proc, Part)
ToolSearchParameters.dElevation = EgtSurfTmFacetElevationInBBox( Strategy.idTenonCutPlane, 0, Part.b3Part, true, GDB_ID.ROOT)
ToolSearchParameters.vtToolDirection = Proc.FeatureInfo.vtTenonN
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Machining.Cutting.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
+20
View File
@@ -8,6 +8,8 @@
"sValue": "15",
"sDescriptionShort": "Max radius left on corners",
"sDescriptionLong": "Radius-limit left by the tool at each corner of the feature",
"idDescriptionShortMsg": 1000063,
"idDescriptionLongMsg": 1000064,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,16 +20,32 @@
"sValue": "false",
"sDescriptionShort": "Use Anti-Splint strategy",
"sDescriptionLong": "The strategy will apply blade cuts on corner to avoid wood splint",
"idDescriptionShortMsg": 1000065,
"idDescriptionLongMsg": 1000066,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "dExtendAfterTail",
"sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "",
"sDescriptionShort": "Extend after tail",
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
"idDescriptionShortMsg": 1000067,
"idDescriptionLongMsg": 1000068,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "dOpenMinSafe",
"sNameNge": "OPENMINSAFE",
"sValue": "10",
"sDescriptionShort": "Minimum approach distance on open sides",
"sDescriptionLong": "Minimum approach distance on open sides",
"idDescriptionShortMsg": 1000069,
"idDescriptionLongMsg": 1000070,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +56,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to pocket the feature",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000071,
"idDescriptionLongMsg": 1000072,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
+124 -19
View File
@@ -19,6 +19,7 @@ local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
-- Tabella per definizione modulo
local STR0002 = {}
@@ -26,7 +27,8 @@ local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function IsTopologyOk( Proc)
if Proc.Topology.sName == 'Pocket-5-Blind' or
if Proc.Topology.sFamily == 'PseudoPocket' or
Proc.Topology.sName == 'Pocket-5-Blind' or
Proc.Topology.sName == 'RafterNotch-5-Through' or
Proc.Topology.sName == 'Tunnel-4-Through' or
Proc.Topology.sName == 'Groove-4-Blind' or
@@ -107,7 +109,7 @@ local function GetBestPocketingStrategy( Proc, Part)
local Milling = {}
local ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
Machining.sTypeMachining = 'None' -- Bottom-Side1-Side2\ Bottom-Side1\ Bottom-Side2\ Side1-Side2\ Bottom\ Side1 \ Side2 \ None
Machining.sTypeMachining = 'None' -- Bottom-Side1-Side2\ Bottom-Bottom2\ Bottom-Side1\ Bottom-Side2\ Side1-Side2\ Bottom\ Side1 \ Side2 \ None
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
-- caso speciale Tunnel che non ha faccia bottom
@@ -120,7 +122,7 @@ local function GetBestPocketingStrategy( Proc, Part)
ToolSearchParameters.sType = 'MILL_STD'
ToolSearchParameters.dMaxToolDiameter = min( Strategy.Parameters.dMaxCornerRadius * 2, Proc.FeatureInfo.dFaceLength / 2)
-- imposto dati per cercare la fresa migliore
elseif Proc.Topology.sName == 'Pocket-5-Blind' then
elseif Proc.Topology.sName == 'Pocket-5-Blind' or Proc.Topology.sFamily == 'PseudoPocket' then
local dFaceWidth, dFaceLength
if Proc.MainFaces.BottomFaces[1].MainEdges then
dFaceWidth = Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].dLength
@@ -170,10 +172,14 @@ local function GetBestPocketingStrategy( Proc, Part)
-- cerco utensile per lavorare faccia Bottom
Milling.bIsApplicable = false
if Proc.Topology.sName ~= 'Tunnel-4-Through' then
-- TODO in caso che la faccia crei un piano asportando tutto il materiale, si potrebbe forzare elevazione a zero e scegliere quindi fresa di diametro maggiore.
-- Il discorso non vale se la feature viene spezzata o se non ancora separata, in quanto ci sarebbe comunque del materiale da considerare nell'elevazione.
-- In quel caso, un 'Bevel-1-Through' è come se fosse un 'Bevel-2-Blind', quindi l'elevazione deve essere considerata.
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[1].vtN
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[1].id
Milling.bAddAntiSplint = Strategy.Parameters.bAntiSplint
Milling.idProc = Proc.id
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[1].vtN
Milling.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
@@ -204,13 +210,14 @@ local function GetBestPocketingStrategy( Proc, Part)
-- caso speciale 'Rabbet-2-Through' seconda faccia principale
Milling = {}
Milling.bIsApplicable = false
if Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' or
if Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' or
Proc.Topology.sName == 'DoubleBevel-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' then
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id
Milling.bAddAntiSplint = Strategy.Parameters.bAntiSplint
Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
Milling.ToolInfo = {}
@@ -227,7 +234,7 @@ local function GetBestPocketingStrategy( Proc, Part)
-- cerco utensile per lavorare di fianco 1
Milling = {}
Milling.bIsApplicable = false
if Proc.Topology.sName ~= 'DoubleBevel-2-Through'
if Proc.Topology.sName ~= 'DoubleBevel-2-Through' and Proc.Topology.sFamily ~= 'PseudoPocket'
and Proc.Topology.sName ~= 'Pocket-5-Blind' and Proc.Topology.sName ~= 'RafterNotch-5-Through' then
if Proc.Topology.sName == 'Groove-4-Blind' then
@@ -238,12 +245,21 @@ local function GetBestPocketingStrategy( Proc, Part)
Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
elseif Proc.Topology.sName == 'Groove-3-Blind' or Proc.Topology.sName == 'Bevel-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
if Proc.MainFaces.LongFaces and Proc.MainFaces.LongFaces[1] 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
elseif Proc.MainFaces.BottomFaces[2] 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
end
elseif Proc.MainFaces.TunnelAddedFaces then -- 'Tunnel-4-Through', 'Groove-3-Through', 'Rabbet-2-Through', 'VGroove-2-Through', 'Bevel-2-Blind'
-- se lavoro di fianco, devo comunque rispettare il raggio massimo
ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2)
@@ -254,6 +270,8 @@ local function GetBestPocketingStrategy( Proc, Part)
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
Milling.bMachAppliedToTunnelFace = true
else
ToolSearchParameters.vtToolDirection = nil
end
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.ToolInfo = {}
@@ -263,6 +281,19 @@ local function GetBestPocketingStrategy( Proc, Part)
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
-- se la faccia tunnel è troppo piccola non si lavora
if Milling.bMachAppliedToTunnelFace then
local dLongestEdgeLength = 0
for i = 1, #Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges do
if Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength > dLongestEdgeLength + 10 * GEO.EPS_SMALL then
dLongestEdgeLength = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength
end
end
if dLongestEdgeLength < TOOLS[Milling.ToolInfo.nToolIndex].dDiameter then
Milling.bIsApplicable = false
ParametersMRR = {}
end
end
end
end
table.insert( Machining, Milling)
@@ -272,6 +303,7 @@ local function GetBestPocketingStrategy( Proc, Part)
Milling.bIsApplicable = false
if Proc.Topology.sName ~= 'DoubleBevel-2-Through'
and Proc.Topology.sName ~= 'Pocket-5-Blind'
and Proc.Topology.sFamily ~= 'PseudoPocket'
and Proc.Topology.sName ~= 'RafterNotch-5-Through'
and Proc.Topology.sName ~= 'Groove-4-Blind'
and Proc.Topology.sName ~= 'Bevel-3-Blind' then
@@ -294,6 +326,8 @@ local function GetBestPocketingStrategy( Proc, Part)
Milling.idFaceToMachine = Proc.MainFaces.SideFaces[1].id
Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.SideFaces[1].dElevation
else
ToolSearchParameters.vtToolDirection = nil
end
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.ToolInfo = {}
@@ -303,13 +337,60 @@ local function GetBestPocketingStrategy( Proc, Part)
local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR)
-- se la faccia tunnel è troppo piccola non si lavora
if Milling.bMachAppliedToTunnelFace then
local dLongestEdgeLength = 0
for i = 1, #Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges do
if Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength > dLongestEdgeLength + 10 * GEO.EPS_SMALL then
dLongestEdgeLength = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].Edges[i].dLength
end
end
if dLongestEdgeLength < TOOLS[Milling.ToolInfo.nToolIndex].dDiameter then
Milling.bIsApplicable = false
ParametersMRR = {}
end
end
end
end
table.insert( Machining, Milling)
-- ===== SCELTA LAVORAZIONI =====
-- TODO per DoubleBevel-2-Through si potrebbe lavorare la faccia tunnel su ogni faccia. Bisogna calcolarla!!
-- caso speciale DoubleBevel-2-Through bisogna lavorare entrambe le bottom
if Proc.Topology.sName == 'DoubleBevel-2-Through' then
-- se entrambe applicabili significa che è completo
if Machining[1].bIsApplicable and Machining[2].bIsApplicable then
Machining.sTypeMachining = 'Bottom-Bottom2'
Strategy.Result.sStatus = 'Completed'
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = Machining[1].dMRR + Machining[2].dMRR / 2
Machining[1].ToolInfo.dResidualDepth = 0
Machining[2].ToolInfo.dResidualDepth = 0
return Machining
else
local dMachinedPrercentage = 0
-- se applicabile solo Bottom
if Machining[1].bIsApplicable then
Machining.sTypeMachining = 'Bottom'
Strategy.Result.sStatus = 'Not-Completed'
Machining[1].ToolInfo.dResidualDepth = 0
Strategy.Result.dMRR = Machining[1].dMRR
dMachinedPrercentage = ( Machining[1].dElevation / ( Machining[1].dElevation + Machining[2].dElevation)) * 100
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
-- se applicabile solo Bottom2
elseif Machining[2].bIsApplicable then
Machining.sTypeMachining = 'Bottom2'
Strategy.Result.sStatus = 'Not-Completed'
Machining[2].ToolInfo.dResidualDepth = 0
Strategy.Result.dMRR = Machining[2].dMRR
dMachinedPrercentage = ( Machining[2].dElevation / ( Machining[1].dElevation + Machining[2].dElevation)) * 100
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dMachinedPrercentage)
end
Strategy.Result.sInfo = 'Machining not complete, left ' .. tostring( 100 - ceil( dMachinedPrercentage)) .. '%'
end
return Machining
-- se bottom completa tutto
if Machining[1].bIsApplicable and Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
elseif Machining[1].bIsApplicable and Machining[1].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Machining.sTypeMachining = 'Bottom'
Strategy.Result.sStatus = 'Completed'
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
@@ -321,10 +402,10 @@ local function GetBestPocketingStrategy( Proc, Part)
if ( Proc.nFct == 2 and Proc.AdjacencyMatrix[1][2] >= -89.9)
and Machining[2].bIsApplicable and Machining[2].ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
Machining.sTypeMachining = 'Bottom2'
Machining.sTypeMachining = 'Bottom-Bottom2'
Strategy.Result.sStatus = 'Completed'
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
Strategy.Result.dMRR = Machining[2].dMRR
Strategy.Result.dMRR = Machining[1].dMRR + Machining[2].dMRR / 2
Machining[2].ToolInfo.dResidualDepth = 0
else
Machining[2].bIsApplicable = false
@@ -549,8 +630,8 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
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.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
Pocketing.dResidualDepth = Strategy.Machining[j].ToolInfo.dResidualDepth
-- TODO vedere se questo parametro con svuotature nuove si può rimuovere
@@ -559,11 +640,35 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
if Strategy.Machining[j].bToolInvert then
Pocketing.bToolInvert = true
end
-- eventuali antischeggia
if Strategy.Machining[j].bAddAntiSplint then
local OptionalParametersAntiSplint = {
bIsSplitFeature = ( #vAddId > 1),
dExtendAfterTail = Strategy.Parameters.dExtendAfterTail
}
local AntiSplints = AntiSplintOnFace.Make( Proc, Part, Proc.Faces[ Strategy.Machining[j].idFaceToMachine + 1], OptionalParametersAntiSplint)
local bAreAllAntisplintsApplicable = true
for k = 1, #AntiSplints do
if AntiSplints[k].bIsApplicable then
if bAddMachining then
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, AntiSplints[k])
end
else
bAreAllAntisplintsApplicable = false
end
end
if bAreAllAntisplintsApplicable then
-- TODO qui si dovrà distinguere tra antischeggia di lama e di fresa; al momento è solo di lama
if Strategy.Result.dQuality == FeatureLib.GetStrategyQuality( 'STD') then
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'BEST')
end
end
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}}
Pocketing.vtToolDirection = Strategy.Machining[j].vtFaceNormal
-- TODO controllare parametro danneggiamento ammesso per decidere se spostare dopo taglio seprazione
-- se è aperta sulla coda, dico che deve essere fatta dopo la separazione
if Proc.AffectedFaces.bLeft then
@@ -593,10 +698,10 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
end
if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then
Pocketing.Geometry = {{ nIdTm, k - 1}}
Pocketing.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Pocketing, Part)
Strategy.Result.dTimeToMachine = Strategy.Result.dTimeToMachine + Pocketing.dTimeToMachine
if bAddMachining then
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddMachinings( Proc, Pocketing)
end
+21 -1
View File
@@ -8,6 +8,8 @@
"sValue": "true",
"sDescriptionShort": "Finish with chainsaw if needed",
"sDescriptionLong": "Finish with chainsaw if needed",
"idDescriptionShortMsg": 1000073,
"idDescriptionLongMsg": 1000074,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -17,7 +19,9 @@
"sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "",
"sDescriptionShort": "Extend after tail",
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
"idDescriptionShortMsg": 1000075,
"idDescriptionLongMsg": 1000076,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "false",
"sDescriptionShort": "Force ripping blade",
"sDescriptionLong": "Force the use of ripping blade, designed for cuts parallel to the grain",
"idDescriptionShortMsg": 1000077,
"idDescriptionLongMsg": 1000078,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "true",
"sDescriptionShort": "Not complete with Blade radius imprint left",
"sDescriptionLong": "If the parameter is active, the automatism considers the feature as - not complete - if the blade radius imprint is left",
"idDescriptionShortMsg": 1000079,
"idDescriptionLongMsg": 1000080,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -48,6 +56,8 @@
"sValue": "false",
"sDescriptionShort": "Use Zig-Zag ChainSaw",
"sDescriptionLong": "Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.",
"idDescriptionShortMsg": 1000081,
"idDescriptionLongMsg": 1000082,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -58,6 +68,8 @@
"sValue": "true",
"sDescriptionShort": "Sort by segment",
"sDescriptionLong": "Sort the machinings according to the piece-segment where the machining has inserted",
"idDescriptionShortMsg": 1000083,
"idDescriptionLongMsg": 1000084,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -68,6 +80,8 @@
"sValue": "NEVER",
"sDescriptionShort": "Damage next piece",
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
"idDescriptionShortMsg": 1000085,
"idDescriptionLongMsg": 1000086,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -75,18 +89,24 @@
"sValue": "NEVER",
"sDescriptionShort": "Never damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000087,
"idDescriptionLongMsg": 1000088,
"sMessageId": ""
},
{
"sValue": "ONLY_IF_RAWPART",
"sDescriptionShort": "Damage only if raw",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000089,
"idDescriptionLongMsg": 1000090,
"sMessageId": ""
},
{
"sValue": "ALWAYS",
"sDescriptionShort": "Can damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000091,
"idDescriptionLongMsg": 1000092,
"sMessageId": ""
}
]
+42 -10
View File
@@ -35,12 +35,19 @@ 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
-- canale ammesso solo se lati paralleli a 2 a 2
elseif Proc.Topology.sName == 'Groove-3-Through'
and ( AreOppositeVectorApprox( Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[1].vtN, Proc.MainFaces.BottomFaces[1].MainEdges.LongEdges[2].vtN)) then
return true
else
return false
end
end
@@ -188,6 +195,17 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
Blade.Result = {}
Chainsaw.Result = {}
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
-- TODO riuniure a IsTopologyOk?
if not Proc.MainFaces
or not Proc.MainFaces.LongFaces[1]
or not Proc.MainFaces.LongFaces[1].MainEdges then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
return false, Strategy.Result
end
if not IsTopologyOk( Proc) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
EgtOutLog( sErr)
@@ -195,13 +213,15 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
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 = FeatureLib.GetStrategyResultNotApplicable( 'Direction')
return false, Strategy.Result
-- se canale e lati non a 90deg la strategia non è applicabile
-- TODO questo è temporaneo finchè non si gestiscono correttamente i lati obliqui per le groove-3-through
-- la dPocketHeight è già gestita, ma va allungato il percorso dove c'è l'angolo > 90
if Proc.Topology.sName == 'Groove-3-Through' then
local BottomFace = Proc.MainFaces.BottomFaces[1]
if abs( BottomFace.Edges[1].vtEdge * BottomFace.Edges[2].vtEdge) > 10 * GEO.EPS_SMALL then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
return false, Strategy.Result
end
end
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0)
@@ -223,6 +243,11 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
local dPocketHeight = 0
if Proc.Topology.sFamily == 'Tunnel' then
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
elseif Proc.Topology.sName == 'Groove-3-Through' then
local BottomFace = Proc.MainFaces.BottomFaces[1]
local frFrame = Frame3d( BottomFace.ptCenter, BottomFace.vtN, BottomFace.MainEdges.LongEdges[1].vtEdge)
local b3BottomFace = EgtSurfTmGetFacetBBoxRef( Proc.id, BottomFace.id, GDB_BB.STANDARD, frFrame)
dPocketHeight = b3BottomFace:getDimY()
else
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
end
@@ -390,7 +415,8 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
end
-- ancora materiale residuo - se possibile si lavora dal lato
if Chainsaw.Result.Bottom[#Chainsaw.Result.Bottom].dResidualDepth > 10 * GEO.EPS_SMALL
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
-- si lavora solamente l'impronta lama sul fondo
@@ -673,7 +699,13 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
else
Strategy.Result.sStatus = 'Not-Completed'
end
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Result)
if Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Pocket-5-Blind' then
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'SEMI')
else
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Result)
end
Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Result)
Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6)
else
+13 -1
View File
@@ -8,6 +8,8 @@
"sValue": "false",
"sDescriptionShort": "Use Zig-Zag ChainSaw",
"sDescriptionLong": "Enable the parameter to set the Zig-Zag movement on the ChainSaw machining. Deactivate it to use One-Way movement.",
"idDescriptionShortMsg": 1000093,
"idDescriptionLongMsg": 1000094,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -17,7 +19,9 @@
"sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "",
"sDescriptionShort": "Extend after tail",
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
"idDescriptionShortMsg": 1000095,
"idDescriptionLongMsg": 1000096,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "NEVER",
"sDescriptionShort": "Damage next piece",
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
"idDescriptionShortMsg": 1000097,
"idDescriptionLongMsg": 1000098,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -35,18 +41,24 @@
"sValue": "NEVER",
"sDescriptionShort": "Never damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000099,
"idDescriptionLongMsg": 1000100,
"sMessageId": ""
},
{
"sValue": "ONLY_IF_RAWPART",
"sDescriptionShort": "Damage only if raw",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000101,
"idDescriptionLongMsg": 1000102,
"sMessageId": ""
},
{
"sValue": "ALWAYS",
"sDescriptionShort": "Can damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000103,
"idDescriptionLongMsg": 1000104,
"sMessageId": ""
}
]
+33 -5
View File
@@ -112,8 +112,6 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
Chainsaw.Result = {}
if not IsTopologyOk( Proc) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
EgtOutLog( sErr)
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
return false, Strategy.Result
end
@@ -134,10 +132,25 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
bIsSplitFeature = true
end
-- se arriva una feature senza MainFaces o MainEdges necessari la strategia non è applicabile
-- TODO riuniure a IsTopologyOk?
if not Proc.MainFaces
or not Proc.MainFaces.LongFaces[1]
or not Proc.MainFaces.LongFaces[1].MainEdges then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
return false, Strategy.Result
end
-- altezza tasca
local dPocketHeight = 0
if Proc.Topology.sFamily == 'Tunnel' then
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength
elseif Proc.Topology.sName == 'Groove-3-Through' then
local BottomFace = Proc.MainFaces.BottomFaces[1]
local frFrame = Frame3d( BottomFace.ptCenter, BottomFace.vtN, BottomFace.MainEdges.LongEdges[1].vtEdge)
local b3BottomFace = EgtSurfTmGetFacetBBoxRef( Proc.id, BottomFace.id, GDB_BB.STANDARD, frFrame)
dPocketHeight = b3BottomFace:getDimY()
else
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
end
@@ -172,13 +185,17 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
and #Proc.MainFaces.SideFaces == 1 then
OptionalParameters.OppositeToolDirectionMode = 'Enabled'
local dLengthAlreadyMachined = 0
if Chainsaw.Result.Bottom[1].bIsApplicable then
dLengthAlreadyMachined = Chainsaw.Result.Bottom[1].dDepthToMachine
end
if BottomEdge.bIsStartOpen then
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters)
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine)
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - dLengthAlreadyMachined)
elseif BottomEdge.bIsEndOpen then
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters)
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine)
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - dLengthAlreadyMachined)
end
Chainsaw.AddResult( Mortising)
@@ -235,10 +252,21 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters)
Chainsaw.AddResult( Mortising)
-- se dal lato OppositeEdge1 non è applicabile (solitamente per finecorsa) si prova dal lato opposto
if not Chainsaw.Result.Opposite[1].bIsApplicable then
OptionalParameters.dDepthToMachine = OppositeEdge2.dElevation + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters)
Chainsaw.AddResult( Mortising)
end
-- se lavorando solo da un lato rimane materiale residuo, si lavora da entrambi
if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL then
if Chainsaw.Result.Opposite[1].dResidualDepth > 10 * GEO.EPS_SMALL
or ( Chainsaw.Result.Opposite[2] and Chainsaw.Result.Opposite[2].dResidualDepth > 10 * GEO.EPS_SMALL) then
Chainsaw.Result.Opposite[1].bIsApplicable = false
if Chainsaw.Result.Opposite[2] then
Chainsaw.Result.Opposite[2].bIsApplicable = false
end
OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN
+31 -1
View File
@@ -8,6 +8,8 @@
"sValue": "false",
"sDescriptionShort": "Force ripping blade",
"sDescriptionLong": "Force the use of ripping blade, designed for cuts parallel to the grain",
"idDescriptionShortMsg": 1000105,
"idDescriptionLongMsg": 1000106,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -17,7 +19,9 @@
"sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "",
"sDescriptionShort": "Extend after tail",
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
"idDescriptionShortMsg": 1000107,
"idDescriptionLongMsg": 1000108,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "NEVER",
"sDescriptionShort": "Damage next piece",
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
"idDescriptionShortMsg": 1000109,
"idDescriptionLongMsg": 1000110,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -35,18 +41,24 @@
"sValue": "NEVER",
"sDescriptionShort": "Never damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000111,
"idDescriptionLongMsg": 1000112,
"sMessageId": ""
},
{
"sValue": "ONLY_IF_RAWPART",
"sDescriptionShort": "Damage only if raw",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000113,
"idDescriptionLongMsg": 1000114,
"sMessageId": ""
},
{
"sValue": "ALWAYS",
"sDescriptionShort": "Can damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000115,
"idDescriptionLongMsg": 1000116,
"sMessageId": ""
}
]
@@ -57,6 +69,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Cutting strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000117,
"idDescriptionLongMsg": 1000118,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -64,18 +78,24 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000119,
"idDescriptionLongMsg": 1000120,
"sMessageId": ""
},
{
"sValue": "DROP_WASTE",
"sDescriptionShort": "Drop waste",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000121,
"idDescriptionLongMsg": 1000122,
"sMessageId": ""
},
{
"sValue": "KEEP_WASTE_ATTACHED",
"sDescriptionShort": "Keep waste attached",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000123,
"idDescriptionLongMsg": 1000124,
"sMessageId": ""
}
]
@@ -86,6 +106,8 @@
"sValue": "false",
"sDescriptionShort": "Disable dicing",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000125,
"idDescriptionLongMsg": 1000126,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -96,6 +118,8 @@
"sValue": "false",
"sDescriptionShort": "Prioritize machining speed over quality",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000127,
"idDescriptionLongMsg": 1000128,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -106,6 +130,8 @@
"sValue": "5",
"sDescriptionShort": "Strip width",
"sDescriptionLong": "In case the waste is still kept attached, this is the wigth dimension of the strip",
"idDescriptionShortMsg": 1000129,
"idDescriptionLongMsg": 1000130,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -116,6 +142,8 @@
"sValue": "true",
"sDescriptionShort": "Clean blade radius with mill",
"sDescriptionLong": "Clean blade radius with mill",
"idDescriptionShortMsg": 1000131,
"idDescriptionLongMsg": 1000132,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -126,6 +154,8 @@
"sValue": "1",
"sDescriptionShort": "Milling offset from side",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000133,
"idDescriptionLongMsg": 1000134,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
+1 -1
View File
@@ -66,7 +66,7 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
local dQualityAddedFace = 0
-- più di 3 facce non supportate
if Proc.nFct > 3 then
if Proc.nFct > 3 and ( not Proc.Topology.sFamily == 'DoubleBevel') then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'More than 3 faces not supported')
end
+18
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on tenon length",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000135,
"idDescriptionLongMsg": 1000136,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on tenon width",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000137,
"idDescriptionLongMsg": 1000138,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "3",
"sDescriptionShort": "Maximum number of milling passes",
"sDescriptionLong": "Maximum number of milling passes. If more passes are required, pocketing is performed",
"idDescriptionShortMsg": 1000139,
"idDescriptionLongMsg": 1000140,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Cutting Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000141,
"idDescriptionLongMsg": 1000142,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -45,24 +53,32 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000143,
"idDescriptionLongMsg": 1000144,
"sMessageId": ""
},
{
"sValue": "BLADE_FORCED",
"sDescriptionShort": "Blade only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000145,
"idDescriptionLongMsg": 1000146,
"sMessageId": ""
},
{
"sValue": "MILL_FORCED",
"sDescriptionShort": "Mill only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000147,
"idDescriptionLongMsg": 1000148,
"sMessageId": ""
},
{
"sValue": "CHAINSAW_FORCED",
"sDescriptionShort": "ChainSaw only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000149,
"idDescriptionLongMsg": 1000150,
"sMessageId": ""
}
]
@@ -73,6 +89,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the tenon",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000151,
"idDescriptionLongMsg": 1000152,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
+24
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on Mortise length",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000153,
"idDescriptionLongMsg": 1000154,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on Mortise width",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000155,
"idDescriptionLongMsg": 1000156,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "3",
"sDescriptionShort": "Maximum number of milling passes",
"sDescriptionLong": "Maximum number of milling passes. If more passes are required, pocketing is performed",
"idDescriptionShortMsg": 1000157,
"idDescriptionLongMsg": 1000158,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "true",
"sDescriptionShort": "Use DoveTail tool in case of pocketing",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000159,
"idDescriptionLongMsg": 1000160,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -48,6 +56,8 @@
"sValue": "true",
"sDescriptionShort": "Add Anti-Splint",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000161,
"idDescriptionLongMsg": 1000162,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -58,6 +68,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Cutting Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000163,
"idDescriptionLongMsg": 1000164,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -65,24 +77,32 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000165,
"idDescriptionLongMsg": 1000166,
"sMessageId": ""
},
{
"sValue": "BLADE_FORCED",
"sDescriptionShort": "Blade only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000167,
"idDescriptionLongMsg": 1000168,
"sMessageId": ""
},
{
"sValue": "MILL_FORCED",
"sDescriptionShort": "Mill only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000169,
"idDescriptionLongMsg": 1000170,
"sMessageId": ""
},
{
"sValue": "CHAINSAW_FORCED",
"sDescriptionShort": "ChainSaw only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000171,
"idDescriptionLongMsg": 1000172,
"sMessageId": ""
}
]
@@ -93,6 +113,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the mortise cut surface",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000173,
"idDescriptionLongMsg": 1000174,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
@@ -104,6 +126,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the dovetail mortise",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000175,
"idDescriptionLongMsg": 1000176,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
+1 -1
View File
@@ -441,7 +441,7 @@ function STR0007.Make( bAddMachining, Proc, Part, CustomParameters)
local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.id, 1, GDB_ID.ROOT)
if ptCutC and vtCutN and AreSameVectorApprox( Proc.FeatureInfo.vtMortiseN, vtCutN) then
-- recupero gruppo per geometria addizionale
local nAddGrpId = Part.idTempGroup
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
Strategy.idMortiseCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, Part.b3Part, GDB_RT.GLOB)
end
end
+18
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on mortise length",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000177,
"idDescriptionLongMsg": 1000178,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial on mortise width",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000179,
"idDescriptionLongMsg": 1000180,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Cutting Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000181,
"idDescriptionLongMsg": 1000182,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -35,24 +41,32 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000183,
"idDescriptionLongMsg": 1000184,
"sMessageId": ""
},
{
"sValue": "BLADE_FORCED",
"sDescriptionShort": "Blade only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000185,
"idDescriptionLongMsg": 1000186,
"sMessageId": ""
},
{
"sValue": "MILL_FORCED",
"sDescriptionShort": "Mill only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000187,
"idDescriptionLongMsg": 1000188,
"sMessageId": ""
},
{
"sValue": "CHAINSAW_FORCED",
"sDescriptionShort": "ChainSaw only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000189,
"idDescriptionLongMsg": 1000190,
"sMessageId": ""
}
]
@@ -63,6 +77,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the mortise cut surface",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000191,
"idDescriptionLongMsg": 1000192,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
@@ -74,6 +90,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the mortise",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000193,
"idDescriptionLongMsg": 1000194,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
+7 -5
View File
@@ -311,11 +311,13 @@ function STR0008.Make( bAddMachining, Proc, Part, CustomParameters)
-- si applicano le lavorazioni di svuotatura
for i = 1, #Strategy.Machining.Pocketing do
if Strategy.Machining.Pocketing[i].bIsApplicable then
Pocketing = {}
Pocketing.Steps = {}
Pocketing.LeadIn = {}
Pocketing.nType = MCH_MY.POCKETING
Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT
Pocketing = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
-- se mortasa aperta su un lato si usa SpiralIn
if ( Proc.AffectedFaces.bFront or Proc.AffectedFaces.bBack) and ( Proc.AffectedFaces.bTop or Proc.AffectedFaces.bBottom) then
Pocketing.nSubType = MCH_POCK_SUB.SPIRALIN
else
Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT
end
Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG
Pocketing.Steps.dStep = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dStep
Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dSideStep
+11 -25
View File
@@ -1,6 +1,6 @@
{
"sStrategyId": "STR0009",
"sStrategyName": "Mill Heading",
"sStrategyName": "ScarfJoint",
"ParameterList" : [
{
"sName": "dDepthChamfer",
@@ -8,46 +8,32 @@
"sValue": "0",
"sDescriptionShort": "Depth Chamfer",
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
"idDescriptionShortMsg": 1000195,
"idDescriptionLongMsg": 1000196,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "dOverMaterial",
"sNameNge": "OVERMAT",
"sValue": "0",
"sDescriptionShort": "Overmaterial",
"sDescriptionLong": "",
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bForceStrip",
"sNameNge": "FORCE_STRIP",
"sName": "bAntiSplint",
"sNameNge": "ANTISPLINT",
"sValue": "false",
"sDescriptionShort": "Force strip",
"sDescriptionLong": "Enable the parameter to force the software to leave a strip to sustain the piece",
"sDescriptionShort": "Use Anti-Splint strategy",
"sDescriptionLong": "The strategy will apply blade cuts on corner to avoid wood splint",
"idDescriptionShortMsg": 1000197,
"idDescriptionLongMsg": 1000198,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "dStripWidth",
"sNameNge": "STRIP_WIDTH",
"sValue": "0",
"sDescriptionShort": "Strip width",
"sDescriptionLong": "Width of the strip in case if foreseen from the machining",
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "sMillingList",
"sNameNge": "PROFILE_TOOL_LIST",
"sValue": "",
"sDescriptionShort": "Available mill to machine the profile",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000199,
"idDescriptionLongMsg": 1000200,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
+178 -199
View File
@@ -1,7 +1,6 @@
-- Strategia: STR0009
-- Descrizione
-- Fresatura di contorno
-- Feature tipo Arco
-- Feature tipo ScarfJoint
-- carico librerie
@@ -10,156 +9,182 @@ local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
-- strategie di base
local BladeToWaste = require('BLADETOWASTE')
local BladeToWaste = require( 'BLADETOWASTE')
local FaceByMill = require( 'FACEBYMILL')
local FaceByBlade = require( 'FACEBYBLADE')
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
-- Tabella per definizione modulo
local STR0009 = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
-- TODO gestire il caso in cui non si trova l'utensile
local function GetArcStrategy( Proc, Part)
local Machining = {}
local ToolSearchParameters = {}
local function GetFacesIdOrder( Proc, Part)
local Faces = {}
if Proc.nFct == 5 then
-- carico gli id delle facce
for i = 1, Proc.nFct do
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
end
elseif Proc.nFct == 4 then
local vtN1 = Proc.Faces[1].vtN
local vtN2 = Proc.Faces[2].vtN
local nIndex = EgtIf( abs( vtN1:getX()) > abs( vtN2:getX()), 1, 2)
for i = nIndex, Proc.nFct do
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
end
-- TODO manca il caso in cui mancano facce 4 e 5
else -- Proc.nFct == 3
for i = 2, Proc.nFct do
Faces[#Faces + 1] = BeamLib.TableCopyDeep( Proc.Faces[i])
end
end
-- recupero e verifico l'entità curva
local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i')
if idAux then idAux = idAux + Proc.id end
if not idAux or ( EgtGetType( idAux) & GDB_FY.GEO_CURVE) == 0 then
local sErr = 'Error on process ' .. tostring( Proc.id) .. ' missing profile geometry'
return Faces
end
-------------------------------------------------------------------------------------------------------------
local function GetEdgeToMachine( ClosingFace, idBottomFace)
local EdgeToMachine
for i = 1, #ClosingFace.Edges do
if ClosingFace.Edges[i].idAdjacentFace == idBottomFace then
EdgeToMachine = ClosingFace.Edges[i]
break
end
end
return EdgeToMachine
end
-------------------------------------------------------------------------------------------------------------
local function GetScarfJointStrategy( Proc, Part)
-- ordino le facce in base al loro numero e al parallelismo delle due facce principali
-- faccia 0: superficie tappo (*potrebbe non esserci)
-- faccia 1: superficie principale di fondo
-- faccia 2: superficie opposta alla faccia 1
-- faccia 3: superficie principale superiore
-- faccia 4: superficie di testa (*potrebbe non esserci)
-- creo una tabella unica contenente tutte le lavorazioni
local Result = {}
local Cutting = { Machinings = {}, Result = {}}
local AntiSplints = {}
local Pocketing = {}
Result.dTimeToMachine = 0
local Faces = GetFacesIdOrder( Proc)
-- taglio su faccia 4
if Faces[4] and Faces[4].vtN then
-- recupero gruppo per geometria addizionale
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
-- TODO la nuova faccia creata sulla 4 può tagliare faccia 1. In caso tagliasse faccia 1, bisogna calcolare i cubetti con 2 facce
Strategy.idFeatureCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, Faces[4].ptCenter, Faces[4].vtN, Part.b3Part, GDB_RT.GLOB)
Cutting.Machinings, Cutting.Result = BladeToWaste.Make( Strategy.idFeatureCutPlane, Part)
if Cutting.Result.sStatus == 'Completed' then
Cutting.Machinings.bIsApplicable = true
end
end
-- antischeggia facce 1 e 3
local bAreAllAntisplintsApplicable = true
if Strategy.Parameters.bAntiSplint then
AntiSplints = AntiSplintOnFace.Make( Proc, Part, Faces[2])
for k = 1, #AntiSplints do
if not AntiSplints[k].bIsApplicable then
bAreAllAntisplintsApplicable = false
break
end
end
end
-- svuotatura faccia 2
if Faces[2] then
local frPock, dL, dW = EgtSurfTmFacetMinAreaRectangle( Proc.id, Faces[2].id, GDB_ID.ROOT)
local ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.vtToolDirection = Faces[2].vtN
ToolSearchParameters.dElevation = abs( ( Faces[2].ptCenter - Faces[4].ptCenter) * Faces[2].vtN)
ToolSearchParameters.dMaxToolDiameter = min( dL, dW)
ToolSearchParameters.ToolInfo = {}
ToolSearchParameters.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if ToolSearchParameters.ToolInfo.nToolIndex then
local Machining = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
Machining.Geometry = {{ Proc.id, Faces[2].id}}
Machining.dElevation = ToolSearchParameters.dElevation
Machining.dMaxElev = Machining.dElevation
Machining.vtToolDirection = ToolSearchParameters.vtToolDirection
Machining.nSubType = MCH_POCK_SUB.SPIRALIN
Machining.LeadIn.nType = MCH_POCK_LI.ZIGZAG
Machining.Steps.dStep = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dStep
Machining.Steps.dSideStep = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dSideStep
Machining.nToolIndex = ToolSearchParameters.ToolInfo.nToolIndex
Machining.LeadIn.dTangentDistance = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dDiameter / 2
Machining.LeadIn.dElevation = TOOLS[ToolSearchParameters.ToolInfo.nToolIndex].dDiameter / 2
Machining.sDepth = 0
Machining.dResidualDepth = ToolSearchParameters.ToolInfo.dResidualDepth
-- TODO vedere se questo parametro con svuotature nuove si può rimuovere
Machining.dOpenMinSafe = Strategy.Parameters.dOpenMinSafe
Machining.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
Result.dTimeToMachine = Result.dTimeToMachine + Machining.dTimeToMachine
table.insert( Pocketing, Machining)
Pocketing.bIsApplicable = true
-- se non sono stati fatti i passaggi antischeggia si verifica che le facce siano a 90°, altrimenti serve passaggio con fresa
if not Strategy.Parameters.bAntiSplint or not bAreAllAntisplintsApplicable then
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] or 0
-- si fa passaggio con fresa
if dAngleBetweenFaces > -90 then
local EdgeToMachine = GetEdgeToMachine( Faces[1], Faces[2].id)
local CuttingClosingFace = FaceByBlade.Make( Proc, Part, Faces[1], EdgeToMachine)
if CuttingClosingFace.bIsApplicable then
table.insert( AntiSplints, CuttingClosingFace)
end
end
end
end
end
-- se manca taglio principale, feature non eseguibile
if not Cutting.Machinings.bIsApplicable then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable'
EgtOutLog( sErr)
return false, sErr
end
Proc.idAddAuxGeom = idAux
-- recupero i dati della curva e del profilo
local dDepth = abs( EgtCurveThickness( idAux))
local vtExtr = EgtCurveExtrusion( idAux, GDB_RT.GLOB)
local bToolInvert = ( vtExtr:getZ() < -0.1)
local bIsHorizontal = abs( vtExtr:getZ()) < 10 * GEO.EPS_SMALL
local bIsFeatureDown = Proc.AffectedFaces.bBottom and not Proc.AffectedFaces.bTop
local bIsFeatureBack = Proc.AffectedFaces.bBack and not Proc.AffectedFaces.bFront
local bForceStrip = Strategy.Parameters.bForceStrip
local dDimStrip = EgtIf( Strategy.Parameters.dStripWidth < 100 * GEO.EPS_SMALL, nil, Strategy.Parameters.dStripWidth)
local bExecStrip = false
-- se la lavorazione si trova nella parte inferiore o in battuta dietro, il codolo va sempre lasciato
if bIsFeatureDown or bIsFeatureBack or bForceStrip then
if bIsFeatureDown or bIsFeatureBack then
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP or 5, 5)
else
dDimStrip = dDimStrip or max( BeamData.DIM_STRIP_SMALL or 5, 1)
end
bExecStrip = true
end
if not bExecStrip then
dDimStrip = 0
end
-- se lavorazione orizzontale
if bIsHorizontal then
local bDouble
local Milling = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
Milling.bIsApplicable = false
ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.dElevation = EgtIf( bExecStrip, ( dDepth - dDimStrip) / 2, dDepth + BeamData.MILL_OVERLAP)
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
-- se posso lavorare in una passata, ma utensile trovato non completa la lavorazione,
-- allora provo a cercare utensile con massimo materiale sufficiente per fare le due passate, magari trova un utensile più prestante
if Milling.ToolInfo.dResidualDepth > 10 * GEO.EPS_SMALL and not bExecStrip then
bDouble = true
ToolSearchParameters.dElevation = ( dDepth + BeamData.MILL_OVERLAP) / 2
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
end
Milling.bToolInvert = bToolInvert
Milling.vtToolDirection = vtExtr
if bDouble or bExecStrip then
if bDouble then
Milling.sDepth = ( dDepth + BeamData.MILL_OVERLAP) / 2
else
Milling.sDepth = ( dDepth - dDimStrip) / 2
end
table.insert( Machining, Milling)
local Milling2 = BeamLib.TableCopyDeep( Milling)
table.insert( Machining, Milling2)
else
Milling.sDepth = dDepth + BeamData.MILL_OVERLAP
table.insert( Machining, Milling)
end
-- se lavorazione verticale
Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
else
-- si cerca utensile 1
local Milling = {}
Milling.bIsApplicable = false
ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, -vtExtr, vtExtr)
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
Milling.ToolInfo = {}
Milling.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
-- si cerca utensile 2
local Milling2 = {}
Milling2.bIsApplicable = false
ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD'
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP
ToolSearchParameters.vtToolDirection = EgtIf( bToolInvert, vtExtr, -vtExtr)
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sMillingList, 'Milling')
Milling2.ToolInfo = {}
Milling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
-- se serve codolo
if bExecStrip then
-- se a disposizione entrambi gli utensili
if Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
table.insert( Machining, Milling)
table.insert( Machining, Milling2)
-- se disponibile solo primo utensile
elseif Milling.ToolInfo.nToolIndex then
table.insert( Machining, Milling)
-- se disponibile solo secondo utensile
elseif Milling2.ToolInfo.nToolIndex then
table.insert( Machining, Milling2)
-- nessun utensile disponibile
local dCompletionPercentage = 100
-- completa se svuotatura eseguita e antisplit eseguiti (o non richiesti)
if Pocketing.bIsApplicable and ( bAreAllAntisplintsApplicable or not Strategy.Parameters.bAntiSplint) then
Result.sStatus = 'Completed'
if bAreAllAntisplintsApplicable then
Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
else
-- non si fa nulla
Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
end
-- altrimenti senza codolo
-- altrimenti non completa
else
-- se utensile 1 esegue completamente
if Milling.ToolInfo.nToolIndex and Milling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
table.insert( Machining, Milling)
-- se utensile 2 esegue completamente
elseif Milling2.ToolInfo.nToolIndex and Milling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
table.insert( Machining, Milling2)
-- se possono lavorare entrambi
elseif Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then
table.insert( Machining, Milling)
table.insert( Machining, Milling2)
-- se utensile 1 non completo
elseif Milling.ToolInfo.nToolIndex then
table.insert( Machining, Milling)
-- se utensile 2 non completo
elseif Milling2.ToolInfo.nToolIndex then
table.insert( Machining, Milling2)
Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
Result.sStatus = 'Not-Completed'
-- se fa solo svuotatura
if Pocketing.bIsApplicable then
dCompletionPercentage = 90
Result.sInfo = 'Anti-Split not executed'
elseif Strategy.Parameters.bAntiSplint and bAreAllAntisplintsApplicable then
dCompletionPercentage = 75
Result.sInfo = 'Pocketing not executed'
else
dCompletionPercentage = 50
Result.sInfo = 'Only the cut has been executed'
end
end
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage)
end
-- TODO VOTO DA FARE!!!!
Strategy.Result.sStatus = 'Completed'
Strategy.Result.dCompletionIndex = 5
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo)
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'MILL')
Strategy.Result.sInfo = ''
-- creo una tabella unica contenente tutte le lavorazioni
local Machinings = {}
EgtJoinTables( Machinings, Cutting.Machinings)
EgtJoinTables( Machinings, AntiSplints)
EgtJoinTables( Machinings, Pocketing)
return Machining
return Machinings, Result
end
-------------------------------------------------------------------------------------------------------------
@@ -173,79 +198,33 @@ function STR0009.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Result = {}
local bAreAllMachiningsAdded = true
local Milling = {}
Strategy.Machinings = GetArcStrategy( Proc, Part)
-- controlli preliminari
if Proc.nFct < 3 or Proc.nFct > 5 then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable'
EgtOutLog( sErr)
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
return false, Strategy.Result
end
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
-- eventuali punti di spezzatura
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
Strategy.Machinings, Strategy.Result = GetScarfJointStrategy( Proc, Part)
for i = 1, #Strategy.Machinings do
Strategy.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}}
Strategy.Machinings[i].nToolIndex = Strategy.Machinings[i].ToolInfo.nToolIndex
Strategy.Machinings[i].nType = MCH_MY.MILLING
Strategy.Machinings[i].dStartSafetyLength = 0
Strategy.Machinings[i].Steps = {}
Strategy.Machinings[i].Steps = MachiningLib.GetMachiningSteps( false, tonumber( Strategy.Machinings[i].sDepth), TOOLS[Strategy.Machinings[i].nToolIndex].dStep)
-- LeadIn / LeadOut
Strategy.Machinings[i].LeadIn = {}
Strategy.Machinings[i].LeadOut = {}
Strategy.Machinings[i].LeadIn.nType = MCH_MILL_LI.TANGENT
Strategy.Machinings[i].LeadOut.nType = MCH_MILL_LI.TANGENT
Strategy.Machinings[i].LeadIn.dTangentDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Machinings[i].LeadIn.dPerpDistance = 0
Strategy.Machinings[i].LeadIn.dStartAddLength = 0
Strategy.Machinings[i].LeadOut.dTangentDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Machinings[i].LeadOut.dPerpDistance = 0
Strategy.Machinings[i].LeadOut.dEndAddLength = 0
local dLengthOnX = Proc.b3Box:getDimX()
Strategy.bCanMoveAfterSplit = MachiningLib.CanMoveAfterSplitcut( dLengthOnX, Part)
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Strategy.Machinings[i].sStage = 'AfterTail'
end
-- preparo attacco/uscita in caso di spezzatura arco
Strategy.Machinings[i].LeadInForSplit = BeamLib.TableCopyDeep( Strategy.Machinings[i].LeadIn)
Strategy.Machinings[i].LeadOutForSplit = BeamLib.TableCopyDeep( Strategy.Machinings[i].LeadOut)
Strategy.Machinings[i].LeadInForSplit.nType = MCH_MILL_LI.LINEAR
Strategy.Machinings[i].LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
Strategy.Machinings[i].LeadInForSplit.dTangentDistance = 0
Strategy.Machinings[i].LeadInForSplit.dPerpDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Machinings[i].LeadOutForSplit.dTangentDistance = 0
Strategy.Machinings[i].LeadOutForSplit.dPerpDistance = TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
-- sistemo il lato e la direzione di lavoro
if i == 1 then
Strategy.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, false, true)
Strategy.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
else
Strategy.Machinings[i].bToolInvert = true
Strategy.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, true, false)
Strategy.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
end
Strategy.Machinings[i].ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Machinings[i].ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Machinings[i].dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
Strategy.Machinings[i].vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Machinings[i].dLengthOnX = Proc.b3Box:getDimX()
local MachiningToSplit = {}
table.insert( MachiningToSplit, Strategy.Machinings[i])
local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part)
-- aggiunta lavorazioni
if #Strategy.Machinings > 0 then
if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
-- aggiunge lavorazione
for j = 1, #MachiningResult do
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j])
for j = 1, #Strategy.Machinings do
if Proc.AffectedFaces.bLeft then
Strategy.Machinings[j].sStage = 'AfterTail'
end
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machinings[j])
end
end
else
bAreAllMachiningsAdded = false
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
end
return bAreAllMachiningsAdded, Strategy.Result
end
+38 -2
View File
@@ -3,11 +3,13 @@
"sStrategyName": "Milling",
"ParameterList" : [
{
"sName": "dAntiSplintWithBlade",
"sName": "bAntiSplintWithBlade",
"sNameNge": "ANTISPLINT_BLADE",
"sValue": "false",
"sDescriptionShort": "Antisplint with blade",
"sDescriptionLong": "Use the blade as antisplint in case the geometry is not through",
"idDescriptionShortMsg": 1000201,
"idDescriptionLongMsg": 1000202,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -17,7 +19,33 @@
"sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "",
"sDescriptionShort": "Extend after tail",
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
"idDescriptionShortMsg": 1000203,
"idDescriptionLongMsg": 1000204,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bFinishWithMill",
"sNameNge": "ALLOW_FINISH_MILL",
"sValue": "true",
"sDescriptionShort": "Clean radius with mill",
"sDescriptionLong": "Clean radius with mill",
"idDescriptionShortMsg": 1000205,
"idDescriptionLongMsg": 1000206,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "dMillingOffsetFromSide",
"sNameNge": "MILLING_OFFSET_SIDE",
"sValue": "1",
"sDescriptionShort": "Milling offset from side",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000207,
"idDescriptionLongMsg": 1000208,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +56,8 @@
"sValue": "NEVER",
"sDescriptionShort": "Damage next piece",
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
"idDescriptionShortMsg": 1000209,
"idDescriptionLongMsg": 1000210,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -35,18 +65,24 @@
"sValue": "NEVER",
"sDescriptionShort": "Never damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000211,
"idDescriptionLongMsg": 1000212,
"sMessageId": ""
},
{
"sValue": "ONLY_IF_RAWPART",
"sDescriptionShort": "Damage only if raw",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000213,
"idDescriptionLongMsg": 1000214,
"sMessageId": ""
},
{
"sValue": "ALWAYS",
"sDescriptionShort": "Can damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000215,
"idDescriptionLongMsg": 1000216,
"sMessageId": ""
}
]
+226 -79
View File
@@ -9,7 +9,9 @@ local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib')
-- strategie di base
local FaceByMill = require('FACEBYMILL')
local FaceByMill = require( 'FACEBYMILL')
local FaceByBlade = require( 'FACEBYBLADE')
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
-- Tabella per definizione modulo
local STR0010 = {}
@@ -34,7 +36,7 @@ local function GetStrategyCompletionPercentage( Machinings)
if nWeightsCount ~= 0 and nWeightsCount ~= i then
error( 'GetWeightedCompletionPercentage : inconsistent weights')
end
local dWeightedCompletionPercentage = Machining.dCompletionPercentage / 100 * dWeight
local dWeightedCompletionPercentage = ( Machining.dCompletionPercentage or 0) / 100 * dWeight
if Machining.bIsApplicable then
dCompletionPercentageNumerator = dCompletionPercentageNumerator + dWeightedCompletionPercentage
end
@@ -47,34 +49,52 @@ local function GetStrategyCompletionPercentage( Machinings)
end
-------------------------------------------------------------------------------------------------------------
local function CompareEdges( EdgeA, EdgeB)
-- prima i lati orientati lungo X
if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then
local function CompareEdgesLongestTop( EdgeA, EdgeB)
-- si preferiscono i lati più lunghi
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
return true
elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
return false
-- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato)
-- se stessa lunghezza si preferiscono i lati più in basso
else
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
return false
-- se stessa lunghezza si preferiscono i lati più in basso
-- TODO qui dipenderà dalla lama scelta
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
else
return false
end
return false
end
end
end
end
-------------------------------------------------------------------------------------------------------------
local function CompareEdgesLongestBottom( EdgeA, EdgeB)
-- si preferiscono i lati più lunghi
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
return false
-- se stessa lunghezza si preferiscono i lati più in alto
else
if EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
return false
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
else
return false
end
end
end
@@ -93,7 +113,7 @@ end
-------------------------------------------------------------------------------------------------------------
-- TODO modificare funzione e verificare pinzaggio con regioni e area outline
local function IsPositionOK( Proc, Part)
local function IsPositionOk( Proc, Part)
local bIsFeatureLong = FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
-- se impatta su faccia retro o sotto, controllo fattibilità
if Proc.AffectedFaces.bBack then
@@ -112,31 +132,24 @@ local function IsPositionOK( Proc, Part)
end
-------------------------------------------------------------------------------------------------------------
-- TODO da sistemare
local function GetBottomFaceEdge( Proc, nIndexFace)
local function GetLongEdgeToMachine( Face, bHeadType)
local Edge = {}
-- si lavora la bottom longitudinalmente
if Proc.nFct == 1 or Proc.Topology.sFamily == 'DoubleBevel' then
local BottomEdgesSorted = {}
for i = 1, #Proc.MainFaces.BottomFaces[nIndexFace].Edges do
table.insert( BottomEdgesSorted, Proc.MainFaces.BottomFaces[nIndexFace].Edges[i])
end
table.sort( BottomEdgesSorted, CompareEdges)
Edge = BottomEdgesSorted[1]
-- edge in comune tra le due facce
elseif Proc.nFct == 2 then
if nIndexFace == 1 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1]
elseif nIndexFace == 2 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge
end
local EdgesSorted = {}
for i = 1, #Face.Edges do
table.insert( EdgesSorted, Face.Edges[i])
end
if bHeadType.bBottom then
table.sort( EdgesSorted, CompareEdgesLongestBottom)
else
if nIndexFace == 1 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1]
elseif nIndexFace == 2 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge
end
table.sort( EdgesSorted, CompareEdgesLongestTop)
end
-- se il lato migliore è accessibile si sceglie questo, altrimenti il lato opposto; se entrambi non accessibili (faccia chiusa da due lati) si mantiene il lato scelto
Edge = EdgesSorted[1]
local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN)
if ( not EdgeOpposite.bIsOpen) and Edge.bIsOpen then
Edge = EdgeOpposite
end
return Edge
@@ -148,15 +161,28 @@ local function SortMachiningsBySegment( MachiningA, MachiningB)
return false
elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then
return true
-- se segmento uguale, si guarda la priorità
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
if MachiningA.nInternalSortingPriority > MachiningB.nInternalSortingPriority then
return false
elseif MachiningB.nInternalSortingPriority > MachiningA.nInternalSortingPriority then
return true
-- se priorità uguale, si minimizzano i cambi di lato
else
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then
return true
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' then
local bIsOddSegment = ( MachiningA.nFeatureSegment % 2 ~= 0)
if MachiningA.vtToolDirection:getY() < MachiningB.vtToolDirection:getY() - 10 * GEO.EPS_SMALL then
if bIsOddSegment then
return true
else
return false
end
elseif MachiningA.vtToolDirection:getY() > MachiningB.vtToolDirection:getY() + 10 * GEO.EPS_SMALL then
if bIsOddSegment then
return false
else
return true
end
else
return false
end
end
@@ -172,6 +198,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config)
Strategy.Machinings = {}
Strategy.Result = {}
local CalculatedMachinings = {}
-- controllo su topologia
if not IsTopologyOk( Proc) then
@@ -181,7 +208,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
-- controllo dimensioni solo se non è forzata
if not CustomParameters.bForcedStrategy then
if not IsPositionOK( Proc, Part) then
if not IsPositionOk( Proc, Part) then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Feature not machinable in this position')
return false, Strategy.Result
end
@@ -198,8 +225,6 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
-- volume della feature
local dFeatureVolume = Proc.dVolume
-- TODO taglio su eventuali facce di chiusura
-- eventuali punti di spezzatura
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
local bIsSplitFeature = false
@@ -212,45 +237,167 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
dExtendAfterTail = 10000
end
-- lavorazione della BottomFace
local bAreAllMachiningsAdded = true
local Milling = {}
local OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
local EdgeToMachine = GetBottomFaceEdge( Proc, 1)
if EdgeToMachine.bIsOpen then
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
end
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[1], EdgeToMachine, OptionalParametersFaceByMill)
if Milling.bIsApplicable then
table.insert( Strategy.Machinings, Milling)
-- ricerca delle Bottom (la principale deve avere 4 lati esatti)
local BottomFace1 = Proc.MainFaces.BottomFaces[1]
local BottomFace2 = Proc.MainFaces.BottomFaces[2]
if #BottomFace1.Edges ~= 4 then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
return false, Strategy.Result
end
-- si lavora seconda BottomFace
if Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' then
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2]
-- se convesso o concavo maggiore di angolo retto
if dAngleBetweenFaces >= -91 then
Milling = {}
OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
EdgeToMachine = GetBottomFaceEdge( Proc, 2)
if EdgeToMachine.bIsOpen then
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
-- ricerca utensile
local ToolSearchParameters = {}
ToolSearchParameters.dElevation = BottomFace1.dElevation
ToolSearchParameters.vtToolDirection = BottomFace1.vtN
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = true
ToolSearchParameters.sMillShape = 'STANDARD'
local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
local nToolIndex = ToolInfo.nToolIndex
-- se utensile non trovato si esce subito
if not TOOLS[nToolIndex] or not TOOLS[nToolIndex].sName then
local sMessage = 'Mill not found'
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sMessage)
return false, Strategy.Result
end
-- per prima si lavora sempre la Bottom principale
local Milling1 = {}
local OptionalParametersMilling1 = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
local BottomEdgeToMachine1 = GetLongEdgeToMachine( BottomFace1, TOOLS[nToolIndex].SetupInfo.HeadType)
if BottomEdgeToMachine1.bIsOpen then
OptionalParametersMilling1.dDepthToMachine = BottomEdgeToMachine1.dElevation + BeamData.CUT_EXTRA
end
Milling1 = FaceByMill.Make( Proc, Part, BottomFace1, BottomEdgeToMachine1, OptionalParametersMilling1)
Milling1.nInternalSortingPriority = 2
Milling1.dResultWeight = 0.3
table.insert( CalculatedMachinings, Milling1)
-- se necessario si lavora la seconda Bottom (solo se ha 4 lati esatti)
local Milling2
local BottomEdgeToMachine2
if BottomFace2 then
local dAngleBetweenFaces = Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1]
if dAngleBetweenFaces >= -89.5 then
Milling2 = {}
if #BottomFace2.Edges == 4 then
local OptionalParametersMilling2 = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, TOOLS[nToolIndex].SetupInfo.HeadType)
if BottomEdgeToMachine2.bIsOpen then
OptionalParametersMilling2.dDepthToMachine = BottomEdgeToMachine2.dElevation + BeamData.CUT_EXTRA
end
Milling2 = FaceByMill.Make( Proc, Part, BottomFace2, BottomEdgeToMachine2, OptionalParametersMilling2)
Milling2.nInternalSortingPriority = 2
Milling2.dResultWeight = 0.3
else
Milling2.bIsApplicable = false
end
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[2], EdgeToMachine, OptionalParametersFaceByMill)
if Milling.bIsApplicable then
table.insert( Strategy.Machinings, Milling)
table.insert( CalculatedMachinings, Milling2)
end
end
-- fresatura eventuali facce di chiusura (se non già lavorate)
-- TODO funzione
if Strategy.Parameters.bFinishWithMill then
if Milling1 then
-- si recuperano i lati chiusi non lavorati
local EdgesClosedNotMachined = {}
for i = 1, #BottomFace1.Edges do
if not( ( BottomFace1.Edges[i].id == BottomEdgeToMachine1.id) or BottomFace1.Edges[i].bIsOpen) then
table.insert( EdgesClosedNotMachined, BottomFace1.Edges[i])
end
end
-- su ognuno si fa la fresatura di pulizia
for i = 1, #EdgesClosedNotMachined do
local dMillingOffsetFromSide = Strategy.Parameters.bAntiSplintWithBlade and Strategy.Parameters.dMillingOffsetFromSide or 0
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
local dToolMarkLength = Milling1.dToolMarkLength or 0
local OptionalParameters = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
dRadialStepSpan = dToolMarkLength,
dDepthToMachine = dDepthToMachine
}
local Milling = FaceByMill.Make( Proc, Part, BottomFace1, EdgesClosedNotMachined[i], OptionalParameters)
Milling.nInternalSortingPriority = 3
Milling.dResultWeight = 0.05
table.insert( CalculatedMachinings, Milling)
end
end
if Milling2 then
-- si recuperano i lati chiusi non lavorati
local EdgesClosedNotMachined = {}
for i = 1, #BottomFace2.Edges do
if not( ( BottomFace2.Edges[i].id == BottomEdgeToMachine2.id) or BottomFace2.Edges[i].bIsOpen) then
table.insert( EdgesClosedNotMachined, BottomFace2.Edges[i])
end
end
-- su ognuno si fa la fresatura di pulizia
for i = 1, #EdgesClosedNotMachined do
local dMillingOffsetFromSide = Strategy.Parameters.bAntiSplintWithBlade and Strategy.Parameters.dMillingOffsetFromSide or 0
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
local dToolMarkLength = Milling2.dToolMarkLength or 0
local OptionalParameters = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
dRadialStepSpan = dToolMarkLength,
dDepthToMachine = dDepthToMachine
}
local Milling = FaceByMill.Make( Proc, Part, BottomFace2, EdgesClosedNotMachined[i], OptionalParameters)
Milling.nInternalSortingPriority = 3
Milling.dResultWeight = 0.05
table.insert( CalculatedMachinings, Milling)
end
end
end
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili
Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( Strategy.Machinings)
-- antischeggia sulle facce di chiusura delle facce lavorate
local CalculatedMachiningsNoAntisplint = BeamLib.TableCopyDeep( CalculatedMachinings)
if Strategy.Parameters.bAntiSplintWithBlade then
local OptionalParametersAntiSplint = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
nInternalSortingPriority = 1,
dResultWeight = 0.15
}
local AntiSplints1 = AntiSplintOnFace.Make( Proc, Part, BottomFace1, OptionalParametersAntiSplint)
for i = 1, #AntiSplints1 do
table.insert( CalculatedMachinings, AntiSplints1[i])
end
if Milling2 then
local AntiSplints2 = AntiSplintOnFace.Make( Proc, Part, BottomFace2, OptionalParametersAntiSplint)
for i = 1, #AntiSplints2 do
table.insert( CalculatedMachinings, AntiSplints2[i])
end
end
end
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili, ma non gli antischeggia (quelle alzano la qualità e sono già contemplate)
Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( CalculatedMachiningsNoAntisplint)
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( Strategy.Result.dCompletionPercentage)
-- lavorazioni da applicare spostate in lista finale
for i = 1, #CalculatedMachinings do
if CalculatedMachinings[i].bIsApplicable then
table.insert( Strategy.Machinings, CalculatedMachinings[i])
end
end
Strategy.Machinings = MachiningLib.GetSplitMachinings( Strategy.Machinings, FeatureSplittingPoints, Part)
table.sort( Strategy.Machinings, SortMachiningsBySegment)
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Strategy.Machinings)
-- se non ci sono lati chiusi, la qualità è migliore
if Proc.Topology.sName == 'Bevel-1-Through' or Proc.Topology.sName == 'DoubleBevel-2-Through' or Proc.Topology.sName == 'Cut-1-Through' then
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
else
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( Strategy.Machinings)
end
Strategy.Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Strategy.Machinings)
Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6)
if Strategy.Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
+14
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Tolerance on Diameter",
"sDescriptionLong": "Tolerance on Diameter",
"idDescriptionShortMsg": 1000217,
"idDescriptionLongMsg": 1000218,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "0",
"sDescriptionShort": "Depth PreHole",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000219,
"idDescriptionLongMsg": 1000220,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Drilling Mode",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000221,
"idDescriptionLongMsg": 1000222,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -35,18 +41,24 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000223,
"idDescriptionLongMsg": 1000224,
"sMessageId": ""
},
{
"sValue": "PREFER_ONE",
"sDescriptionShort": "Preferred machining from one side only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000225,
"idDescriptionLongMsg": 1000226,
"sMessageId": ""
},
{
"sValue": "FORCE_TWO",
"sDescriptionShort": "Force machining from two sides",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000227,
"idDescriptionLongMsg": 1000228,
"sMessageId": ""
}
]
@@ -57,6 +69,8 @@
"sValue": "",
"sDescriptionShort": "Available Drillbit list",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000229,
"idDescriptionLongMsg": 1000230,
"sType": "tool",
"sSubType": "MCH_TF.DRILLBIT",
"sMessageId": " ",
+23
View File
@@ -16,6 +16,27 @@ local Strategy = {}
-- TODO Da fare completamente gestione foratura doppia con 2 teste
-------------------------------------------------------------------------------------------------------------
local function GetSCC( vtMachiningDirection)
-- TODO implementare SCC come per FacesBySaw
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
-------------------------------------------------------------------------------------------------------------
local function GetDrillingStrategy( Proc, Part)
local ToolSearchParameters = {}
@@ -39,6 +60,7 @@ local function GetDrillingStrategy( Proc, Part)
Drilling.nToolIndex = Drilling.ToolInfo.nToolIndex
Drilling.vtToolDirection = Proc.FeatureInfo.vtDrillExtrusion
Drilling.dStep = TOOLS[Drilling.nToolIndex].dStep
Drilling.nSCC = GetSCC( -Drilling.vtToolDirection)
end
-- TODO se utensile 2 che si torverà è il gemello da usare nelle lavorazioni in doppio, allora gestire di conseguenza l'applicazione delle lavorazioni in doppio
@@ -61,6 +83,7 @@ local function GetDrillingStrategy( Proc, Part)
Drilling2.bInvert = true
Drilling2.vtToolDirection = -Proc.FeatureInfo.vtDrillExtrusion
Drilling2.dStep = TOOLS[Drilling2.nToolIndex].dStep
Drilling2.nSCC = GetSCC( -Drilling2.vtToolDirection)
end
end
+19 -1
View File
@@ -7,7 +7,9 @@
"sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "",
"sDescriptionShort": "Extend after tail",
"sDescriptionLong": "The automatism considers this lenght as machinable. This means you accept to damage the next piece in the bar",
"sDescriptionLong": "The automatism considers this length as machinable. This means you accept to damage the next piece in the bar",
"idDescriptionShortMsg": 1000231,
"idDescriptionLongMsg": 1000232,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "NEVER",
"sDescriptionShort": "Damage next piece",
"sDescriptionLong": "This option allows you to decide how to consider the next piece in the bar. The software calculates specifics LeadIn/out to respect the parameter. This parameter may change the machining time",
"idDescriptionShortMsg": 1000233,
"idDescriptionLongMsg": 1000234,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -25,18 +29,24 @@
"sValue": "NEVER",
"sDescriptionShort": "Never damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000235,
"idDescriptionLongMsg": 1000236,
"sMessageId": ""
},
{
"sValue": "ONLY_IF_RAWPART",
"sDescriptionShort": "Damage only if raw",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000237,
"idDescriptionLongMsg": 1000238,
"sMessageId": ""
},
{
"sValue": "ALWAYS",
"sDescriptionShort": "Can damage",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000239,
"idDescriptionLongMsg": 1000240,
"sMessageId": ""
}
]
@@ -47,6 +57,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Ridge Lap strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000241,
"idDescriptionLongMsg": 1000242,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -54,18 +66,24 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000243,
"idDescriptionLongMsg": 1000244,
"sMessageId": ""
},
{
"sValue": "BLADE",
"sDescriptionShort": "Use blade",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000245,
"idDescriptionLongMsg": 1000246,
"sMessageId": ""
},
{
"sValue": "MILL",
"sDescriptionShort": "Use mill",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000247,
"idDescriptionLongMsg": 1000248,
"sMessageId": ""
}
]
+16
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Tolerance on Diameter",
"sDescriptionLong": "Tolerance on Diameter",
"idDescriptionShortMsg": 1000249,
"idDescriptionLongMsg": 1000250,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "0",
"sDescriptionShort": "Use mill as a drillbit",
"sDescriptionLong": "Admit to use the mill as a drillbit",
"idDescriptionShortMsg": 1000251,
"idDescriptionLongMsg": 1000252,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "0",
"sDescriptionShort": "Execute contour only",
"sDescriptionLong": "Execute the contour anyway, even the hole is bigger than the tool diameter",
"idDescriptionShortMsg": 1000253,
"idDescriptionLongMsg": 1000254,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Drilling mode",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000255,
"idDescriptionLongMsg": 1000256,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -45,18 +53,24 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000257,
"idDescriptionLongMsg": 1000258,
"sMessageId": ""
},
{
"sValue": "PREFER_ONE",
"sDescriptionShort": "Preferred machining from one side only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000259,
"idDescriptionLongMsg": 1000260,
"sMessageId": ""
},
{
"sValue": "FORCE_TWO",
"sDescriptionShort": "Force machining from two sides",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000261,
"idDescriptionLongMsg": 1000262,
"sMessageId": ""
}
]
@@ -67,6 +81,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine drills",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000263,
"idDescriptionLongMsg": 1000264,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
+25 -1
View File
@@ -14,6 +14,27 @@ local FeatureLib = require( 'FeatureLib')
local STR0013 = {}
local Strategy = {}
-------------------------------------------------------------------------------------------------------------
local function GetSCC( vtMachiningDirection)
-- TODO implementare SCC come per FacesBySaw
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
-------------------------------------------------------------------------------------------------------------
local function GetDrillingWithMillStrategy( Proc, Part)
local ToolSearchParameters = {}
@@ -74,7 +95,7 @@ local function GetDrillingWithMillStrategy( Proc, Part)
HalfMilling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
-- se entrambi gli utensili lavorano in modo completo fino alla metà del foro, li sostituisco a qeulli trovati in precedenza
if HalfMilling.ToolInfo.dResidualDepth < 0 and HalfMilling2.ToolInfo.dResidualDepth < 0 then
if HalfMilling.ToolInfo.dResidualDepth and HalfMilling2.ToolInfo.dResidualDepth and HalfMilling.ToolInfo.dResidualDepth < 0 and HalfMilling2.ToolInfo.dResidualDepth < 0 then
if Milling.ToolInfo.nToolIndex ~= HalfMilling.ToolInfo.nToolIndex then
Milling.ToolInfo.nToolIndex, Milling.ToolInfo.dResidualDepth = HalfMilling.ToolInfo.nToolIndex, HalfMilling.ToolInfo.dResidualDepth
end
@@ -172,6 +193,7 @@ function STR0013.Make( bAddMachining, Proc, Part, CustomParameters)
MachiningToAdd = MachiningLib.InitMachiningParameters( MCH_MY.DRILLING)
MachiningToAdd = BeamLib.MergeTables( MachiningToAdd, Strategy.Machinings[j])
MachiningToAdd.Steps.dStep = TOOLS[nIndexTool].dStep / 3
MachiningToAdd.nSCC = GetSCC( -MachiningToAdd.vtToolDirection)
-- se diametro foro più grande della fresa, ma non oltre il doppio del diametro, si fa contornatura a spirale
elseif Proc.FeatureInfo.dDrillDiam < ( TOOLS[nIndexTool].dDiameter * 0.75) * 2 or Strategy.Parameters.bOnlyContouring then
MachiningToAdd = MachiningLib.InitMachiningParameters( MCH_MY.MILLING)
@@ -184,6 +206,7 @@ function STR0013.Make( bAddMachining, Proc, Part, CustomParameters)
MachiningToAdd.LeadOut.dTangentDistance = 0.5
MachiningToAdd.LeadOut.dPerpDistance = 0.5
MachiningToAdd.LeadOut.dElevation = Proc.FeatureInfo.dDrillLen
MachiningToAdd.nSCC = GetSCC( -MachiningToAdd.vtToolDirection)
-- se diametro foro più grande del doppio del diametro fresa, si fa svuotatura
else
MachiningToAdd = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
@@ -194,6 +217,7 @@ function STR0013.Make( bAddMachining, Proc, Part, CustomParameters)
MachiningToAdd.LeadIn.nType = MCH_POCK_LI.HELIX
MachiningToAdd.LeadIn.dTangentDistance = TOOLS[nIndexTool].dDiameter / 2
MachiningToAdd.LeadIn.dElevation = MachiningToAdd.Steps.dStep / 2
MachiningToAdd.nSCC = GetSCC( -MachiningToAdd.vtToolDirection)
end
MachiningToAdd.nToolIndex = nIndexTool
+12
View File
@@ -8,6 +8,8 @@
"sValue": "1",
"sDescriptionShort": "Machining Depth",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000265,
"idDescriptionLongMsg": 1000266,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine mark and text",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000267,
"idDescriptionLongMsg": 1000268,
"sType": "tool",
"sSubType": "MCH_TF.MILL",
"sMessageId": " ",
@@ -29,6 +33,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Marking Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000269,
"idDescriptionLongMsg": 1000270,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -36,18 +42,24 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000271,
"idDescriptionLongMsg": 1000272,
"sMessageId": ""
},
{
"sValue": "PEN_FORCED",
"sDescriptionShort": "Pen only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000273,
"idDescriptionLongMsg": 1000274,
"sMessageId": ""
},
{
"sValue": "VMILL_FORCED",
"sDescriptionShort": "V-Mill only",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000275,
"idDescriptionLongMsg": 1000276,
"sMessageId": ""
}
]
+16 -2
View File
@@ -24,6 +24,8 @@ local function GetSCC( Machining)
if TOOLS[Machining.nToolIndex].SetupInfo.bToolOnAggregate then
nSCC = MCH_SCC.ADIR_NEAR
elseif TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC then
nSCC = TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC
elseif Machining.vtToolDirection:getY() <= 0 then
nSCC = MCH_SCC.ADIR_YM
else
@@ -96,7 +98,7 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Machining.nSCC = GetSCC( Strategy.Machining)
Strategy.Machining.nType = MCH_MY.MILLING
Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, 5)
Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, TOOLS[Strategy.Machining.nToolIndex].dMaxMaterial)
Strategy.Machining.nWorkside = MCH_MILL_WS.CENTER
-- LeadIn / LeadOut
@@ -104,12 +106,24 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Machining.LeadOut = {}
Strategy.Machining.LeadIn.nType = MCH_MILL_LI.NONE
Strategy.Machining.LeadOut.nType = MCH_MILL_LI.NONE
-- se è una penna, si limita la lavorazione per evitare di partire fuori dal grezzo
if ToolSearchParameters.sMillShape == 'PEN' then
Strategy.Machining.LeadIn.dStartAddLength = -20
Strategy.Machining.LeadOut.dEndAddLength = -20
end
-- TODO gestire meglio
-- se utensile montato su aggregato flottante
if TOOLS[Strategy.Machining.nToolIndex].bToolOnFloatingTH then
Strategy.Machining.dMaxElev = Strategy.Parameters.dMachiningDepth
Strategy.Machining.dLongitudinalOffset = -5
end
-- stessi parametri cambia solo al geometria
for i = 1, #Proc.FeatureInfo.AdditionalGeometries do
local AuxId = Proc.id + Proc.FeatureInfo.AdditionalGeometries[i]
Strategy.AuxiliaryData.Clones[i+1] = {}
Strategy.AuxiliaryData.Clones[i+1].Geometry = EgtSetMachiningGeometry( {{ AuxId, -1}})
Strategy.AuxiliaryData.Clones[i+1].Geometry = {{ AuxId, -1}}
end
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining, Strategy.AuxiliaryData)
+26
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Depth Chamfer",
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
"idDescriptionShortMsg": 1000277,
"idDescriptionLongMsg": 1000278,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "false",
"sDescriptionShort": "Only Chamfer",
"sDescriptionLong": "Execute the chamfer only, no other machining",
"idDescriptionShortMsg": 1000279,
"idDescriptionLongMsg": 1000280,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "0",
"sDescriptionShort": "Overmaterial",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000281,
"idDescriptionLongMsg": 1000282,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "15",
"sDescriptionShort": "Max radius left on corners",
"sDescriptionLong": "Radius-limit left by the tool at each corner of the feature",
"idDescriptionShortMsg": 1000283,
"idDescriptionLongMsg": 1000284,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -48,6 +56,8 @@
"sValue": "true",
"sDescriptionShort": "Execute cut to remove material",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000285,
"idDescriptionLongMsg": 1000286,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -58,6 +68,8 @@
"sValue": "false",
"sDescriptionShort": "Force strip",
"sDescriptionLong": "Enable the parameter to force the software to leave a strip to sustain the piece",
"idDescriptionShortMsg": 1000287,
"idDescriptionLongMsg": 1000288,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -68,6 +80,8 @@
"sValue": "0",
"sDescriptionShort": "Strip width",
"sDescriptionLong": "Width of the strip in case if foreseen from the machining",
"idDescriptionShortMsg": 1000289,
"idDescriptionLongMsg": 1000290,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -78,6 +92,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Cutting Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000291,
"idDescriptionLongMsg": 1000292,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -85,24 +101,32 @@
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000293,
"idDescriptionLongMsg": 1000294,
"sMessageId": ""
},
{
"sValue": "NONE",
"sDescriptionShort": "No machining",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000295,
"idDescriptionLongMsg": 1000296,
"sMessageId": ""
},
{
"sValue": "BLADE_FORCED",
"sDescriptionShort": "Blade forced",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000297,
"idDescriptionLongMsg": 1000298,
"sMessageId": ""
},
{
"sValue": "MILL_FORCED",
"sDescriptionShort": "Mill forced",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000299,
"idDescriptionLongMsg": 1000300,
"sMessageId": ""
}
]
@@ -113,6 +137,8 @@
"sValue": "",
"sDescriptionShort": "Available mill to machine the profile",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000301,
"idDescriptionLongMsg": 1000302,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
+52 -34
View File
@@ -704,6 +704,21 @@ local function GetFeatureResult( Proc)
return Result
end
-------------------------------------------------------------------------------------------------------------
local function GetSCC( Proc, vtToolDirection)
local nSCC = MCH_SCC.NONE
if Proc.AffectedFaces.bRight and not Proc.AffectedFaces.bLeft then
nSCC = MCH_SCC.ADIR_XP
elseif Proc.AffectedFaces.bLeft and not Proc.AffectedFaces.bRight then
nSCC = MCH_SCC.ADIR_XM
elseif vtToolDirection and AreSameOrOppositeVectorApprox( vtToolDirection, Z_AX()) then
nSCC = MCH_SCC.ADIR_YP
end
return nSCC
end
-------------------------------------------------------------------------------------------------------------
function STR0015.Make( bAddMachining, Proc, Part, CustomParameters)
-- carico parametri de default e li aggiorno con quelli passati dal chiamante (potrebbero non essere congruenti)
@@ -814,53 +829,56 @@ function STR0015.Make( bAddMachining, Proc, Part, CustomParameters)
if Strategy.Profile.Machinings then
for i = 1, #Strategy.Profile.Machinings do
Strategy.Profile.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}}
Strategy.Profile.Machinings[i].nToolIndex = Strategy.Profile.Machinings[i].ToolInfo.nToolIndex
Strategy.Profile.Machinings[i].nType = MCH_MY.MILLING
Strategy.Profile.Machinings[i].Steps = MachiningLib.GetMachiningSteps( false, tonumber( Strategy.Profile.Machinings[i].sDepth), TOOLS[Strategy.Profile.Machinings[i].nToolIndex].dStep)
Strategy.Profile.Machinings[i].Steps.nStepType = MCH_MILL_ST.ONEWAY
local CurrentMachining = Strategy.Profile.Machinings[i]
CurrentMachining.Geometry = {{ Proc.idAddAuxGeom, -1}}
CurrentMachining.nToolIndex = CurrentMachining.ToolInfo.nToolIndex
CurrentMachining.nType = MCH_MY.MILLING
CurrentMachining.Steps = MachiningLib.GetMachiningSteps( false, tonumber( CurrentMachining.sDepth), TOOLS[CurrentMachining.nToolIndex].dStep)
CurrentMachining.Steps.nStepType = MCH_MILL_ST.ONEWAY
CurrentMachining.nSCC = GetSCC( Proc, CurrentMachining.vtToolDirection)
-- LeadIn / LeadOut
Strategy.Profile.Machinings[i].LeadIn.nType = MCH_MILL_LI.TANGENT
Strategy.Profile.Machinings[i].LeadOut.nType = MCH_MILL_LI.TANGENT
Strategy.Profile.Machinings[i].LeadIn.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Profile.Machinings[i].LeadIn.dPerpDistance = 0
Strategy.Profile.Machinings[i].LeadIn.dStartAddLength = 0
Strategy.Profile.Machinings[i].LeadOut.dTangentDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Profile.Machinings[i].LeadOut.dPerpDistance = 0
Strategy.Profile.Machinings[i].LeadOut.dEndAddLength = 0
CurrentMachining.LeadIn.nType = MCH_MILL_LI.TANGENT
CurrentMachining.LeadOut.nType = MCH_MILL_LI.TANGENT
CurrentMachining.LeadIn.dTangentDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
CurrentMachining.LeadIn.dPerpDistance = 0
CurrentMachining.LeadIn.dStartAddLength = 0
CurrentMachining.LeadOut.dTangentDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
CurrentMachining.LeadOut.dPerpDistance = 0
CurrentMachining.LeadOut.dEndAddLength = 0
if Proc.AffectedFaces.bLeft and Strategy.bCanMoveAfterSplit then
Strategy.Profile.Machinings[i].sStage = 'AfterTail'
CurrentMachining.sStage = 'AfterTail'
end
-- preparo attacco/uscita in caso di spezzatura arco
Strategy.Profile.Machinings[i].LeadInForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadIn)
Strategy.Profile.Machinings[i].LeadOutForSplit = BeamLib.TableCopyDeep( Strategy.Profile.Machinings[i].LeadOut)
Strategy.Profile.Machinings[i].LeadInForSplit.nType = MCH_MILL_LI.LINEAR
Strategy.Profile.Machinings[i].LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
Strategy.Profile.Machinings[i].LeadInForSplit.dTangentDistance = 0
Strategy.Profile.Machinings[i].LeadInForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
Strategy.Profile.Machinings[i].LeadOutForSplit.dTangentDistance = 0
Strategy.Profile.Machinings[i].LeadOutForSplit.dPerpDistance = TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
CurrentMachining.LeadInForSplit = BeamLib.TableCopyDeep( CurrentMachining.LeadIn)
CurrentMachining.LeadOutForSplit = BeamLib.TableCopyDeep( CurrentMachining.LeadOut)
CurrentMachining.LeadInForSplit.nType = MCH_MILL_LI.LINEAR
CurrentMachining.LeadOutForSplit.nType = MCH_MILL_LI.LINEAR
CurrentMachining.LeadInForSplit.dTangentDistance = 0
CurrentMachining.LeadInForSplit.dPerpDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
CurrentMachining.LeadOutForSplit.dTangentDistance = 0
CurrentMachining.LeadOutForSplit.dPerpDistance = TOOLS[CurrentMachining.ToolInfo.nToolIndex].dDiameter / 2 + BeamData.COLL_SIC
-- sistemo il lato e la direzione di lavoro
if Strategy.Profile.Machinings[i].bOtherDirection then
Strategy.Profile.Machinings[i].bToolInvert = true
Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, true, false)
Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
if CurrentMachining.bOtherDirection then
CurrentMachining.bToolInvert = true
CurrentMachining.bInvert = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, true, false)
CurrentMachining.nWorkside = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
else
Strategy.Profile.Machinings[i].bInvert = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, false, true)
Strategy.Profile.Machinings[i].nWorkside = EgtIf( TOOLS[Strategy.Profile.Machinings[i].ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
CurrentMachining.bInvert = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, false, true)
CurrentMachining.nWorkside = EgtIf( TOOLS[CurrentMachining.ToolInfo.nToolIndex].bIsCCW, MCH_MILL_WS.RIGHT, MCH_MILL_WS.LEFT)
end
Strategy.Profile.Machinings[i].ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Profile.Machinings[i].ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Profile.Machinings[i].dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
Strategy.Profile.Machinings[i].vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
Strategy.Profile.Machinings[i].dLengthOnX = Proc.b3Box:getDimX()
CurrentMachining.ptEdge1 = EgtSP( Proc.idAddAuxGeom, GDB_ID.ROOT)
CurrentMachining.ptEdge2 = EgtEP( Proc.idAddAuxGeom, GDB_ID.ROOT)
CurrentMachining.dEdgeLength = EgtCurveLength( Proc.idAddAuxGeom)
CurrentMachining.vtEdgeDirection = EgtSV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtMV( Proc.idAddAuxGeom, GDB_ID.ROOT) + EgtEV( Proc.idAddAuxGeom, GDB_ID.ROOT)
CurrentMachining.dLengthOnX = Proc.b3Box:getDimX()
local MachiningToSplit = {}
table.insert( MachiningToSplit, Strategy.Profile.Machinings[i])
table.insert( MachiningToSplit, CurrentMachining)
local MachiningResult = MachiningLib.GetSplitMachinings( MachiningToSplit, FeatureSplittingPoints, Part)
-- aggiunge lavorazione
for j = 1, #MachiningResult do
+8
View File
@@ -8,6 +8,8 @@
"sValue": "0",
"sDescriptionShort": "Depth Chamfer",
"sDescriptionLong": "Depth of the V-Mill to execute chamfers on cut-edges",
"idDescriptionShortMsg": 1000309,
"idDescriptionLongMsg": 1000310,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -18,6 +20,8 @@
"sValue": "false",
"sDescriptionShort": "Force to use chain saw",
"sDescriptionLong": "Force to use chain saw",
"idDescriptionShortMsg": 1000311,
"idDescriptionLongMsg": 1000312,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -28,6 +32,8 @@
"sValue": "true",
"sDescriptionShort": "Force to add PreCuts",
"sDescriptionLong": "Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length",
"idDescriptionShortMsg": 1000313,
"idDescriptionLongMsg": 1000314,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -38,6 +44,8 @@
"sValue": "true",
"sDescriptionShort": "Finish with mill",
"sDescriptionLong": "Use a mill to finish the surface if split with chain saw",
"idDescriptionShortMsg": 1000315,
"idDescriptionLongMsg": 1000316,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
+5 -3
View File
@@ -41,6 +41,11 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- si setta che è taglio di coda
Strategy.bIsTailCut = true
-- quando si aggiunge la lavorazione, si cambia il nome della feature
if bAddMachining then
-- si forza il nome della feature
EgtSetName( Proc.id, 'EndCut')
end
-- separazione solo se esiste grezzo successivo con pezzi o scaricabile
Strategy.bSplit = not( Part.bIsLastPart) or Part.dRestLength >= BeamData.dMinRaw
@@ -89,9 +94,6 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- se devo applicare le lavorazioni
if bAddMachining then
-- si forza il nome della feature
EgtSetName( Proc.id, 'EndCut')
-- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then
MakeChamfer()
+3 -3
View File
@@ -7,8 +7,8 @@ STR0004 = Topologia tipo LapJoint. Motosega
STR0005 = 1, 2 o 3 facce. Lama con taglio singolo o cubetti. Se richiesto o necessario codolo.
STR0006 = Tenone. Lama + fresa
STR0007 = Mortasa a coda di rondine e mortasa frontale a coda di rondine
STR0008 = Svuotatura tasca
STR0009 = !!DEPRECATA!! Sostituita da STR0015. RIUTILIZZABILE!
STR0008 = Svuotatura mortasa (raggiata)
STR0009 = ScarfJoint
STR0010 = Fresatura perpendicolare (tipo cut, longcut)
STR0011 = Foratura
STR0012 = RidgeLap
@@ -79,7 +79,7 @@ STR0015 = Profilo arcuato (Head Cambered Profile)
; Feature : French Ridge Lap
35,1,Feature,
; Feature : Chamfer
36,0,Feature,
36,0,Feature,STR0002,STR0005,STR0010
; Feature : Block Haus Half Lap
37,0,Feature,
; Feature : Block Haus Front
+55
View File
@@ -0,0 +1,55 @@
-- Strategia: FACEBYBLADE
-- Descrizione
-- Strategia di base per la lavorazione delle facce con lama
-- carico librerie
local FaceByBlade = require( 'FACEBYBLADE')
-- Tabella per definizione modulo
local ANTISPLINTONFACE = {}
-------------------------------------------------------------------------------------------------------------
function ANTISPLINTONFACE.Make( Proc, Part, Face, OptionalParameters)
local Machinings = {}
-- parametri opzionali
if not OptionalParameters then
OptionalParameters = {}
end
local bIsSplitFeature = OptionalParameters.bIsSplitFeature or false
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
local nInternalSortingPriority = OptionalParameters.nInternalSortingPriority or 1
local dResultWeight = OptionalParameters.dResultWeight or 0.15
local bMachineAllClosedEdges = OptionalParameters.bMachineAllClosedEdges or false
local ClosingFacesAgainstGrain = {}
for i = 1, #Face.Edges do
local CurrentFace = Proc.Faces[Face.Edges[i].idAdjacentFace + 1]
if ( not Face.Edges[i].bIsOpen) and ( Face.Edges[i].bIsStartOpen or Face.Edges[i].bIsEndOpen or bMachineAllClosedEdges) then
table.insert( ClosingFacesAgainstGrain, CurrentFace)
end
end
for i = 1, #ClosingFacesAgainstGrain do
local EdgeToMachine = {}
for j = 1, #ClosingFacesAgainstGrain[i].Edges do
if ClosingFacesAgainstGrain[i].Edges[j].idAdjacentFace == Face.id then
EdgeToMachine = ClosingFacesAgainstGrain[i].Edges[j]
break
end
end
local Cutting = {}
local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail}
Cutting = FaceByBlade.Make( Proc, Part, ClosingFacesAgainstGrain[i], EdgeToMachine, OptionalParametersFaceByBlade)
Cutting.nInternalSortingPriority = nInternalSortingPriority
Cutting.dResultWeight = dResultWeight
table.insert( Machinings, Cutting)
end
return Machinings
end
-------------------------------------------------------------------------------------------------------------
return ANTISPLINTONFACE
+244 -128
View File
@@ -14,45 +14,63 @@ local MachiningLib = require( 'MachiningLib')
local BeamLib = require('BeamLib')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
local FaceByMill = require('FACEBYMILL')
local FaceByMill = require( 'FACEBYMILL')
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
-- tabelle per definizione modulo
-------------------------------------------------------------------------------------------------------------
local function CompareEdges( EdgeA, EdgeB)
-- prima i lati orientati lungo X
if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then
local function CompareEdgesLongestTop( EdgeA, EdgeB)
-- si preferiscono i lati più lunghi
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
return true
elseif abs( EdgeA.vtN:getX()) > abs( EdgeB.vtN:getX()) + 10 * GEO.EPS_SMALL then
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
return false
-- se stessa X si preferiscono i lati più lunghi (nel caso di 5 lati è quello non spezzato)
-- se stessa lunghezza si preferiscono i lati più in basso
else
if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.dLength < EdgeB.dLength - 10 * GEO.EPS_SMALL then
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
return false
-- se stessa lunghezza si preferiscono i lati più in basso
-- TODO qui dipenderà dalla lama scelta
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
-- se stessa Z si preferiscono i lati verso il fronte della trave
else
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then
return true
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
else
return false
end
return false
end
end
end
end
local function GetLongEdgeToMachine( Face, bHeadType)
local Edge = {}
local EdgesSorted = {}
for i = 1, #Face.Edges do
table.insert( EdgesSorted, Face.Edges[i])
end
table.sort( EdgesSorted, CompareEdgesLongestTop)
-- se il lato migliore è accessibile si sceglie questo, altrimenti il lato opposto; se entrambi non accessibili (faccia chiusa da due lati) la lavorazione non è applicabile
Edge = EdgesSorted[1]
local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN)
if not EdgeOpposite.bIsOpen then
if Edge.bIsOpen then
Edge = EdgeOpposite
-- entrambi i lati non accessibili: codolo non applicabile
else
return nil
end
end
return Edge
end
local function SortMachiningsBySegment( MachiningA, MachiningB)
if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then
return false
@@ -118,6 +136,76 @@ local function GetStrategyCompletionPercentage( Machinings)
end
local function MakeBottomFace( Proc, Part, BottomFace, EdgeToMachine, Parameters)
local Cuttings = {}
local Cutting1 = {}
local Cutting2 = {}
-- parametri dal chiamante
local bIsSplitFeature = Parameters.bIsSplitFeature
local dExtendAfterTail = Parameters.dExtendAfterTail
local nToolIndex = Parameters.nToolIndex
local dStripWidth = Parameters.dStripWidth
local OtherBottomFace = Parameters.OtherBottomFace
local dDepthToMachine = EdgeToMachine.dElevation / 2 - dStripWidth / 2
local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( BottomFace.Edges, -EdgeToMachine.vtN)
-- primo lato
if EdgeToMachineOpposite.bIsOpen then
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade1)
end
Cutting1.nInternalSortingPriority = 2
Cutting1.dResultWeight = 0.3
-- secondo lato
local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1)
OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled'
if EdgeToMachine.bIsOpen then
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade2)
end
Cutting2.nInternalSortingPriority = 2
Cutting2.dResultWeight = 0.3
-- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto
if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then
-- se si lavora il lato in comune con l'altra BottomFace significa ci si deve fermare piú indietro
if OtherBottomFace and ( EdgeToMachine.idAdjacentFace == OtherBottomFace.id) then
dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth
end
dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade2)
Cutting2.nInternalSortingPriority = 2
Cutting2.dResultWeight = 0.3
table.insert( Cuttings, Cutting2)
elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then
-- se si lavora il lato in comune con l'altra BottomFace significa ci si deve fermare piú indietro
if OtherBottomFace and ( EdgeToMachine.idAdjacentFace == OtherBottomFace.id) then
dStripWidth = TOOLS[Cutting1.nToolIndex].dThickness + 2 * dStripWidth
end
dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade1)
Cutting1.nInternalSortingPriority = 2
Cutting1.dResultWeight = 0.3
table.insert( Cuttings, Cutting1)
else
table.insert( Cuttings, Cutting1)
table.insert( Cuttings, Cutting2)
end
return Cuttings
end
function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
-- TODO verificare funzionamento con lama da sotto
-- TODO scelta utensile è corretto lasciarla a FaceByBlade?
@@ -126,30 +214,29 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
local Result = {}
local Machinings = {}
local CalculatedMachinings = {}
local Cutting1 = {}
local Cutting2 = {}
-- controlli preventivi
if Proc.nFct > 3 then
error( 'BladeKeepWaste : max 3 faces supported')
if Proc.nFct > 3 and Proc.Topology.sFamily ~= 'DoubleBevel' then
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : max 3 faces supported')
return Machinings, Result
elseif Proc.nFct == 2 then
-- per angolo tra le facce >= 90deg (feature convessa) non applicabile
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
Result = FeatureLib.GetStrategyResultNotApplicable()
return Machinings, Result
end
elseif Proc.nFct == 3 then
-- caso speciale RidgeLap - per angolo tra le facce >= 90deg (feature convessa) non applicabile
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
Result = FeatureLib.GetStrategyResultNotApplicable()
return Machinings, Result
end
if Proc.AdjacencyMatrix[1][3] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][3] < -91 then
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
Result = FeatureLib.GetStrategyResultNotApplicable()
return Machinings, Result
end
if Proc.AdjacencyMatrix[2][3] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[2][3] < -91 then
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : angle between faces must be concave and >= 90deg')
Result = FeatureLib.GetStrategyResultNotApplicable()
return Machinings, Result
end
end
@@ -160,12 +247,7 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
end
local nToolIndex = OptionalParameters.nToolIndex
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
local bFinishWithMill
if OptionalParameters.bFinishWithMill == nil then
bFinishWithMill = true
else
bFinishWithMill = OptionalParameters.bFinishWithMill
end
local bFinishWithMill = ( OptionalParameters.bFinishWithMill ~= false)
local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1
local dStripWidth = OptionalParameters.dStripWidth or 5
local bForced = OptionalParameters.bForced or false
@@ -173,28 +255,26 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
-- volume della feature
local dFeatureVolume = Proc.dVolume
-- si trovano le facce da lavorare
local BottomFace = {}
local LongFaces = {}
-- si trovano le facce da lavorare (solo 4 lati esatti)
local BottomFace1
local BottomFace2
if Proc.nFct == 1 then
BottomFace = Proc.Faces[1]
BottomFace1 = Proc.Faces[1]
else
if not Proc.MainFaces then
Proc.MainFaces = FaceData.GetMainFaces( Proc, Part)
end
BottomFace = Proc.MainFaces.BottomFaces[1]
LongFaces = Proc.MainFaces.LongFaces
BottomFace1 = Proc.MainFaces.BottomFaces[1]
BottomFace2 = Proc.MainFaces.BottomFaces[2]
end
-- si trova il lato della faccia di fondo da lavorare
local BottomEdgeToMachine = {}
local BottomEdgesSorted = {}
for i = 1, #BottomFace.Edges do
table.insert( BottomEdgesSorted, BottomFace.Edges[i])
if #BottomFace1.Edges ~= 4 then
Result = FeatureLib.GetStrategyResultNotApplicable()
return Machinings, Result
end
local bConvexAngle
if BottomFace2 then
bConvexAngle = ( Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1]) > 0
end
table.sort( BottomEdgesSorted, CompareEdges)
BottomEdgeToMachine = BottomEdgesSorted[1]
-- eventuali punti di spezzatura
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
@@ -203,92 +283,126 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
bIsSplitFeature = true
end
-- calcolo lavorazioni
-- taglio eventuali facce di chiusura o seconda faccia
for i = 1, #LongFaces do
local Cutting = {}
local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
Cutting = FaceByBlade.Make( Proc, Part, LongFaces[i], LongFaces[i].MainEdges.BottomEdge, OptionalParametersFaceByBlade)
Cutting.nInternalSortingPriority = 1
Cutting.dResultWeight = 0.15
table.insert( CalculatedMachinings, Cutting)
end
-- taglio con codolo faccia di fondo; si provano solo i lati a cui si può accedere (lato opposto aperto)
-- TODO il check del lato opposto aperto andrà messo nella FaceByBlade
-- TODO verificare se il calcolo del completamento (aggiunta lavorazioni applicabili/non) é corretto
local dDepthToMachine = BottomEdgeToMachine.dElevation / 2 - dStripWidth / 2
local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
local BottomEdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( BottomFace.Edges, -BottomEdgeToMachine.vtN)
-- primo lato
if BottomEdgeToMachineOpposite.bIsOpen then
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1)
-- calcolo lavorazioni faccia principale
-- ricerca lato da lavorare
local BottomEdgeToMachine1 = GetLongEdgeToMachine( BottomFace1, { bTop = true})
if not BottomEdgeToMachine1 then
Result = FeatureLib.GetStrategyResultNotApplicable()
return Machinings, Result
end
Cutting1.nInternalSortingPriority = 3
Cutting1.dResultWeight = 0.3
-- secondo lato
local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1)
OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled'
if BottomEdgeToMachine.bIsOpen then
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2)
-- calcolo lavorazione
local Parameters1 = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
nToolIndex = nToolIndex,
dStripWidth = dStripWidth,
OtherBottomFace = BottomFace2
}
local Cuttings1 = MakeBottomFace( Proc, Part, BottomFace1, BottomEdgeToMachine1, Parameters1)
-- aggiunta lavorazioni alla lista principale
for i = 1, #Cuttings1 do
table.insert( CalculatedMachinings, Cuttings1[i])
end
Cutting2.nInternalSortingPriority = 3
Cutting2.dResultWeight = 0.3
-- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto
if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then
-- se si lavora il lato in comune con la LongFace significa che la LongFace non é di chiusura ma un'altra faccia vera e propria
-- ci si deve quindi fermare piú indietro
for i = 1, #LongFaces do
if BottomEdgeToMachine.idAdjacentFace == LongFaces[i].id then
dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth
break
-- calcolo lavorazioni faccia secondaria, solo se lato convesso; se concavo, sarà lavorato come antisplint
local Cuttings2
local BottomEdgeToMachine2
if BottomFace2 then
if bConvexAngle then
-- ricerca lato da lavorare
BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, { bTop = true})
if BottomEdgeToMachine2 then
-- calcolo lavorazione
local Parameters2 = BeamLib.TableCopyDeep( Parameters1)
Parameters2.OtherBottomFace = BottomFace1
Cuttings2 = MakeBottomFace( Proc, Part, BottomFace2, BottomEdgeToMachine2, Parameters2)
for i = 1, #Cuttings2 do
table.insert( CalculatedMachinings, Cuttings2[i])
end
end
end
dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth)
OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2)
Cutting2.nInternalSortingPriority = 3
Cutting2.dResultWeight = 0.3
table.insert( CalculatedMachinings, Cutting2)
elseif not Cutting2.bIsApplicable and Cutting1.bIsApplicable then
-- se si lavora il lato in comune con la LongFace significa che la LongFace non é di chiusura ma un'altra faccia vera e propria
-- ci si deve quindi fermare piú indietro
for i = 1, #LongFaces do
if BottomEdgeToMachine.idAdjacentFace == LongFaces[i].id then
dStripWidth = TOOLS[Cutting1.nToolIndex].dThickness + 2 * dStripWidth
break
end
end
dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, BottomEdgeToMachine.dElevation - dStripWidth)
OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade1)
Cutting1.nInternalSortingPriority = 3
Cutting1.dResultWeight = 0.3
table.insert( CalculatedMachinings, Cutting1)
else
table.insert( CalculatedMachinings, Cutting1)
table.insert( CalculatedMachinings, Cutting2)
end
-- fresatura eventuali facce di chiusura
-- antischeggia sulle facce di chiusura delle facce lavorate
local OptionalParametersAntiSplint = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
nInternalSortingPriority = 1,
dResultWeight = 0.15,
bMachineAllClosedEdges = true
}
local AntiSplints1 = AntiSplintOnFace.Make( Proc, Part, BottomFace1, OptionalParametersAntiSplint)
for i = 1, #AntiSplints1 do
table.insert( CalculatedMachinings, AntiSplints1[i])
end
if BottomFace2 and bConvexAngle then
OptionalParametersAntiSplint.bMachineAllClosedEdges = false
local AntiSplints2 = AntiSplintOnFace.Make( Proc, Part, BottomFace2, OptionalParametersAntiSplint)
for i = 1, #AntiSplints2 do
table.insert( CalculatedMachinings, AntiSplints2[i])
end
end
-- pulitura con fresa dei lati chiusi non lavorati
-- TODO funzione
if bFinishWithMill then
for i = 1, #LongFaces do
if BottomEdgeToMachine.idAdjacentFace ~= LongFaces[i].id then
local dDepthToMachineMill = BottomFace.MainEdges.LongEdges[i].dElevation - dMillingOffsetFromSide
local dToolMarkLength = max( Cutting1.dToolMarkLength or 0, Cutting2.dToolMarkLength or 0)
local OptionalParametersFaceByMill = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail,
dRadialStepSpan = dToolMarkLength, dDepthToMachine = dDepthToMachineMill
}
local Milling = FaceByMill.Make( Proc, Part, BottomFace, BottomFace.MainEdges.LongEdges[i], OptionalParametersFaceByMill)
Milling.nInternalSortingPriority = 2
if Cuttings1 then
-- si recuperano i lati chiusi non lavorati
local EdgesClosedNotMachined = {}
for i = 1, #BottomFace1.Edges do
if not( ( BottomFace1.Edges[i].id == BottomEdgeToMachine1.id) or BottomFace1.Edges[i].bIsOpen) then
table.insert( EdgesClosedNotMachined, BottomFace1.Edges[i])
end
end
-- su ognuno si fa la fresatura di pulizia
for i = 1, #EdgesClosedNotMachined do
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
local dToolMarkLength = 0
-- si prende l'impronta dell'utensile più grande
for j = 1, #Cuttings1 do
if Cuttings1[j].dToolMarkLength > dToolMarkLength + 10 * GEO.EPS_SMALL then
dToolMarkLength = Cuttings1[j].dToolMarkLength
end
end
local OptionalParametersMilling = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
dRadialStepSpan = dToolMarkLength,
dDepthToMachine = dDepthToMachine
}
local Milling = FaceByMill.Make( Proc, Part, BottomFace1, EdgesClosedNotMachined[i], OptionalParametersMilling)
Milling.nInternalSortingPriority = 3
Milling.dResultWeight = 0.05
table.insert( CalculatedMachinings, Milling)
end
end
if Cuttings2 and BottomEdgeToMachine2 then
-- si recuperano i lati chiusi non lavorati
local EdgesClosedNotMachined = {}
for i = 1, #BottomFace2.Edges do
if not( ( BottomFace2.Edges[i].id == BottomEdgeToMachine2.id) or BottomFace2.Edges[i].bIsOpen) then
table.insert( EdgesClosedNotMachined, BottomFace2.Edges[i])
end
end
-- su ognuno si fa la fresatura di pulizia
for i = 1, #EdgesClosedNotMachined do
local dDepthToMachine = EdgesClosedNotMachined[i].dElevation - dMillingOffsetFromSide
local dToolMarkLength = 0
-- si prende l'impronta dell'utensile più grande
for j = 1, #Cuttings2 do
if Cuttings2[j].dToolMarkLength > dToolMarkLength + 10 * GEO.EPS_SMALL then
dToolMarkLength = Cuttings2[j].dToolMarkLength
end
end
local OptionalParametersMilling = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
dRadialStepSpan = dToolMarkLength,
dDepthToMachine = dDepthToMachine
}
local Milling = FaceByMill.Make( Proc, Part, BottomFace2, EdgesClosedNotMachined[i], OptionalParametersMilling)
Milling.nInternalSortingPriority = 3
Milling.dResultWeight = 0.05
table.insert( CalculatedMachinings, Milling)
end
@@ -317,7 +431,9 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
table.sort( Machinings, SortMachiningsBySegment)
-- calcolo risultati
if Cutting1.bIsApplicable or Cutting2.bIsApplicable then
if ( Cuttings1 and ( ( Cuttings1[1] and Cuttings1[1].bIsApplicable) or ( Cuttings1[2] and Cuttings1[2].bIsApplicable)))
or ( Cuttings2 and ( ( Cuttings2[1] and Cuttings2[1].bIsApplicable) or ( Cuttings2[2] and Cuttings2[2].bIsApplicable))) then
Result.dQuality = FeatureLib.GetStrategyQuality( Machinings)
Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings)
Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)
+104 -34
View File
@@ -260,7 +260,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
local dShortPartLength = OptionalParameters.dShortPartLength or BeamData.LEN_SHORT_PART
local EdgeToMachineTop = OptionalParameters.EdgeToMachineTop
local EdgeToMachineBottom = OptionalParameters.EdgeToMachineBottom
local bIsDicing = OptionalParameters.bIsDicing
local idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength
-- TODO qui sarebbe meglio avere dExtra come OptionalParameter???
@@ -289,7 +289,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
FaceToMachine = Face,
EdgeToMachine = EdgeToMachineTop,
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -304,7 +304,7 @@ local function GetBestBlade( Proc, Part, Face, OptionalParameters)
FaceToMachine = Face,
EdgeToMachine = EdgeToMachineBottom,
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -371,7 +371,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters)
local bReduceBladePath = OptionalParameters.bReduceBladePath or false
local bAllowFastCuts = OptionalParameters.bAllowFastCuts or false
local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1]
local bIsDicing = OptionalParameters.bIsDicing or false
local idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
-- lati da lavorare in base al tipo di lama
@@ -390,7 +390,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters)
EdgeToMachineTop = EdgeToMachineList.Top,
EdgeToMachineBottom = EdgeToMachineList.Bottom,
nToolIndex = nToolIndex,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
}
@@ -442,7 +442,7 @@ local function GetSingleCutStrategy( Proc, Part, OptionalParameters)
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachineList.TopGuillotine,
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -475,7 +475,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
OptionalParameters = OptionalParameters or {}
local nToolIndex = OptionalParameters.nToolIndex
local FaceToMachine = Proc.Faces[OptionalParameters.nFaceToMachineIndex or 1]
local bIsDicing = OptionalParameters.bIsDicing or false
local idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
@@ -499,7 +499,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachine,
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -512,7 +512,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
FaceToMachine = FaceToMachine,
EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN),
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -534,7 +534,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
FaceToMachine = FaceToMachine,
EdgeToMachine = BeamLib.FindEdgeBestOrientedAsDirection( FaceToMachine.Edges, -EdgeToMachine.vtN),
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -553,7 +553,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachine,
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -589,7 +589,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
FaceToMachine = FaceToMachine,
EdgeToMachine = EdgeToMachine,
Part = Part,
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
})
@@ -607,7 +607,7 @@ local function GetDualSideCutStrategy( Proc, Part, OptionalParameters)
dDepthToMachine = dDepthToMachine
}
local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
}
@@ -782,6 +782,52 @@ local function CutWholeWaste( Proc, Part, OptionalParameters)
end
local function UpdateDiceRaw( idRaw, idParallelTm, idPerpendicularTm, Part, MainFace, OtherFace)
-- frame solidale alla feature
local vtZ = MainFace.vtN
local vtX = OtherFace and OtherFace.vtN or nil
local frMainFace = Frame3d( MainFace.ptCenter, vtZ, vtX)
-- box del cubetto in riferimento feature
local b3Surf = EgtGetBBoxRef( idParallelTm, GDB_BB.STANDARD, frMainFace)
if idPerpendicularTm then
local b3SurfPerpendicular = EgtGetBBoxRef( idPerpendicularTm, GDB_BB.STANDARD, frMainFace)
b3Surf:Add( b3SurfPerpendicular)
else
-- se non arriva la superficie perpendicolare è un solo taglio parallelo: si estende il box in Z in modo da uscire dal pezzo
local ptDeltaZ = b3Surf:getMax() + vtZ * ( MainFace.dElevation + 5)
b3Surf:Add( ptDeltaZ)
end
-- estensione box per non avere problemi nella sottrazione booleana
if OtherFace and idPerpendicularTm then
local vtY = vtZ ^ vtX
local ptDeltaX = b3Surf:getMax() + vtX * 1
local ptDeltaZ = b3Surf:getMax() + vtZ * 1
local ptDeltaYplus = b3Surf:getMax() + vtY * 1
local ptDeltaYminus = b3Surf:getMin() - vtY * 1
b3Surf:Add( ptDeltaX)
b3Surf:Add( ptDeltaZ)
b3Surf:Add( ptDeltaYplus)
b3Surf:Add( ptDeltaYminus)
else
b3Surf:expand( 1)
end
-- si porta il box in riferimento globale
b3Surf:toGlob( frMainFace)
-- conversione box cubetto in superficie
local idSurfTmToSubtract = EgtSurfTmBBox( Part.idTempGroup, b3Surf, false, GDB_RT.GLOB)
-- sottrazione del cubetto dal grezzo
EgtSurfTmSubtract( idRaw, idSurfTmToSubtract)
return idRaw
end
local function CalculateDiceMachinings( vCuts, Parameters)
local Machinings = {}
local bMoveAfterSplit = false
@@ -789,25 +835,24 @@ local function CalculateDiceMachinings( vCuts, Parameters)
local Proc = Parameters.Proc
local Part = Parameters.Part
local MainFace = Parameters.MainFace
local OtherFace = next( Parameters.OtherFace) and Parameters.OtherFace or nil
local Tool = Parameters.Tool
local sChosenBladeType = Parameters.sChosenBladeType
local dExtendAfterTail = Parameters.dExtendAfterTail
local bReduceBladePath = Parameters.bReduceBladePath
local sRestLengthSideForPreSimulation = Parameters.sRestLengthSideForPreSimulation
local bCannotSplitRestLength = Parameters.bCannotSplitRestLength
local bReduceDiceDepth = Parameters.bReduceDiceDepth
-- trimesh con RestLength
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
local idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
-- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria
local bAreOrthogonalCutsInverted = false
for i = 1, #vCuts do
for j = 1, #vCuts[i] do
SetDiceFaceInfo( Proc, vCuts[i][j])
if ( i % 2) == 1 then
local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
if MachiningLib.IsFaceZOutOfRange( vtO, Tool) then
EgtInvertSurf( vCuts[i][j])
bAreOrthogonalCutsInverted = true
end
end
end
end
-- calcolo lavorazioni
@@ -848,19 +893,17 @@ local function CalculateDiceMachinings( vCuts, Parameters)
end
-- calcolo lavorazione della singola faccia
-- per tagli paralleli e faccia aperta si prova a tagliare come se fosse una faccia singola, accorpando i tagli
-- TODO bIsDicing è da mettere a true?
local bCanMergeParallelCuts = ( ( i % 2) == 0) and ( Proc.nFct == 1)
local bIsDicingOk = true
if bCanMergeParallelCuts then
local nAddGrpId = BeamLib.GetAddGroup( Part.id)
local nSurfToCut = EgtSurfTmBySewing( nAddGrpId, vCuts[i], false)
local ProcTrimesh = FeatureLib.GetProcFromTrimesh( nSurfToCut, Part)
local idSurfToCut = EgtSurfTmBySewing( nAddGrpId, vCuts[i], false)
local ProcTrimesh = FeatureLib.GetProcFromTrimesh( idSurfToCut, Part)
local OptionalParametersCutWholeWaste = {
nToolIndex = Tool.nIndex,
dExtendAfterTail = dExtendAfterTail,
bReduceBladePath = bReduceBladePath,
bIsDicing = false,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
}
@@ -873,16 +916,25 @@ local function CalculateDiceMachinings( vCuts, Parameters)
bMoveAfterSplit = true
end
end
-- aggiornamento grezzo dinamico
if i % 2 == 0 then
UpdateDiceRaw( idCheckCollisionTm, idSurfToCut, vCuts[i-1][#vCuts[i-1]], Part, MainFace, OtherFace)
end
else
EgtErase( nSurfToCut)
EgtErase( idSurfToCut)
bIsDicingOk = false
end
end
-- caso standard (tagli perpendicolari o paralleli non accorpabili)
if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then
for j = 1, #vCuts[i] do
-- in generale sta sollevato di pochissimo
local dExtraCut = -0.1
-- se abilitato, la lama sta sollevata per non rovinare le facce
local dExtraCut
if bReduceDiceDepth == false then
dExtraCut = 0
else
dExtraCut = -0.1
end
-- se tagli paralleli
if ( i % 2) == 0 then
-- se non ci sono tagli ortogonali devo affondare
@@ -910,8 +962,10 @@ local function CalculateDiceMachinings( vCuts, Parameters)
dRadialStepSpan = 0,
dExtendAfterTail = dExtendAfterTail,
bIsDicing = true,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = true
}
Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade)
Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0)
@@ -926,6 +980,10 @@ local function CalculateDiceMachinings( vCuts, Parameters)
if Cutting.sStage == 'AfterTail' then
bMoveAfterSplit = true
end
-- aggiornamento grezzo dinamico
if i % 2 == 0 then
UpdateDiceRaw( idCheckCollisionTm, vCuts[i][j], vCuts[i-1][j], Part, MainFace, OtherFace)
end
end
end
end
@@ -961,10 +1019,13 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
end
end
-- angolo tra le facce, se più di una
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] or 0
-- scelta lama da sopra o da sotto
local sChosenBladeType = ''
if not nToolIndex then
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, Face1)
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part)
end
-- se non trovata lama la lavorazione non è fattibile
@@ -1000,12 +1061,14 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
Proc = Proc,
Part = Part,
MainFace = Face1,
OtherFace = Face2,
Tool = TOOLS[nToolIndex],
sChosenBladeType = sChosenBladeType,
dExtendAfterTail = dExtendAfterTail,
bReduceBladePath = bReduceBladePath,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
bCannotSplitRestLength = bCannotSplitRestLength,
bReduceDiceDepth = ( dAngleBetweenFaces < - 10) -- per facce molto aperte non si riduce l'affondamento della lama nei cubetti (rischio che non si stacchino)
}
bIsDicingOk, Machinings, bMoveAfterSplit = CalculateDiceMachinings( vCuts, Parameters)
@@ -1215,14 +1278,21 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
else
-- per ogni faccia si calcola la lavorazione
for i = 1, #Proc.Faces do
-- ricerca lato in comune da lavorare
-- ricerca lato in comune da lavorare; se non trovato è una feature splittata (DoubleBevel) e il lato sarà scelto della GetSingleCutStratetegy
local nCommonEdgeIndex
for j = 1, #Proc.Faces[i].Edges do
if Proc.Faces[i].Edges[j].idAdjacentFace > -1 then
nCommonEdgeIndex = j
end
end
local EdgeToMachine = Proc.Faces[i].Edges[nCommonEdgeIndex]
local EdgeToMachine
if nCommonEdgeIndex then
EdgeToMachine = Proc.Faces[i].Edges[nCommonEdgeIndex]
end
local EdgeToMachineList
if EdgeToMachine then
EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine}
end
-- scelta lama
local nToolIndex = OptionalParameters.nToolIndex
@@ -1230,11 +1300,11 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
local OptionalParametersGetSingleCutStrategy = {
bReduceBladePath = false,
nFaceToMachineIndex = i,
EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine},
EdgeToMachineList = EdgeToMachineList,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
}
nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy)
nToolIndex, EdgeToMachine = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy)
end
-- se lama non trovata si provano i cubetti
+31 -12
View File
@@ -72,6 +72,12 @@ local function GetLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
LeadOut.dTotalLength = sqrt( LeadOut.dPerpDistance ^ 2 + LeadOut.dTangentDistance ^ 2)
end
-- se accorciamenti maggiori della lunghezza lato, la lavorazione non è fattibile
if LeadIn.dStartAddLength + LeadOut.dEndAddLength + EdgeToMachine.dLength < 1 then
return
end
-- se lavorazione con OppositeToolDirection o ridotta l'attacco va corretto
if not AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then
LeadIn.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset
@@ -203,8 +209,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
local dRadialStepSpan = OptionalParameters.dRadialStepSpan
local sUserNotes = OptionalParameters.sUserNotes or ''
local bIsDicing = OptionalParameters.bIsDicing or false
local idCheckCollisionTm = OptionalParameters.idCheckCollisionTm
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
-- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato
Cutting.dEdgeLength = EdgeToMachine.dLength
@@ -225,10 +233,15 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Tool = TOOLS[Cutting.nToolIndex],
dDepthToMachine = dDepthToMachine
}
if OppositeToolDirectionMode == 'Enabled' then
BladeEngagementParameters.Edge = EdgeToMachineOpposite
end
local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
}
local Engagement
TIMER:startElapsed( 'GetBladeEngagement')
@@ -252,6 +265,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
ToolSearchParameters.Part = Part
ToolSearchParameters.sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation
ToolSearchParameters.bCannotSplitRestLength = bCannotSplitRestLength
ToolSearchParameters.bDisableRealElevationCheck = bDisableRealElevationCheck
local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
Cutting.nToolIndex = ToolInfo.nToolIndex
@@ -285,16 +299,18 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
return Cutting, EdgeToMachine.dElevation
end
-- TODO vedere se la rimozione di questo crea problemi
-- se tasca chiusa da entrambi i lati e più stretta della lama la lavorazione non è applicabile
if not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then
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)
-- if not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then
-- 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
-- return Cutting, EdgeToMachine.dElevation
-- end
-- end
-- parametri della lavorazione
@@ -320,7 +336,6 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.bInvert = not Cutting.bInvert
end
-- TODO al momento commentato per trovare i casi in cui nei riposizionamenti scende sul pezzo; poi valutare se lasciare o togliere
-- se dicing, lato di lavoro e inversione per avere taglio sempre verso l'alto
if bIsDicing
and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL)
@@ -347,8 +362,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
}
local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
}
TIMER:startElapsed( 'GetBladeEngagement')
local bIsApplicableOpposite, EngagementOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
@@ -464,8 +481,10 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
}
local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing,
idCheckCollisionTm = idCheckCollisionTm,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength
bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
}
TIMER:startElapsed( 'GetBladeEngagement')
local bIsApplicable, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters )
+54 -14
View File
@@ -6,6 +6,7 @@
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib')
local PreSimulationLib = require( 'PreSimulationLib')
-- Tabella per definizione modulo
local FACEBYCHAINSAW = {}
@@ -42,6 +43,11 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, sSideToMachine, dLe
LeadOut.dEndAddLength = BeamData.CUT_EXTRA
end
-- punti dell'attacco
local dLengthToAdd = EgtIf( Machining.bToolInvert, -Machining.dStartSafetyLength, EdgeToMachine.dElevation - ( Machining.dMaxElev or 0) + Machining.dStartSafetyLength)
LeadIn.ptPoint = EdgeToMachine.ptStart - EdgeToMachine.vtEdge * LeadIn.dStartAddLength + EdgeToMachine.vtN * dLengthToAdd
LeadOut.ptPoint = EdgeToMachine.ptEnd + EdgeToMachine.vtEdge * LeadOut.dEndAddLength + EdgeToMachine.vtN * dLengthToAdd
return LeadIn, LeadOut
end
@@ -75,12 +81,29 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
local sDepth = OptionalParameters.sDepth or 'TH'
local dLongitudinalStepSpan = OptionalParameters.dLongitudinalStepSpan
-- lunghezze e punti caratteristici della lavorazione e del lato lavorato
-- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato
Mortising.dEdgeLength = EdgeToMachine.dLength
if OppositeToolDirectionMode == 'Enabled' then
Mortising.vtToolDirection = -EdgeToMachine.vtN
local dCalculatedMaxElev = FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].dLength
if FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].dLength > FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].dLength + 10 * GEO.EPS_SMALL then
dCalculatedMaxElev = FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].dLength
end
-- la direzione di lavoro è calcolata in accordo con la direzione calcolata dal Cam5
-- fine chiusa
if EdgeToMachine.bIsStartOpen and not EdgeToMachine.bIsEndOpen then
Mortising.vtToolDirection = FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].vtEdge
-- inizio chiuso
elseif EdgeToMachine.bIsEndOpen and not EdgeToMachine.bIsStartOpen then
Mortising.vtToolDirection = -FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].vtEdge
-- entrambi aperti o entrambi chiusi
else
Mortising.vtToolDirection = EdgeToMachine.vtN
local vtTemp = ( FaceToMachine.Edges[EdgeToMachine.nNextEdgeIndex].vtEdge - FaceToMachine.Edges[EdgeToMachine.nPreviousEdgeIndex].vtEdge) * 0.5
vtTemp:normalize()
Mortising.vtToolDirection = vtTemp
end
if OppositeToolDirectionMode == 'Enabled' then
Mortising.vtToolDirection = -Mortising.vtToolDirection
else
Mortising.vtToolDirection = Mortising.vtToolDirection
end
Mortising.vtEdgeDirection = Vector3d( EdgeToMachine.vtEdge)
Mortising.ptEdge1, Mortising.ptEdge2 = EdgeToMachine.ptStart, EdgeToMachine.ptEnd
@@ -164,11 +187,13 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
-- massima elevazione
if dCustomMaxElev < Mortising.dDepthToMachine - 10 * GEO.EPS_SMALL then
Mortising.dMaxElev = max( dCustomMaxElev, dCustomMaxElev - Mortising.dLongitudinalOffset)
else
Mortising.dMaxElev = dCalculatedMaxElev
end
-- offset radiale
Mortising.dRadialOffset = 0
-- distanza di sicurezza
Mortising.dStartSafetyLength = max( EdgeToMachine.dElevation, ( TOOLS[Mortising.nToolIndex].SetupInfo.dZSafeDelta or 60) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ))
Mortising.dStartSafetyLength = ( TOOLS[Mortising.nToolIndex].SetupInfo.dZSafeDelta or 0) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ)
-- overlap
Mortising.dOverlap = 0
-- step
@@ -189,16 +214,31 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
-- SCC
Mortising.SCC = MCH_SCC.NONE
-- asse bloccato e angoli suggeriti
local vtRes = FaceToMachine.vtN ^ EdgeToMachine.vtN
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.vtN, 1)
elseif EdgeToMachine.vtN:getZ() < 10 * GEO.EPS_SMALL then
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN)
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtN, 2)
end
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'perpendicular', Part.b3Raw, FaceToMachine.vtN)
Mortising.sInitialAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, Mortising.vtToolDirection, 1)
-- approccio e retrazione
Mortising.LeadIn, Mortising.LeadOut = CalculateLeadInOut( Mortising, EdgeToMachine, sSideToMachine, dLengthToMachine)
-- check finecorsa nei punti di attacco
local PointsOnToolTipCenter = {
Mortising.LeadIn.ptPoint,
Mortising.LeadOut.ptPoint
}
local vtAux = FaceToMachine.vtN
if Mortising.bToolInvert then
vtAux = -FaceToMachine.vtN
end
local bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, Mortising.vtToolDirection, Mortising.nSCC, TOOLS[Mortising.nToolIndex], vtAux, Mortising.sBlockedAxis)
-- se finecorsa si prova a bloccare l'altro asse
if bOutOfStroke then
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN)
Mortising.sInitialAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, Mortising.vtToolDirection, 2)
bOutOfStroke = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, Mortising.vtToolDirection, Mortising.nSCC, TOOLS[Mortising.nToolIndex], vtAux, Mortising.sBlockedAxis)
if bOutOfStroke then
Mortising.sMessage = 'Out of stroke'
Mortising.bIsApplicable = false
return Mortising
end
end
-- eventuale step verticale
Mortising.CloneStepsLongitudinal = {}
if not dLongitudinalStepSpan then
@@ -211,7 +251,7 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
Mortising.CloneStepsLongitudinal.dStep = dPocketHeight
end
-- lunghezza lavorata
-- TODO per il calcolo della dLenghtOnX ripetere il calcolo del FACEBYBLADE con proiezione del lato; serve prolungare con la Add Length secondo la vtEdgeDirection
-- TODO per il calcolo della dlengthOnX ripetere il calcolo del FACEBYBLADE con proiezione del lato; serve prolungare con la Add Length secondo la vtEdgeDirection
-- TODO fare funzione EstimatePathLength o simile
Mortising.dLengthToMachine = Mortising.dEdgeLength + Mortising.LeadIn.dStartAddLength + Mortising.LeadOut.dEndAddLength
Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtN:getY())
+2 -2
View File
@@ -1,4 +1,4 @@
==== Beam Update Log ====
Versione 2.6-- (--/--/2024)
- Primo commit creazione nuovo automatismo BEAM con strategie
Versione 3.1e1 (29/05/2026)
- Primo commit nuovo automatismo a strategie
+2 -2
View File
@@ -2,5 +2,5 @@
-- Gestione della versione di Beam
NAME = 'Beam'
VERSION = '2.8a1'
MIN_EXE = '2.7j2'
VERSION = '3.1e1'
MIN_EXE = '3.1e1'