74 Commits

Author SHA1 Message Date
luca.mazzoleni f58004dfeb - in PreSimulationLIb correzioni importanti in test collisione 2026-05-08 11:54:16 +02:00
luca.mazzoleni 7c485360de Merge branch 'ScarfJoint' into develop 2026-04-27 18:18:19 +02:00
luca.mazzoleni 967117cc23 - in FeatureLib, per ScarfJoint e ScarfSimple, si scrivono sempre AdjacencyMatrix e Faces
- in STR0009 aggiunto antischeggia di lama e, nel caso sia disattivato, lavorazione con lama dell'eventuale faccia inclinata
2026-04-27 18:18:07 +02:00
andrea.villa 64b2e86a2d Abbozzata gestione (non funzionante) passaggio supplementare in caso di angolo > 90° che necessita di passata extra 2026-04-24 16:47:40 +02:00
andrea.villa 89b342a564 Prima versione Scarf Joint. Manca:
- lavorazioni di antischeggia con fresa e lama
 - Il primo taglio de ve essere calcolato con 2 facce se il piano di taglio attraversa faccia 1
 - gestione caso con facce 4 e 5 mancanti
2026-04-24 14:45:31 +02:00
andrea.villa 117e475de5 STR0009 riutilizzata per ScarfJoint. Primo commit, da sviluppare completamente. 2026-04-24 08:52:56 +02:00
andrea.villa a7b817b211 STR0014 corretta lavorazione cloni 2026-04-24 08:41:25 +02:00
andrea.villa d8c6a8ad55 In STR0008 si aggiunge svuotatura con paraemtri di default 2026-04-23 10:35:03 +02:00
andrea.villa 9026acd9ca In STR0007 la faccia di taglio deve essere messa sul gruppo aggiuntivo. Prima era su quello temporaneo che però viene poi cancellato 2026-04-21 10:03:05 +02:00
andrea.villa 204346326f In STR0003 controllo delle MainFaces spostato a prima del controllo topologia 2026-04-21 08:13:41 +02:00
luca.mazzoleni 5d6e4c397d - in MachiningLib.FindMill si evita di lavorare troppo sotto con la fresa, a meno che sia in testa o coda; temporaneo in attesa di test collisione anche per fresa e attacco corretto dal lato 2026-04-20 18:09:22 +02:00
luca.mazzoleni 64bde8924d - in STR0002 si evita di lavorare la faccia tunnel se troppo piccola 2026-04-20 16:27:59 +02:00
luca.mazzoleni cb6115d23f - in STR0010 (fresatura) migliorata qualità se no lati chiusi 2026-04-20 15:25:19 +02:00
luca.mazzoleni 771c1367b1 - in PreSimulationLib, se taglio perpendicolare a cubetti, non si verifica l'elevazione reale del taglio 2026-04-20 10:47:41 +02:00
luca.mazzoleni 6092063daa - in BLADETOWASTE piccola correzione 2026-04-20 09:21:52 +02:00
luca.mazzoleni 44650c303c Merge branch 'test' into develop 2026-04-17 18:31:27 +02:00
luca.mazzoleni 69fa0d741d - piccole correzioni ai cubetti nel caso di due facce molto aperte 2026-04-17 18:31:22 +02:00
luca.mazzoleni 8e55ddda1f - in PreSimulationLib aggiunto check collisione anche per punti di attacco perpendicolare 2026-04-17 17:25:06 +02:00
andrea.villa 7a8fb04ebe In STR0013 (foro con fresa) si controlla che abbia trovato fresa prima di verificare se foro completo. Se non trovava fresa andava in crash 2026-04-17 12:36:26 +02:00
luca.mazzoleni 77c27d911c Merge branch 'PreSimulationV2' into develop 2026-04-16 17:02:43 +02:00
luca.mazzoleni 3a29f273c9 - in PreSimulationLib alcune correzioni 2026-04-16 17:02:39 +02:00
luca.mazzoleni bab5b07bd1 Merge remote-tracking branch 'origin/develop' into PreSimulationV2 2026-04-15 17:45:20 +02:00
luca.mazzoleni 683ae78c65 - in PreSimulationLib si usano le funzioni MachineCalc per la precollisione 2026-04-15 17:45:15 +02:00
andrea.villa 06d9529b7b Per ruotare il pezzo non lo si toglie più dalla barra, ma lo si gira in "Draw" 2026-04-14 09:05:46 +02:00
andrea.villa 922a7ac846 Correzioni varie in strategie per gestire casi strani dove non vengono calcolate le MainFaces 2026-04-14 07:57:59 +02:00
andrea.villa a21a3979f1 Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2026-04-13 13:02:10 +02:00
andrea.villa fcbed252e1 Merge branch 'PreRotationInterface' into develop 2026-04-13 13:02:06 +02:00
andrea.villa b68bbb2c48 - Report TXT ora gestisce bene le prerotazioni
- Corretta info indice rotazione su Proc
2026-04-13 13:01:56 +02:00
andrea.villa 6fe6b41e87 Migliorie calcolo prerotazioni 2026-04-13 12:28:09 +02:00
andrea.villa 78189631c1 Aggiunto inversione 2026-04-13 09:43:47 +02:00
andrea.villa 1a6433d5f8 Prima versione che sistema il pezzo in interfaccia come è stato preruotato 2026-04-13 08:08:14 +02:00
luca.mazzoleni 28026358b9 - aggiunto GetBeamData per lettura parametri macchina da interfaccia 2026-04-10 11:19:27 +02:00
luca.mazzoleni b73fb86be9 - in BatchProcessNew si sposta cancellazione gruppo temporaneo a dopo la ProcessAlternatives
- in BLADETOWASTE CalculateDiceMachinings commentata inversione facce per normale non raggiungibile (ci pensa già la FaceByBlade)
2026-04-09 15:59:30 +02:00
luca.mazzoleni 1032557782 Merge branch 'FlipRotInBatchProcessNew' into develop 2026-04-08 13:33:17 +02:00
andrea.villa 0ca5f92b96 - tolto paraemtro generale GEN_bTestAlternative, sostituito da GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION'. Se utente abilita ricerca delle prerotazioni anche a 90°, significa che accetta anche ottimizzazioni nel nesting ruotando pezzo a 90°, probabilmente fibra non importante
- In BatchProcessNew, quando si crea la barra, il paraemtro FlipRot dipende dal BEAM.FLAG == 10
2026-04-03 16:13:15 +02:00
luca.mazzoleni 0f58c026d0 - in BatchProcessNew gestito Flag 10 per FlipRot 2026-04-03 15:05:15 +02:00
luca.mazzoleni 70d170b2a3 Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2026-04-02 18:13:38 +02:00
luca.mazzoleni 06bc0f77df Merge branch 'AntiSplintOnSTR0002' into develop 2026-04-02 18:13:34 +02:00
luca.mazzoleni a40cc026c9 - in STR0002 implementato AntiSplint
- in ANTISPLINTONFACE piccole modifiche
2026-04-02 18:13:25 +02:00
andrea.villa 34fb38ac00 Piccola correzione sul nome della feature StartCut e EndCut 2026-04-01 16:31:15 +02:00
andrea.villa aaa06c1af5 Corretto indice rotazione da verificare in caso di soluzione invertita. Si aggiunge un offset di 4, l'indice nella tabella delle rotazioni sono 5-6-7-8 2026-04-01 13:17:28 +02:00
luca.mazzoleni 98a48522ee Merge branch 'FlipRot' into develop 2026-04-01 11:41:42 +02:00
andrea.villa 6fd356f757 - Aggiunta tolleranza nella scelta della migliore combinazione di lavorazione. Se voto uguale non era chiaro quale avrebbe scelto prima
- Quando si processano alternative, si resetta flag bPartInCombiIsInverted
2026-04-01 11:06:15 +02:00
andrea.villa 83895cc3bf In STR0002 migliorata gestione topologia 'DoubleBevel-2-Through' 2026-03-31 17:44:49 +02:00
luca.mazzoleni d001273704 - in FlipRot e ProcessAlternatives si scrivono le variabili globali nella tabella Beam per l'interfaccia 2026-03-31 16:11:54 +02:00
luca.mazzoleni 621c9149b5 Merge branch 'ChainsawVerifyOutStroke' into develop 2026-03-26 17:44:22 +01:00
luca.mazzoleni f6f625c7cc - in FACEBYCHAINSAW si escludono casi in cui l'asse bloccato non è calcolato 2026-03-26 17:43:09 +01:00
luca.mazzoleni 9d8985093d - in PreSimulationLib.CheckOutStrokePoint modifiche per contemplare terzo asse rotativo 2026-03-26 17:25:56 +01:00
luca.mazzoleni fe8275f05a - in PreSimulationLib.CheckOutOfStrokeFromPoints e altri si contemplano vettore ausiliario e asse bloccato per verificare finecorsa sega a catena
- in STR0004 se non applicabile si cambia lato, se possibile
- in FACEBYCHAINSAW si verifica finecorsa
2026-03-24 14:36:52 +01:00
andrea.villa d32403f546 Il parametro GEN_nMaxReProcessCycles viene letto ora dal pezzo e non dalla lista dei parametri generali (la quale potrebbe avere quelli -sbagliati- di default). 2026-03-18 10:27:29 +01:00
luca.mazzoleni 63d4ca7176 - in PreSimulationLib correzione al calcolo vtC, vettore asse C 2026-03-17 17:07:42 +01:00
luca.mazzoleni 0889ae5c7a - in STR0002 corretti casi in cui non ci sono le LongFaces
- in STR0003 e STR0004 se non ci sono MainFaces e MainEdges necessari si esce
2026-03-17 16:37:00 +01:00
andrea.villa 0fc9e1dd09 - Se la lavorazione non ha percorso, la si disattiva
- Se rotazione impostata su "IF_NECESSARY", prima del numero rotazioni, si controllano il numero di feature non eseguite
2026-03-13 13:26:20 +01:00
luca.mazzoleni 63308c0349 - correzione in BLADEKEEPWASTE 2026-03-12 17:24:25 +01:00
luca.mazzoleni 7e5ab8ecd3 Merge branch 'BLADEKEEPWASTEImprovement' into develop 2026-03-12 17:08:19 +01:00
luca.mazzoleni bddaf91fb7 - in STR0003 si evita caso con Groove-3 passante e pareti oblique
- in STR0010 migliorie
- in BLADEKEEPWASTE aggiunta pulizia lati chiusi con sistema nuovo
2026-03-12 17:08:07 +01:00
luca.mazzoleni 2c77277c85 - alle StrategyLibs aggiunta ANTISPLINTONFACE per calcolare le lavorazioni antischeggia passando una faccia; STR0010 e BLADEKEEPWASTE modificate di conseguenza
- in BLADEKEEPWASTE migliorie e correzioni; manca ancora la pulitura con fresa
- in FACEBYBLADE rimossa dimensione minima lato maggiore del diametro lama. Si può avere un accorciamento massimo pari alla lunghezza lato
2026-03-06 18:23:24 +01:00
luca.mazzoleni 38a6ac237e Merge branch 'develop' into BLADEKEEPWASTEImprovement 2026-03-06 12:43:28 +01:00
luca.mazzoleni ed4d97ba51 Merge branch 'STR0010Improvement' into develop 2026-03-06 12:43:13 +01:00
luca.mazzoleni 7b12eaf331 - in BatchProcessNew -> GET_TOPOLOGY si legge anche nParts (serve nel Classify Topology)
- in STR0005 si ammettono feature a più di 3 lati se la topologia è DoubleBevel
- in BLADEKEEPWASTE si gestisce topologia DoubleBevel e migliorie varie
2026-03-06 12:42:53 +01:00
luca.mazzoleni 3e55af917e - in BLADETOWASTE gestito caso in cui arrivano due facce separate 2026-03-04 18:02:43 +01:00
luca.mazzoleni 73b6d80510 - in FeatureLib->ClassifyTopology correzione al riconoscimento DoubleBevel su più parti
- in FaceData correzioni per i casi DoubleBevel su più parti
- in BeamExec->CollectFeatures si scrive il numero di parti di cui è composta la trimesh
2026-03-04 16:13:31 +01:00
luca.mazzoleni 65c2c244d6 in STR0010 aggiunto antischeggia facce di chiusura 2026-03-04 12:19:29 +01:00
luca.mazzoleni 2ae547a24e - in FeatureLib correzioni a classificazione topologia DoubleBevel
- in STR0010 aggiunte passate di finitura con fresa e piccole correzioni
2026-03-04 09:26:47 +01:00
luca.mazzoleni aff61f1daa Merge remote-tracking branch 'origin/develop' into STR0010Improvement 2026-03-03 09:45:20 +01:00
luca.mazzoleni 0db6a74f8c - in FaceData e FeatureLib modifiche per gestire DoubleBevel
- in STR0010 modifiche per gestire casi non contemplati
2026-03-03 09:45:11 +01:00
andrea.villa f68533944c Merge branch 'NewRotationMng' into develop 2026-03-02 13:26:56 +01:00
andrea.villa 37e08e3f42 - Aggiunto tempo di calcolo delle alternative
- Di default la ricerca delle alternative è disattiva
- Piccole migliorie varie
2026-03-02 13:23:28 +01:00
andrea.villa c6ced91b14 - Aggiunti parametri configurabili GEN_bTestAlternative e GEN_bGetAlternativesNesting2D per testare altre alternative valide
- Aggiunta funzione dedicata alla creazione del gruppo ausiliario al MachGroup
- Alla funzione BeamExec.GetCombinationListFromMatrix si può passare una lista con le sole combinazioni da provare
- Nella BeamExec aggiunta funzione ProcessAlternatives solo per provare le alternative (simile alla ProcessFeatures, ma completamente slegata). La ProcessFeature decide il posizionamento iniziale, la ProcessAlternatives verifica solamente le alternative.
- FlipRot adeguata a nuovo funzionamento
- Altre piccole migliorie varie
- TODO :
   1) manca la parte per settare nelle info pezzo la rotazione iniziale (per vista in Aedifica) e le altre alternative (per ottimizzazione in nesting)
   2) In FlipRot gestire interazione con Aedifica, dato che verrà lanciato direttamente dal programma (per ora funziona lanciato come la Process)
