Compare commits

..

145 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
luca.mazzoleni 8efb64810a - in FaceData si raccolgono informazioni sulle facce fino a 6 lati compresi 2026-02-26 17:56:12 +01:00
59 changed files with 4841 additions and 1551 deletions
+38 -10
View File
@@ -250,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
@@ -387,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
@@ -446,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
@@ -491,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
@@ -548,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, false)
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
@@ -637,6 +657,7 @@ if bToProcess then
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
TIMER:stopElapsed('Json')
-- 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
@@ -690,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, false)
BeamExec.GetCombinationMatrix( PARTS, false)
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 = ''
@@ -722,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)
@@ -738,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)
@@ -764,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)
@@ -772,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
+6 -1
View File
@@ -145,7 +145,12 @@ local function MyProcessFeatures()
BeamExec.GetProcessings( PARTS, true)
BeamExec.GetCombinationMatrix( PARTS, true)
BeamExec.ProcessMachinings( PARTS)
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 = ''
+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
+548 -269
View File
File diff suppressed because it is too large Load Diff
+157 -14
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
@@ -395,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???
@@ -512,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)
@@ -785,17 +890,18 @@ 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
@@ -803,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
@@ -816,7 +922,7 @@ function BeamLib.DecimalToBinary( dNumber)
for i = #tmp, 1, -1 do
sResult = sResult..tmp[i]
end
return tonumber( sResult)
end
@@ -830,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)
+98 -71
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,7 +1443,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
bSplitExecuted = true
MACHININGS.Info.bSplitExecuted = true
BeamLib.AddPhaseWithRawParts( Part.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( Part.idRaw)
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BeamData.dMinRaw then
@@ -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')
+9 -1
View File
@@ -131,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()
@@ -304,7 +312,7 @@ local function MyProcessFeatures()
BeamExec.GetProcessings( PARTS, false)
BeamExec.GetCombinationMatrix( PARTS, false)
BeamExec.ProcessMachinings( PARTS)
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" }]
}
]
},
+48 -14
View File
@@ -1,4 +1,3 @@
[
{
"nGroup": "PIECE LOADING",
@@ -7,6 +6,8 @@
"sValue": "BTL_POSITION",
"sDescriptionShort": "Part loading position",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000001,
"idDescriptionLongMsg": 1000002,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -14,18 +15,24 @@
"sValue": "BTL_POSITION",
"sDescriptionShort": "Loading position from BTL, no pre-rotation",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000003,
"idDescriptionLongMsg": 1000004,
"sMessageId": ""
},
{
"sValue": "STD_PRE_ROTATION",
"sDescriptionShort": "Get Best loading position from 0° and 180°",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000005,
"idDescriptionLongMsg": 1000006,
"sMessageId": ""
},
{
"sValue": "FULL_PRE_ROTATION",
"sDescriptionShort": "Get Best loading position in each piece rotation",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000007,
"idDescriptionLongMsg": 1000008,
"sMessageId": ""
}
]
@@ -37,17 +44,8 @@
"sValue": "false",
"sDescriptionShort": "Allow piece inversion",
"sDescriptionLong": "",
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"nGroup": "PIECE LOADING",
"sName": "GEN_bTestAlternative",
"sNameNge": "TEST_ALTERNATIVE",
"sValue": "false",
"sDescriptionShort": "Enable the possibility to load the piece 90° turned",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000009,
"idDescriptionLongMsg": 1000010,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -57,8 +55,10 @@
"sName": "GEN_bGetAlternativesNesting2D",
"sNameNge": "GET_ALTERNATIVES_NEST2D",
"sValue": "false",
"sDescriptionShort": "Enable material optimization function in nesting",
"sDescriptionShort": "Enable material optimization function in nesting (part rotation disabled)",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000011,
"idDescriptionLongMsg": 1000012,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
@@ -70,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": [
@@ -77,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": ""
}
]
@@ -100,6 +108,8 @@
"sValue": "AUTO",
"sDescriptionShort": "Machining Strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000021,
"idDescriptionLongMsg": 1000022,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
@@ -107,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": ""
}
]
@@ -130,6 +154,8 @@
"sValue": "1",
"sDescriptionShort": "Max number of reprocessing cycles",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000031,
"idDescriptionLongMsg": 1000032,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "10"
@@ -141,6 +167,8 @@
"sValue": "true",
"sDescriptionShort": "Use entire blade diameter to shorten path",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000033,
"idDescriptionLongMsg": 1000034,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "5"
@@ -152,6 +180,8 @@
"sValue": "300",
"sDescriptionShort": "Maximum length for dropped waste",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000035,
"idDescriptionLongMsg": 1000036,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "5"
@@ -163,6 +193,8 @@
"sValue": "6000000",
"sDescriptionShort": "Maximum volume for dropped waste",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000037,
"idDescriptionLongMsg": 1000038,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "5"
@@ -174,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'