2026-03-02 12:35:12 +01:00
luca.mazzoleni 8efb64810a - in FaceData si raccolgono informazioni sulle facce fino a 6 lati compresi 2026-02-26 17:56:12 +01:00
andrea.villa 02390c2e9b - Tolte pre-rotazioni dalla Process
- FlipRot modificata, ora ereditata dalla Process
2026-02-24 16:50:48 +01:00
andrea.villa 7f7d75c113 - BatchProcess non calcola più le prerotazioni
- Modifiche varie per nuova gestione pre-rotazioni
- Nuovo script FlipRot (per ora copiata da BatchProcess, poi dovrà ruotare i pezzi e posizionarli in base alla migliore posizione di lavoro)
2026-02-23 16:24:43 +01:00
andrea.villa ecd50c0fea Piccola correzione gestione ricalcolo lavorazioni dopo applicazione 2026-02-10 13:33:05 +01:00
andrea.villa 6f195e7fac Merge branch 'ReprocessOnApplyError' into develop 2026-02-10 09:45:49 +01:00
38 changed files with 2275 additions and 864 deletions
+21 -14
View File
@@ -214,9 +214,6 @@ end
local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. ( BEAM.MACHINE or EgtGetCurrMachineName()) .. ', ' .. sFlag local sLog = 'BatchProcess : ' .. BEAM.FILE .. ', ' .. ( BEAM.MACHINE or EgtGetCurrMachineName()) .. ', ' .. sFlag
EgtOutLog( sLog) EgtOutLog( sLog)
-- TODO forzatura calcolo con prerotazioni. Cancellare dopo che è stata aggiunta la gestione corretta
local bCalcBestPieceUnloadPosition = true or BEAM.FLAG == 10
-- Dati dei file -- Dati dei file
-- TODO spostare a quando flag ~= 6 e 9 -- TODO spostare a quando flag ~= 6 e 9
local sDir, sTitle = EgtSplitPath( BEAM.FILE) local sDir, sTitle = EgtSplitPath( BEAM.FILE)
@@ -253,6 +250,7 @@ elseif BEAM.FLAG == 9 then
local Proc = FeatureLib.GetProcFromTrimesh( BEAM.FEATUREID, Part) local Proc = FeatureLib.GetProcFromTrimesh( BEAM.FEATUREID, Part)
Proc.nGrp = EgtGetInfo( Proc.id, 'GRP', 'i') Proc.nGrp = EgtGetInfo( Proc.id, 'GRP', 'i')
Proc.nPrc = EgtGetInfo( Proc.id, 'PRC', 'i') Proc.nPrc = EgtGetInfo( Proc.id, 'PRC', 'i')
Proc.nParts = EgtSurfTmPartCount( Proc.id) or 1
Proc.Topology = {} Proc.Topology = {}
if FeatureLib.NeedTopologyFeature( Proc, Part) then if FeatureLib.NeedTopologyFeature( Proc, Part) then
@@ -494,6 +492,7 @@ if bToProcess then
return return
end end
-- TODO in caso di "GEN_sPiecesLoadingPosition = FULL_PRE_ROTATION" bisogna controllare anche sezione ribaltata di 90°
-- Verifico sezione barra non troppo grande -- Verifico sezione barra non troppo grande
if not BeamData.MAX_WIDTH2 or not BeamData.MAX_HEIGHT2 then 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 if ( dRawW > BeamData.MAX_WIDTH + 10 * GEO.EPS_SMALL or dRawH > BeamData.MAX_HEIGHT + 10 * GEO.EPS_SMALL) then
@@ -551,7 +550,7 @@ if bToProcess then
end end
-- Sistemo le travi nel grezzo -- Sistemo le travi nel grezzo
local bPbOk, sPbErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, nil, PARTS, BEAM.FLAG ~= 6, bCalcBestPieceUnloadPosition) local bPbOk, sPbErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, nil, PARTS, BEAM.FLAG ~= 6, BEAM.FLAG == 10)
if not bPbOk then if not bPbOk then
BEAM.ERR = 18 BEAM.ERR = 18
BEAM.MSG = sPbErr BEAM.MSG = sPbErr
@@ -640,7 +639,8 @@ if bToProcess then
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig) BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON) PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
TIMER:stopElapsed('Json') TIMER:stopElapsed('Json')
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bCalcBestPieceUnloadPosition) -- parametro FlipRot sempre a false perchè a barra già creata non si possono più ruotare i pezzi
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], false)
-- sovramateriale in testa al pezzo -- sovramateriale in testa al pezzo
local dDeltaS = max( PARTS[i].dPosX - ( dBarLen - dLen), 0) local dDeltaS = max( PARTS[i].dPosX - ( dBarLen - dLen), 0)
@@ -693,12 +693,9 @@ if bToProcess then
-- TODO gestire errori e messaggi di ritorno in questo caso -- TODO gestire errori e messaggi di ritorno in questo caso
if not GetDataConfig() then return end if not GetDataConfig() then return end
BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) BeamExec.GetProcessings( PARTS, BEAM.FLAG == 10)
BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) BeamExec.GetCombinationMatrix( PARTS, BEAM.FLAG == 10)
BeamExec.ProcessMachinings( PARTS) BeamExec.ProcessMachinings( PARTS, BEAM.FLAG == 10)
-- si cancella gruppo temporaneo contenente entità da cancellare
EgtErase( idTempGroup)
local sOutput = '' local sOutput = ''
@@ -725,7 +722,7 @@ if bToProcess then
BEAM.ERR = 0 BEAM.ERR = 0
BEAM.MSG = '---' BEAM.MSG = '---'
end 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.CUTID = RESULT[i].idCut
BEAM.TASKID = RESULT[i].idTask BEAM.TASKID = RESULT[i].idTask
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
@@ -741,7 +738,7 @@ if bToProcess then
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg) sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
BEAM.ERR = 19 BEAM.ERR = 19
BEAM.MSG = sMsg 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.CUTID = RESULT[i].idCut
BEAM.TASKID = RESULT[i].idTask BEAM.TASKID = RESULT[i].idTask
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
@@ -767,7 +764,7 @@ if bToProcess then
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg) sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
BEAM.ERR = -19 BEAM.ERR = -19
BEAM.MSG = 'Incomplete : Completion index ' .. RESULT[i].ChosenStrategy.dCompletionIndex .. '/5\n' .. sMsg 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.CUTID = RESULT[i].idCut
BEAM.TASKID = RESULT[i].idTask BEAM.TASKID = RESULT[i].idTask
WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID) WriteErrToLogFile( BEAM.ERR, BEAM.MSG, BEAM.ROT, BEAM.CUTID, BEAM.TASKID)
@@ -775,6 +772,16 @@ if bToProcess then
end end
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 -- TODO: se scarico a caduta (-101, -102) le lavorazioni dopo separazione vanno disattivate. Scrivere info feature incompleta su quelle feature
-- Salvo il progetto -- Salvo il progetto
+247
View File
@@ -0,0 +1,247 @@
-- Process.lua by Egalware s.r.l. 2024/04/02
-- Gestione calcolo disposizione e lavorazioni per Travi
-- Si opera sulla macchina corrente
-- 2024/04/02 PRIMA VERSIONE
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
-- Imposto direttorio strategie. N.B. Le strategie dovranno essere caricate con il nome del direttorio padre
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua')
EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.lua')
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
local sMachDir = EgtGetCurrMachineDir()
if not sMachDir then
EgtOutBox( 'Errore nel caricamento della macchina corrente', 'Lavora Travi', 'ERROR')
return
end
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
EgtOutBox( 'La macchina corrente non è configurata per lavorare travi', 'Lavora Travi', 'ERROR')
return
end
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
EgtRemoveBaseMachineDirFromPackagePath()
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
-- Segnalazione avvio
EgtOutLog( '*** Beam Process Start ***', 1)
-- Carico le librerie
_G.package.loaded.BasicCustomerStrategies = nil
_G.package.loaded.BeamExec = nil
_G.package.loaded.BeamLib = nil
_G.package.loaded.DiceCut = nil
_G.package.loaded.FaceData = nil
_G.package.loaded.FeatureLib = nil
_G.package.loaded.Identity = nil
_G.package.loaded.Logs = nil
_G.package.loaded.MachiningLib = nil
_G.package.loaded.PreSimulationLib = nil
_G.package.loaded.LeadInOutLib = nil
-- strategie di base sempre presenti
_G.package.loaded['HEADCUT\\HEADCUT'] = nil
_G.package.loaded['TAILCUT\\TAILCUT'] = nil
-- libreria macchina
_G.package.loaded.BeamDataNew = nil
-- libreria calcolo tempo esecuzione
_G.package.loaded.TimeLib = nil
-- TODO controllare se c'è un modo migliore per resettare librerie delle strategie caricate precedentemente
-- Per ottimizzare potremmo anche ciclare solo fino al numero di strategie raggiunto per il momento.
-- Infatti difficile ci siano 9999 strategie.
-- reset strategie caricate come librerie
for i = 1, 9999 do
local idSTRTemp = EgtReplaceString( EgtNumToString( i/10000, -4), '0.', '')
local sLibraryToReload = "STR" .. idSTRTemp .. "\\STR" .. idSTRTemp
if _G.package.loaded[sLibraryToReload] then
_G.package.loaded[sLibraryToReload] = nil
end
end
local vtCoreStrategiesNames = EgtFindAllFiles( BEAM.BASEDIR .. '\\StrategyLibs\\*.lua')
for i = 1, #vtCoreStrategiesNames do
local sCurrentName = EgtSplitString( vtCoreStrategiesNames[i], '.')[1]
if _G.package.loaded[sCurrentName] then
_G.package.loaded[sCurrentName] = nil
end
end
-- Variabili globali
PARTS = {} -- tabella contenente tutte le informazioni di ogni pezzo
-- Carico i dati globali
local BeamData = require( 'BeamDataNew')
-- carico librerie
local BeamExec = require( 'BeamExec')
local BeamLib = require( 'BeamLib')
-------------------------------------------------------------------------------------------------------------
-- *** Recupero trave (E' SEMPRE E SOLO UNA) ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessInputData()
-- Recupero il pezzo e i suoi dati
local nId = EgtGetFirstPart()
if nId then
table.insert( PARTS, { nInd = #PARTS + 1, id = nId, sName = ( EgtGetName( nId) or ( 'Id=' .. tonumber( nId)))})
local Ls = EgtGetFirstNameInGroup( PARTS[1].id, 'Box')
local b3Solid = EgtGetBBoxGlob( Ls or GDB_ID.NULL, GDB_BB.STANDARD)
if not b3Solid then
return false
end
PARTS[1].b3PartOriginal = b3Solid
else
return false
end
return true
end
-------------------------------------------------------------------------------------------------------------
local function GetDataConfig()
-- recupero utensili dal magazzino
BeamExec.GetToolsFromDB()
-- TODO da gestire eventuali errori bloccanti
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle travi nel grezzo ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessBeams()
-- Lunghezza totale delle travi
local dLen = PARTS[1].b3PartOriginal:getDimX()
local dRawW = PARTS[1].b3PartOriginal:getDimY()
local dRawH = PARTS[1].b3PartOriginal:getDimZ()
-- Determinazione minimo grezzo scaricabile
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH)
local dOvmHead = BeamData.OVM_HEAD or 10
local dOvmMid = BeamData.OVM_MID or 10
local dRawL = max( dLen + dOvmHead + dOvmMid, BeamData.dMinRaw)
-- Recupero info pezzi
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, true)
if not bOk then
EgtOutLog( sErr)
return false
end
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Inserimento delle lavorazioni nelle travi ***
-------------------------------------------------------------------------------------------------------------
local function MyProcessFeatures()
BeamExec.GetProcessings( PARTS, true)
BeamExec.GetCombinationMatrix( PARTS, true)
BeamExec.ProcessMachinings( PARTS, true)
-- scrittura variabili globali per interfaccia
BEAM.PREROTATE90 = PARTS[1].nInitialPosition - 1
BEAM.PREINVERT = EgtIf( PARTS[1].bPartInCombiIsInverted, 1, 0)
local nErrCnt = 0
local nWarnCnt = 0
local sOutput = ''
for i = 1, #RESULT do
local sMsg = ''
if RESULT[i].sType == 'Feature' then
sMsg = RESULT[i].ChosenStrategy.sInfo
elseif RESULT[i].sType == 'Part' then
sMsg = RESULT[i].sMsg
end
sMsg = string.gsub( sMsg or '', '\n', ' ', 10)
sMsg = string.gsub( sMsg or '', '\r', ' ', 10)
-- trovata almeno una strategia e feature lavorata completamente
if RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Completed' then
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg or '')
-- trovata almeno una strategia ma nessuna applicabile oppure non trovata alcuna strategia
elseif RESULT[i].sType == 'Feature'
and ( ( RESULT[i].ChosenStrategy.sStatus == 'Not-Applicable')
or ( not RESULT[i].ChosenStrategy.sStrategyName)) then
nErrCnt = nErrCnt + 1
if #sMsg == 0 then
sMsg = 'No applicable strategy found'
end
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
else
-- segnalazione scarico pezzo standard, incompleto o a caduta
if RESULT[i].sType == 'Part' and ( RESULT[i].nErr == -100 or RESULT[i].nErr == -101 or RESULT[i].nErr == -102) then
-- nulla da segnalare
-- feature incompleta e altro
elseif RESULT[i].sType == 'Feature' and RESULT[i].ChosenStrategy.sStatus == 'Not-Completed' then
nWarnCnt = nWarnCnt + 1
sMsg = 'Incomplete : Completion index ' .. RESULT[i].ChosenStrategy.dCompletionIndex .. '/5\n' .. sMsg
sOutput = sOutput .. string.format( '[%d,%d] %s\n', RESULT[i].idCut, RESULT[i].idTask, sMsg)
end
end
end
-- si calcolano alternative
TIMER:startElapsed('Alternatives')
BeamExec.ProcessAlternatives( PARTS)
TIMER:stopElapsed('Alternatives')
-- cancello gruppo temporaneo
local idTempGroup = BeamLib.GetTempGroup()
EgtErase( idTempGroup)
if #sOutput > 0 then EgtOutLog( sOutput) end
if nErrCnt > 0 then
EgtOutBox( sOutput, 'Lavora Travi', 'ERRORS')
return false
elseif nWarnCnt > 0 then
EgtOutBox( sOutput, 'Lavora Travi', 'WARNINGS')
return true
end
return true
end
-------------------------------------------------------------------------------------------------------------
-- *** Esecuzione ***
-------------------------------------------------------------------------------------------------------------
-- calcolo tempo esecuzione
TIMER:start()
EgtOutLog( ' Execution timer started')
-- script principale
if not MyProcessInputData() then return end
-- recupero parametri generali da progetto
BeamExec.GetGeneralParameters()
-- creo un gruppo temporaneo dove finiranno tutte le entità che non bisogna salvare, alla fine lo si cancella
BeamLib.CreateTempGroup()
if not MyProcessBeams() then return end
if not GetDataConfig() then return end
-- Abilito Vmill
EgtSetInfo( EgtGetCurrMachGroup(), 'Vm', '1')
MyProcessFeatures()
-- log tempi di esecuzione
if EgtGetDebugLevel() >= 3 then
TIMER:logAllElapsed()
end
+44
View File
@@ -0,0 +1,44 @@
-- GetWallData.lua by Egaltech s.r.l. 2022/06/28
-- Recupero dati da file WallData.lua di macchina
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Per test
--GWD = {}
--GWD.MACHINE = 'Essetre-90480019_MW'
local sLog = 'GetBeamData : ' .. GWD.MACHINE
EgtOutLog( sLog)
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( GWD.BASEDIR .. '\\LuaLibs\\?.lua')
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
local sMachDir = EgtGetCurrMachineDir()
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamDataNew.lua') then
GWD.ERR = 12
GWD.MSG = 'Error not configured for beam machine : ' .. GWD.MACHINE
WriteErrToLogFile( GWD.ERR, GWD.MSG)
PostErrView( GWD.ERR, GWD.MSG)
return
end
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
EgtRemoveBaseMachineDirFromPackagePath()
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
-- Carico i dati globali
_G.package.loaded.BeamData = nil
local BD = require( 'BeamDataNew')
-- Assegno valori di interesse
GWD.SIMUL_VIEW_DIR = BD.SIMUL_VIEW_DIR
GWD.OVM_MID = BD.OVM_MID
-- Tutto ok
GWD.ERR = 0
EgtOutLog( ' +++ GetBeamData completed')
+577 -147
View File
@@ -251,28 +251,28 @@ function BeamExec.GetStrategiesFromJSONinBD( sAISetupConfigName)
end end
end end
-- TODO prevedere parametri per preferire carico del pezzo verticale oppure orizzontale?
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- funzione che controlla validità delle combinazioni proposte -- funzione che controlla validità delle combinazioni proposte
local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection, GeneralParameters, bCalcBestPieceUnloadPosition) local function IsCombinationAvailable( sCombination, nUnloadPos, GeneralParameters, bIsFlipRot)
-- PREROTATION : flip-rot, si considerano tutte le posizioni possibili, a meno che non si voglia come da BTL -- PREROTATION : flip-rot, si considerano tutte le posizioni possibili, a meno che non si voglia come da BTL
if bCalcBestPieceUnloadPosition and GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then if bIsFlipRot and GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then
local nRotation90 = EgtIf( nUnloadPos + 1 > 4, nUnloadPos + 1 - 4, nUnloadPos + 1) local nRotation90 = EgtIf( nUnloadPos + 1 > 4, nUnloadPos + 1 - 4, nUnloadPos + 1)
local nRotation180 = EgtIf( nUnloadPos + 2 > 4, nUnloadPos + 2 - 4, nUnloadPos + 2) local nRotation180 = EgtIf( nUnloadPos + 2 > 4, nUnloadPos + 2 - 4, nUnloadPos + 2)
local nExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3) local nExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3)
if not bSquareSection and ( nUnloadPos == 2 or nUnloadPos == 4) then -- se fase di unload disabilitata e soluzioni con terza rotazione sempre disabilitate
if string.sub( sCombination, nUnloadPos, nUnloadPos) ~= '1' or string.sub( sCombination, nExtraRotation, nExtraRotation) == '1' then
return false
elseif GeneralParameters.GEN_sPiecesLoadingPosition == 'STD_PRE_ROTATION' and ( nUnloadPos == 2 or nUnloadPos == 4) then
return false return false
else else
if string.sub( sCombination, nUnloadPos, nUnloadPos) ~= '1' or string.sub( sCombination, nExtraRotation, nExtraRotation) == '1' then if ( not BeamData.ROT90 or GeneralParameters.GEN_sPiecesLoadingPosition == 'STD_PRE_ROTATION') and string.sub( sCombination, nRotation90, nRotation90) == '1' then
return false
elseif not BeamData.ROT180 and string.sub( sCombination, nRotation180, nRotation180) == '1' then
return false return false
else else
if not BeamData.ROT90 and string.sub( sCombination, nRotation90, nRotation90) == '1' then return true
return false
elseif not BeamData.ROT180 and string.sub( sCombination, nRotation180, nRotation180) == '1' then
return false
else
return true
end
end end
end end
-- se invece si è nel caso standard di calcolo -- se invece si è nel caso standard di calcolo
@@ -286,7 +286,7 @@ local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection,
end end
-- STANDARD : posizione di scarico come posizionamento iniziale -- STANDARD : posizione di scarico come posizionamento iniziale
else else
local ExtraRotation = nUnloadPos + 3 local ExtraRotation = EgtIf( nUnloadPos + 3 > 4, nUnloadPos + 3 - 4, nUnloadPos + 3)
if nUnloadPos ~= 1 then if nUnloadPos ~= 1 then
return false return false
elseif string.sub( sCombination, nUnloadPos, nUnloadPos) == '1' and string.sub( sCombination, ExtraRotation, ExtraRotation) == '0' then elseif string.sub( sCombination, nUnloadPos, nUnloadPos) == '1' and string.sub( sCombination, ExtraRotation, ExtraRotation) == '0' then
@@ -305,12 +305,16 @@ local function IsCombinationAvailable( sCombination, nUnloadPos, bSquareSection,
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamExec.GetAvailableCombinations( PartInfo, bCalcBestPieceUnloadPosition) function BeamExec.GetAvailableCombinations( PartInfo, bIsFlipRot)
local CombinationList = {} local CombinationList = {}
CombinationList.Rotations = {0, 0, 0, 0} -- indice rotazione attiva, per calcolo collect feature CombinationList.Rotations = {0, 0, 0, 0} -- indice rotazione attiva, per calcolo collect feature
local nCycles = 1
-- se si sta calcolando il migliore posizionamento del pezzo, verifico se sono ammesse le combinazioni con pezzo invertito
if bIsFlipRot and PartInfo.GeneralParameters.GEN_bAllowPieceInversion then
nCycles = 2
end
-- se sto effettivamente calcolando, il pezzo è già in posizione e non può essere invertito. Se sono in preverifica, allora devo considerare anche eventuali inversioni del pezzo
local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PartInfo.GeneralParameters.GEN_sPiecesLoadingPosition == 'BEST_POSITION', 2, 1)
-- verifico tutte le combinazioni che possono essere considerate -- verifico tutte le combinazioni che possono essere considerate
for nInvertIndex = 1, nCycles do for nInvertIndex = 1, nCycles do
for nUnloadPos = 1, 4 do for nUnloadPos = 1, 4 do
@@ -318,7 +322,7 @@ function BeamExec.GetAvailableCombinations( PartInfo, bCalcBestPieceUnloadPositi
local nBitIndexCombination = BeamLib.DecimalToBinary( i) local nBitIndexCombination = BeamLib.DecimalToBinary( i)
local sBitIndexCombination = BeamLib.CalculateStringBinaryFormat( nBitIndexCombination, 4) local sBitIndexCombination = BeamLib.CalculateStringBinaryFormat( nBitIndexCombination, 4)
-- si calcolano le combinazioni all'inizio, ottimizzando calcolo della collect solo nelle rotazioni che possono essere considerate -- si calcolano le combinazioni all'inizio, ottimizzando calcolo della collect solo nelle rotazioni che possono essere considerate
if IsCombinationAvailable( sBitIndexCombination, nUnloadPos, PartInfo.bSquareSection, PartInfo.GeneralParameters, bCalcBestPieceUnloadPosition) then if IsCombinationAvailable( sBitIndexCombination, nUnloadPos, PartInfo.GeneralParameters, bIsFlipRot) then
local Combination = {} local Combination = {}
Combination.sBitIndexCombination = sBitIndexCombination Combination.sBitIndexCombination = sBitIndexCombination
Combination.nUnloadPos = nUnloadPos Combination.nUnloadPos = nUnloadPos
@@ -354,7 +358,7 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- *** funzioni posizionamento pezzi all'interno della barra *** -- *** funzioni posizionamento pezzi all'interno della barra ***
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bCalcBestPieceUnloadPosition) function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bIsFlipRot)
-- gruppo per geometrie temporanee -- gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup() local idTempGroup = BeamLib.GetTempGroup()
@@ -504,7 +508,7 @@ function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, b
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig) BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON) PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
TIMER:stopElapsed('Json') TIMER:stopElapsed('Json')
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bCalcBestPieceUnloadPosition) PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bIsFlipRot)
PARTS[i].idTempGroup = idTempGroup PARTS[i].idTempGroup = idTempGroup
else else
@@ -641,6 +645,8 @@ local function CollectFeatures( Part, dRotIndex)
Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part)
-- volume feature approssimato -- volume feature approssimato
Proc.dVolume = FeatureLib.GetFeatureVolume( Proc, Part) Proc.dVolume = FeatureLib.GetFeatureVolume( Proc, Part)
-- se trimesh, numero di parti di cui è composta
Proc.nParts = EgtSurfTmPartCount( Proc.id) or 1
-- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL -- calcolo topologia solo se necessario, altrimenti si sfruttano le informazioni della feature BTL
local bIsFeatureReadyForProcessing = false local bIsFeatureReadyForProcessing = false
if FeatureLib.NeedTopologyFeature( Proc, Part) then if FeatureLib.NeedTopologyFeature( Proc, Part) then
@@ -966,7 +972,6 @@ local function CalculateStrategies( vProcSingleRot, Part)
-- eseguo file config con i parametri di default -- eseguo file config con i parametri di default
local CurrentStrategy = {} local CurrentStrategy = {}
CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId) CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId)
-- TODO in caso di ulteriore ciclo dovuto a errori imprevisti, controllare se questa strategia è quella che ha dato errore e disabilitarla senza calcolare nulla
-- controllo che le librerie siano state effettivamente caricate -- controllo che le librerie siano state effettivamente caricate
if CurrentStrategy.Config and CurrentStrategy.Script then if CurrentStrategy.Config and CurrentStrategy.Script then
-- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati -- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
@@ -1075,7 +1080,7 @@ local function OrderFeatures( vProc)
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
local function AddFeatureResultToGlobalList( Proc, OptionalParameters) local function AddFeatureResultToGlobalList( Part, Proc, OptionalParameters)
local sStrategyId local sStrategyId
local sStatus local sStatus
local dCompletionIndex local dCompletionIndex
@@ -1094,13 +1099,14 @@ local function AddFeatureResultToGlobalList( Proc, OptionalParameters)
if Proc.isVirtualProc then if Proc.isVirtualProc then
return return
end end
local ChosenStrategyTable = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation][Proc.nIndexMasterProc].ChosenStrategy local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
local ChosenStrategyTable = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation+nOffsetIndex][Proc.nIndexMasterProc].ChosenStrategy
if ChosenStrategyTable then if ChosenStrategyTable then
sStrategyId = ChosenStrategyTable.sStrategyId sStrategyId = ChosenStrategyTable.sStrategyId
sStatus = ChosenStrategyTable.Result.sStatus sStatus = ChosenStrategyTable.Result.sStatus
dCompletionIndex = ChosenStrategyTable.Result.dCompletionIndex dCompletionIndex = ChosenStrategyTable.Result.dCompletionIndex
dCompositeRating = ChosenStrategyTable.Result.dCompositeRating dCompositeRating = ChosenStrategyTable.Result.dCompositeRating
local idFeature = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation][Proc.nIndexMasterProc].idFeature local idFeature = PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation+nOffsetIndex][Proc.nIndexMasterProc].idFeature
sApplyInfo = 'Skipped. Feature machined: ' .. EgtNumToString( idFeature) sApplyInfo = 'Skipped. Feature machined: ' .. EgtNumToString( idFeature)
end end
elseif Proc.ChosenStrategy then elseif Proc.ChosenStrategy then
@@ -1189,15 +1195,16 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
_, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy) _, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy)
-- se tutte le strategie disponibili non sono applicabili -- se tutte le strategie disponibili non sono applicabili
else else
local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
-- se non esiste una strategia scelta (non dovrebbe mai succedere) cancello da lista generale -- se non esiste una strategia scelta (non dovrebbe mai succedere) cancello da lista generale
PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation][Proc.nIndexInVProc].ChosenStrategy = nil PROCESSINGS[Proc.nIndexPartInParts].Rotation[Proc.nIndexRotation+nOffsetIndex][Proc.nIndexInVProc].ChosenStrategy = nil
-- TODO dare messaggio che la feature non è stata eseguita nonostante la presenza di strategie disponibili -- TODO dare messaggio che la feature non è stata eseguita nonostante la presenza di strategie disponibili
end end
end end
-- scrivo risultato in tabella globale -- scrivo risultato in tabella globale
AddFeatureResultToGlobalList( Proc, { nRotation = nCurrRotation}) AddFeatureResultToGlobalList( Part, Proc, { nRotation = nCurrRotation})
end end
-- ripristino pezzo in posizione originale -- ripristino pezzo in posizione originale
@@ -1224,8 +1231,8 @@ local function PrintFeatures( vProc, Part)
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) -- funzione che recupera tutti i processing di tutti i pezzi in tutte le rotazioni
-- recupero tutti i processing di tutti i pezzi in tutte le rotazioni function BeamExec.GetProcessings( PARTS, bIsFlipRot)
-- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola -- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola
EgtSetTableAreaOffset( 2000, 2000, 2000, 2000) EgtSetTableAreaOffset( 2000, 2000, 2000, 2000)
@@ -1235,7 +1242,8 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
local vProcRot = {} local vProcRot = {}
-- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti -- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION', 2, 1) local bCalcInverted = bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion
local nCycles = EgtIf( bCalcInverted, 2, 1)
-- per ogni inversione -- per ogni inversione
for nInvertIndex = 1, nCycles do for nInvertIndex = 1, nCycles do
-- per ogni rotazione -- per ogni rotazione
@@ -1246,7 +1254,7 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
if PARTS[nPart].CombinationList.Rotations[nRotIndex] == 1 then if PARTS[nPart].CombinationList.Rotations[nRotIndex] == 1 then
-- recupero le feature di lavorazione della trave -- recupero le feature di lavorazione della trave
table.insert( vProcRot, CollectFeatures( PARTS[nPart], nIndex)) table.insert( vProcRot, CollectFeatures( PARTS[nPart], nIndex))
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse -- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no -- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
vProcRot[nIndex] = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart]) vProcRot[nIndex] = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart])
@@ -1260,7 +1268,8 @@ function BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition)
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD)
end end
if bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then -- se si devono calcolare anche gli invertiti
if bCalcInverted then
-- inversione pezzo testa-coda -- inversione pezzo testa-coda
BeamLib.InvertRawPart( PARTS[nPart], 2) BeamLib.InvertRawPart( PARTS[nPart], 2)
-- aggiorno info pezzo -- aggiorno info pezzo
@@ -1290,7 +1299,7 @@ local function GetBestCombination( ListToCompare, Part)
-- scelgo soluzione senza rotazioni -- scelgo soluzione senza rotazioni
if ListToCompare[ListIndex].nRotations == 0 then if ListToCompare[ListIndex].nRotations == 0 then
-- scelgo soluzione con voto più alto -- scelgo soluzione con voto più alto
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then if ListToCompare[nIndexBestCombination].dTotalRating + 10 * GEO.EPS_SMALL < ListToCompare[ListIndex].dTotalRating then
nIndexBestCombination = ListIndex nIndexBestCombination = ListIndex
end end
end end
@@ -1308,8 +1317,11 @@ local function GetBestCombination( ListToCompare, Part)
else else
-- se rotazione ha un grande impatto -- se rotazione ha un grande impatto
if Part.GeneralParameters.GEN_sPieceRotation == 'IF_NECESSARY' then if Part.GeneralParameters.GEN_sPieceRotation == 'IF_NECESSARY' then
-- scelgo soluzione con meno feature saltate
if ListToCompare[ListIndex].nNotExecute < ListToCompare[nIndexBestCombination].nNotExecute then
nIndexBestCombination = ListIndex
-- scelgo soluzione con meno rotazioni indipendentemente dal voto -- scelgo soluzione con meno rotazioni indipendentemente dal voto
if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then elseif ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
nIndexBestCombination = ListIndex nIndexBestCombination = ListIndex
-- se stesso numero di rotazioni -- se stesso numero di rotazioni
elseif ListToCompare[nIndexBestCombination].nRotations == ListToCompare[ListIndex].nRotations then elseif ListToCompare[nIndexBestCombination].nRotations == ListToCompare[ListIndex].nRotations then
@@ -1318,7 +1330,7 @@ local function GetBestCombination( ListToCompare, Part)
nIndexBestCombination = ListIndex nIndexBestCombination = ListIndex
elseif ListToCompare[ListIndex].nComplete == ListToCompare[nIndexBestCombination].nComplete then elseif ListToCompare[ListIndex].nComplete == ListToCompare[nIndexBestCombination].nComplete then
-- scelgo soluzione con voto più alto -- scelgo soluzione con voto più alto
if ListToCompare[nIndexBestCombination].dTotalRating < ListToCompare[ListIndex].dTotalRating then if ListToCompare[nIndexBestCombination].dTotalRating + 10 * GEO.EPS_SMALL < ListToCompare[ListIndex].dTotalRating then
nIndexBestCombination = ListIndex nIndexBestCombination = ListIndex
end end
end end
@@ -1333,10 +1345,10 @@ local function GetBestCombination( ListToCompare, Part)
local dOtherTotalRating = ListToCompare[ListIndex].dTotalRating local dOtherTotalRating = ListToCompare[ListIndex].dTotalRating
-- scelgo soluzione con voto più alto -- scelgo soluzione con voto più alto
if dBestTotalRating < dOtherTotalRating then if dBestTotalRating + 10 * GEO.EPS_SMALL < dOtherTotalRating then
nIndexBestCombination = ListIndex nIndexBestCombination = ListIndex
-- se stesso voto -- se stesso voto
elseif dBestTotalRating == dOtherTotalRating then elseif abs( dBestTotalRating - dOtherTotalRating) < 10 * GEO.EPS_SMALL then
-- scelgo soluzione con meno rotazioni -- scelgo soluzione con meno rotazioni
if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then if ListToCompare[nIndexBestCombination].nRotations > ListToCompare[ListIndex].nRotations then
nIndexBestCombination = ListIndex nIndexBestCombination = ListIndex
@@ -1436,115 +1448,130 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- funzione che calcola le combinazioni di rotazione per lavorare la trave e sceglie la migliore -- funzione che calcola le combinazioni di rotazione per lavorare la trave e sceglie la migliore
local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bReProcessEmptyChosenStrategy) local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bReProcessEmptyChosenStrategy, BitCombinationListToReprocess)
local CombinationsList = { dAllCombinationsTotalTime = 0} local CombinationsList = { dAllCombinationsTotalTime = 0}
-- calcolo per tutte le combinazioni disponibili precedentemente verificate -- calcolo per tutte le combinazioni disponibili precedentemente verificate
for i = 1, #PartInfo.CombinationList do for i = 1, #PartInfo.CombinationList do
local bRot90, bRot180 local bToProcess = false
local SingleCombination = {} -- controllo se debbano essere ricalcolate solo alcune soluzioni
local nUnloadPos = PartInfo.CombinationList[i].nUnloadPos if BitCombinationListToReprocess and #BitCombinationListToReprocess > 0 then
SingleCombination.nRotations = 0 for c = 1, #BitCombinationListToReprocess do
SingleCombination.dTotalTimeToMachine = 0 if PartInfo.CombinationList[i].sBitIndexCombination == BitCombinationListToReprocess[c].sBitIndexCombination and
SingleCombination.dTotalQuality = 0 PartInfo.CombinationList[i].bPartInCombiIsInverted == BitCombinationListToReprocess[c].bPartInCombiIsInverted then
SingleCombination.dTotalCompletionIndex = 0 bToProcess = true
SingleCombination.nComplete = 0 end
SingleCombination.nNotComplete = 0 end
SingleCombination.nNotExecute = 0 else
SingleCombination.sBitIndexCombination = PartInfo.CombinationList[i].sBitIndexCombination bToProcess = true
-- TODO se pezzo invertito bisogna considerare le rotazioni nell'array dalla 5 alla 8 end
SingleCombination.bPartInCombiIsInverted = PartInfo.CombinationList[i].bPartInCombiIsInverted -- si riprocessano tutte a meno che non sia indicata una specifica da riprovare
SingleCombination.nUnloadPos = nUnloadPos if bToProcess then
-- creo liste dei proc suddivisi per rotazione local bRot90, bRot180
SingleCombination.Rot0 = {} local SingleCombination = {}
SingleCombination.Rot90 = {} local nUnloadPos = PartInfo.CombinationList[i].nUnloadPos
SingleCombination.Rot180 = {} SingleCombination.nRotations = 0
SingleCombination.dTotalTimeToMachine = 0
SingleCombination.dTotalQuality = 0
SingleCombination.dTotalCompletionIndex = 0
SingleCombination.nComplete = 0
SingleCombination.nNotComplete = 0
SingleCombination.nNotExecute = 0
SingleCombination.sBitIndexCombination = PartInfo.CombinationList[i].sBitIndexCombination
-- TODO se pezzo invertito bisogna considerare le rotazioni nell'array dalla 5 alla 8
SingleCombination.bPartInCombiIsInverted = PartInfo.CombinationList[i].bPartInCombiIsInverted
SingleCombination.nUnloadPos = nUnloadPos
-- creo liste dei proc suddivisi per rotazione
SingleCombination.Rot0 = {}
SingleCombination.Rot90 = {}
SingleCombination.Rot180 = {}
-- ciclo su tutte le feature, ad eccezione dei tagli testa/coda che dipendono dal risultato delle altre -- ciclo su tutte le feature, ad eccezione dei tagli testa/coda che dipendono dal risultato delle altre
-- tagli testa e coda vengono aggiunti sempre alla fine -- tagli testa e coda vengono aggiunti sempre alla fine
for nProc = 1, #ProcessingsOnPart.Rotation[1] do for nProc = 1, #ProcessingsOnPart.Rotation[1] do
-- Si controlla sempre la rotazione 1 perchè la dipendenza di una feature da un'altra non dipende dalla rotazione -- Si controlla sempre la rotazione 1 perchè la dipendenza di una feature da un'altra non dipende dalla rotazione
-- se feature disattivata perchè eseguita da master a lei associata dichiaro comunque eseguita -- se feature disattivata perchè eseguita da master a lei associata dichiaro comunque eseguita
if ProcessingsOnPart.Rotation[1][nProc].nFlg == 0 and ProcessingsOnPart.Rotation[1][nProc].nIndexMasterProc then if ProcessingsOnPart.Rotation[1][nProc].nFlg == 0 and ProcessingsOnPart.Rotation[1][nProc].nIndexMasterProc then
ProcessingsOnPart.Rotation[1][nProc].nIndexRotation = nUnloadPos ProcessingsOnPart.Rotation[1][nProc].nIndexRotation = nUnloadPos
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[1][nProc]) table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[1][nProc])
SingleCombination.nComplete = SingleCombination.nComplete + 1 SingleCombination.nComplete = SingleCombination.nComplete + 1
else else
if not ID.IsHeadCut( ProcessingsOnPart.Rotation[1][nProc]) and not ID.IsTailCut( ProcessingsOnPart.Rotation[1][nProc]) then
-- ciclo sulle rotazioni
local nNextRot = nUnloadPos
local nOffsetIndex = EgtIf( SingleCombination.bPartInCombiIsInverted, 4, 0) local nOffsetIndex = EgtIf( SingleCombination.bPartInCombiIsInverted, 4, 0)
local ResultsList = {} if not ID.IsHeadCut( ProcessingsOnPart.Rotation[1][nProc]) and not ID.IsTailCut( ProcessingsOnPart.Rotation[1][nProc]) then
for nRotation = 1, 3 do -- ciclo sulle rotazioni
-- se rotazione abilitata da combinazione local nNextRot = nUnloadPos
if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then local ResultsList = {}
local CurrProc = ProcessingsOnPart.Rotation[nNextRot+nOffsetIndex][nProc] for nRotation = 1, 3 do
-- se è ultima rotazione oppure se feature non impatta su misura laser, allora è valida e può essere effettivamente considerata -- se rotazione abilitata da combinazione
if nNextRot == nUnloadPos or not( CurrProc.bHindersLaserMeasure) then if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
-- se non è settata la ChosenStrtegy, provo a cercare comunque tra quelle disponibili local CurrProc = ProcessingsOnPart.Rotation[nNextRot+nOffsetIndex][nProc]
if not CurrProc.ChosenStrategy and bReProcessEmptyChosenStrategy then -- se è ultima rotazione oppure se feature non impatta su misura laser, allora è valida e può essere effettivamente considerata
CurrProc = GetFeatureBestStrategy( CurrProc, PartInfo) if nNextRot == nUnloadPos or not( CurrProc.bHindersLaserMeasure) then
end -- se non è settata la ChosenStrtegy, provo a cercare comunque tra quelle disponibili
-- controllo se è stata scelta una strategia if not CurrProc.ChosenStrategy and bReProcessEmptyChosenStrategy then
if CurrProc.ChosenStrategy then CurrProc = GetFeatureBestStrategy( CurrProc, PartInfo)
local Proc = {} end
Proc.nRotation = nNextRot -- controllo se è stata scelta una strategia
table.insert( Proc, CurrProc) if CurrProc.ChosenStrategy then
table.insert( ResultsList, Proc) local Proc = {}
Proc.nRotation = nNextRot
table.insert( Proc, CurrProc)
table.insert( ResultsList, Proc)
end
end end
end end
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
end end
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
end
-- se la feature può essere lavorata in almeno una rotazione -- se la feature può essere lavorata in almeno una rotazione
if #ResultsList > 0 then if #ResultsList > 0 then
local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo) local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo)
Proc.nIndexRotation = Data.nIndexRotation Proc.nIndexRotation = Data.nIndexRotation
-- inserisco la Proc nell'apposita lista -- inserisco la Proc nell'apposita lista
if Data.nIndexRotation == nUnloadPos then if Data.nIndexRotation == nUnloadPos then
table.insert( SingleCombination.Rot0, Proc) table.insert( SingleCombination.Rot0, Proc)
elseif Data.nIndexRotation == nUnloadPos + 1 then elseif Data.nIndexRotation == nUnloadPos + 1 then
table.insert( SingleCombination.Rot90, Proc) table.insert( SingleCombination.Rot90, Proc)
bRot90 = true bRot90 = true
else
table.insert( SingleCombination.Rot180, Proc)
bRot180 = true
end
SingleCombination.dTotalTimeToMachine = SingleCombination.dTotalTimeToMachine + Data.dTimeToMachine
SingleCombination.dTotalQuality = SingleCombination.dTotalQuality + Data.dQuality
SingleCombination.dTotalCompletionIndex = SingleCombination.dTotalCompletionIndex + Data.dCompletionIndex
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotApplicable, 1, 0)
SingleCombination.nIndexInCombinationList = i
SingleCombination.nIndexRotation = nUnloadPos
else else
table.insert( SingleCombination.Rot180, Proc) ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nIndexRotation = nUnloadPos
bRot180 = true ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nFlg = 0
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc])
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
end end
SingleCombination.dTotalTimeToMachine = SingleCombination.dTotalTimeToMachine + Data.dTimeToMachine
SingleCombination.dTotalQuality = SingleCombination.dTotalQuality + Data.dQuality
SingleCombination.dTotalCompletionIndex = SingleCombination.dTotalCompletionIndex + Data.dCompletionIndex
SingleCombination.nComplete = SingleCombination.nComplete + EgtIf( Data.bComplete, 1, 0)
SingleCombination.nNotComplete = SingleCombination.nNotComplete + EgtIf( Data.bNotComplete, 1, 0)
SingleCombination.nNotExecute = SingleCombination.nNotExecute + EgtIf( Data.bNotApplicable, 1, 0)
SingleCombination.nIndexInCombinationList = i
SingleCombination.nIndexRotation = nUnloadPos
else else
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nIndexRotation = nUnloadPos if ID.IsHeadCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nFlg = 0 SingleCombination.nIndexHeadCutInVProc = nProc
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc]) elseif ID.IsTailCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1 SingleCombination.nIndexTailCutInVProc = nProc
end end
else
if ID.IsHeadCut( ProcessingsOnPart.Rotation[1][nProc]) then
SingleCombination.nIndexHeadCutInVProc = nProc
elseif ID.IsTailCut( ProcessingsOnPart.Rotation[1][nProc]) then
SingleCombination.nIndexTailCutInVProc = nProc
end end
end end
end end
-- aggiungo rotazioni
SingleCombination.nRotations = EgtIf( bRot90, 1, 0) + EgtIf( bRot180, 1, 0)
-- aggiungo tempo totale considerando le rotazioni -- TODO per il momento la rotazione impiega 1 minuto. Serve configurare?
SingleCombination.dTotalTimeToMachine = SingleCombination.dTotalTimeToMachine + ( SingleCombination.nRotations * 1)
-- aggiungo la combinazione all'elenco delle combinazioni disponibili
table.insert( CombinationsList, SingleCombination)
-- aggiorno tempo totale di tutte le combinazioni
CombinationsList.dAllCombinationsTotalTime = CombinationsList.dAllCombinationsTotalTime + SingleCombination.dTotalTimeToMachine
end end
-- aggiungo rotazioni
SingleCombination.nRotations = EgtIf( bRot90, 1, 0) + EgtIf( bRot180, 1, 0)
-- aggiungo tempo totale considerando le rotazioni -- TODO per il momento la rotazione impiega 1 minuto. Serve configurare?
SingleCombination.dTotalTimeToMachine = SingleCombination.dTotalTimeToMachine + ( SingleCombination.nRotations * 1)
-- aggiungo la combinazione all'elenco delle combinazioni disponibili
table.insert( CombinationsList, SingleCombination)
-- aggiorno tempo totale di tutte le combinazioni
CombinationsList.dAllCombinationsTotalTime = CombinationsList.dAllCombinationsTotalTime + SingleCombination.dTotalTimeToMachine
end end
-- si calsola il total rating -- si calsola il total rating
@@ -1554,10 +1581,10 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) function BeamExec.GetCombinationMatrix( PARTS, bIsFlipRot)
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni -- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
for nPart = 1, #PARTS do for nPart = 1, #PARTS do
local nCycles = EgtIf( bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION', 2, 1) local nCycles = EgtIf( bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion, 2, 1)
-- per ogni inversione -- per ogni inversione
for nInvertIndex = 1, nCycles do for nInvertIndex = 1, nCycles do
-- calcolo della migliore strategia per ogni rotazione del pezzo -- calcolo della migliore strategia per ogni rotazione del pezzo
@@ -1574,7 +1601,8 @@ function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw) PARTS[nPart].b3Raw = EgtGetRawPartBBox( PARTS[nPart].idRaw)
PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD) PARTS[nPart].b3Part = EgtGetBBoxGlob( PARTS[nPart].idBoxTm, GDB_BB.STANDARD)
end end
if bCalcBestPieceUnloadPosition and PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition ~= 'BTL_POSITION' then -- se bisogna invertire
if bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
-- inversione del pezzo testa-coda -- inversione del pezzo testa-coda
BeamLib.InvertRawPart( PARTS[nPart], 2) BeamLib.InvertRawPart( PARTS[nPart], 2)
-- aggiorno info pezzo -- aggiorno info pezzo
@@ -1586,21 +1614,23 @@ function BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition)
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamExec.ProcessMachinings( PARTS) function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
-- ciclo sui pezzi -- ciclo sui pezzi
local nTotErr = 0 local nTotErr = 0
local Stats = {} local Stats = {}
local nOrd = 1 local nOrd = 1
local nMaxReProcessCycles = EgtClamp( GENERAL_PARAMETERS.PROJECT.GEN_nMaxReProcessCycles, 1, 3)
local bTryToReProcess = false local bTryToReProcess = false
-- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni -- ricerca strategia di lavorazione per ogni pezzo e applicazione lavorazioni
for nPart = 1, #PARTS do for nPart = 1, #PARTS do
local nCycles = 1 local nCycles = 1
local nMaxReProcessCycles = EgtClamp( PARTS[nPart].GeneralParameters.GEN_nMaxReProcessCycles, 1, 3)
-- la parte di applicazione lavorazioni può essere lanciata più volte in caso della presenza di errori -- la parte di applicazione lavorazioni può essere lanciata più volte in caso della presenza di errori
local bProcess = true local bProcess = true
while bProcess do while bProcess do
-- si resetta la variabile per riprocessare, sarà la AddOperation a decidere se serve riprocessare oppure no
bProcess = false
-- scrittura nel log del risultato della scelta della strategia migliore tra quelle disponibili -- scrittura nel log del risultato della scelta della strategia migliore tra quelle disponibili
if EgtGetDebugLevel() >= 3 then if EgtGetDebugLevel() >= 3 then
Logs.WriteFeaturesLog( PROCESSINGS[nPart], PARTS[nPart], nCycles) Logs.WriteFeaturesLog( PROCESSINGS[nPart], PARTS[nPart], nCycles)
@@ -1665,7 +1695,7 @@ function BeamExec.ProcessMachinings( PARTS)
MACHININGS.Info.nSplitCutRotation = 1 MACHININGS.Info.nSplitCutRotation = 1
-- anche se non ci sono feature da eseguire, bisogna comunque scrivrere i risultati -- anche se non ci sono feature da eseguire, bisogna comunque scrivrere i risultati
for nProc = 1, #vProc do for nProc = 1, #vProc do
AddFeatureResultToGlobalList( vProc[nProc]) AddFeatureResultToGlobalList( PARTS[nPart], vProc[nProc])
end end
-- altrimenti si fanno tutti i calcoli -- altrimenti si fanno tutti i calcoli
else else
@@ -1681,8 +1711,6 @@ function BeamExec.ProcessMachinings( PARTS)
MACHININGS.Info.nSplitCutRotation = 1 MACHININGS.Info.nSplitCutRotation = 1
end end
end end
-- salvo sul PART la posizione di partenza che è stata scelta
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
local nOffsetIndex = EgtIf( PARTS[nPart].bPartInCombiIsInverted, 4, 0) local nOffsetIndex = EgtIf( PARTS[nPart].bPartInCombiIsInverted, 4, 0)
-- aggiunge tagli testa e coda in fasi opportune -- aggiunge tagli testa e coda in fasi opportune
@@ -1690,36 +1718,34 @@ function BeamExec.ProcessMachinings( PARTS)
if nRotHeadCut > 4 then if nRotHeadCut > 4 then
nRotHeadCut = nRotHeadCut - 4 nRotHeadCut = nRotHeadCut - 4
end end
nRotHeadCut = nRotHeadCut + nOffsetIndex
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1 local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
if nRotSplitCut > 4 then if nRotSplitCut > 4 then
nRotSplitCut = nRotSplitCut - 4 nRotSplitCut = nRotSplitCut - 4
end end
nRotSplitCut = nRotSplitCut + nOffsetIndex
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata -- setto nella Proc l'indice rotazione nella quale deve essere lavorata
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
-- si imposta flag rotazione per taglio di testa -- si imposta flag rotazione per taglio di testa
if MACHININGS.Info.nHeadCutRotation == 2 then if MACHININGS.Info.nHeadCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bSide = true PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = true
elseif MACHININGS.Info.nHeadCutRotation == 3 then elseif MACHININGS.Info.nHeadCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bDown = true PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = true
else else
PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc].bStd = true PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = true
end end
-- si imposta flag rotazione per taglio di coda -- si imposta flag rotazione per taglio di coda
if MACHININGS.Info.nSplitCutRotation == 2 then if MACHININGS.Info.nSplitCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bSide = true PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = true
elseif MACHININGS.Info.nSplitCutRotation == 3 then elseif MACHININGS.Info.nSplitCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bDown = true PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = true
else else
PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc].bStd = true PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = true
end end
local vProcHeadTail = {} local vProcHeadTail = {}
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut][MatrixResult.nIndexHeadCutInVProc]) table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc])
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut][MatrixResult.nIndexTailCutInVProc]) table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc])
MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition) MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
@@ -1742,6 +1768,42 @@ function BeamExec.ProcessMachinings( PARTS)
nRawId = EgtGetNextRawPart( nRawId) nRawId = EgtGetNextRawPart( nRawId)
end end
local nInitialPosition = MatrixResult.nInitialPosition
-- PREROTAZIONE PEZZO
if MatrixResult.nInitialPosition ~= 1 or PARTS[nPart].bPartInCombiIsInverted then
-- si esce dalle lavorazioni e si torna in disegna
local nCurrMachGroup = EgtGetCurrMachGroup()
EgtResetCurrMachGroup()
-- salvo situazione precedente su lista BEAM ( scrittura variabili globali per interfaccia)
if bIsFlipRot then
BEAM.PREROTATE90 = MatrixResult.nInitialPosition - 1
BEAM.PREINVERT = EgtIf( PARTS[nPart].bPartInCombiIsInverted, 1, 0)
end
-- se c'è stata inversione, si inverte il pezzo anche in disegna
if PARTS[nPart].bPartInCombiIsInverted then
local ptInv = PARTS[nPart].b3PartOriginal:getMin() + Vector3d( PARTS[nPart].b3PartOriginal:getDimX() / 2, PARTS[nPart].b3PartOriginal:getDimY() / 2, 0)
EgtRotate( PARTS[nPart].id, ptInv, Z_AX(), 180, GDB_RT.GLOB)
PARTS[nPart].bIsInverted = true
end
-- se c'è una prerotazione, si inverte il pezzo
if MatrixResult.nInitialPosition ~= 1 then
local ptRot = PARTS[nPart].b3PartOriginal:getMin() + Vector3d( 0, PARTS[nPart].b3PartOriginal:getDimY() / 2, PARTS[nPart].b3PartOriginal:getDimZ() / 2)
local nRotationDeg = 90 * ( MatrixResult.nInitialPosition - 1)
EgtRotate( PARTS[nPart].id, ptRot, X_AX(), nRotationDeg, GDB_RT.GLOB)
end
-- si riattiva il MachGroup, i pezzi son rimasti dove erano
EgtSetCurrMachGroup( nCurrMachGroup)
end
-- salvo sul PART la posizione di partenza che è stata scelta
PARTS[nPart].nInitialPosition = MatrixResult.nInitialPosition
local bAreAllMachiningApplyOk local bAreAllMachiningApplyOk
local sErr local sErr
local bSplitAlreadyExecuted = false local bSplitAlreadyExecuted = false
@@ -1755,7 +1817,6 @@ function BeamExec.ProcessMachinings( PARTS)
-- creazione effettiva delle lavorazioni -- creazione effettiva delle lavorazioni
MACHININGS.Info = {} MACHININGS.Info = {}
local nCurrPosition = 1 local nCurrPosition = 1
local nInitialPosition = MatrixResult.nInitialPosition
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata -- se c'è almeno una lavorazione in posizionamento con trave ribaltata
if MatrixResult.bSomeFeatureDown then if MatrixResult.bSomeFeatureDown then
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2) local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
@@ -1897,5 +1958,374 @@ function BeamExec.ProcessMachinings( PARTS)
return ( nTotErr == 0), RESULT return ( nTotErr == 0), RESULT
end end
-------------------------------------------------------------------------------------------------------------
function BeamExec.ProcessAlternatives( PARTS)
-- inizializzazione variabili globali per interfaccia
BEAM.ALTERNATIVESNEST2D = ''
BEAM.ALTERNATIVES = ''
-- ciclo sui pezzi
local BestCombination = {}
local nPart = 1
local nOrd = 1
local nMaxReProcessCycles = EgtClamp( PARTS[nPart].GeneralParameters.GEN_nMaxReProcessCycles, 1, 3)
local bTryToReProcess = false
-- se non serve trovare altre soluzioni, si esce subito
if not ( PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION' and not PARTS[nPart].bSquareSection) and not PARTS[nPart].GeneralParameters.GEN_bGetAlternativesNesting2D then
return
end
-- si copia il MachGroup originale
local nOriginalMachGroup = EgtGetCurrMachGroup()
local sMachGroupName = EgtGetMachGroupName( nOriginalMachGroup)
local sTempMachGroupName = sMachGroupName .. '_A'
local nTempMachGroupName = EgtCopyMachGroup( sMachGroupName, sTempMachGroupName)
EgtSetCurrMachGroup( nTempMachGroupName)
EgtRemoveAllOperations()
BeamLib.CreateAddGroup( PARTS[nPart].id, sTempMachGroupName)
-- si aggiorna il raw dopo averlo copiato
PARTS[nPart].idRaw = EgtGetFirstRawPart()
-- si riporta pezzo in posizione iniziale
-- se combinazione prevedeva inversione, si rigira il pezzo
if PARTS[nPart].bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], -2)
end
-- si ribalta il pezzo in posizione iniziale
BeamLib.RotateRawPart( PARTS[nPart], 1 - PARTS[nPart].nInitialPosition)
local TotalCombiToTest = {}
-- se serve calcolare soluzione alternativa ruotata di 90°
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION' and not PARTS[nPart].bSquareSection then
local CombinationListToCheck = {}
for i = 1, #PARTS[nPart].CombinationList do
local nUnloadPos = PARTS[nPart].nInitialPosition
local nOtherSimilarUnloadPos = EgtIf( nUnloadPos + 2 > 4, nUnloadPos + 2 - 4, nUnloadPos + 2)
-- restano abilitate soluzioni ruotate di 90° o 270° rispetto alla migliore soluzione trovata nella prima analisi
if PARTS[nPart].CombinationList[i].nUnloadPos ~= nUnloadPos and PARTS[nPart].CombinationList[i].nUnloadPos ~= nOtherSimilarUnloadPos then
table.insert( CombinationListToCheck, { sBitIndexCombination = PARTS[nPart].CombinationList[i].sBitIndexCombination,
bPartInCombiIsInverted = PARTS[nPart].CombinationList[i].bPartInCombiIsInverted})
end
end
-- se c'è almeno una combinazione da testare
if #CombinationListToCheck > 0 then
table.insert( TotalCombiToTest, CombinationListToCheck)
end
end
-- se serve calcolare posizione per ottimizzazione tagli in nesting (le soluzioni non possono avere ribaltamenti)
if PARTS[nPart].GeneralParameters.GEN_bGetAlternativesNesting2D then
-- POSIZIONE 0 (e invertito)
local sCombinationToCheck = BeamLib.StringReplaceChar( '0000', PARTS[nPart].nInitialPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
end
-- POSIZIONE 180 (e invertito)
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'STD_PRE_ROTATION' then
local nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 2 > 4, PARTS[nPart].nInitialPosition + 2 - 4, PARTS[nPart].nInitialPosition + 2)
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
end
end
-- POSIZIONE 90/270 (e invertito)
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION' then
local nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 1 > 4, PARTS[nPart].nInitialPosition + 1 - 4, PARTS[nPart].nInitialPosition + 1)
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
end
nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 3 > 4, PARTS[nPart].nInitialPosition + 3 - 4, PARTS[nPart].nInitialPosition + 3)
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
end
end
end
-- fino a che ci sono soluzioni da testare
for z = 1, #TotalCombiToTest do
-- si svuota il machgroup e si resettano le variabili
EgtRemoveAllOperations()
MACHININGS = {}
MACHININGS.Info = {}
nOrd = 1
local nCycles = 1
local bCombinationFound = true
-- la parte di applicazione lavorazioni può essere lanciata più volte in caso della presenza di errori
local bProcess = true
while bProcess do
bProcess = false
-- si ricavano tutte le combinazioni possibili
local CombinationListFromMatrix = GetCombinationListFromMatrix( PROCESSINGS[nPart], PARTS[nPart], nCycles > 1, TotalCombiToTest[z])
-- se ci sono soluzioni possibili
if #CombinationListFromMatrix > 0 then
BestCombination = GetBestCombination( CombinationListFromMatrix, PARTS[nPart])
-- se la soluzione alternativa migliore è completa, allora la verifico, altrimenti si tiene la migliore in assoluto
if BestCombination.nNotComplete == 0 and BestCombination.nNotExecute == 0 then
PARTS[nPart].bPartInCombiIsInverted = BestCombination.bPartInCombiIsInverted
-- compilazione della vProc finale contenente le feature da lavorare nella giusta rotazione
local vProc, MatrixResult = GetProcessingListFromCombination( BestCombination)
-- si mette subito il pezzo nella fase
EgtSetCurrPhase( 1)
-- si sposta il pezzo nella posizione originale, di quando è stata fatta la collect. In questo modo tutti i dati calcolati nella collect restano validi.
-- Altrimenti bisognava ricalcolare tutto, aumentando tempo di calcolo.
local vtRawOffsetPos = PARTS[nPart].b3Raw:getMin() - EgtGetRawPartBBox( PARTS[nPart].idRaw):getMin()
local nRawId = PARTS[nPart].idRaw
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
EgtKeepRawPart( nRawId)
EgtMoveRawPart( nRawId, vtRawOffsetPos)
nRawId = EgtGetNextRawPart( nRawId)
end
if BestCombination.bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], 2)
end
-- se la posizione iniziale non è calcolata, significa che non ci sono feature da eseguire. Solo taglio testa/coda
if not MatrixResult.nInitialPosition then
MatrixResult.nInitialPosition = 1
MACHININGS.Info.nHeadCutRotation = 1
MACHININGS.Info.nSplitCutRotation = 1
-- altrimenti si fanno tutti i calcoli
else
-- TODO serve ancora ordinare le feature con nuovo metodo di calcolo ottimizzazione lavorazioni?
-- ordinamento di base delle feature
vProc = OrderFeatures( vProc)
-- esegue le strategie migliori che ha precedentemente scelto e salva le lavorazioni nella lista globale
MACHININGS = CalculateMachinings( vProc, PARTS[nPart], MatrixResult.nInitialPosition)
-- se non sono sono settate le rotazioni di lavorazione di testa e coda, significa che le feature da eseguire non sono state eseguite per qualche problema. Si forza rotazione 1
if not MACHININGS.Info.nHeadCutRotation or not MACHININGS.Info.nSplitCutRotation then
MACHININGS.Info.nHeadCutRotation = 1
MACHININGS.Info.nSplitCutRotation = 1
end
end
local nOffsetIndex = EgtIf( BestCombination.bPartInCombiIsInverted, 4, 0)
-- aggiunge tagli testa e coda in fasi opportune
local nRotHeadCut = MatrixResult.nInitialPosition + MACHININGS.Info.nHeadCutRotation - 1
if nRotHeadCut > 4 then
nRotHeadCut = nRotHeadCut - 4
end
local nRotSplitCut = MatrixResult.nInitialPosition + MACHININGS.Info.nSplitCutRotation - 1
if nRotSplitCut > 4 then
nRotSplitCut = nRotSplitCut - 4
end
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
-- si imposta flag rotazione per taglio di testa
if MACHININGS.Info.nHeadCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = true
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = nil
elseif MACHININGS.Info.nHeadCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = true
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = nil
else
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = true
end
-- si imposta flag rotazione per taglio di coda
if MACHININGS.Info.nSplitCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = true
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = nil
elseif MACHININGS.Info.nSplitCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = true
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = nil
else
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = true
end
local vProcHeadTail = {}
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc])
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc])
MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
-- finiti i calcoli di applicazione delle lavorazioni, si riporta il pezzo nello zero della fase
nRawId = PARTS[nPart].idRaw
while nRawId and abs( vtRawOffsetPos:len()) > 0 do
EgtKeepRawPart( nRawId)
EgtMoveRawPart( nRawId, -vtRawOffsetPos)
nRawId = EgtGetNextRawPart( nRawId)
end
local bAreAllMachiningApplyOk
local sErr
local bSplitAlreadyExecuted = false
local bSplitExecutedOnRot = false
local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'TYPE', 'START')
EgtSetInfo( idDisp, 'ORD', nOrd)
-- creazione effettiva delle lavorazioni
MACHININGS.Info = {}
local nCurrPosition = 1
local nInitialPosition = MatrixResult.nInitialPosition
BestCombination.nInitialPosition = MatrixResult.nInitialPosition
-- se c'è almeno una lavorazione in posizionamento con trave ribaltata
if MatrixResult.bSomeFeatureDown then
local nRotation = EgtIf( nInitialPosition + 2 > 4, nInitialPosition + 2 - 4, nInitialPosition + 2)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -2)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess
end
-- se c'è almeno una lavorazione in posizionamento con trave ruotata
if MatrixResult.bSomeFeatureSide then
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd)
-- se c'è già stata separazione
if bSplitAlreadyExecuted then
EgtSetInfo( idDisp, 'TYPE', 'MID2')
else
EgtSetInfo( idDisp, 'TYPE', 'MID')
end
-- se combinazione prevede inversione, si gira il pezzo
if BestCombination.bPartInCombiIsInverted and not PARTS[nPart].bIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], 2)
end
end
local nRotation = EgtIf( nInitialPosition + 1 > 4, nInitialPosition + 1 - 4, nInitialPosition + 1)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -1)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess
end
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd)
-- se c'è già stata separazione
if bSplitAlreadyExecuted then
EgtSetInfo( idDisp, 'TYPE', 'END2')
else
EgtSetInfo( idDisp, 'TYPE', 'MID')
end
-- se combinazione prevede inversione, si gira il pezzo
if BestCombination.bPartInCombiIsInverted and not PARTS[nPart].bIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], 2)
end
end
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
-- aggiunta lavorazioni in ultima fase
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD')
bProcess = bProcess or bTryToReProcess
-- se bisogna riprocessare, si annulla tutto
nCycles = nCycles + 1
if bProcess and nCycles <= nMaxReProcessCycles then
-- azzero liste
MACHININGS = {}
MACHININGS.Info = {}
RESULT = {}
EgtRemoveAllOperations()
-- si riporta pezzo in posizione iniziale
-- se combinazione prevedeva inversione, si rigira il pezzo
if BestCombination.bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], -2)
end
-- si ribalta il pezzo in posizione iniziale
BeamLib.RotateRawPart( PARTS[nPart], 1 - nInitialPosition)
else
bProcess = false
end
else
bCombinationFound = false
end
else
bCombinationFound = false
end
end
nOrd = nOrd + 1
-- se ho trovato almeno una combinazione possibile
if bCombinationFound then
-- ===== finiti i pezzi, si scarica il restante =====
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'TYPE', 'REST')
EgtSetInfo( idDisp, 'ORD', nOrd)
end
-- Aggiornamento finale di tutto
EgtSetCurrPhase( 1)
local bApplOk, _, _ = EgtApplyAllMachinings()
-- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia
if bApplOk then
local Alternatives = {}
local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '')
if TotalCombiToTest[z].bIsNesting2D then
if BEAM.ALTERNATIVESNEST2D and BEAM.ALTERNATIVESNEST2D ~= "" then
table.insert( Alternatives, BEAM.ALTERNATIVESNEST2D)
end
table.insert( Alternatives, sBitIndexCombinationWithInvert)
BEAM.ALTERNATIVESNEST2D = table.concat( Alternatives, ', ')
else
if BEAM.ALTERNATIVES and BEAM.ALTERNATIVES ~= "" then
table.insert( Alternatives, BEAM.ALTERNATIVES)
end
table.insert( Alternatives, sBitIndexCombinationWithInvert)
BEAM.ALTERNATIVES = table.concat( Alternatives, ', ')
end
end
-- se ultima combinazione, si esce e non si riporta in posizione inizale. Verrà infatti cancellata
if z == #TotalCombiToTest then break end
-- si riporta pezzo in posizione iniziale
-- se combinazione prevedeva inversione, si rigira il pezzo
if BestCombination.bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], -2)
end
-- si ribalta il pezzo in posizione iniziale
BeamLib.RotateRawPart( PARTS[nPart], 1 - BestCombination.nInitialPosition)
end
end
-- si cancella eventuale mach group creato per le alternative
EgtRemoveMachGroup( nTempMachGroupName)
end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
return BeamExec return BeamExec
+19 -8
View File
@@ -328,6 +328,18 @@ function BeamLib.RotateRawPart( Part, nNumberOfRotations)
end end
end end
-------------------------------------------------------------------------------------------------------------
function BeamLib.CreateAddGroup( PartId, sGroupName)
AddGrpId = EgtGroup( PartId or GDB_ID.NULL)
if not AddGrpId then
return false
end
-- assegno nome, flag di layer per gruppo di lavoro e colore
EgtSetName( AddGrpId, sGroupName)
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 25))
end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamLib.CreateOrEmptyAddGroup( PartId) function BeamLib.CreateOrEmptyAddGroup( PartId)
-- recupero i dati del gruppo aggiuntivo -- recupero i dati del gruppo aggiuntivo
@@ -341,15 +353,9 @@ function BeamLib.CreateOrEmptyAddGroup( PartId)
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup()) EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
return EgtEmptyGroup( AddGrpId) return EgtEmptyGroup( AddGrpId)
end end
-- altrimenti lo creo -- altrimenti lo creo
AddGrpId = EgtGroup( PartId or GDB_ID.NULL) BeamLib.CreateAddGroup( PartId, sMchGrp)
if not AddGrpId then
return false
end
-- assegno nome, flag di layer per gruppo di lavoro e colore
EgtSetName( AddGrpId, sMchGrp)
EgtSetInfo( AddGrpId, GDB_SI.MGRPONLY, EgtGetCurrMachGroup())
EgtSetColor( AddGrpId, Color3d( 80, 160, 160, 25))
return true return true
end end
@@ -769,6 +775,11 @@ function BeamLib.GetBlockedAxis( nToolIndex, sBlockedAxis, b3Raw, vtTool, vtOut)
return '' return ''
end end
-------------------------------------------------------------------------------------------------------------
function BeamLib.StringReplaceChar( sOriginal, nPosition, sChar)
return sOriginal:sub( 1, nPosition-1) .. sChar .. sOriginal:sub( nPosition+1)
end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamLib.BinaryToDecimal( dNumber) function BeamLib.BinaryToDecimal( dNumber)
local sNumberToConvert = tostring( dNumber) local sNumberToConvert = tostring( dNumber)
+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 -- se piani non ortogonali, diminuisco la distanza di offset opportunamente
local dOffsetParallelOriginal = dOffsetParallel local dOffsetParallelOriginal = dOffsetParallel
if not bGetOrtoPlanes then if not bGetOrtoPlanes then
local dCoeff = ( vtNMainFace ^ vtNSubordinateFace):len() local dCoeff = max( ( vtNMainFace ^ vtNSubordinateFace):len(), 0.5)
dOffsetParallel = dOffsetParallel * dCoeff dOffsetParallel = dOffsetParallel * dCoeff
dOffsetOrthogonal = dOffsetOrthogonal * dCoeff dOffsetOrthogonal = dOffsetOrthogonal * dCoeff
end end
+35 -9
View File
@@ -91,7 +91,9 @@ function FaceData.GetFacesByAdjacencyNumber( Proc)
FacesByAdjacencyNumber[i] = {} FacesByAdjacencyNumber[i] = {}
end end
for i = 1, Proc.nFct do 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 end
return FacesByAdjacencyNumber return FacesByAdjacencyNumber
@@ -186,7 +188,7 @@ function FaceData.GetFacesInfo( Proc, Part, FacesToGet)
Faces[i].id = i - 1 Faces[i].id = i - 1
Faces[i].idTrimesh = Proc.id Faces[i].idTrimesh = Proc.id
Faces[i].ptCenter, Faces[i].vtN = EgtSurfTmFacetCenter( Proc.id, i - 1, GDB_ID.ROOT) 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 -- frame OCS faccia
Faces[i].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN) Faces[i].frFrameHV = Frame3d( Faces[i].ptCenter, Faces[i].vtN)
-- elevazione calcolata rispetto al box della parte -- elevazione calcolata rispetto al box della parte
@@ -383,10 +385,28 @@ local function GetBottomFaces( Proc)
return { Proc.Faces[1]} return { Proc.Faces[1]}
end 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) local FacesByAdjacencyNumber = FaceData.GetFacesByAdjacencyNumber( Proc)
if FacesByAdjacencyNumber then if FacesByAdjacencyNumber then
BottomFaces = FacesByAdjacencyNumber[ Proc.nFct - 1] 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 -- si rimuovono le facce non adatte ad essere lavorate
local nBottomFaces = #BottomFaces local nBottomFaces = #BottomFaces
local nCurrentFace = 1 local nCurrentFace = 1
@@ -476,7 +496,7 @@ end
local function GetLongFaces( Proc, MainFaces) local function GetLongFaces( Proc, MainFaces)
local LongFaces = {} local LongFaces = {}
if Proc.nFct > 5 then if Proc.nFct > 6 then
error( 'GetLongFaces : Topology not implemented') error( 'GetLongFaces : Topology not implemented')
elseif Proc.nFct == 1 then elseif Proc.nFct == 1 then
return {} return {}
@@ -584,7 +604,7 @@ end
local function GetSideFaces( Proc, MainFaces) local function GetSideFaces( Proc, MainFaces)
local SideFaces = {} local SideFaces = {}
if Proc.nFct > 5 then if Proc.nFct > 6 then
error( 'GetSideFaces : Topology not implemented') error( 'GetSideFaces : Topology not implemented')
elseif Proc.nFct == 1 then elseif Proc.nFct == 1 then
return {} return {}
@@ -690,15 +710,21 @@ function FaceData.GetMainFaces( Proc, Part)
Proc.Topology.sFamily == 'Pocket' or Proc.Topology.sFamily == 'Tunnel' or Proc.Topology.sFamily == 'Bevel' 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 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) 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 or ( Proc.nFct == 1) or Proc.Topology.sName == 'Bevel-2-Blind') then
MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc, Part) MainFaces.TunnelAddedFaces = GetTunnelFaces( Proc, Part)
end end
MainFaces.BottomFaces = GetBottomFaces( Proc) MainFaces.BottomFaces = GetBottomFaces( Proc)
MainFaces.LongFaces = GetLongFaces( Proc, MainFaces) if Proc.nParts == 1 then
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces) MainFaces.LongFaces = GetLongFaces( Proc, MainFaces)
MainFaces.SideFaces = GetSideFaces( Proc, MainFaces)
-- caso tipo DoubleBevel con facce separate
else
MainFaces.LongFaces = {}
MainFaces.SideFaces = {}
end
else else
MainFaces = nil MainFaces = nil
+12 -5
View File
@@ -226,13 +226,13 @@ function FeatureLib.ClassifyTopology( Proc, Part)
elseif Proc.nFct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then elseif Proc.nFct == 2 and bAllAnglesConcave and #vTriangularFaces == 1 then
sFamily = 'Bevel' sFamily = 'Bevel'
bIsThrough = false 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' sFamily = 'Rabbet'
bIsThrough = true bIsThrough = true
elseif Proc.nFct == 2 and bAllAnglesConcave then elseif Proc.nFct == 2 and bAllAnglesConcave and Proc.nParts == 1 then
sFamily = 'VGroove' sFamily = 'VGroove'
bIsThrough = true 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' sFamily = 'DoubleBevel'
bIsThrough = true bIsThrough = true
elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 1 and #vTriangularFaces == 2 then 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 elseif Proc.nFct == 3 and bAllAnglesConcave and #vFacesByAdjNumber[2] == 3 then
sFamily = 'Groove' sFamily = 'Groove'
bIsThrough = false 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' sFamily = 'DoubleBevel'
bIsThrough = false bIsThrough = false
elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then elseif Proc.nFct == 4 and bAllAnglesConcave and #vFacesByAdjNumber[3] == 2 then
@@ -259,7 +261,9 @@ function FeatureLib.ClassifyTopology( Proc, Part)
elseif Proc.nFct == 5 and bAllAnglesConcave and #vFacesByAdjNumber[4] == 1 then elseif Proc.nFct == 5 and bAllAnglesConcave and #vFacesByAdjNumber[4] == 1 then
sFamily = 'Pocket' sFamily = 'Pocket'
bIsThrough = false 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' sFamily = 'DoubleBevel'
bIsThrough = false bIsThrough = false
end end
@@ -333,6 +337,9 @@ function FeatureLib.GetAdditionalInfo( Proc, Part)
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc) Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
Proc.Faces = FaceData.GetFacesInfo( Proc, Part) Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
Proc.FeatureInfo, Proc.MainFaces = FeatureLib.GetRafterNotchData( Proc) 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 end
return Proc return Proc
+88 -52
View File
@@ -363,16 +363,22 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters)
-- attacco perpendicolare -- attacco perpendicolare
local PerpendicularLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Perpendicular', Parameters, LeadInOutOptionalParameters) local PerpendicularLeadInOut = LeadInOutLib.CalculateLeadInOut( 'Perpendicular', Parameters, LeadInOutOptionalParameters)
-- check extracorsa nei punti di attacco -- check extracorsa nei punti di attacco
PointsOnToolTipCenter = { PointsOnToolTipCenter = {
PreSimulationLib.GetPointOnToolTipCenter( PerpendicularLeadInOut.LeadIn.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool), PreSimulationLib.GetPointOnToolTipCenter( PerpendicularLeadInOut.LeadIn.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool),
PreSimulationLib.GetPointOnToolTipCenter( PerpendicularLeadInOut.LeadOut.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) 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 if not bOutOfStrokePerpendicular then
LeadInOut.Perpendicular = PerpendicularLeadInOut CheckCollisionOptionalParameters.PointsToCheck = {}
LeadInOut.Perpendicular.bMoveAfterSplit = bMoveAfterSplit table.insert( CheckCollisionOptionalParameters.PointsToCheck, PerpendicularLeadInOut.LeadIn.ptPoint)
table.insert( CheckCollisionOptionalParameters.PointsToCheck, PerpendicularLeadInOut.LeadOut.ptPoint)
local bCollisionFoundPerpendicular, bMoveAfterSplitPerpendicular = PreSimulationLib.CheckCollision( sBladeEngagement, CheckCollisionParameters, CheckCollisionOptionalParameters)
-- attacco perpendicolare possibile
if not bCollisionFoundPerpendicular then
LeadInOut.Perpendicular = PerpendicularLeadInOut
LeadInOut.Perpendicular.bMoveAfterSplit = bMoveAfterSplitPerpendicular
end
end end
-- se c'è almeno un lato chiuso l'unico attacco possibile è il perpendicolare -- se c'è almeno un lato chiuso l'unico attacco possibile è il perpendicolare
if not ( Edge.bIsStartOpen and Edge.bIsEndOpen) then if not ( Edge.bIsStartOpen and Edge.bIsEndOpen) then
@@ -468,6 +474,11 @@ end
function MachiningLib.FindMill( Proc, ToolSearchParameters) function MachiningLib.FindMill( Proc, ToolSearchParameters)
local ToolInfo = {} 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 nBestToolIndex
local dBestToolResidualDepth = 0 local dBestToolResidualDepth = 0
for i = 1, #TOOLS do for i = 1, #TOOLS do
@@ -511,6 +522,18 @@ function MachiningLib.FindMill( Proc, ToolSearchParameters)
bIsToolCompatible = false bIsToolCompatible = false
end end
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 -- scelgo il migliore
if bIsToolCompatible then if bIsToolCompatible then
@@ -579,6 +602,7 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- funzione per cercare utensile tipo LAMA con certe caratteristiche -- funzione per cercare utensile tipo LAMA con certe caratteristiche
-- TODO da rivedere/completare -- TODO da rivedere/completare
-- TODO per Engagement serviranno (opzionali) sBlockedAxis e vtAux
function MachiningLib.FindBlade( Proc, ToolSearchParameters) function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local ToolInfo = {} local ToolInfo = {}
@@ -607,6 +631,7 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local bIsDicing = ToolSearchParameters.bIsDicing or false local bIsDicing = ToolSearchParameters.bIsDicing or false
local sRestLengthSideForPreSimulation = ToolSearchParameters.sRestLengthSideForPreSimulation or 'Tail' local sRestLengthSideForPreSimulation = ToolSearchParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = ToolSearchParameters.bCannotSplitRestLength or false local bCannotSplitRestLength = ToolSearchParameters.bCannotSplitRestLength or false
local bDisableRealElevationCheck = ToolSearchParameters.bDisableRealElevationCheck or false
local nBestToolIndex local nBestToolIndex
local dBestToolResidualDepth = 0 local dBestToolResidualDepth = 0
@@ -640,7 +665,8 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
local BladeEngagementOptionalParameters = { local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing, bIsDicing = bIsDicing,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
} }
TIMER:startElapsed( 'GetBladeEngagement') TIMER:startElapsed( 'GetBladeEngagement')
bIsBladeOk, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) bIsBladeOk, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
@@ -1355,13 +1381,19 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
MachStartAxesPos = EgtGetMachiningStartAxes(), MachStartAxesPos = EgtGetMachiningStartAxes(),
MachEndAxesPos = EgtGetMachiningEndAxes()} MachEndAxesPos = EgtGetMachiningEndAxes()}
table.insert( DB_MACH_APPLIED, MachExtraInfo) 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 -- se errore in applicazione
if not bIsApplyOk then if not bIsApplyOk then
bAreAllMachiningApplyOk = false bAreAllMachiningApplyOk = false
nErr, sErr = EgtGetLastMachMgrError() nErr, sErr = EgtGetLastMachMgrError()
EgtSetOperationMode( nOperationId, false) 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 -- 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.sStatus = 'Not-Applicable'
CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sInfo = 'REJECTED (' .. sErr .. ')' CurrProc.AvailableStrategies[CurrProc.nIndexBestStrategy].Result.sInfo = 'REJECTED (' .. sErr .. ')'
@@ -1378,7 +1410,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
-- se applicazione andata a buon fine -- se applicazione andata a buon fine
else 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 if not MACHININGS[i].AuxiliaryData.bIgnoreNotClampableLength then
-- salvo ingombro non pinzabile testa/coda -- salvo ingombro non pinzabile testa/coda
local nCurrRotation = MACHININGS[i].Proc.nIndexRotation local nCurrRotation = MACHININGS[i].Proc.nIndexRotation
@@ -1420,9 +1452,9 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
bSplitExecuted = true bSplitExecuted = true
MACHININGS.Info.bSplitExecuted = true MACHININGS.Info.bSplitExecuted = true
BeamLib.AddPhaseWithRawParts( MACHININGS[i].Proc.idRaw, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET) BeamLib.AddPhaseWithRawParts( Part.idRaw, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
-- se grezzo successivo senza pezzi e finale, va tolto -- se grezzo successivo senza pezzi e finale, va tolto
local nNextRawId = EgtGetNextRawPart( MACHININGS[i].Proc.idRaw) local nNextRawId = EgtGetNextRawPart( Part.idRaw)
if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BeamData.dMinRaw then if nNextRawId and EgtGetPartInRawPartCount( nNextRawId) == 0 and EgtGetRawPartBBox( nNextRawId):getDimX() < BeamData.dMinRaw then
EgtRemoveRawPartFromCurrPhase( nNextRawId) EgtRemoveRawPartFromCurrPhase( nNextRawId)
end end
@@ -1436,18 +1468,20 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
local nPhase = EgtGetCurrPhase() local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase) local idDisp = EgtGetPhaseDisposition( nPhase)
-- posizione iniziale considerando eventuiali prerotazioni
local nRealInitialPosition = Part.nInitialPosition
if sRotation == 'DOWN' then 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) BeamLib.RotateRawPart( Part, nRotation)
EgtSetInfo( idDisp, 'ROT', -2) EgtSetInfo( idDisp, 'ROT', -2)
EgtSetInfo( idDisp, 'TYPE', 'MID2') EgtSetInfo( idDisp, 'TYPE', 'MID2')
elseif sRotation == 'SIDE' then 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) BeamLib.RotateRawPart( Part, nRotation)
EgtSetInfo( idDisp, 'ROT', -1) EgtSetInfo( idDisp, 'ROT', -1)
EgtSetInfo( idDisp, 'TYPE', 'MID2') EgtSetInfo( idDisp, 'TYPE', 'MID2')
else else
local nRotation = Part.nInitialPosition - 1 local nRotation = nRealInitialPosition - 1
BeamLib.RotateRawPart( Part, nRotation) BeamLib.RotateRawPart( Part, nRotation)
EgtSetInfo( idDisp, 'TYPE', 'END') EgtSetInfo( idDisp, 'TYPE', 'END')
end end
@@ -1516,14 +1550,14 @@ function MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machining, Part)
if Machining.nType == MCH_MY.DRILLING then if Machining.nType == MCH_MY.DRILLING then
local function fact(n) return n == 0 and 1 or n * fact(n - 1) end local function fact(n) return n == 0 and 1 or n * fact(n - 1) end
local nSteps = ceil( Machining.sDepth / Machining.dStep) 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 -- numero dei movimenti a step, compresi andata e ritorno per scarico truciolo
local nTotStepMovement = 2 * fact( nSteps) local nTotStepMovement = 2 * fact( nSteps)
-- in feed si lavorano solo gli step -- in feed si lavorano solo gli step
local dFeedTime = ( ( dLenghtEachStep + Machining.dStartSafetyLength) * nSteps) / dToolFeed local dFeedTime = ( ( dLengthEachStep + Machining.dStartSafetyLength) * nSteps) / dToolFeed
-- ritorno per scaricare e approccio al prossimo step seno in feed finale -- ritorno per scaricare e approccio al prossimo step sono in feed finale
local dEndFeedTime = ( dLenghtEachStep * ( nTotStepMovement - nSteps) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ) * 2) / dToolEndFeed local dEndFeedTime = ( dLengthEachStep * ( nTotStepMovement - nSteps) + EgtMdbGetGeneralParam( MCH_GP.SAFEZ) * 2) / dToolEndFeed
dLengthToMachineAllStepsWithLeadInOut = dLenghtEachStep * nTotStepMovement dLengthToMachineAllStepsWithLeadInOut = dLengthEachStep * nTotStepMovement
dTimeToMachineTotal = dFeedTime + dEndFeedTime dTimeToMachineTotal = dFeedTime + dEndFeedTime
elseif Machining.nType == MCH_MY.MILLING then elseif Machining.nType == MCH_MY.MILLING then
-- stima LeadIn e LeadOut; se non settati si impostano a valori di default -- stima LeadIn e LeadOut; se non settati si impostano a valori di default
@@ -1780,44 +1814,46 @@ function MachiningLib.ShortestPathSorting()
-- se è una lavorazione -- se è una lavorazione
while DB_MACH_APPLIED[i] and DB_MACH_APPLIED[i].sType ~= 'DISP' do while DB_MACH_APPLIED[i] and DB_MACH_APPLIED[i].sType ~= 'DISP' do
-- se lavorazione non attiva non va considerata if DB_MACH_APPLIED[i].MachStartAxesPos and DB_MACH_APPLIED[i].MachEndAxesPos then
local nOperationId = DB_MACH_APPLIED[i].nOperationId -- se lavorazione non attiva non va considerata
if EgtGetOperationMode( nOperationId) then local nOperationId = DB_MACH_APPLIED[i].nOperationId
local ptMinX, ptMaxX if EgtGetOperationMode( nOperationId) then
-- aggiungo lavorazioni local ptMinX, ptMaxX
local nToolIndex = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nToolIndex -- aggiungo lavorazioni
EgtOptMachAddTool( nToolIndex, 2, 2) -- , [ num dTC_X, num dTC_Y, num dTC_Z, num dTC_A, num dTC_B, num dTC_C]) local nToolIndex = MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nToolIndex
-- viene eseguito prima il gruppo con indice più alto, quindi si inverte indice dato che lo stage è dal più piccolo al più grande EgtOptMachAddTool( nToolIndex, 2, 2) -- , [ num dTC_X, num dTC_Y, num dTC_Z, num dTC_A, num dTC_B, num dTC_C])
local nGroup = 10 - MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage -- viene eseguito prima il gruppo con indice più alto, quindi si inverte indice dato che lo stage è dal più piccolo al più grande
local MachStartAxesPos = DB_MACH_APPLIED[i].MachStartAxesPos local nGroup = 10 - MACHININGS[DB_MACH_APPLIED[i].nIndexInMachinings].Machining.nStage
local MachEndAxesPos = DB_MACH_APPLIED[i].MachEndAxesPos local MachStartAxesPos = DB_MACH_APPLIED[i].MachStartAxesPos
EgtOptMachAddMachining( i, nToolIndex, nGroup, MachStartAxesPos, MachEndAxesPos) local MachEndAxesPos = DB_MACH_APPLIED[i].MachEndAxesPos
table.insert( MachiningOptList, i) EgtOptMachAddMachining( i, nToolIndex, nGroup, MachStartAxesPos, MachEndAxesPos)
table.insert( MachiningOptList, i)
-- si salvano i punti minimi e massimi tra tutte le lavorazioni di ogni gruppo -- si salvano i punti minimi e massimi tra tutte le lavorazioni di ogni gruppo
if MachStartAxesPos[1] < MachEndAxesPos[1] then if MachStartAxesPos[1] < MachEndAxesPos[1] then
ptMinX = MachStartAxesPos ptMinX = MachStartAxesPos
ptMaxX = MachEndAxesPos ptMaxX = MachEndAxesPos
else else
ptMinX = MachEndAxesPos ptMinX = MachEndAxesPos
ptMaxX = MachStartAxesPos 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
end 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 end
i = i + 1 i = i + 1
end end
+167 -107
View File
@@ -34,12 +34,12 @@ local function GetMachineAxes()
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
local function LogOutstroke( ptOnToolTipCenter, vtHead, OptionalParameters) local function LogOutstroke( sToolName, ptOnToolTipCenter, vtHead, OptionalParameters)
-- parametri opzionali -- parametri opzionali
OptionalParameters = OptionalParameters or {} OptionalParameters = OptionalParameters or {}
local LinearAxes = OptionalParameters.LinearAxes local LinearAxesValues = OptionalParameters.LinearAxesValues
local RotativeAxes = OptionalParameters.RotativeAxes local RotativeAxesValues = OptionalParameters.RotativeAxesValues
-- gruppo per geometrie temporanee -- gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup() local idTempGroup = BeamLib.GetTempGroup()
@@ -50,15 +50,18 @@ local function LogOutstroke( ptOnToolTipCenter, vtHead, OptionalParameters)
EgtSetColor( idPoint, RED()) EgtSetColor( idPoint, RED())
EgtSetColor( idVector, RED()) EgtSetColor( idVector, RED())
-- nome utensile
EgtOutLog( 'Tool ' .. sToolName)
-- si loggano valori di punto e vettore -- si loggano valori di punto e vettore
EgtOutLog( ' Presimulation : OutStroke, Tip Point = ' .. tostring( ptOnToolTipCenter) .. ', id = ' .. idPoint .. ', vtHead = ' .. tostring( vtHead) .. ', id = ' .. idVector) EgtOutLog( ' Presimulation : OutStroke, Tip Point = ' .. tostring( ptOnToolTipCenter) .. ', id = ' .. idPoint .. ', vtHead = ' .. tostring( vtHead) .. ', id = ' .. idVector)
-- se disponibili, si loggano anche i valori calcolati degli assi -- se disponibili, si loggano anche i valori calcolati degli assi
if LinearAxes then if LinearAxesValues then
EgtOutLog( ' ' .. LinearAxes[1].sName .. ' = ' .. tostring( LinearAxes[1].dValue) .. ', ' .. LinearAxes[2].sName .. ' = ' .. tostring( LinearAxes[2].dValue) .. ', ' .. LinearAxes[3].sName .. ' = ' .. tostring( LinearAxes[3].dValue)) EgtOutLog( ' ' .. 'Lin1' .. ' = ' .. tostring( LinearAxesValues[1]) .. ', ' .. 'Lin2' .. ' = ' .. tostring( LinearAxesValues[2]) .. ', ' .. 'Lin3' .. ' = ' .. tostring( LinearAxesValues[3]))
end end
if RotativeAxes then if RotativeAxesValues then
EgtOutLog( ' ' .. RotativeAxes[1].sName .. ' = ' .. tostring( RotativeAxes[1].dValue) .. ', ' .. RotativeAxes[2].sName .. ' = ' .. tostring( RotativeAxes[2].dValue)) EgtOutLog( ' ' .. 'Rot1' .. ' = ' .. tostring( RotativeAxesValues[1]) .. ', ' .. 'Rot2' .. ' = ' .. tostring( RotativeAxesValues[2]) .. ', ' .. 'Rot3' .. ' = ' .. tostring( RotativeAxesValues[3]))
end end
return return
@@ -110,7 +113,7 @@ local function GetToolExitPoint( ptMachining, vtNEdge, vtHead, Tool, bIsDownUp)
end 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) local function GetGlobalPivot( ptToolExit, vtC, vtHead, vtMovePivot)
-- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito) -- frame solidale all'utensile (lo stesso in cui vtMovePivot è definito)
@@ -150,27 +153,28 @@ local function GetCollisionPointsToCheck( Edge, dDepthToMachine)
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool) local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool, vtAux, sBlockedAxis)
-- impostazione utensile -- 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 -- settaggio SCC per discriminare soluzioni multiple
EgtSetCalcSolCh( nSCC) EgtSetCalcSolCh( nSCC)
-- assi macchina da calcolare -- se presente, settaggio asse bloccato
local LinearAxes, RotativeAxes = GetMachineAxes() if sBlockedAxis and type( sBlockedAxis) == "string" then
local BlockedAxis = EgtSplitString( sBlockedAxis, '=')
-- se più di 3 assi lineari e 2 assi rotativi, macchina non supportata EgtSetRotAxisBlock( BlockedAxis[1], tonumber( BlockedAxis[2]))
if #LinearAxes > 3 or #RotativeAxes > 2 then
error(' CheckOutOfStrokePoint : too many axes')
end end
-- calcolo assi rotativi -- calcolo assi rotativi
local bOkAngles, nSolutionsAngles, dRot1, dRot2 = EgtGetCalcAngles( vtHead) local bOkAngles, nSolutionsAngles, RotativeAxesValues = EgtGetCalcAnglesEx( vtHead, vtAux)
RotativeAxes[1].dValue = dRot1 local dRotative1 = RotativeAxesValues[1]
RotativeAxes[2].dValue = dRot2 local dRotative2 = RotativeAxesValues[2]
local dRotative3 = RotativeAxesValues[3]
if not bOkAngles then if not bOkAngles then
error( ' CheckOutOfStrokePoint : error') error( ' CheckOutOfStrokePoint : error')
@@ -180,40 +184,27 @@ local function CheckOutOfStrokePoint( ptOnToolTipCenter, vtHead, nSCC, Tool)
if nSolutionsAngles == 0 then if nSolutionsAngles == 0 then
if EgtGetDebugLevel() >= 3 then if EgtGetDebugLevel() >= 3 then
LogOutstroke( ptOnToolTipCenter, vtHead) LogOutstroke( Tool.sName, ptOnToolTipCenter, vtHead, { RotativeAxesValues = { dRotative1, dRotative2, dRotative3}})
end end
return true return true
end end
-- calcolo assi lineari -- calcolo assi lineari
local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, RotativeAxes[1].dValue, RotativeAxes[2].dValue) local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
LinearAxes[1].dValue = dLinear1
LinearAxes[2].dValue = dLinear2
LinearAxes[3].dValue = dLinear3
if not bOkPositions then if not bOkPositions then
error( ' CheckOutOfStrokePoint : error') error( ' CheckOutOfStrokePoint : error')
end end
-- verifica finecorsa per tutti gli assi -- verifica finecorsa per assi lineari (assi rotativi già verificati)
-- siccome non si sa a priori il numero di assi lineari e rotativi, si aggiungono tutti a Args in ordine local bAllAxesInStroke = EgtVerifyOutstroke( dLinear1, dLinear2, dLinear3)
-- 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))
-- extracorsa -- extracorsa
if not bAllAxesInStroke then if not bAllAxesInStroke then
if EgtGetDebugLevel() >= 3 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 end
return true return true
end end
@@ -230,11 +221,11 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- check extracorsa da punti sul tip dell'utensile -- 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 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 -- se trovato extracorsa inutile procedere con gli altri punti
if bOutOfStroke then if bOutOfStroke then
@@ -249,7 +240,7 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- check extracorsa da geometria -- check extracorsa da geometria
-- TODO da considerare anche gli attacchi -- 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 b3GeomMaxOffset = EgtGetBBoxGlob( idGeometry, GDB_BB.STANDARD)
local ptBoxCenter = b3GeomMaxOffset:getCenter() local ptBoxCenter = b3GeomMaxOffset:getCenter()
@@ -272,38 +263,76 @@ function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC
-- Z- -- Z-
table.insert( PointsOnToolTipCenter, Point3d( ptBoxCenter - dBoxDimZ / 2 * Z_AX())) 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 return bOutOfStroke
end 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 if not bOkAngles then
local vtDirectionX = PreCollisionData.Directions.vtDirectionX error( ' MoveMachineAxesToPosition : error')
local vtDirectionY = PreCollisionData.Directions.vtDirectionY end
local vtDirectionZ = PreCollisionData.Directions.vtDirectionZ
-- costruzione trimesh a partire dalla curva di collisione -- calcolo assi lineari
-- recupero punti da macchina per costruire trimesh local bOkPositions, _, dLinear1, dLinear2, dLinear3 = EgtGetCalcPositions( ptOnToolTipCenter, dRotative1, dRotative2, dRotative3)
local CollisionCurvePoints = PreCollisionData.Points
-- curva di collisione in riferimento locale if not bOkPositions then
local idCollisionCurve = EgtCurveCompoFromPoints( Part.idTempGroup, CollisionCurvePoints)
-- curva in riferimento globale error( ' MoveMachineAxesToPosition : error')
local frReference = Frame3d( ptPivot, vtDirectionZ, vtDirectionX) end
EgtTransform( idCollisionCurve, frReference, GDB_RT.GLOB)
-- trimesh di collisione local AxesNames = EgtGetAllCurrAxesNames()
local idCollisionSurfTm local dTHome = EgtGetAxisHomePos( AxesNames[1])
if PreCollisionData.bSurfTmByRevolve then
idCollisionSurfTm = EgtSurfTmByRevolve( Part.idTempGroup, idCollisionCurve, ptPivot, vtDirectionY, true, 0.05, GDB_RT.GLOB) -- spostamento assi in posizione (la T non si sposta perchè si sposta il pezzo)
else EgtSetAxisPos( AxesNames[2], dLinear2)
local vtPreMove = -vtDirectionZ * ( PreCollisionData.dExtrusionDepth / 2) EgtSetAxisPos( AxesNames[3], dLinear3)
EgtMove( idCollisionCurve, vtPreMove, GDB_RT.GLOB) EgtSetAxisPos( AxesNames[4], dRotative1)
local vtExtrusion = vtDirectionZ * PreCollisionData.dExtrusionDepth EgtSetAxisPos( AxesNames[5], dRotative2)
idCollisionSurfTm = EgtSurfTmByRegionExtrusion( Part.idTempGroup, idCollisionCurve, vtExtrusion, 0.05, GDB_RT.GLOB) if dRotative3 then
EgtSetAxisPos( AxesNames[6], dRotative3)
end
return dLinear1 - dTHome
end
-------------------------------------------------------------------------------------------------------------
local function CheckCollisionPoint( sAxis, ptOnToolTipCenter, vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
-- 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 end
-- check collisione con pezzo -- check collisione con pezzo
@@ -315,16 +344,22 @@ local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollision
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation) local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB) idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
end end
bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, idCollisionSurfTm, BeamData.COLL_SIC) for i = 1, #CollisionSurfTmId do
if not type( bCollisionFoundPiece) == "boolean" then bCollisionFoundPiece = EgtCDeSolidSolid( idCheckCollisionTm, CollisionSurfTmId[i], BeamData.COLL_SIC)
error( 'Presimulation fail') if not type( bCollisionFoundPiece) == "boolean" then
end error( 'Presimulation fail')
if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then end
EgtSetColor( idCollisionSurfTm, RED()) if EgtGetDebugLevel() >= 3 and bCollisionFoundPiece then
EgtSetColor( CollisionSurfTmId[i], RED())
end
if bCollisionFoundPiece then
break
end
end end
-- se trovata collisione con pezzo è inutile procedere con il grezzo -- se trovata collisione con pezzo è inutile procedere con il grezzo
if bCollisionFoundPiece then if bCollisionFoundPiece then
return true return true
end end
end end
@@ -334,12 +369,17 @@ local function CheckCollisionPoint( ptToolExitToCheck, vtC, vtHead, PreCollision
if not ( bCollisionFoundPiece or bCannotSplitRestLength) then if not ( bCollisionFoundPiece or bCannotSplitRestLength) then
local idRestLengthSurfFr = GetRestlengthSurfTm( Part, sRestLengthSideForPreSimulation) local idRestLengthSurfFr = GetRestlengthSurfTm( Part, sRestLengthSideForPreSimulation)
if idRestLengthSurfFr then if idRestLengthSurfFr then
bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, idCollisionSurfTm, BeamData.COLL_SIC) for i = 1, #CollisionSurfTmId do
if not type( bCollisionFoundRestLength) == "boolean" then bCollisionFoundRestLength = EgtCDeSolidSolid( idRestLengthSurfFr, CollisionSurfTmId[i], BeamData.COLL_SIC)
error( 'Presimulation fail') if not type( bCollisionFoundRestLength) == "boolean" then
end error( 'Presimulation fail')
if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then end
EgtSetColor( idCollisionSurfTm, ORANGE()) if EgtGetDebugLevel() >= 3 and bCollisionFoundRestLength then
EgtSetColor( CollisionSurfTmId[i], ORANGE())
end
if bCollisionFoundRestLength then
break
end
end end
end end
end end
@@ -364,43 +404,29 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
local bCheckOnlyRestlength = OptionalParameters.bCheckOnlyRestlength or false local bCheckOnlyRestlength = OptionalParameters.bCheckOnlyRestlength or false
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
local vtAux = OptionalParameters.vtAux
-- se normale faccia non parallela a direzione testa c'è qualcosa che non va -- se normale faccia non parallela a direzione testa c'è qualcosa che non va
if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then
error( 'CheckCollisionWithAxis : invalid directions') error( 'CheckCollisionWithAxis : invalid directions')
end end
-- punti notevoli della lavorazione in cui fare il check -- punti notevoli della lavorazione in cui fare il check
local PointsToCheck = OptionalParameters.PointsToCheck or GetCollisionPointsToCheck( Edge, dDepthToMachine) local PointsToCheck = OptionalParameters.PointsToCheck or GetCollisionPointsToCheck( Edge, dDepthToMachine)
-- punti in centro lama su naso mandrino o aggregato. In base a direzione e punto -- punti sul tip dell'utensile, in centro
local bIsDownUp = AreOppositeVectorApprox( vtNFace, vtHead) local PointsOnToolTipCenter = {}
local ToolExitPoints = {}
for i = 1, #PointsToCheck do 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 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 local bMoveAfterSplit = false
-- se almeno in un punto c'è collisione con il pezzo si ritorna collisione -- 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) -- 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) local bCollisionFoundPiece, bCollisionFoundRestLength = CheckCollisionPoint( sAxis, PointsOnToolTipCenter[i], vtHead, vtAux, Part, bCannotSplitRestLength, sRestLengthSideForPreSimulation, bCheckOnlyRestlength)
-- se trovata collisione con pezzo è inutile controllare gli altri punti -- se trovata collisione con pezzo è inutile controllare gli altri punti
if bCollisionFoundPiece then if bCollisionFoundPiece then
@@ -422,7 +448,12 @@ end
function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, OptionalParameters) function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, OptionalParameters)
local bCollisionFound 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 -- parametri opzionali, in parte da far transitare
OptionalParameters = OptionalParameters or {} OptionalParameters = OptionalParameters or {}
@@ -432,8 +463,12 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional
OptionalParametersCheckCollisionWithAxis.PointsToCheck = OptionalParameters.PointsToCheck or nil OptionalParametersCheckCollisionWithAxis.PointsToCheck = OptionalParameters.PointsToCheck or nil
OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' OptionalParametersCheckCollisionWithAxis.sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false OptionalParametersCheckCollisionWithAxis.bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
OptionalParametersCheckCollisionWithAxis.sBlockedAxis = OptionalParameters.sBlockedAxis
OptionalParametersCheckCollisionWithAxis.vtAux = OptionalParameters.vtAux
local sBlockedAxis = OptionalParameters.sBlockedAxis
local bIsDicing = OptionalParameters.bIsDicing or false local bIsDicing = OptionalParameters.bIsDicing or false
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
local bCheckOnlyRestlengthForAxisABC = false local bCheckOnlyRestlengthForAxisABC = 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) -- 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)
@@ -441,7 +476,7 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional
bCheckOnlyRestlengthForAxisABC = true bCheckOnlyRestlengthForAxisABC = true
-- se l'elevazione reale (rispetto al pezzo + eventuale materiale in testa/coda) è maggiore del massimo materiale è sempre collisione -- se l'elevazione reale (rispetto al pezzo + eventuale materiale in testa/coda) è maggiore del massimo materiale è sempre collisione
-- TODO rifare con funzione -- TODO rifare con funzione
else elseif not bDisableRealElevationCheck then
local Edge = Parameters.Edge local Edge = Parameters.Edge
local vtNFace = Parameters.vtNFace local vtNFace = Parameters.vtNFace
local dDepthToMachine = Parameters.dDepthToMachine local dDepthToMachine = Parameters.dDepthToMachine
@@ -464,21 +499,46 @@ function PreSimulationLib.CheckCollision( sBladeEngagement, Parameters, Optional
end end
end end
-- asse Z si controlla sempre -- SCC
bCollisionFound, bMoveAfterSplitZ = CheckCollisionWithAxis( 'Z', Parameters, OptionalParametersCheckCollisionWithAxis) local nSCC = Tool.SetupInfo.GetSCC( Edge.vtN, Edge.vtEdge, vtNFace)
-- assi AB e C: se richiesto si controlla la collisione solo col grezzo -- 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
-- 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)
-- assi rotativi: se richiesto si controlla la collisione solo col grezzo
OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = bCheckOnlyRestlengthForAxisABC OptionalParametersCheckCollisionWithAxis.bCheckOnlyRestlength = bCheckOnlyRestlengthForAxisABC
if not bCollisionFound then if sR3 and not bCollisionFound then
bCollisionFound, bMoveAfterSplitAB = CheckCollisionWithAxis( 'AB', Parameters, OptionalParametersCheckCollisionWithAxis) bCollisionFound, bMoveAfterSplitR3 = CheckCollisionWithAxis( sR3, Parameters, OptionalParametersCheckCollisionWithAxis)
end end
if not bCollisionFound then if not bCollisionFound then
bCollisionFound, bMoveAfterSplitC = CheckCollisionWithAxis( 'C', Parameters, OptionalParametersCheckCollisionWithAxis) bCollisionFound, bMoveAfterSplitR2 = CheckCollisionWithAxis( sR2, Parameters, OptionalParametersCheckCollisionWithAxis)
end 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 return bCollisionFound, bMoveAfterSplit
end end
+4 -7
View File
@@ -15,9 +15,6 @@ EgtAddToPackagePath( BEAM.BASEDIR .. '\\LuaLibs\\?.lua')
EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua') EgtAddToPackagePath( BEAM.BASEDIR .. '\\Strategies\\Standard\\?.lua')
EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.lua') EgtAddToPackagePath( BEAM.BASEDIR .. '\\StrategyLibs\\?.lua')
-- TODO forzatura calcolo con prerotazioni. Cancellare dopo che è stata aggiunta la gestione corretta
local bCalcBestPieceUnloadPosition = true
-- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi -- Verifico che la macchina corrente sia abilitata per la lavorazione delle Travi
local sMachDir = EgtGetCurrMachineDir() local sMachDir = EgtGetCurrMachineDir()
if not sMachDir then if not sMachDir then
@@ -290,7 +287,7 @@ local function MyProcessBeams()
end end
-- Sistemo le travi nel grezzo -- Sistemo le travi nel grezzo
local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, bCalcBestPieceUnloadPosition) local bOk, sErr = BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, nil, false)
if not bOk then if not bOk then
EgtOutLog( sErr) EgtOutLog( sErr)
EgtOutBox( sErr, 'Lavora Travi', 'ERROR') EgtOutBox( sErr, 'Lavora Travi', 'ERROR')
@@ -305,9 +302,9 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
local function MyProcessFeatures() local function MyProcessFeatures()
BeamExec.GetProcessings( PARTS, bCalcBestPieceUnloadPosition) BeamExec.GetProcessings( PARTS, false)
BeamExec.GetCombinationMatrix( PARTS, bCalcBestPieceUnloadPosition) BeamExec.GetCombinationMatrix( PARTS, false)
BeamExec.ProcessMachinings( PARTS) BeamExec.ProcessMachinings( PARTS, false)
local nErrCnt = 0 local nErrCnt = 0
local nWarnCnt = 0 local nWarnCnt = 0
local sOutput = '' local sOutput = ''
+1 -1
View File
@@ -688,7 +688,7 @@
"TopologyList" : [ "TopologyList" : [
{ "sName": "Feature", { "sName": "Feature",
"sImage": "ConfigStrategy\\ScarfJoint.png", "sImage": "ConfigStrategy\\ScarfJoint.png",
"StrategyList" : [ ] "StrategyList" : [ { "sStrategyId": "STR0009" }]
} }
] ]
}, },
+29 -7
View File
@@ -1,10 +1,10 @@
[ [
{ {
"nGroup": "MACHINE", "nGroup": "PIECE LOADING",
"sName": "GEN_sPiecesLoadingPosition", "sName": "GEN_sPiecesLoadingPosition",
"sNameNge": "GEN_PIECES_LOADING", "sNameNge": "GEN_PIECES_LOADING",
"sValue": "BEST_POSITION", "sValue": "BTL_POSITION",
"sDescriptionShort": "Part loading position", "sDescriptionShort": "Part loading position",
"sDescriptionLong": "", "sDescriptionLong": "",
"sType": "combo", "sType": "combo",
@@ -12,24 +12,46 @@
"Choices": [ "Choices": [
{ {
"sValue": "BTL_POSITION", "sValue": "BTL_POSITION",
"sDescriptionShort": "Last piece position as BTL", "sDescriptionShort": "Loading position from BTL, no pre-rotation",
"sDescriptionLong": "", "sDescriptionLong": "",
"sMessageId": "" "sMessageId": ""
}, },
{ {
"sValue": "BEST_ROTATION", "sValue": "STD_PRE_ROTATION",
"sDescriptionShort": "Allow piece rotations", "sDescriptionShort": "Get Best loading position from 0° and 180°",
"sDescriptionLong": "", "sDescriptionLong": "",
"sMessageId": "" "sMessageId": ""
}, },
{ {
"sValue": "BEST_POSITION", "sValue": "FULL_PRE_ROTATION",
"sDescriptionShort": "Allow piece rotation and inversion", "sDescriptionShort": "Get Best loading position in each piece rotation",
"sDescriptionLong": "", "sDescriptionLong": "",
"sMessageId": "" "sMessageId": ""
} }
] ]
}, },
{
"nGroup": "PIECE LOADING",
"sName": "GEN_bAllowPieceInversion",
"sNameNge": "ADMIT_INVERSION",
"sValue": "false",
"sDescriptionShort": "Allow piece inversion",
"sDescriptionLong": "",
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"nGroup": "PIECE LOADING",
"sName": "GEN_bGetAlternativesNesting2D",
"sNameNge": "GET_ALTERNATIVES_NEST2D",
"sValue": "false",
"sDescriptionShort": "Enable material optimization function in nesting",
"sDescriptionLong": "",
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{ {
"nGroup": "MACHINE", "nGroup": "MACHINE",
"sName": "GEN_sPieceRotation", "sName": "GEN_sPieceRotation",
+5 -3
View File
@@ -40,6 +40,11 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- si setta che è taglio di testa -- si setta che è taglio di testa
Strategy.bIsHeadCut = true 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) -- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then if Strategy.Parameters.bExecutePreCut then
@@ -67,9 +72,6 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- se devo applicare le lavorazioni -- se devo applicare le lavorazioni
if bAddMachining then if bAddMachining then
-- si forza il nome della feature
EgtSetName( Proc.id, 'StartCut')
-- inserimento smussi su spigoli del taglio -- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then if Strategy.Parameters.bMakeChamfer then
MakeChamfer() MakeChamfer()
+10
View File
@@ -22,6 +22,16 @@
"sMessageId": " ", "sMessageId": " ",
"sMinUserLevel": "1" "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",
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{ {
"sName": "dOpenMinSafe", "sName": "dOpenMinSafe",
"sNameNge": "OPENMINSAFE", "sNameNge": "OPENMINSAFE",
+119 -16
View File
@@ -19,6 +19,7 @@ local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamDataNew') local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib') local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib') local FeatureLib = require( 'FeatureLib')
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
-- Tabella per definizione modulo -- Tabella per definizione modulo
local STR0002 = {} local STR0002 = {}
@@ -107,7 +108,7 @@ local function GetBestPocketingStrategy( Proc, Part)
local Milling = {} local Milling = {}
local ToolSearchParameters = {} local ToolSearchParameters = {}
ToolSearchParameters.sMillShape = 'STANDARD' 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') Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
-- caso speciale Tunnel che non ha faccia bottom -- caso speciale Tunnel che non ha faccia bottom
@@ -170,10 +171,14 @@ local function GetBestPocketingStrategy( Proc, Part)
-- cerco utensile per lavorare faccia Bottom -- cerco utensile per lavorare faccia Bottom
Milling.bIsApplicable = false Milling.bIsApplicable = false
if Proc.Topology.sName ~= 'Tunnel-4-Through' then 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.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[1].vtN ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[1].vtN
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing') ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[1].id Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[1].id
Milling.bAddAntiSplint = Strategy.Parameters.bAntiSplint
Milling.idProc = Proc.id Milling.idProc = Proc.id
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[1].vtN Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[1].vtN
Milling.dElevation = Proc.MainFaces.BottomFaces[1].dElevation Milling.dElevation = Proc.MainFaces.BottomFaces[1].dElevation
@@ -204,13 +209,14 @@ local function GetBestPocketingStrategy( Proc, Part)
-- caso speciale 'Rabbet-2-Through' seconda faccia principale -- caso speciale 'Rabbet-2-Through' seconda faccia principale
Milling = {} Milling = {}
Milling.bIsApplicable = false 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 Proc.Topology.sName == 'DoubleBevel-2-Through' or Proc.Topology.sName == 'VGroove-2-Through' then
ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation ToolSearchParameters.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN ToolSearchParameters.vtToolDirection = Proc.MainFaces.BottomFaces[2].vtN
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing') ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN Milling.vtFaceNormal = Proc.MainFaces.BottomFaces[2].vtN
Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id Milling.idFaceToMachine = Proc.MainFaces.BottomFaces[2].id
Milling.bAddAntiSplint = Strategy.Parameters.bAntiSplint
Milling.idProc = Proc.id Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
Milling.ToolInfo = {} Milling.ToolInfo = {}
@@ -238,12 +244,21 @@ local function GetBestPocketingStrategy( Proc, Part)
Milling.idProc = Proc.id Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation Milling.dElevation = Proc.MainFaces.BottomFaces[2].dElevation
elseif Proc.Topology.sName == 'Groove-3-Blind' or Proc.Topology.sName == 'Bevel-3-Blind' then elseif Proc.Topology.sName == 'Groove-3-Blind' or Proc.Topology.sName == 'Bevel-3-Blind' then
ToolSearchParameters.dElevation = Proc.MainFaces.LongFaces[1].dElevation if Proc.MainFaces.LongFaces and Proc.MainFaces.LongFaces[1] then
ToolSearchParameters.vtToolDirection = Proc.MainFaces.LongFaces[1].vtN ToolSearchParameters.dElevation = Proc.MainFaces.LongFaces[1].dElevation
Milling.vtFaceNormal = Proc.MainFaces.LongFaces[1].vtN ToolSearchParameters.vtToolDirection = Proc.MainFaces.LongFaces[1].vtN
Milling.idFaceToMachine = Proc.MainFaces.LongFaces[1].id Milling.vtFaceNormal = Proc.MainFaces.LongFaces[1].vtN
Milling.idProc = Proc.id Milling.idFaceToMachine = Proc.MainFaces.LongFaces[1].id
Milling.dElevation = Proc.MainFaces.LongFaces[1].dElevation 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' 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 -- se lavoro di fianco, devo comunque rispettare il raggio massimo
ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2) ToolSearchParameters.dMaxToolDiameter = min( ToolSearchParameters.dMaxToolDiameter, Strategy.Parameters.dMaxCornerRadius * 2)
@@ -254,6 +269,8 @@ local function GetBestPocketingStrategy( Proc, Part)
Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id Milling.idProc = Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.id
Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP Milling.dElevation = ( Proc.MainFaces.TunnelAddedFaces.MiddleFaceTm.Faces[1].dElevation * 2) + BeamData.MILL_OVERLAP
Milling.bMachAppliedToTunnelFace = true Milling.bMachAppliedToTunnelFace = true
else
ToolSearchParameters.vtToolDirection = nil
end end
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing') ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.ToolInfo = {} Milling.ToolInfo = {}
@@ -263,6 +280,19 @@ local function GetBestPocketingStrategy( Proc, Part)
local ParametersMRR = {} local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR) 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
end end
table.insert( Machining, Milling) table.insert( Machining, Milling)
@@ -294,6 +324,8 @@ local function GetBestPocketingStrategy( Proc, Part)
Milling.idFaceToMachine = Proc.MainFaces.SideFaces[1].id Milling.idFaceToMachine = Proc.MainFaces.SideFaces[1].id
Milling.idProc = Proc.id Milling.idProc = Proc.id
Milling.dElevation = Proc.MainFaces.SideFaces[1].dElevation Milling.dElevation = Proc.MainFaces.SideFaces[1].dElevation
else
ToolSearchParameters.vtToolDirection = nil
end end
ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing') ToolSearchParameters.AvailableToolList = MachiningLib.GetAvailableToolList( Proc, Strategy.Parameters.sPocketingList, 'Pocketing')
Milling.ToolInfo = {} Milling.ToolInfo = {}
@@ -303,13 +335,60 @@ local function GetBestPocketingStrategy( Proc, Part)
local ParametersMRR = {} local ParametersMRR = {}
ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex ParametersMRR.nToolIndex = Milling.ToolInfo.nToolIndex
Milling.dMRR = MachiningLib.GetToolMRR( ParametersMRR) 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
end end
table.insert( Machining, Milling) table.insert( Machining, Milling)
-- ===== SCELTA LAVORAZIONI ===== -- ===== 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 -- 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' Machining.sTypeMachining = 'Bottom'
Strategy.Result.sStatus = 'Completed' Strategy.Result.sStatus = 'Completed'
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100)
@@ -321,10 +400,10 @@ local function GetBestPocketingStrategy( Proc, Part)
if ( Proc.nFct == 2 and Proc.AdjacencyMatrix[1][2] >= -89.9) 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 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.sStatus = 'Completed'
Strategy.Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( 100) 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 Machining[2].ToolInfo.dResidualDepth = 0
else else
Machining[2].bIsApplicable = false Machining[2].bIsApplicable = false
@@ -549,8 +628,8 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
Pocketing.Steps.dStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dStep Pocketing.Steps.dStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dStep
Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dSideStep Pocketing.Steps.dSideStep = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dSideStep
Pocketing.nToolIndex = Strategy.Machining[j].ToolInfo.nToolIndex Pocketing.nToolIndex = Strategy.Machining[j].ToolInfo.nToolIndex
Pocketing.LeadIn.dTangentDistance = 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.LeadIn.dElevation = TOOLS[Strategy.Machining[j].ToolInfo.nToolIndex].dDiameter / 2
Pocketing.sDepth = -Strategy.Machining[j].ToolInfo.dResidualDepth Pocketing.sDepth = -Strategy.Machining[j].ToolInfo.dResidualDepth
Pocketing.dResidualDepth = Strategy.Machining[j].ToolInfo.dResidualDepth Pocketing.dResidualDepth = Strategy.Machining[j].ToolInfo.dResidualDepth
-- TODO vedere se questo parametro con svuotature nuove si può rimuovere -- TODO vedere se questo parametro con svuotature nuove si può rimuovere
@@ -559,11 +638,35 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
if Strategy.Machining[j].bToolInvert then if Strategy.Machining[j].bToolInvert then
Pocketing.bToolInvert = true Pocketing.bToolInvert = true
end 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 -- se ho una sola trimesh, sto lavorando la Proc direttamente e non ho spezzato. Applico direttamente alla geometria calcolata prima
if #vAddId == 1 then if #vAddId == 1 then
Pocketing.Geometry = {{ Strategy.Machining[j].idProc, Strategy.Machining[j].idFaceToMachine}} Pocketing.Geometry = {{ Strategy.Machining[j].idProc, Strategy.Machining[j].idFaceToMachine}}
Pocketing.vtToolDirection = Strategy.Machining[j].vtFaceNormal Pocketing.vtToolDirection = Strategy.Machining[j].vtFaceNormal
-- TODO controllare parametro danneggiamento ammesso per decidere se spostare dopo taglio seprazione -- TODO controllare parametro danneggiamento ammesso per decidere se spostare dopo taglio seprazione
-- se è aperta sulla coda, dico che deve essere fatta dopo la separazione -- se è aperta sulla coda, dico che deve essere fatta dopo la separazione
if Proc.AffectedFaces.bLeft then if Proc.AffectedFaces.bLeft then
@@ -593,10 +696,10 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
end end
if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then if vtNSplitFace and AreSameVectorApprox( vtNSplitFace * EgtIf( Pocketing.bToolInvert, -1, 1), Strategy.Machining[j].vtFaceNormal) then
Pocketing.Geometry = {{ nIdTm, k - 1}} Pocketing.Geometry = {{ nIdTm, k - 1}}
Pocketing.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Pocketing, Part) Pocketing.dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Pocketing, Part)
Strategy.Result.dTimeToMachine = Strategy.Result.dTimeToMachine + Pocketing.dTimeToMachine Strategy.Result.dTimeToMachine = Strategy.Result.dTimeToMachine + Pocketing.dTimeToMachine
if bAddMachining then if bAddMachining then
bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddMachinings( Proc, Pocketing) bAreAllMachiningsAdded = bAreAllMachiningsAdded and MachiningLib.AddMachinings( Proc, Pocketing)
end end
+1 -1
View File
@@ -17,7 +17,7 @@
"sNameNge": "EXTEND_AFTER_TAIL", "sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "", "sValue": "",
"sDescriptionShort": "Extend after tail", "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",
"sType": "d", "sType": "d",
"sMessageId": " ", "sMessageId": " ",
"sMinUserLevel": "1" "sMinUserLevel": "1"
+33 -8
View File
@@ -35,12 +35,19 @@ Chainsaw.Result = {}
local function IsTopologyOk( Proc) local function IsTopologyOk( Proc)
if Proc.Topology.bAllRightAngles and if Proc.Topology.bAllRightAngles and
( Proc.Topology.sName == 'Pocket-5-Blind' or ( Proc.Topology.sName == 'Pocket-5-Blind' or
Proc.Topology.sName == 'Groove-3-Through' or
Proc.Topology.sName == 'Groove-4-Blind' or Proc.Topology.sName == 'Groove-4-Blind' or
Proc.Topology.sName == 'Tunnel-4-Through') then Proc.Topology.sName == 'Tunnel-4-Through') then
return true 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 else
return false return false
end end
end end
@@ -188,6 +195,17 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
Blade.Result = {} Blade.Result = {}
Chainsaw.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 if not IsTopologyOk( Proc) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented' local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
EgtOutLog( sErr) EgtOutLog( sErr)
@@ -195,13 +213,15 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
return false, Strategy.Result return false, Strategy.Result
end end
-- se tasca su faccia sotto la strategia non è applicabile (la sega a catena in generale non può lavorare da sotto) -- se canale e lati non a 90deg la strategia non è applicabile
-- TODO se OnlySaw questo test è da rimuovere ma bisogna considerare anche la lama da sotto -- TODO questo è temporaneo finchè non si gestiscono correttamente i lati obliqui per le groove-3-through
if Proc.AffectedFaces.bBottom and ( Proc.nFct > 3 or not Proc.AffectedFaces.bTop) then -- la dPocketHeight è già gestita, ma va allungato il percorso dove c'è l'angolo > 90
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not applicable - pocket on bottom face' if Proc.Topology.sName == 'Groove-3-Through' then
EgtOutLog( sErr) local BottomFace = Proc.MainFaces.BottomFaces[1]
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Direction') if abs( BottomFace.Edges[1].vtEdge * BottomFace.Edges[2].vtEdge) > 10 * GEO.EPS_SMALL then
return false, Strategy.Result Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
return false, Strategy.Result
end
end end
local dExtendAfterTail = Strategy.Parameters.dExtendAfterTail or max( Part.dDistanceToNextPiece - BeamData.CUT_EXTRA, 0) 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 local dPocketHeight = 0
if Proc.Topology.sFamily == 'Tunnel' then if Proc.Topology.sFamily == 'Tunnel' then
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength 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 else
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
end end
+1 -1
View File
@@ -17,7 +17,7 @@
"sNameNge": "EXTEND_AFTER_TAIL", "sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "", "sValue": "",
"sDescriptionShort": "Extend after tail", "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",
"sType": "d", "sType": "d",
"sMessageId": " ", "sMessageId": " ",
"sMinUserLevel": "1" "sMinUserLevel": "1"
+33 -5
View File
@@ -112,8 +112,6 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
Chainsaw.Result = {} Chainsaw.Result = {}
if not IsTopologyOk( Proc) then if not IsTopologyOk( Proc) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. Strategy.sName .. ' not implemented'
EgtOutLog( sErr)
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology') Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Topology')
return false, Strategy.Result return false, Strategy.Result
end end
@@ -134,10 +132,25 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
bIsSplitFeature = true bIsSplitFeature = true
end 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 -- altezza tasca
local dPocketHeight = 0 local dPocketHeight = 0
if Proc.Topology.sFamily == 'Tunnel' then if Proc.Topology.sFamily == 'Tunnel' then
dPocketHeight = Proc.MainFaces.SideFaces[1].MainEdges.OppositeEdges[1].dLength 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 else
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
end end
@@ -172,13 +185,17 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
and #Proc.MainFaces.SideFaces == 1 then and #Proc.MainFaces.SideFaces == 1 then
OptionalParameters.OppositeToolDirectionMode = 'Enabled' OptionalParameters.OppositeToolDirectionMode = 'Enabled'
local dLengthAlreadyMachined = 0
if Chainsaw.Result.Bottom[1].bIsApplicable then
dLengthAlreadyMachined = Chainsaw.Result.Bottom[1].dDepthToMachine
end
if BottomEdge.bIsStartOpen then if BottomEdge.bIsStartOpen then
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters) 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 elseif BottomEdge.bIsEndOpen then
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters) 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 end
Chainsaw.AddResult( Mortising) Chainsaw.AddResult( Mortising)
@@ -235,10 +252,21 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters) Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters)
Chainsaw.AddResult( Mortising) 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 -- 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 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 OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN
+1 -1
View File
@@ -17,7 +17,7 @@
"sNameNge": "EXTEND_AFTER_TAIL", "sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "", "sValue": "",
"sDescriptionShort": "Extend after tail", "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",
"sType": "d", "sType": "d",
"sMessageId": " ", "sMessageId": " ",
"sMinUserLevel": "1" "sMinUserLevel": "1"
+1 -1
View File
@@ -66,7 +66,7 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
local dQualityAddedFace = 0 local dQualityAddedFace = 0
-- più di 3 facce non supportate -- 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') Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'More than 3 faces not supported')
end end
+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) local ptCutC, vtCutN = EgtSurfTmFacetCenter( Proc.id, 1, GDB_ID.ROOT)
if ptCutC and vtCutN and AreSameVectorApprox( Proc.FeatureInfo.vtMortiseN, vtCutN) then if ptCutC and vtCutN and AreSameVectorApprox( Proc.FeatureInfo.vtMortiseN, vtCutN) then
-- recupero gruppo per geometria addizionale -- 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) Strategy.idMortiseCutPlane = EgtSurfTmPlaneInBBox( nAddGrpId, ptCutC, vtCutN, Part.b3Part, GDB_RT.GLOB)
end end
end end
+1 -4
View File
@@ -311,10 +311,7 @@ function STR0008.Make( bAddMachining, Proc, Part, CustomParameters)
-- si applicano le lavorazioni di svuotatura -- si applicano le lavorazioni di svuotatura
for i = 1, #Strategy.Machining.Pocketing do for i = 1, #Strategy.Machining.Pocketing do
if Strategy.Machining.Pocketing[i].bIsApplicable then if Strategy.Machining.Pocketing[i].bIsApplicable then
Pocketing = {} Pocketing = MachiningLib.InitMachiningParameters( MCH_MY.POCKETING)
Pocketing.Steps = {}
Pocketing.LeadIn = {}
Pocketing.nType = MCH_MY.POCKETING
Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT Pocketing.nSubType = MCH_POCK_SUB.SPIRALOUT
Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG Pocketing.LeadIn.nType = MCH_POCK_LI.ZIGZAG
Pocketing.Steps.dStep = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dStep Pocketing.Steps.dStep = TOOLS[Strategy.Machining.Pocketing[i].ToolInfo.nToolIndex].dStep
+5 -25
View File
@@ -1,6 +1,6 @@
{ {
"sStrategyId": "STR0009", "sStrategyId": "STR0009",
"sStrategyName": "Mill Heading", "sStrategyName": "ScarfJoint",
"ParameterList" : [ "ParameterList" : [
{ {
"sName": "dDepthChamfer", "sName": "dDepthChamfer",
@@ -13,35 +13,15 @@
"sMinUserLevel": "1" "sMinUserLevel": "1"
}, },
{ {
"sName": "dOverMaterial", "sName": "bAntiSplint",
"sNameNge": "OVERMAT", "sNameNge": "ANTISPLINT",
"sValue": "0",
"sDescriptionShort": "Overmaterial",
"sDescriptionLong": "",
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bForceStrip",
"sNameNge": "FORCE_STRIP",
"sValue": "false", "sValue": "false",
"sDescriptionShort": "Force strip", "sDescriptionShort": "Use Anti-Splint strategy",
"sDescriptionLong": "Enable the parameter to force the software to leave a strip to sustain the piece", "sDescriptionLong": "The strategy will apply blade cuts on corner to avoid wood splint",
"sType": "b", "sType": "b",
"sMessageId": " ", "sMessageId": " ",
"sMinUserLevel": "1" "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", "sName": "sMillingList",
"sNameNge": "PROFILE_TOOL_LIST", "sNameNge": "PROFILE_TOOL_LIST",
+178 -199
View File
@@ -1,7 +1,6 @@
-- Strategia: STR0009 -- Strategia: STR0009
-- Descrizione -- Descrizione
-- Fresatura di contorno -- Feature tipo ScarfJoint
-- Feature tipo Arco
-- carico librerie -- carico librerie
@@ -10,156 +9,182 @@ local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib') local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib') local FeatureLib = require( 'FeatureLib')
-- strategie di base -- 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 -- Tabella per definizione modulo
local STR0009 = {} local STR0009 = {}
local Strategy = {} local Strategy = {}
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- TODO gestire il caso in cui non si trova l'utensile local function GetFacesIdOrder( Proc, Part)
local function GetArcStrategy( Proc, Part) local Faces = {}
local Machining = {} if Proc.nFct == 5 then
local ToolSearchParameters = {} -- 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 return Faces
local idAux = EgtGetInfo( Proc.id, 'AUXID', 'i') end
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' 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) EgtOutLog( sErr)
return false, sErr Result = FeatureLib.GetStrategyResultNotApplicable( 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
else else
-- si cerca utensile 1 local dCompletionPercentage = 100
local Milling = {} -- completa se svuotatura eseguita e antisplit eseguiti (o non richiesti)
Milling.bIsApplicable = false if Pocketing.bIsApplicable and ( bAreAllAntisplintsApplicable or not Strategy.Parameters.bAntiSplint) then
ToolSearchParameters = {} Result.sStatus = 'Completed'
ToolSearchParameters.sMillShape = 'STANDARD' if bAreAllAntisplintsApplicable then
ToolSearchParameters.dElevation = dDepth + BeamData.MILL_OVERLAP Result.dQuality = FeatureLib.GetStrategyQuality( 'FINE')
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
else else
-- non si fa nulla Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
end end
-- altrimenti senza codolo -- altrimenti non completa
else else
-- se utensile 1 esegue completamente Result.dQuality = FeatureLib.GetStrategyQuality( 'STD')
if Milling.ToolInfo.nToolIndex and Milling.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then Result.sStatus = 'Not-Completed'
table.insert( Machining, Milling) -- se fa solo svuotatura
-- se utensile 2 esegue completamente if Pocketing.bIsApplicable then
elseif Milling2.ToolInfo.nToolIndex and Milling2.ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then dCompletionPercentage = 90
table.insert( Machining, Milling2) Result.sInfo = 'Anti-Split not executed'
-- se possono lavorare entrambi elseif Strategy.Parameters.bAntiSplint and bAreAllAntisplintsApplicable then
elseif Milling.ToolInfo.nToolIndex and Milling2.ToolInfo.nToolIndex then dCompletionPercentage = 75
table.insert( Machining, Milling) Result.sInfo = 'Pocketing not executed'
table.insert( Machining, Milling2) else
-- se utensile 1 non completo dCompletionPercentage = 50
elseif Milling.ToolInfo.nToolIndex then Result.sInfo = 'Only the cut has been executed'
table.insert( Machining, Milling)
-- se utensile 2 non completo
elseif Milling2.ToolInfo.nToolIndex then
table.insert( Machining, Milling2)
end end
end end
Result.dCompletionIndex = FeatureLib.GetFeatureCompletionIndex( dCompletionPercentage)
end end
-- TODO VOTO DA FARE!!!! -- creo una tabella unica contenente tutte le lavorazioni
Strategy.Result.sStatus = 'Completed' local Machinings = {}
Strategy.Result.dCompletionIndex = 5 EgtJoinTables( Machinings, Cutting.Machinings)
Strategy.Result.dMRR = MachiningLib.GetToolMRR( Machining[1].ToolInfo or Machining[2].ToolInfo) EgtJoinTables( Machinings, AntiSplints)
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'MILL') EgtJoinTables( Machinings, Pocketing)
Strategy.Result.sInfo = ''
return Machining return Machinings, Result
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
@@ -173,79 +198,33 @@ function STR0009.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Result = {} Strategy.Result = {}
local bAreAllMachiningsAdded = true 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 Strategy.Machinings, Strategy.Result = GetScarfJointStrategy( Proc, Part)
-- eventuali punti di spezzatura
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
for i = 1, #Strategy.Machinings do -- aggiunta lavorazioni
if #Strategy.Machinings > 0 then
Strategy.Machinings[i].Geometry = {{ Proc.idAddAuxGeom, -1}} if bAddMachining and Strategy.Result.sStatus ~= 'Not-Applicable' then
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)
-- aggiunge lavorazione -- aggiunge lavorazione
for j = 1, #MachiningResult do for j = 1, #Strategy.Machinings do
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, MachiningResult[j]) if Proc.AffectedFaces.bLeft then
Strategy.Machinings[j].sStage = 'AfterTail'
end
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machinings[j])
end end
end end
else else
bAreAllMachiningsAdded = false Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
end end
return bAreAllMachiningsAdded, Strategy.Result return bAreAllMachiningsAdded, Strategy.Result
end end
+22 -2
View File
@@ -3,7 +3,7 @@
"sStrategyName": "Milling", "sStrategyName": "Milling",
"ParameterList" : [ "ParameterList" : [
{ {
"sName": "dAntiSplintWithBlade", "sName": "bAntiSplintWithBlade",
"sNameNge": "ANTISPLINT_BLADE", "sNameNge": "ANTISPLINT_BLADE",
"sValue": "false", "sValue": "false",
"sDescriptionShort": "Antisplint with blade", "sDescriptionShort": "Antisplint with blade",
@@ -17,7 +17,27 @@
"sNameNge": "EXTEND_AFTER_TAIL", "sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "", "sValue": "",
"sDescriptionShort": "Extend after tail", "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",
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bFinishWithMill",
"sNameNge": "ALLOW_FINISH_MILL",
"sValue": "true",
"sDescriptionShort": "Clean radius with mill",
"sDescriptionLong": "Clean radius with mill",
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "dMillingOffsetFromSide",
"sNameNge": "MILLING_OFFSET_SIDE",
"sValue": "1",
"sDescriptionShort": "Milling offset from side",
"sDescriptionLong": "",
"sType": "d", "sType": "d",
"sMessageId": " ", "sMessageId": " ",
"sMinUserLevel": "1" "sMinUserLevel": "1"
+226 -79
View File
@@ -9,7 +9,9 @@ local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib') local MachiningLib = require( 'MachiningLib')
local FeatureLib = require( 'FeatureLib') local FeatureLib = require( 'FeatureLib')
-- strategie di base -- strategie di base
local FaceByMill = require('FACEBYMILL') local FaceByMill = require( 'FACEBYMILL')
local FaceByBlade = require( 'FACEBYBLADE')
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
-- Tabella per definizione modulo -- Tabella per definizione modulo
local STR0010 = {} local STR0010 = {}
@@ -34,7 +36,7 @@ local function GetStrategyCompletionPercentage( Machinings)
if nWeightsCount ~= 0 and nWeightsCount ~= i then if nWeightsCount ~= 0 and nWeightsCount ~= i then
error( 'GetWeightedCompletionPercentage : inconsistent weights') error( 'GetWeightedCompletionPercentage : inconsistent weights')
end end
local dWeightedCompletionPercentage = Machining.dCompletionPercentage / 100 * dWeight local dWeightedCompletionPercentage = ( Machining.dCompletionPercentage or 0) / 100 * dWeight
if Machining.bIsApplicable then if Machining.bIsApplicable then
dCompletionPercentageNumerator = dCompletionPercentageNumerator + dWeightedCompletionPercentage dCompletionPercentageNumerator = dCompletionPercentageNumerator + dWeightedCompletionPercentage
end end
@@ -47,34 +49,52 @@ local function GetStrategyCompletionPercentage( Machinings)
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
local function CompareEdges( EdgeA, EdgeB) local function CompareEdgesLongestTop( EdgeA, EdgeB)
-- prima i lati orientati lungo X -- si preferiscono i lati più lunghi
if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
return true 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 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 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 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 return false
-- se stessa lunghezza si preferiscono i lati più in basso -- se stessa Z si preferiscono i lati verso il fronte della trave
-- TODO qui dipenderà dalla lama scelta
else 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 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 return false
-- se stessa Z si preferiscono i lati verso il fronte della trave
else else
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then return false
return true end
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then end
return false end
else end
return false
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 end
end end
@@ -93,7 +113,7 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- TODO modificare funzione e verificare pinzaggio con regioni e area outline -- 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}) local bIsFeatureLong = FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
-- se impatta su faccia retro o sotto, controllo fattibilità -- se impatta su faccia retro o sotto, controllo fattibilità
if Proc.AffectedFaces.bBack then if Proc.AffectedFaces.bBack then
@@ -112,31 +132,24 @@ local function IsPositionOK( Proc, Part)
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- TODO da sistemare local function GetLongEdgeToMachine( Face, bHeadType)
local function GetBottomFaceEdge( Proc, nIndexFace)
local Edge = {} local Edge = {}
-- si lavora la bottom longitudinalmente local EdgesSorted = {}
if Proc.nFct == 1 or Proc.Topology.sFamily == 'DoubleBevel' then for i = 1, #Face.Edges do
local BottomEdgesSorted = {} table.insert( EdgesSorted, Face.Edges[i])
for i = 1, #Proc.MainFaces.BottomFaces[nIndexFace].Edges do end
table.insert( BottomEdgesSorted, Proc.MainFaces.BottomFaces[nIndexFace].Edges[i]) if bHeadType.bBottom then
end table.sort( EdgesSorted, CompareEdgesLongestBottom)
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
else else
if nIndexFace == 1 then table.sort( EdgesSorted, CompareEdgesLongestTop)
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.LongEdges[1] end
elseif nIndexFace == 2 then
Edge = Proc.MainFaces.BottomFaces[nIndexFace].MainEdges.BottomEdge -- 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
end Edge = EdgesSorted[1]
local EdgeOpposite = BeamLib.FindEdgeBestOrientedAsDirection( Face.Edges, -Edge.vtN)
if ( not EdgeOpposite.bIsOpen) and Edge.bIsOpen then
Edge = EdgeOpposite
end end
return Edge return Edge
@@ -148,15 +161,28 @@ local function SortMachiningsBySegment( MachiningA, MachiningB)
return false return false
elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then elseif MachiningB.nFeatureSegment > MachiningA.nFeatureSegment then
return true return true
-- se segmento uguale, si guarda la priorità
else else
if TOOLS[ MachiningA.nToolIndex].sFamily == 'SAWBLADE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'MORTISE' then if MachiningA.nInternalSortingPriority > MachiningB.nInternalSortingPriority then
return true
elseif TOOLS[ MachiningA.nToolIndex].sFamily == 'MORTISE' and TOOLS[ MachiningB.nToolIndex].sFamily == 'SAWBLADE' then
return false return false
elseif MachiningB.nInternalSortingPriority > MachiningA.nInternalSortingPriority then
return true
-- se priorità uguale, si minimizzano i cambi di lato
else else
if MachiningA.sEdgeType == 'Side' and MachiningB.sEdgeType ~= 'Side' then local bIsOddSegment = ( MachiningA.nFeatureSegment % 2 ~= 0)
return true if MachiningA.vtToolDirection:getY() < MachiningB.vtToolDirection:getY() - 10 * GEO.EPS_SMALL then
elseif MachiningB.sEdgeType == 'Side' and MachiningA.sEdgeType ~= 'Side' 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 return false
end end
end end
@@ -172,6 +198,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config) Strategy.Parameters = BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, StrategyLib.Config)
Strategy.Machinings = {} Strategy.Machinings = {}
Strategy.Result = {} Strategy.Result = {}
local CalculatedMachinings = {}
-- controllo su topologia -- controllo su topologia
if not IsTopologyOk( Proc) then if not IsTopologyOk( Proc) then
@@ -181,7 +208,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
-- controllo dimensioni solo se non è forzata -- controllo dimensioni solo se non è forzata
if not CustomParameters.bForcedStrategy then 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') Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( 'Feature not machinable in this position')
return false, Strategy.Result return false, Strategy.Result
end end
@@ -198,8 +225,6 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
-- volume della feature -- volume della feature
local dFeatureVolume = Proc.dVolume local dFeatureVolume = Proc.dVolume
-- TODO taglio su eventuali facce di chiusura
-- eventuali punti di spezzatura -- eventuali punti di spezzatura
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
local bIsSplitFeature = false local bIsSplitFeature = false
@@ -212,45 +237,167 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
dExtendAfterTail = 10000 dExtendAfterTail = 10000
end end
-- lavorazione della BottomFace
local bAreAllMachiningsAdded = true local bAreAllMachiningsAdded = true
local Milling = {}
local OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} -- ricerca delle Bottom (la principale deve avere 4 lati esatti)
local EdgeToMachine = GetBottomFaceEdge( Proc, 1) local BottomFace1 = Proc.MainFaces.BottomFaces[1]
if EdgeToMachine.bIsOpen then local BottomFace2 = Proc.MainFaces.BottomFaces[2]
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA if #BottomFace1.Edges ~= 4 then
end Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[1], EdgeToMachine, OptionalParametersFaceByMill) return false, Strategy.Result
if Milling.bIsApplicable then
table.insert( Strategy.Machinings, Milling)
end end
-- si lavora seconda BottomFace -- ricerca utensile
if Proc.Topology.sFamily == 'DoubleBevel' or Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind' then local ToolSearchParameters = {}
local dAngleBetweenFaces = Proc.AdjacencyMatrix[1][2] ToolSearchParameters.dElevation = BottomFace1.dElevation
-- se convesso o concavo maggiore di angolo retto ToolSearchParameters.vtToolDirection = BottomFace1.vtN
if dAngleBetweenFaces >= -91 then ToolSearchParameters.bAllowTopHead = true
Milling = {} ToolSearchParameters.bAllowBottomHead = true
OptionalParametersFaceByMill = { nStepType = MCH_MILL_ST.ONEWAY, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail} ToolSearchParameters.sMillShape = 'STANDARD'
EdgeToMachine = GetBottomFaceEdge( Proc, 2) local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
if EdgeToMachine.bIsOpen then local nToolIndex = ToolInfo.nToolIndex
OptionalParametersFaceByMill.dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
-- 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 end
Milling = FaceByMill.Make( Proc, Part, Proc.MainFaces.BottomFaces[2], EdgeToMachine, OptionalParametersFaceByMill) table.insert( CalculatedMachinings, Milling2)
if Milling.bIsApplicable then end
table.insert( Strategy.Machinings, Milling) 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 end
end end
-- calcolo completamento, serve la lista di lavorazioni che comprende le non applicabili -- antischeggia sulle facce di chiusura delle facce lavorate
Strategy.Result.dCompletionPercentage = GetStrategyCompletionPercentage( Strategy.Machinings) 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) 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) Strategy.Machinings = MachiningLib.GetSplitMachinings( Strategy.Machinings, FeatureSplittingPoints, Part)
table.sort( Strategy.Machinings, SortMachiningsBySegment) 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.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Strategy.Machinings)
Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6) Strategy.Result.dMRR = ( dFeatureVolume / Strategy.Result.dTimeToMachine) / pow( 10, 6)
if Strategy.Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then if Strategy.Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
+1 -1
View File
@@ -7,7 +7,7 @@
"sNameNge": "EXTEND_AFTER_TAIL", "sNameNge": "EXTEND_AFTER_TAIL",
"sValue": "", "sValue": "",
"sDescriptionShort": "Extend after tail", "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",
"sType": "d", "sType": "d",
"sMessageId": " ", "sMessageId": " ",
"sMinUserLevel": "1" "sMinUserLevel": "1"
+1 -1
View File
@@ -74,7 +74,7 @@ local function GetDrillingWithMillStrategy( Proc, Part)
HalfMilling2.ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) 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 -- 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 if Milling.ToolInfo.nToolIndex ~= HalfMilling.ToolInfo.nToolIndex then
Milling.ToolInfo.nToolIndex, Milling.ToolInfo.dResidualDepth = HalfMilling.ToolInfo.nToolIndex, HalfMilling.ToolInfo.dResidualDepth Milling.ToolInfo.nToolIndex, Milling.ToolInfo.dResidualDepth = HalfMilling.ToolInfo.nToolIndex, HalfMilling.ToolInfo.dResidualDepth
end end
+1 -1
View File
@@ -109,7 +109,7 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
for i = 1, #Proc.FeatureInfo.AdditionalGeometries do for i = 1, #Proc.FeatureInfo.AdditionalGeometries do
local AuxId = Proc.id + Proc.FeatureInfo.AdditionalGeometries[i] local AuxId = Proc.id + Proc.FeatureInfo.AdditionalGeometries[i]
Strategy.AuxiliaryData.Clones[i+1] = {} Strategy.AuxiliaryData.Clones[i+1] = {}
Strategy.AuxiliaryData.Clones[i+1].Geometry = EgtSetMachiningGeometry( {{ AuxId, -1}}) Strategy.AuxiliaryData.Clones[i+1].Geometry = {{ AuxId, -1}}
end end
bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining, Strategy.AuxiliaryData) bAreAllMachiningsAdded = MachiningLib.AddMachinings( Proc, Strategy.Machining, Strategy.AuxiliaryData)
+5 -3
View File
@@ -41,6 +41,11 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- si setta che è taglio di coda -- si setta che è taglio di coda
Strategy.bIsTailCut = true 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 -- separazione solo se esiste grezzo successivo con pezzi o scaricabile
Strategy.bSplit = not( Part.bIsLastPart) or Part.dRestLength >= BeamData.dMinRaw 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 -- se devo applicare le lavorazioni
if bAddMachining then if bAddMachining then
-- si forza il nome della feature
EgtSetName( Proc.id, 'EndCut')
-- inserimento smussi su spigoli del taglio -- inserimento smussi su spigoli del taglio
if Strategy.Parameters.bMakeChamfer then if Strategy.Parameters.bMakeChamfer then
MakeChamfer() MakeChamfer()
+2 -2
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. STR0005 = 1, 2 o 3 facce. Lama con taglio singolo o cubetti. Se richiesto o necessario codolo.
STR0006 = Tenone. Lama + fresa STR0006 = Tenone. Lama + fresa
STR0007 = Mortasa a coda di rondine e mortasa frontale a coda di rondine STR0007 = Mortasa a coda di rondine e mortasa frontale a coda di rondine
STR0008 = Svuotatura tasca STR0008 = Svuotatura mortasa (raggiata)
STR0009 = !!DEPRECATA!! Sostituita da STR0015. RIUTILIZZABILE! STR0009 = ScarfJoint
STR0010 = Fresatura perpendicolare (tipo cut, longcut) STR0010 = Fresatura perpendicolare (tipo cut, longcut)
STR0011 = Foratura STR0011 = Foratura
STR0012 = RidgeLap STR0012 = RidgeLap
+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
+240 -124
View File
@@ -14,45 +14,63 @@ local MachiningLib = require( 'MachiningLib')
local BeamLib = require('BeamLib') local BeamLib = require('BeamLib')
-- strategie di base -- strategie di base
local FaceByBlade = require('FACEBYBLADE') local FaceByBlade = require('FACEBYBLADE')
local FaceByMill = require('FACEBYMILL') local FaceByMill = require( 'FACEBYMILL')
local AntiSplintOnFace = require( 'ANTISPLINTONFACE')
-- tabelle per definizione modulo -- tabelle per definizione modulo
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
local function CompareEdges( EdgeA, EdgeB) local function CompareEdgesLongestTop( EdgeA, EdgeB)
-- prima i lati orientati lungo X -- si preferiscono i lati più lunghi
if abs( EdgeA.vtN:getX()) < abs( EdgeB.vtN:getX()) - 10 * GEO.EPS_SMALL then if EdgeA.dLength > EdgeB.dLength + 10 * GEO.EPS_SMALL then
return true 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 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 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 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 return false
-- se stessa lunghezza si preferiscono i lati più in basso -- se stessa Z si preferiscono i lati verso il fronte della trave
-- TODO qui dipenderà dalla lama scelta
else 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 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 return false
-- se stessa Z si preferiscono i lati verso il fronte della trave
else else
if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then return false
return true
elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then
return false
else
return false
end
end end
end end
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) local function SortMachiningsBySegment( MachiningA, MachiningB)
if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then if MachiningA.nFeatureSegment > MachiningB.nFeatureSegment then
return false return false
@@ -118,6 +136,76 @@ local function GetStrategyCompletionPercentage( Machinings)
end 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) function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
-- TODO verificare funzionamento con lama da sotto -- TODO verificare funzionamento con lama da sotto
-- TODO scelta utensile è corretto lasciarla a FaceByBlade? -- TODO scelta utensile è corretto lasciarla a FaceByBlade?
@@ -126,12 +214,11 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
local Result = {} local Result = {}
local Machinings = {} local Machinings = {}
local CalculatedMachinings = {} local CalculatedMachinings = {}
local Cutting1 = {}
local Cutting2 = {}
-- controlli preventivi -- controlli preventivi
if Proc.nFct > 3 then if Proc.nFct > 3 and ( not Proc.Topology.sFamily == 'DoubleBevel') then
error( 'BladeKeepWaste : max 3 faces supported') Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : max 3 faces supported')
return Machinings, Result
elseif Proc.nFct == 2 then elseif Proc.nFct == 2 then
-- per angolo tra le facce >= 90deg (feature convessa) non applicabile -- 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 if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
@@ -160,12 +247,7 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
end end
local nToolIndex = OptionalParameters.nToolIndex local nToolIndex = OptionalParameters.nToolIndex
local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000 local dExtendAfterTail = OptionalParameters.dExtendAfterTail or 10000
local bFinishWithMill local bFinishWithMill = ( OptionalParameters.bFinishWithMill ~= false)
if OptionalParameters.bFinishWithMill == nil then
bFinishWithMill = true
else
bFinishWithMill = OptionalParameters.bFinishWithMill
end
local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1 local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1
local dStripWidth = OptionalParameters.dStripWidth or 5 local dStripWidth = OptionalParameters.dStripWidth or 5
local bForced = OptionalParameters.bForced or false local bForced = OptionalParameters.bForced or false
@@ -173,28 +255,26 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
-- volume della feature -- volume della feature
local dFeatureVolume = Proc.dVolume local dFeatureVolume = Proc.dVolume
-- si trovano le facce da lavorare -- si trovano le facce da lavorare (solo 4 lati esatti)
local BottomFace = {} local BottomFace1
local LongFaces = {} local BottomFace2
if Proc.nFct == 1 then if Proc.nFct == 1 then
BottomFace = Proc.Faces[1] BottomFace1 = Proc.Faces[1]
else else
if not Proc.MainFaces then if not Proc.MainFaces then
Proc.MainFaces = FaceData.GetMainFaces( Proc, Part) Proc.MainFaces = FaceData.GetMainFaces( Proc, Part)
end end
BottomFace = Proc.MainFaces.BottomFaces[1] BottomFace1 = Proc.MainFaces.BottomFaces[1]
LongFaces = Proc.MainFaces.LongFaces BottomFace2 = Proc.MainFaces.BottomFaces[2]
end end
if #BottomFace1.Edges ~= 4 then
Result = FeatureLib.GetStrategyResultNotApplicable()
-- si trova il lato della faccia di fondo da lavorare return Machinings, Result
local BottomEdgeToMachine = {} end
local BottomEdgesSorted = {} local bConvexAngle
for i = 1, #BottomFace.Edges do if BottomFace2 then
table.insert( BottomEdgesSorted, BottomFace.Edges[i]) bConvexAngle = ( Proc.AdjacencyMatrix[BottomFace1.id + 1][BottomFace2.id + 1]) > 0
end end
table.sort( BottomEdgesSorted, CompareEdges)
BottomEdgeToMachine = BottomEdgesSorted[1]
-- eventuali punti di spezzatura -- eventuali punti di spezzatura
local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part) local FeatureSplittingPoints = FeatureLib.GetFeatureSplittingPoints( Proc, Part)
@@ -203,92 +283,126 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
bIsSplitFeature = true bIsSplitFeature = true
end end
-- calcolo lavorazioni -- calcolo lavorazioni faccia principale
-- taglio eventuali facce di chiusura o seconda faccia -- ricerca lato da lavorare
for i = 1, #LongFaces do local BottomEdgeToMachine1 = GetLongEdgeToMachine( BottomFace1, { bTop = true})
local Cutting = {} if not BottomEdgeToMachine1 then
local OptionalParametersFaceByBlade = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex} Result = FeatureLib.GetStrategyResultNotApplicable()
Cutting = FaceByBlade.Make( Proc, Part, LongFaces[i], LongFaces[i].MainEdges.BottomEdge, OptionalParametersFaceByBlade) return Machinings, Result
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)
end end
Cutting1.nInternalSortingPriority = 3 -- calcolo lavorazione
Cutting1.dResultWeight = 0.3 local Parameters1 = {
bIsSplitFeature = bIsSplitFeature,
-- secondo lato dExtendAfterTail = dExtendAfterTail,
local OptionalParametersFaceByBlade2 = BeamLib.TableCopyDeep( OptionalParametersFaceByBlade1) nToolIndex = nToolIndex,
OptionalParametersFaceByBlade2.OppositeToolDirectionMode = 'Enabled' dStripWidth = dStripWidth,
if BottomEdgeToMachine.bIsOpen then OtherBottomFace = BottomFace2
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, BottomEdgeToMachine, OptionalParametersFaceByBlade2) }
local Cuttings1 = MakeBottomFace( Proc, Part, BottomFace1, BottomEdgeToMachine1, Parameters1)
-- aggiunta lavorazioni alla lista principale
for i = 1, #Cuttings1 do
table.insert( CalculatedMachinings, Cuttings1[i])
end end
Cutting2.nInternalSortingPriority = 3
Cutting2.dResultWeight = 0.3
-- se uno dei due lati non è riuscito, si estende il più possibile il lato rimasto -- calcolo lavorazioni faccia secondaria, solo se lato convesso; se concavo, sarà lavorato come antisplint
if not Cutting1.bIsApplicable and Cutting2.bIsApplicable then local Cuttings2
local BottomEdgeToMachine2
-- se si lavora il lato in comune con la LongFace significa che la LongFace non é di chiusura ma un'altra faccia vera e propria if BottomFace2 then
-- ci si deve quindi fermare piú indietro if bConvexAngle then
for i = 1, #LongFaces do -- ricerca lato da lavorare
if BottomEdgeToMachine.idAdjacentFace == LongFaces[i].id then BottomEdgeToMachine2 = GetLongEdgeToMachine( BottomFace2, { bTop = true})
dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth if BottomEdgeToMachine2 then
break -- 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
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 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 if bFinishWithMill then
for i = 1, #LongFaces do
if BottomEdgeToMachine.idAdjacentFace ~= LongFaces[i].id then if Cuttings1 then
local dDepthToMachineMill = BottomFace.MainEdges.LongEdges[i].dElevation - dMillingOffsetFromSide -- si recuperano i lati chiusi non lavorati
local dToolMarkLength = max( Cutting1.dToolMarkLength or 0, Cutting2.dToolMarkLength or 0) local EdgesClosedNotMachined = {}
local OptionalParametersFaceByMill = { bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, for i = 1, #BottomFace1.Edges do
dRadialStepSpan = dToolMarkLength, dDepthToMachine = dDepthToMachineMill if not( ( BottomFace1.Edges[i].id == BottomEdgeToMachine1.id) or BottomFace1.Edges[i].bIsOpen) then
} table.insert( EdgesClosedNotMachined, BottomFace1.Edges[i])
local Milling = FaceByMill.Make( Proc, Part, BottomFace, BottomFace.MainEdges.LongEdges[i], OptionalParametersFaceByMill) end
Milling.nInternalSortingPriority = 2 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 Milling.dResultWeight = 0.05
table.insert( CalculatedMachinings, Milling) table.insert( CalculatedMachinings, Milling)
end end
@@ -317,7 +431,9 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
table.sort( Machinings, SortMachiningsBySegment) table.sort( Machinings, SortMachiningsBySegment)
-- calcolo risultati -- 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.dQuality = FeatureLib.GetStrategyQuality( Machinings)
Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings) Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings)
Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6) Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)
+36 -15
View File
@@ -795,19 +795,23 @@ local function CalculateDiceMachinings( vCuts, Parameters)
local bReduceBladePath = Parameters.bReduceBladePath local bReduceBladePath = Parameters.bReduceBladePath
local sRestLengthSideForPreSimulation = Parameters.sRestLengthSideForPreSimulation local sRestLengthSideForPreSimulation = Parameters.sRestLengthSideForPreSimulation
local bCannotSplitRestLength = Parameters.bCannotSplitRestLength local bCannotSplitRestLength = Parameters.bCannotSplitRestLength
local bReduceDiceDepth = Parameters.bReduceDiceDepth
-- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria -- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria
local bAreOrthogonalCutsInverted = false local bAreOrthogonalCutsInverted = false
for i = 1, #vCuts do for i = 1, #vCuts do
for j = 1, #vCuts[i] do for j = 1, #vCuts[i] do
SetDiceFaceInfo( Proc, vCuts[i][j]) SetDiceFaceInfo( Proc, vCuts[i][j])
if ( i % 2) == 1 then -- TODO vedere se questa parte serve ancora; in teoria no perchè il taglio è girato automaticamente nella FaceByBlade
local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT) -- if ( i % 2) == 1 then
if MachiningLib.IsFaceZOutOfRange( vtO, Tool) then -- local vtO = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
EgtInvertSurf( vCuts[i][j]) -- if MachiningLib.IsFaceZOutOfRange( vtO, Tool) then
bAreOrthogonalCutsInverted = true -- EgtInvertSurf( vCuts[i][j])
end -- local vtCurrentFaceNormal = EgtSurfTmFacetNormVersor( vCuts[i][j], 0, GDB_ID.ROOT)
end -- EgtMove( vCuts[i][j], -vtCurrentFaceNormal * Tool.dThickness, GDB_RT.GLOB)
-- bAreOrthogonalCutsInverted = true
-- end
-- end
end end
end end
-- calcolo lavorazioni -- calcolo lavorazioni
@@ -881,8 +885,13 @@ local function CalculateDiceMachinings( vCuts, Parameters)
-- caso standard (tagli perpendicolari o paralleli non accorpabili) -- caso standard (tagli perpendicolari o paralleli non accorpabili)
if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then if ( not bCanMergeParallelCuts) or ( not bIsDicingOk) then
for j = 1, #vCuts[i] do for j = 1, #vCuts[i] do
-- in generale sta sollevato di pochissimo -- se abilitato, la lama sta sollevata per non rovinare le facce
local dExtraCut = -0.1 local dExtraCut
if bReduceDiceDepth == false then
dExtraCut = 0
else
dExtraCut = -0.1
end
-- se tagli paralleli -- se tagli paralleli
if ( i % 2) == 0 then if ( i % 2) == 0 then
-- se non ci sono tagli ortogonali devo affondare -- se non ci sono tagli ortogonali devo affondare
@@ -911,7 +920,8 @@ local function CalculateDiceMachinings( vCuts, Parameters)
dExtendAfterTail = dExtendAfterTail, dExtendAfterTail = dExtendAfterTail,
bIsDicing = true, bIsDicing = true,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = ( i % 2) > 0 -- se taglio perpendicolare non si deve mai considerare il materiale precedente
} }
Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade) Cutting = FaceByBlade.Make( ProcTrimesh, Part, FaceToMachine, EdgeToMachine, OptionalParametersFaceByBlade)
Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0) Cutting.ptCenter = Point3d( ProcTrimesh.Faces[1].ptCenter:getX(), 0, 0)
@@ -961,6 +971,9 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
end end
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 -- scelta lama da sopra o da sotto
local sChosenBladeType = '' local sChosenBladeType = ''
if not nToolIndex then if not nToolIndex then
@@ -1005,7 +1018,8 @@ local function CutWithDicing( Proc, Part, OptionalParameters)
dExtendAfterTail = dExtendAfterTail, dExtendAfterTail = dExtendAfterTail,
bReduceBladePath = bReduceBladePath, bReduceBladePath = bReduceBladePath,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, 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) bIsDicingOk, Machinings, bMoveAfterSplit = CalculateDiceMachinings( vCuts, Parameters)
@@ -1215,14 +1229,21 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
else else
-- per ogni faccia si calcola la lavorazione -- per ogni faccia si calcola la lavorazione
for i = 1, #Proc.Faces do 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 local nCommonEdgeIndex
for j = 1, #Proc.Faces[i].Edges do for j = 1, #Proc.Faces[i].Edges do
if Proc.Faces[i].Edges[j].idAdjacentFace > -1 then if Proc.Faces[i].Edges[j].idAdjacentFace > -1 then
nCommonEdgeIndex = j nCommonEdgeIndex = j
end end
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 -- scelta lama
local nToolIndex = OptionalParameters.nToolIndex local nToolIndex = OptionalParameters.nToolIndex
@@ -1230,11 +1251,11 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
local OptionalParametersGetSingleCutStrategy = { local OptionalParametersGetSingleCutStrategy = {
bReduceBladePath = false, bReduceBladePath = false,
nFaceToMachineIndex = i, nFaceToMachineIndex = i,
EdgeToMachineList = { Top = EdgeToMachine, Bottom = EdgeToMachine}, EdgeToMachineList = EdgeToMachineList,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength bCannotSplitRestLength = bCannotSplitRestLength
} }
nToolIndex = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy) nToolIndex, EdgeToMachine = GetSingleCutStrategy( Proc, Part, OptionalParametersGetSingleCutStrategy)
end end
-- se lama non trovata si provano i cubetti -- se lama non trovata si provano i cubetti
+27 -12
View File
@@ -72,6 +72,12 @@ local function GetLeadInOut( Machining, EdgeToMachine, bIsSplitFeature)
LeadOut.dTotalLength = sqrt( LeadOut.dPerpDistance ^ 2 + LeadOut.dTangentDistance ^ 2) LeadOut.dTotalLength = sqrt( LeadOut.dPerpDistance ^ 2 + LeadOut.dTangentDistance ^ 2)
end 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 -- se lavorazione con OppositeToolDirection o ridotta l'attacco va corretto
if not AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then if not AreSameVectorApprox( Machining.vtToolDirection, EdgeToMachine.vtN) then
LeadIn.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset LeadIn.dPerpDistance = BeamData.CUT_SIC - Machining.dRadialOffset
@@ -205,6 +211,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
local bIsDicing = OptionalParameters.bIsDicing or false local bIsDicing = OptionalParameters.bIsDicing or false
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail' local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
local bDisableRealElevationCheck = OptionalParameters.bDisableRealElevationCheck or false
-- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato -- lunghezze, direzioni e punti caratteristici della lavorazione e del lato lavorato
Cutting.dEdgeLength = EdgeToMachine.dLength Cutting.dEdgeLength = EdgeToMachine.dLength
@@ -225,10 +232,14 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Tool = TOOLS[Cutting.nToolIndex], Tool = TOOLS[Cutting.nToolIndex],
dDepthToMachine = dDepthToMachine dDepthToMachine = dDepthToMachine
} }
if OppositeToolDirectionMode == 'Enabled' then
BladeEngagementParameters.Edge = EdgeToMachineOpposite
end
local BladeEngagementOptionalParameters = { local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing, bIsDicing = bIsDicing,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
} }
local Engagement local Engagement
TIMER:startElapsed( 'GetBladeEngagement') TIMER:startElapsed( 'GetBladeEngagement')
@@ -252,6 +263,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
ToolSearchParameters.Part = Part ToolSearchParameters.Part = Part
ToolSearchParameters.sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation ToolSearchParameters.sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation
ToolSearchParameters.bCannotSplitRestLength = bCannotSplitRestLength ToolSearchParameters.bCannotSplitRestLength = bCannotSplitRestLength
ToolSearchParameters.bDisableRealElevationCheck = bDisableRealElevationCheck
local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters) local ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
Cutting.nToolIndex = ToolInfo.nToolIndex Cutting.nToolIndex = ToolInfo.nToolIndex
@@ -285,16 +297,18 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
return Cutting, EdgeToMachine.dElevation return Cutting, EdgeToMachine.dElevation
end 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 -- 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 not ( EdgeToMachine.bIsStartOpen or EdgeToMachine.bIsEndOpen) then
if TOOLS[Cutting.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then -- if TOOLS[Cutting.nToolIndex].dDiameter > EdgeToMachine.dLength + 10 * GEO.EPS_SMALL then
Cutting.sMessage = 'Pocket too narrow for blade diameter' -- Cutting.sMessage = 'Pocket too narrow for blade diameter'
Cutting.bIsApplicable = false -- Cutting.bIsApplicable = false
EgtOutLog( Cutting.sMessage) -- EgtOutLog( Cutting.sMessage)
return Cutting, EdgeToMachine.dElevation -- return Cutting, EdgeToMachine.dElevation
end -- end
end -- end
-- parametri della lavorazione -- parametri della lavorazione
@@ -320,7 +334,6 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.bInvert = not Cutting.bInvert Cutting.bInvert = not Cutting.bInvert
end 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 -- se dicing, lato di lavoro e inversione per avere taglio sempre verso l'alto
if bIsDicing if bIsDicing
and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL) and ( Cutting.bInvert and Cutting.vtEdgeDirection:getZ() > 100 * GEO.EPS_SMALL)
@@ -348,7 +361,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
local BladeEngagementOptionalParameters = { local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing, bIsDicing = bIsDicing,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
} }
TIMER:startElapsed( 'GetBladeEngagement') TIMER:startElapsed( 'GetBladeEngagement')
local bIsApplicableOpposite, EngagementOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters) local bIsApplicableOpposite, EngagementOpposite = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters)
@@ -465,7 +479,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
local BladeEngagementOptionalParameters = { local BladeEngagementOptionalParameters = {
bIsDicing = bIsDicing, bIsDicing = bIsDicing,
sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation, sRestLengthSideForPreSimulation = sRestLengthSideForPreSimulation,
bCannotSplitRestLength = bCannotSplitRestLength bCannotSplitRestLength = bCannotSplitRestLength,
bDisableRealElevationCheck = bDisableRealElevationCheck
} }
TIMER:startElapsed( 'GetBladeEngagement') TIMER:startElapsed( 'GetBladeEngagement')
local bIsApplicable, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters ) local bIsApplicable, CurrentEngagement = MachiningLib.GetBladeEngagement( BladeEngagementParameters, BladeEngagementOptionalParameters )
+25 -1
View File
@@ -6,6 +6,7 @@
local BeamLib = require( 'BeamLib') local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamDataNew') local BeamData = require( 'BeamDataNew')
local MachiningLib = require( 'MachiningLib') local MachiningLib = require( 'MachiningLib')
local PreSimulationLib = require( 'PreSimulationLib')
-- Tabella per definizione modulo -- Tabella per definizione modulo
local FACEBYCHAINSAW = {} local FACEBYCHAINSAW = {}
@@ -42,6 +43,10 @@ local function CalculateLeadInOut( Machining, EdgeToMachine, sSideToMachine, dLe
LeadOut.dEndAddLength = BeamData.CUT_EXTRA LeadOut.dEndAddLength = BeamData.CUT_EXTRA
end end
-- punti dell'attacco
LeadIn.ptPoint = EdgeToMachine.ptStart - EdgeToMachine.vtEdge * LeadIn.dStartAddLength + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine)
LeadOut.ptPoint = EdgeToMachine.ptEnd + EdgeToMachine.vtEdge * LeadOut.dEndAddLength + EdgeToMachine.vtN * ( EdgeToMachine.dElevation - Machining.dDepthToMachine)
return LeadIn, LeadOut return LeadIn, LeadOut
end end
@@ -196,9 +201,28 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
elseif EdgeToMachine.vtN:getZ() < 10 * GEO.EPS_SMALL then elseif EdgeToMachine.vtN:getZ() < 10 * GEO.EPS_SMALL then
Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN) Mortising.sBlockedAxis = BeamLib.GetBlockedAxis( Mortising.nToolIndex, 'parallel', Part.b3Raw, FaceToMachine.vtN)
Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtN, 2) Mortising.sSuggestedAngles = BeamLib.GetChainSawInitAngs( FaceToMachine.vtN, EdgeToMachine.vtN, 2)
-- TODO al momento si contempla solo sega a catena con asse bloccato
else
Mortising.bIsApplicable = false
return Mortising
end end
-- approccio e retrazione -- approccio e retrazione
Mortising.LeadIn, Mortising.LeadOut = CalculateLeadInOut( Mortising, EdgeToMachine, sSideToMachine, dLengthToMachine) 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)
if bOutOfStroke then
Mortising.sMessage = 'Out of stroke'
Mortising.bIsApplicable = false
return Mortising
end
-- eventuale step verticale -- eventuale step verticale
Mortising.CloneStepsLongitudinal = {} Mortising.CloneStepsLongitudinal = {}
if not dLongitudinalStepSpan then if not dLongitudinalStepSpan then
@@ -211,7 +235,7 @@ function FACEBYCHAINSAW.Make( Proc, Part, FaceToMachine, EdgeToMachine, Optional
Mortising.CloneStepsLongitudinal.dStep = dPocketHeight Mortising.CloneStepsLongitudinal.dStep = dPocketHeight
end end
-- lunghezza lavorata -- 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 -- TODO fare funzione EstimatePathLength o simile
Mortising.dLengthToMachine = Mortising.dEdgeLength + Mortising.LeadIn.dStartAddLength + Mortising.LeadOut.dEndAddLength Mortising.dLengthToMachine = Mortising.dEdgeLength + Mortising.LeadIn.dStartAddLength + Mortising.LeadOut.dEndAddLength
Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtN:getY()) Mortising.dLengthOnX = abs( dLengthToMachine * EdgeToMachine.vtN:getY())