Compare commits

...

72 Commits

Author SHA1 Message Date
andrea.villa adf08876a9 DA CONTROLLARE!!!! Piccole modifiche per far funzionare nesting inclinato 2026-05-29 07:48:14 +02:00
luca.mazzoleni 476f214b99 Merge remote-tracking branch 'origin/develop' into ObliqueNesting 2026-05-21 18:53:12 +02:00
luca.mazzoleni eacabb5af7 - in BeamExec.ProcessBeams correzioni. Sembra funzionare correttamente in tutti i casi 2026-05-21 18:53:02 +02:00
luca.mazzoleni 5c7751aebd - in BeamLib aggiunta GetNewMachGroupName per avere il prossimo numero MachGroup intero libero
- in NestProcess i nomi MachGroup sono sempre interi; si mantiene sempre un BEAM_SAFETY_BUFFER nel riempimento delle barre
- in BeamExec.GetCombinationListFromMatrix corretti indici taglio di testa e coda
2026-05-21 15:02:23 +02:00
luca.mazzoleni 6649842c70 - in NestProcess modifiche per nestare pezzi senza alternative 2026-05-21 10:49:28 +02:00
luca.mazzoleni 27475763a2 - in BeamExec correzioni per il caso di taglio standard che diventa taglio di testa
- in MachiningLib.FindBlade e relativi non si testa più la normale della faccia in caso di informazioni lato mancanti (portava erroneamente a non trovare la lama nei casi solo downUp)
2026-05-21 09:29:55 +02:00
luca.mazzoleni 3fcca044ed - in BeamExec si ritornano stati per l'interfaccia anche per tagli che sono diventati Headcut e TailCut 2026-05-20 16:14:54 +02:00
luca.mazzoleni 630d28bf5b - in BeamExec se un taglio è diventato Headcut o Tailcut viene comunque considerato nel punteggio delle combinazioni 2026-05-20 16:00:15 +02:00
luca.mazzoleni 5e5f3d08c4 - in BeamExec se non è stato trovato nessun taglio di testa o di coda si usa quello settato in precedenza 2026-05-20 14:42:59 +02:00
luca.mazzoleni a773e0156a - in BeamLib.AddPhaseWithRawParts e correlati correzioni in caso di scarico ultimo grezzo 2026-05-19 17:03:21 +02:00
luca.mazzoleni 72e3b7dc8f - in BeamLib.AddPhaseWithRawParts correzioni 2026-05-19 15:53:53 +02:00
luca.mazzoleni 10592ac612 - in BeamLib.AddPhaseWithRawParts correzioni, ma ancora non funziona correttamente 2026-05-19 14:29:16 +02:00
andrea.villa a5d606b225 Prima versione gestione utensile flottante. Per ora solo su marcature.
Gestione da migliorare.
2026-05-19 13:05:15 +02:00
luca.mazzoleni 3ba456f72f - in BeamLib e correlate modificata AddPhaseWithRawParts per funzionare con overlap dei pezzi per nesting obliquo 2026-05-19 12:47:21 +02:00
luca.mazzoleni 608f8da033 - in NestProcess si fanno correttamente inversioni e rotazioni 2026-05-19 09:50:58 +02:00
luca.mazzoleni 08397ae102 - in NestProcess aggiunte eventuali rotazioni/inversioni duplo nella barra 2026-05-18 18:28:57 +02:00
luca.mazzoleni b7dbc7422c - in BeamExec.ProcessAlternatives si passa all'interfaccia da scrivere anche la posizione iniziale del pezzo 2026-05-18 17:26:05 +02:00
luca.mazzoleni 974d1abb41 - in NestProcess correzione bug 2026-05-18 16:40:58 +02:00
andrea.villa c4697fbd6f In STR0014:
- se utensile PEN, si riduce il percorso per evitare di attaccare fuori dal grezzo
- gestione parametro SCC bloccato letto dalla macchina
2026-05-18 16:38:02 +02:00
luca.mazzoleni b79617fbe4 - in NestProcess primo abbozzo della creazione MachGroup 2026-05-18 15:53:18 +02:00
luca.mazzoleni e5f1abc47d - in NestProcess aggiunto lo spostamento delle travi verso la testa della trave (vedere se poi integrare in creazione MachGroup) 2026-05-18 14:45:57 +02:00
luca.mazzoleni 965c6e8f9e - in NestProcess aggiunta MIN_FILLER_LIMITin CONFIG per pulizia codice 2026-05-18 12:40:06 +02:00
luca.mazzoleni d59039eae0 - in NestProcess correzioni in PrintDiagnosticReport 2026-05-18 12:28:36 +02:00
luca.mazzoleni a404bf2f9e - in NestProcess si provano barre nuove solo se non si trovano soluzioni con quelle già attive 2026-05-18 12:03:46 +02:00
luca.mazzoleni 1cde1c94d9 - in NestProcess aggiunta PrintDiagnosticReport per stimare la bontà del nesting; in CalculateMove modificato calcolo efficienza nel caso di barra nuova; correzioni minori 2026-05-18 11:32:15 +02:00
luca.mazzoleni a66054a6c8 - in NestProcess correzioni e modifiche per migliorare l'efficienza. Sembra funzionare, da verificare bontà nesting. Manca creazione MachGroup veri e propri 2026-05-18 10:16:20 +02:00
luca.mazzoleni b77e79d0d0 - in NestProcess loop completo, alcune migliorie possibili per prestazioni; manca la parte che effettivamente crea i MachGroup 2026-05-15 18:33:15 +02:00
luca.mazzoleni cad57b2fd5 - in NestProcess piccole correzioni 2026-05-15 10:37:58 +02:00
luca.mazzoleni 5e503762e5 - in NestProcess agiunto sorting della JobPool 2026-05-15 10:26:30 +02:00
luca.mazzoleni f27000b7bc - in NestProcess.PartTemplates:AddPart si salvano i MaxHeadRecess testa e coda; creata funzione FindBestPartForBeam, da completare 2026-05-15 10:10:25 +02:00
luca.mazzoleni f90dd95880 - in NestProcess creato il loop di base dello script. Mancano funzioni accessorie 2026-05-14 16:44:12 +02:00
luca.mazzoleni 0497877abb - in NestProcess ora si compilano correttamente le tabelle di grezzi e pezzi da nestare, in preparazione al neting 2026-05-14 15:39:29 +02:00
luca.mazzoleni b8299df247 - in BeamExec.ProcessAlternatives si passano correttamente le info a interfaccia da scrivere sul pezzo
- in BeamLib aggiunta funzione ConvertBitIndexToRotationIndex per convertire da BitIndex a RotationIndex
2026-05-13 18:42:01 +02:00
luca.mazzoleni 4a99f2bdf6 - in BeamExec.GetProcessings per HeadcutInfo e TailcutInfo si usano gli indici di rotazione canonici (1,2,3,4 per std e 5,6,7,8 per invertiti) 2026-05-13 16:28:04 +02:00
luca.mazzoleni 1e86180723 - in BeamExec si scrivono HeadcutInfo e TailcutInfo nel PARTS che serviranno per nesting; da completare output alternative 2026-05-13 16:00:20 +02:00
luca.mazzoleni f6d6043c0e - piccole modifiche per test nesting 2026-05-13 12:40:45 +02:00
luca.mazzoleni b048e2ebe2 - in BeamLib.GetSortedVertices piccola correzione 2026-05-13 11:58:28 +02:00
luca.mazzoleni fc47bca0f1 - in NestProcess prime modifiche per nesting obliquo (da completare)
- in BeamExec test BEAM.INFONGEPART per scrittura note pezzo in nge tramite Aedifica
- in BeamLib aggiunta funzione RotateTableFromIndex per reindicizzare una tabella passata
2026-05-13 11:47:25 +02:00
luca.mazzoleni 0274096f57 - in BeamExec.GetFeatureInfoAndDependency si salvano le info necessarie per nesting (offset X dei vertici dei tagli rispetto al box, normali delle facce) 2026-05-12 11:59:26 +02:00
luca.mazzoleni 983609397e - in BeamLib funzione GetSurfTmSortedVertices diventa GetSortedVertices e si passa la Proc direttamente
- in BeamLib aggiunta funzione GetAdjacentIndices per la ricerca degli indici precedente e successivo con circular indexing
2026-05-12 10:45:26 +02:00
luca.mazzoleni 05a8d23f6a - in BeamExec.GetFeatureInfoAndDependency si calcolano i punti ai vertici dei tagli di testa e coda
- in BeamLib aggiunta funzione GetSurfTmSortedVertices per restituire i punti ai vertici già ordinati; da correggere perchè i vertici non arrivano ordinati dalla funzione EgtSurfTmGetAllVertInFacet
2026-05-12 09:06:43 +02:00
luca.mazzoleni 40580cdc69 - NestProcess attuale rinominata Old per test nesting obliqui, con NestProcess ripulita 2026-05-11 12:42:34 +02:00
luca.mazzoleni f6b2477f2b - in BeamExec.GetFeatureInfoAndDependency correzione 2026-05-08 12:29:46 +02:00
luca.mazzoleni 69db74e30e - in BeamExec.ProcessBeams modifiche per accettare grezzi compenetranti
- in BeamExec.GetFeatureInfoAndDependency si scelgono taglio di testa e coda anche obliqui, quelli più verso il centro della trave. Gli altri tagli si disattivano
- da completare
2026-05-08 12:00:58 +02:00
luca.mazzoleni f58004dfeb - in PreSimulationLIb correzioni importanti in test collisione 2026-05-08 11:54:16 +02:00
luca.mazzoleni 7c485360de Merge branch 'ScarfJoint' into develop 2026-04-27 18:18:19 +02:00
luca.mazzoleni 967117cc23 - in FeatureLib, per ScarfJoint e ScarfSimple, si scrivono sempre AdjacencyMatrix e Faces
- in STR0009 aggiunto antischeggia di lama e, nel caso sia disattivato, lavorazione con lama dell'eventuale faccia inclinata
2026-04-27 18:18:07 +02:00
andrea.villa 64b2e86a2d Abbozzata gestione (non funzionante) passaggio supplementare in caso di angolo > 90° che necessita di passata extra 2026-04-24 16:47:40 +02:00
andrea.villa 89b342a564 Prima versione Scarf Joint. Manca:
- lavorazioni di antischeggia con fresa e lama
 - Il primo taglio de ve essere calcolato con 2 facce se il piano di taglio attraversa faccia 1
 - gestione caso con facce 4 e 5 mancanti
2026-04-24 14:45:31 +02:00
andrea.villa 117e475de5 STR0009 riutilizzata per ScarfJoint. Primo commit, da sviluppare completamente. 2026-04-24 08:52:56 +02:00
andrea.villa a7b817b211 STR0014 corretta lavorazione cloni 2026-04-24 08:41:25 +02:00
andrea.villa d8c6a8ad55 In STR0008 si aggiunge svuotatura con paraemtri di default 2026-04-23 10:35:03 +02:00
andrea.villa 9026acd9ca In STR0007 la faccia di taglio deve essere messa sul gruppo aggiuntivo. Prima era su quello temporaneo che però viene poi cancellato 2026-04-21 10:03:05 +02:00
andrea.villa 204346326f In STR0003 controllo delle MainFaces spostato a prima del controllo topologia 2026-04-21 08:13:41 +02:00
luca.mazzoleni 5d6e4c397d - in MachiningLib.FindMill si evita di lavorare troppo sotto con la fresa, a meno che sia in testa o coda; temporaneo in attesa di test collisione anche per fresa e attacco corretto dal lato 2026-04-20 18:09:22 +02:00
luca.mazzoleni 64bde8924d - in STR0002 si evita di lavorare la faccia tunnel se troppo piccola 2026-04-20 16:27:59 +02:00
luca.mazzoleni cb6115d23f - in STR0010 (fresatura) migliorata qualità se no lati chiusi 2026-04-20 15:25:19 +02:00
luca.mazzoleni 771c1367b1 - in PreSimulationLib, se taglio perpendicolare a cubetti, non si verifica l'elevazione reale del taglio 2026-04-20 10:47:41 +02:00
luca.mazzoleni 6092063daa - in BLADETOWASTE piccola correzione 2026-04-20 09:21:52 +02:00
luca.mazzoleni 44650c303c Merge branch 'test' into develop 2026-04-17 18:31:27 +02:00
luca.mazzoleni 69fa0d741d - piccole correzioni ai cubetti nel caso di due facce molto aperte 2026-04-17 18:31:22 +02:00
luca.mazzoleni 8e55ddda1f - in PreSimulationLib aggiunto check collisione anche per punti di attacco perpendicolare 2026-04-17 17:25:06 +02:00
andrea.villa 7a8fb04ebe In STR0013 (foro con fresa) si controlla che abbia trovato fresa prima di verificare se foro completo. Se non trovava fresa andava in crash 2026-04-17 12:36:26 +02:00
luca.mazzoleni 77c27d911c Merge branch 'PreSimulationV2' into develop 2026-04-16 17:02:43 +02:00
luca.mazzoleni 3a29f273c9 - in PreSimulationLib alcune correzioni 2026-04-16 17:02:39 +02:00
luca.mazzoleni bab5b07bd1 Merge remote-tracking branch 'origin/develop' into PreSimulationV2 2026-04-15 17:45:20 +02:00
luca.mazzoleni 683ae78c65 - in PreSimulationLib si usano le funzioni MachineCalc per la precollisione 2026-04-15 17:45:15 +02:00
andrea.villa 06d9529b7b Per ruotare il pezzo non lo si toglie più dalla barra, ma lo si gira in "Draw" 2026-04-14 09:05:46 +02:00
andrea.villa 922a7ac846 Correzioni varie in strategie per gestire casi strani dove non vengono calcolate le MainFaces 2026-04-14 07:57:59 +02:00
andrea.villa a21a3979f1 Merge branch 'develop' of https://gitlab.steamware.net/egalware-cadcam/lua/databeamnew into develop 2026-04-13 13:02:10 +02:00
andrea.villa fcbed252e1 Merge branch 'PreRotationInterface' into develop 2026-04-13 13:02:06 +02:00
luca.mazzoleni 28026358b9 - aggiunto GetBeamData per lettura parametri macchina da interfaccia 2026-04-10 11:19:27 +02:00
24 changed files with 2175 additions and 991 deletions
+3 -1
View File
@@ -390,7 +390,8 @@ if bToProcess then
end end
end end
-- Assegno lunghezza della barra -- Assegno lunghezza della barra
dBarLen = PARTS[1].b3PartOriginal:getDimX() + 10 -- TODO nella ProcessBeams andava in errore con 10mm!!! CONTROLLARE
dBarLen = PARTS[1].b3PartOriginal:getDimX() + 20
if dBarLen < 2200 then if dBarLen < 2200 then
dBarLen = dBarLen + 1800 dBarLen = dBarLen + 1800
end end
@@ -492,6 +493,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
+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')
+407 -224
View File
@@ -153,6 +153,11 @@ function BeamExec.GetToolsFromDB()
Tool.nDouble = EgtGetValInNotes( Tool.sUserNotes, 'DOUBLE', 'd') Tool.nDouble = EgtGetValInNotes( Tool.sUserNotes, 'DOUBLE', 'd')
Tool.bIsProfiledTool = not EgtTdbIsCurrToolStandardDraw() Tool.bIsProfiledTool = not EgtTdbIsCurrToolStandardDraw()
-- TODO per capire se ToolHolder è flottante bisogna leggere nota TYPE='Float' su ToolHolder. Serve funzione
-- info per utensile su ToolHolder flottante
Tool.dOverHang = EgtGetValInNotes( Tool.sUserNotes, 'TOOL_OVERHANG', 'd') or 0
Tool.bToolOnFloatingTH = Tool.dOverHang > 0
-- lettura parametri non comuni ( famiglia DRILLBIT non ha parametri specifici) -- lettura parametri non comuni ( famiglia DRILLBIT non ha parametri specifici)
if sToolFamily ~= 'DRILLBIT' then if sToolFamily ~= 'DRILLBIT' then
Tool.dThickness = EgtTdbGetCurrToolParam( MCH_TP.THICK) Tool.dThickness = EgtTdbGetCurrToolParam( MCH_TP.THICK)
@@ -251,6 +256,27 @@ function BeamExec.GetStrategiesFromJSONinBD( sAISetupConfigName)
end end
end end
-------------------------------------------------------------------------------------------------------------
local function GetRotationName( nRotIndex, nInvertIndex)
local sRotation = ''
if nRotIndex == 1 then
sRotation = '0'
elseif nRotIndex == 2 then
sRotation = '90'
elseif nRotIndex == 3 then
sRotation = '180'
elseif nRotIndex == 4 then
sRotation = '270'
end
if nInvertIndex > 1 then
sRotation = sRotation .. 'INV'
end
return sRotation
end
-- TODO prevedere parametri per preferire carico del pezzo verticale oppure orizzontale? -- 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
@@ -356,188 +382,179 @@ function BeamExec.GetAvailableCombinations( PartInfo, bIsFlipRot)
end 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, bIsFlipRot) function BeamExec.ProcessBeams( dRawW, dRawH, dRawL, dOvmHead, dOvmMid, PARTS, bCreateMachGroup, bIsFlipRot )
-- gruppo per geometrie temporanee -- 1. Inizializzazione e Default
local idTempGroup = BeamLib.GetTempGroup() local idTempGroup = BeamLib.GetTempGroup( )
-- default per nuove costanti qualora non definite BeamData.OVM_BLADE_HBEAM = ( BeamData.OVM_BLADE_HBEAM or 11 )
BeamData.OVM_BLADE_HBEAM = ( BeamData.OVM_BLADE_HBEAM or 11) BeamData.OVM_CHAIN_HBEAM = ( BeamData.OVM_CHAIN_HBEAM or 8 )
BeamData.OVM_CHAIN_HBEAM = ( BeamData.OVM_CHAIN_HBEAM or 8)
-- sovramateriale intermedio nullo se non definito dOvmMid = ( dOvmMid or 5.4 )
dOvmMid = ( dOvmMid or 0) dOvmHead = ( dOvmHead or 0 )
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH )
-- Determinazione minimo grezzo scaricabile -- 2. Gestione Gruppo di Lavoro
BeamExec.CalcMinUnloadableRaw( dRawW, dRawH) if ( bCreateMachGroup == nil ) then bCreateMachGroup = true end
if ( bCreateMachGroup ) then
-- Creazione nuovo gruppo di lavoro (di default va creato) local sMgName = EgtGetMachGroupNewName( 'Mach_1' )
if bCreateMachGroup == nil then local idNewMg = EgtAddMachGroup( sMgName )
bCreateMachGroup = true if ( not idNewMg ) then
end return false, 'Errore creazione gruppo di lavoro'
if bCreateMachGroup then
local sMgName = EgtGetMachGroupNewName( 'Mach_1')
local idNewMg = EgtAddMachGroup( sMgName)
if not idNewMg then
local sOut = 'Errore nella creazione del gruppo di lavoro ' .. sMgName
return false, sOut
end end
end end
-- Impostazione della tavola -- 3. Configurazione Tavola Macchina
EgtSetTable( 'Tab') EgtSetTable( 'Tab' )
local nMGrpId = EgtGetCurrMachGroup( )
-- salvo nota con lunghezza grezzo if ( not EgtGetInfo( nMGrpId, 'BARLEN', 'd' ) ) then
-- Recupero l'identificativo del gruppo di lavoro corrente EgtSetInfo( nMGrpId, 'BARLEN', dRawL )
local nMGrpId = EgtGetCurrMachGroup()
-- Lunghezza della barra
local dBarLen = EgtGetInfo( nMGrpId, 'BARLEN', 'd')
if not dBarLen then
EgtSetInfo( nMGrpId, 'BARLEN', dRawL)
end end
-- Area tavola local b3Tab = EgtGetTableArea( )
local b3Tab = EgtGetTableArea() local dPosY = EgtIf( BeamData.CENTER_BEAM, ( b3Tab:getDimY( ) + dRawW * EgtIf( BeamData.RIGHT_LOAD, -1, 1 ) ) / 2, EgtIf( BeamData.RIGHT_LOAD, 0, b3Tab:getDimY( ) ) )
-- Calcolo posizione estremo TR/BR della tavola rispetto a sua origine in BL
local dPosY = EgtIf( BeamData.CENTER_BEAM, ( b3Tab:getDimY() + dRawW * EgtIf( BeamData.RIGHT_LOAD, -1, 1)) / 2, EgtIf( BeamData.RIGHT_LOAD, 0, b3Tab:getDimY()))
BeamData.ptOriXR = Point3d( b3Tab:getDimX(), dPosY, 0)
BeamData.dPosXR = EgtIf( BeamData.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR)
-- Impostazione dell'attrezzaggio di default BeamData.ptOriXR = Point3d( b3Tab:getDimX( ), dPosY, 0 )
EgtImportSetup() BeamData.dPosXR = EgtIf( BeamData.RIGHT_LOAD, MCH_CR.BR, MCH_CR.TR )
-- Inserimento dei pezzi con il loro grezzo EgtImportSetup( )
-- 4. Ciclo di Inserimento Pezzi
local nCnt = 0 local nCnt = 0
local dLen = dRawL local dMaxX = 0
local idPrevRaw, dPrevDelta local idPrevRaw = nil
local dDeltaS = dOvmHead local dNextStartOffset = dOvmHead -- Il primo pezzo applica il sormonto iniziale a destra (testa)
local dDeltaSMin = 0
local dDeltaE = BeamData.OVM_MID
for i = 1, #PARTS do for i = 1, #PARTS do
-- dati del pezzo local CurrentPart = PARTS[i]
local b3BoxExact = EgtGetBBoxGlob( PARTS[i].id or GDB_ID.NULL, GDB_BB.EXACT) local b3BoxExact = EgtGetBBoxGlob( CurrentPart.id or GDB_ID.NULL, GDB_BB.EXACT )
if b3BoxExact:isEmpty() or PARTS[i].b3PartOriginal:isEmpty() then break end
EgtOutLog( 'PartSez=' .. EgtNumToString( b3BoxExact:getDimY(), 1) .. 'x' .. EgtNumToString( b3BoxExact:getDimZ(), 1), 3)
-- se sezione compatibile e lunghezza disponibile sufficiente
local dPartLen = PARTS[i].b3PartOriginal:getDimX()
local dPartWidth = PARTS[i].b3PartOriginal:getDimY()
local dPartHeight = PARTS[i].b3PartOriginal:getDimZ()
local dNextLen = dLen - EgtIf( i == 1, dDeltaS, 0) - dPartLen - dDeltaE
if (( abs( dPartWidth - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH) < 100 * GEO.EPS_SMALL) or
( abs( dPartHeight - dRawW) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH) < 100 * GEO.EPS_SMALL)) and
dNextLen + dDeltaE >= 0 then
-- eventuale sovramateriale di testa
if i > 1 then
if PARTS[i].dPosX then
dDeltaS = max( PARTS[i].dPosX - ( dRawL - dLen), dDeltaSMin)
else
dDeltaS = max( dOvmMid - dDeltaE, 0)
end
end
-- dimensioni del grezzo
local dCrawLen = min( dPartLen + dDeltaS + dDeltaE, dLen)
local dDelta = dCrawLen - dPartLen - dDeltaS
-- creo e posiziono il grezzo
PARTS[i].idRaw = EgtAddRawPart( Point3d(0,0,0), dCrawLen, dRawW, dRawH, BeamData.RAWCOL)
EgtMoveToCornerRawPart( PARTS[i].idRaw, BeamData.ptOriXR, BeamData.dPosXR) if ( b3BoxExact:isEmpty( ) or CurrentPart.b3PartOriginal:isEmpty( ) ) then break end
EgtMoveRawPart( PARTS[i].idRaw, Vector3d( dLen - dRawL, 0, 0))
-- assegno ordine in lavorazione local dPartLen = CurrentPart.b3PartOriginal:getDimX( )
local dPartWidth = CurrentPart.b3PartOriginal:getDimY( )
local dPartHeight = CurrentPart.b3PartOriginal:getDimZ( )
local dStartOffset = dNextStartOffset
local dEndOffset = dOvmMid
-- LOGICA LOOK-AHEAD: Analisi del gap reale per la ripartizione specchiata
if ( i < #PARTS ) then
local dTotalGap = PARTS[i + 1].dPosX - CurrentPart.dPosX - dPartLen
if ( dTotalGap > dOvmMid ) then
dEndOffset = dOvmMid -- Max 5.4mm sulla coda (lato sinistro del grezzo)
dNextStartOffset = dTotalGap - dOvmMid -- Il residuo sulla testa del prossimo (lato destro)
else
-- Gestione automatica sotto-soglia o compenetrazione geometrica (Nesting Obliquo)
dEndOffset = dTotalGap
dNextStartOffset = 0
end
end
-- MATEMATICA CORRETTA PER X CAD INVERTITA:
-- Il grezzo idRaw si estende verso destra. Spostando il pezzo internamente di dEndOffset (dDelta),
-- lasciamo dEndOffset a sinistra (coda) e matematicamente dStartOffset a destra (testa).
local dCrawLen = dPartLen + dStartOffset + dEndOffset
local dDelta = dEndOffset
local dStartPos = (CurrentPart.dPosX or 0) - dStartOffset
local bIsSectionOk = ( ( abs( dPartWidth - dRawW ) < 100 * GEO.EPS_SMALL and abs( dPartHeight - dRawH ) < 100 * GEO.EPS_SMALL ) or
( abs( dPartHeight - dRawW ) < 100 * GEO.EPS_SMALL and abs( dPartWidth - dRawH ) < 100 * GEO.EPS_SMALL ) )
if ( bIsSectionOk and ( dStartPos + dCrawLen <= dRawL + GEO.EPS_SMALL ) ) then
-- 5. Creazione e Posizionamento del Contenitore RawPart
CurrentPart.idRaw = EgtAddRawPart( Point3d( 0, 0, 0 ), dCrawLen, dRawW, dRawH, BeamData.RAWCOL )
EgtMoveToCornerRawPart( CurrentPart.idRaw, BeamData.ptOriXR, BeamData.dPosXR )
EgtMoveRawPart( CurrentPart.idRaw, Vector3d( -dStartPos, 0, 0 ) )
-- 6. Configurazione Geometrie Pezzo
nCnt = nCnt + 1 nCnt = nCnt + 1
EgtSetInfo( PARTS[i].idRaw, 'ORD', nCnt) EgtSetInfo( CurrentPart.idRaw, 'ORD', nCnt )
-- creo o pulisco gruppo geometrie aggiuntive
if not BeamLib.CreateOrEmptyAddGroup( PARTS[i].id) then
local sOut = 'Error creating Additional Group in Part ' .. tostring( PARTS[i].id)
return false, sOut
end
-- aggiungo faccia per taglio iniziale al pezzo
BeamLib.AddPartStartFace( PARTS[i].id, PARTS[i].b3PartOriginal)
-- se sovramateriale di testa, lo notifico
if dDeltaS > 0.09 then
EgtSetInfo( PARTS[i].idRaw, 'HOVM', dDeltaS)
if idPrevRaw then
EgtSetInfo( idPrevRaw, 'BDST', dDeltaS + dPrevDelta)
end
end
if dDeltaE > 0.09 then
EgtSetInfo( PARTS[i].idRaw, 'TOVM', dDeltaE)
end
-- aggiungo faccia per taglio finale al pezzo
BeamLib.AddPartEndFace( PARTS[i].id, PARTS[i].b3PartOriginal)
-- inserisco il pezzo nel grezzo
EgtDeselectPartObjs( PARTS[i].id)
local ptPos = b3BoxExact:getMin() - PARTS[i].b3PartOriginal:getMin() + Vector3d( dDelta, ( dRawW - dPartWidth) / 2, ( dRawH - dPartHeight) / 2)
EgtAddPartToRawPart( PARTS[i].id, ptPos, PARTS[i].idRaw)
if abs( dPartWidth - dRawW) > 100 * GEO.EPS_SMALL then
-- rotazione attorno a centro geometria complessiva del pezzo
EgtRotatePartInRawPart( PARTS[i].id, X_AX(), 90)
-- correggo per eccentricità solido rispetto a geometria complessiva del pezzo
local vtEccOri = PARTS[i].b3PartOriginal:getCenter() - b3BoxExact:getCenter()
local vtEccRot = Vector3d( vtEccOri)
vtEccRot:rotate( X_AX(), 90)
EgtMovePartInRawPart( PARTS[i].id, ( vtEccOri - vtEccRot))
end
-- aggiorno la lunghezza residua della barra
dLen = dLen - dCrawLen
-- aggiorno grezzo precedente
idPrevRaw = PARTS[i].idRaw
dPrevDelta = dDelta
PARTS[i].bIsLastPart = ( i == #PARTS)
PARTS[i].dDistanceToNextPiece = dDelta
PARTS[i].dRestLength = dLen
PARTS[i].b3Raw = EgtGetRawPartBBox( PARTS[i].idRaw)
PARTS[i].dLength = PARTS[i].b3Raw:getDimX()
PARTS[i].dWidth = PARTS[i].b3Raw:getDimY()
PARTS[i].dHeight = PARTS[i].b3Raw:getDimZ()
PARTS[i].bSquareSection = abs( PARTS[i].dWidth - PARTS[i].dHeight) < 100 * GEO.EPS_SMALL
PARTS[i].idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( PARTS[i].id, 'Box') or GDB_ID.NULL)
PARTS[i].b3Part = EgtGetBBoxGlob( PARTS[i].idBoxTm, GDB_BB.STANDARD)
PARTS[i].nIndexInParts = i
PARTS[i].SplittingPoints = BeamLib.GetPartSplittingPoints( PARTS[i])
PARTS[i].NotClampableLength = { STD = { dHead = 0, dTail = 0}, SIDE = { dHead = 0, dTail = 0}, DOWN = { dHead = 0, dTail = 0}}
PARTS[i].dHeadOverMaterial = dDeltaS
PARTS[i].sBTLInfo = EgtGetInfo( PARTS[i].id, 'PROJ', 's') or nil
PARTS[i].sAISetupConfig = EgtGetInfo( PARTS[i].id, 'AISETUP', 's') or if ( not BeamLib.CreateOrEmptyAddGroup( CurrentPart.id ) ) then
( GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo] and GENERAL_PARAMETERS.BTL[PARTS[i].sBTLInfo].sAISetupConfig) or -- i parametri BTL potrebbero non esistere return false, 'Error creating Additional Group in Part ' .. tostring( CurrentPart.id )
GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil end
-- si carica configurazione lavorazioni BeamLib.AddPartStartFace( CurrentPart.id, CurrentPart.b3PartOriginal )
TIMER:startElapsed('Json') BeamLib.AddPartEndFace( CurrentPart.id, CurrentPart.b3PartOriginal )
BeamExec.GetStrategiesFromJSONinBD( PARTS[i].sAISetupConfig)
PARTS[i].GeneralParameters = BeamLib.GetPieceGeneralParameters( PARTS[i], GENERAL_PARAMETERS_JSON)
TIMER:stopElapsed('Json')
PARTS[i].CombinationList = BeamExec.GetAvailableCombinations( PARTS[i], bIsFlipRot)
PARTS[i].idTempGroup = idTempGroup
-- Inserimento con dDelta (lascia lo spazio vuoto a sinistra e spinge il pezzo a destra)
EgtDeselectPartObjs( CurrentPart.id )
local ptPos = b3BoxExact:getMin( ) - CurrentPart.b3PartOriginal:getMin( ) + Vector3d( dDelta, ( dRawW - dPartWidth ) / 2, ( dRawH - dPartHeight ) / 2 )
EgtAddPartToRawPart( CurrentPart.id, ptPos, CurrentPart.idRaw )
-- Rotazione sezione se necessaria
if ( abs( dPartWidth - dRawW ) > 100 * GEO.EPS_SMALL ) then
EgtRotatePartInRawPart( CurrentPart.id, X_AX( ), 90 )
local vtEccOri = CurrentPart.b3PartOriginal:getCenter( ) - b3BoxExact:getCenter( )
local vtEccRot = Vector3d( vtEccOri )
vtEccRot:rotate( X_AX( ), 90 )
EgtMovePartInRawPart( CurrentPart.id, ( vtEccOri - vtEccRot ) )
end
-- 7. Popolamento Metadati della Tabella CurrentPart
CurrentPart.bIsLastPart = ( i == #PARTS )
CurrentPart.dDistanceToNextPiece = dEndOffset
CurrentPart.b3Raw = EgtGetRawPartBBox( CurrentPart.idRaw )
CurrentPart.dLength = CurrentPart.b3Raw:getDimX( )
CurrentPart.dWidth = CurrentPart.b3Raw:getDimY( )
CurrentPart.dHeight = CurrentPart.b3Raw:getDimZ( )
CurrentPart.bSquareSection = abs( CurrentPart.dWidth - CurrentPart.dHeight ) < 100 * GEO.EPS_SMALL
CurrentPart.idBoxTm = EgtGetFirstInGroup( EgtGetFirstNameInGroup( CurrentPart.id, 'Box' ) or GDB_ID.NULL )
CurrentPart.b3Part = EgtGetBBoxGlob( CurrentPart.idBoxTm, GDB_BB.STANDARD )
CurrentPart.nIndexInParts = i
CurrentPart.SplittingPoints = BeamLib.GetPartSplittingPoints( CurrentPart )
CurrentPart.NotClampableLength = { STD = { dHead = 0, dTail = 0 }, SIDE = { dHead = 0, dTail = 0 }, DOWN = { dHead = 0, dTail = 0 } }
CurrentPart.dHeadOverMaterial = dStartOffset
CurrentPart.sBTLInfo = EgtGetInfo( CurrentPart.id, 'PROJ', 's' ) or nil
CurrentPart.idTempGroup = idTempGroup
-- Notifiche al Post-Processor basate sulla nuova scomposizione
if ( dStartOffset > 0.09 ) then EgtSetInfo( CurrentPart.idRaw, 'HOVM', dStartOffset ) end
if ( dEndOffset > 0.09 ) then EgtSetInfo( CurrentPart.idRaw, 'TOVM', dEndOffset ) end
if ( idPrevRaw ) then EgtSetInfo( idPrevRaw, 'BDST', dStartOffset ) end
-- Caricamento Strategie JSON
CurrentPart.sAISetupConfig = EgtGetInfo( CurrentPart.id, 'AISETUP', 's' ) or
( GENERAL_PARAMETERS.BTL[CurrentPart.sBTLInfo] and GENERAL_PARAMETERS.BTL[CurrentPart.sBTLInfo].sAISetupConfig ) or
GENERAL_PARAMETERS.PROJECT.sAISetupConfig or nil
TIMER:startElapsed( 'Json' )
BeamExec.GetStrategiesFromJSONinBD( CurrentPart.sAISetupConfig )
CurrentPart.GeneralParameters = BeamLib.GetPieceGeneralParameters( CurrentPart, GENERAL_PARAMETERS_JSON )
TIMER:stopElapsed( 'Json' )
CurrentPart.CombinationList = BeamExec.GetAvailableCombinations( CurrentPart, bIsFlipRot )
-- Avanzamento calcolato sulla coordinata reale di fine RawPart (estremità sinistra sulla barra)
dMaxX = max( dMaxX, dStartPos + dCrawLen )
CurrentPart.dRestLength = dRawL - dMaxX
idPrevRaw = CurrentPart.idRaw
else else
local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1) .. ') too big for raw part L(' .. EgtNumToString( dLen - 0.1, 1) .. ')' local sOut = 'Error: part L(' .. EgtNumToString( dPartLen, 1 ) .. ') too big for remaining bar space'
return false, sOut return false, sOut
end end
-- se rimasto troppo poco grezzo, esco
--if Len < BeamData.MinRaw then break end
DeltaS = 0
end
if idPrevRaw then
EgtSetInfo( idPrevRaw, 'BDST', 10000)
end end
-- Se rimasto materiale aggiungo grezzo dell'avanzo -- 8. Chiusura Barra e Gestione Avanzo (Rest Material)
-- TODO valutare se ridurre la dLen minima perchè crea discrepanze tra lunghezza inserita e VMill if ( idPrevRaw ) then EgtSetInfo( idPrevRaw, 'BDST', 10000 ) end
if dLen > 10 then
local idRaw = EgtAddRawPart( Point3d(0,0,0), dLen, dRawW, dRawH, BeamData.RAWCOL) local dRemaining = dRawL - dMaxX
EgtMoveToCornerRawPart( idRaw, BeamData.ptOriXR, BeamData.dPosXR) if ( dRemaining > 10 ) then
EgtMoveRawPart( idRaw, Vector3d( dLen - dRawL, 0, 0)) local idRawRest = EgtAddRawPart( Point3d( 0, 0, 0 ), dRemaining, dRawW, dRawH, BeamData.RAWCOL )
-- assegno ordine in lavorazione EgtMoveToCornerRawPart( idRawRest, BeamData.ptOriXR, BeamData.dPosXR )
EgtMoveRawPart( idRawRest, Vector3d( -dMaxX, 0, 0 ) )
nCnt = nCnt + 1 nCnt = nCnt + 1
EgtSetInfo( idRaw, 'ORD', nCnt) EgtSetInfo( idRawRest, 'ORD', nCnt )
-- aggiorno distanza dell'ultimo pezzo dall'eventuale grezzo scaricabile
if EgtGetRawPartBBox( idRaw):getDimX() < BeamData.dMinRaw then if ( EgtGetRawPartBBox( idRawRest ):getDimX( ) < BeamData.dMinRaw ) then
PARTS[#PARTS].dDistanceToNextPiece = 10000 PARTS[#PARTS].dDistanceToNextPiece = 10000
end end
else else
PARTS[#PARTS].dDistanceToNextPiece = 10000 if ( #PARTS > 0 ) then PARTS[#PARTS].dDistanceToNextPiece = 10000 end
end end
return true return true
@@ -781,9 +798,24 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
local function GetFeatureInfoAndDependency( vProcSingleRot, Part) local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
-- gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup()
local HeadProcOriginal
local TailProcOriginal
local HeadProc
local TailProc
-- ciclo tutte le feature -- ciclo tutte le feature
for i = 1, #vProcSingleRot do for i = 1, #vProcSingleRot do
local Proc = vProcSingleRot[i] local Proc = vProcSingleRot[i]
if Proc.Topology.sName == 'HeadCut' then
HeadProcOriginal = Proc
HeadProcOriginal.bIsOriginalHeadcut = true
elseif Proc.Topology.sName == 'TailCut' then
TailProcOriginal = Proc
TailProcOriginal.bIsOriginalTailcut = true
end
-- se feature abilitata alla lavorazione -- se feature abilitata alla lavorazione
if Proc.nFlg ~= 0 then if Proc.nFlg ~= 0 then
-- controllo la feature con tutte le altre per recuperare le dipendenze -- controllo la feature con tutte le altre per recuperare le dipendenze
@@ -791,6 +823,86 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
local ProcB = vProcSingleRot[j] local ProcB = vProcSingleRot[j]
-- non si controlla la feature con se stessa o se feature disabilitata -- non si controlla la feature con se stessa o se feature disabilitata
if i ~= j and ProcB.nFlg ~= 0 then if i ~= j and ProcB.nFlg ~= 0 then
local bAreBothTruncatingCuts =
( ID.IsCut( Proc) or ID.IsHeadCut( Proc) or ID.IsTailCut( Proc)) and ( ID.IsCut( ProcB) or ID.IsHeadCut( ProcB) or ID.IsTailCut( ProcB))
and ( FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part) and FeatureLib.IsFeatureCuttingEntireSection( ProcB.b3Box, Part))
-- si trovano i veri tagli di testa e coda e si disattivano gli altri, se necessario
if bAreBothTruncatingCuts then
-- testa
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL and ProcB.Faces[1].vtN:getX() > GEO.EPS_SMALL then
-- il primo taglio è più verso il centro della trave
if ( Proc.b3Box:getMin():getX() < ProcB.b3Box:getMin():getX() - 10 * GEO.EPS_SMALL) then
HeadProc = Proc
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
EgtMove( idProcCopy, - 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
EgtMove( idProcBCopy, 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
-- se i tagli non si intersecano, quello più esterno è da disattivare
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
if not Proc.SlaveProcIndexes then
Proc.SlaveProcIndexes = {}
end
table.insert( Proc.SlaveProcIndexes, j)
ProcB.nIndexMasterProc = i
ProcB.nFlg = 0
end
-- il secondo taglio è più verso il centro della trave
elseif Proc.b3Box:getMin():getX() >= ProcB.b3Box:getMin():getX() - 10 * GEO.EPS_SMALL then
HeadProc = ProcB
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
EgtMove( idProcBCopy, - 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
EgtMove( idProcCopy, 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
-- se i tagli non si intersecano, quello più esterno è da disattivare
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
if not ProcB.SlaveProcIndexes then
ProcB.SlaveProcIndexes = {}
end
table.insert( ProcB.SlaveProcIndexes, i)
Proc.nIndexMasterProc = j
Proc.nFlg = 0
end
end
-- coda
elseif Proc.Faces[1].vtN:getX() <= GEO.EPS_SMALL and ProcB.Faces[1].vtN:getX() <= GEO.EPS_SMALL then
-- il primo taglio è più verso il centro della trave
if Proc.b3Box:getMax():getX() > ProcB.b3Box:getMax():getX() + 10 * GEO.EPS_SMALL then
TailProc = Proc
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
EgtMove( idProcCopy, - 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
EgtMove( idProcBCopy, 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
-- se i tagli non si intersecano, quello più esterno è da disattivare
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
if not Proc.SlaveProcIndexes then
Proc.SlaveProcIndexes = {}
end
table.insert( Proc.SlaveProcIndexes, j)
ProcB.nIndexMasterProc = i
ProcB.nFlg = 0
end
-- il secondo taglio è più verso il centro della trave
elseif Proc.b3Box:getMax():getX() >= ProcB.b3Box:getMax():getX() - 10 * GEO.EPS_SMALL then
TailProc = ProcB
local idProcCopy = EgtCopyGlob( Proc.id, idTempGroup)
local idProcBCopy = EgtCopyGlob( ProcB.id, idTempGroup)
EgtMove( idProcBCopy, - 500 * GEO.EPS_SMALL * ProcB.Faces[1].vtN, GDB_RT.GLOB)
EgtMove( idProcCopy, 500 * GEO.EPS_SMALL * Proc.Faces[1].vtN, GDB_RT.GLOB)
-- se i tagli non si intersecano, quello più esterno è da disattivare
if not EgtTestSurfaceSurface( idProcCopy, idProcBCopy, GEO.EPS_SMALL) then
if not ProcB.SlaveProcIndexes then
ProcB.SlaveProcIndexes = {}
end
table.insert( ProcB.SlaveProcIndexes, i)
Proc.nIndexMasterProc = j
Proc.nFlg = 0
end
end
end
end
-- se entrambi tagli di testa, si tiene sempre il primo ( ma non quello aggiunto dall'automatismo) -- se entrambi tagli di testa, si tiene sempre il primo ( ma non quello aggiunto dall'automatismo)
if ( ID.IsHeadCut( Proc) and not EgtGetInfo( Proc.id, 'HEAD_ADD_CUT', 'i')) and ID.IsHeadCut( ProcB) then if ( ID.IsHeadCut( Proc) and not EgtGetInfo( Proc.id, 'HEAD_ADD_CUT', 'i')) and ID.IsHeadCut( ProcB) then
if not Proc.SlaveProcIndexes then if not Proc.SlaveProcIndexes then
@@ -828,7 +940,43 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
end end
end end
end end
return vProcSingleRot
if not HeadProc then
HeadProc = HeadProcOriginal
end
if not TailProc then
TailProc = TailProcOriginal
end
HeadProc.Topology = {}
TailProc.Topology = {}
HeadProc.Topology.sFamily = 'HeadCut'
HeadProc.Topology.sName = 'HeadCut'
TailProc.Topology.sFamily = 'TailCut'
TailProc.Topology.sName = 'TailCut'
HeadProc.AvailableStrategies = GetStrategies( HeadProc, Part.sAISetupConfig)
TailProc.AvailableStrategies = GetStrategies( TailProc, Part.sAISetupConfig)
-- per nesting, si settano come info gli offset X degli estremi dei tagli
local HeadcutInfo = {}
local PtSortedHead = BeamLib.GetSortedVertices( HeadProc)
if PtSortedHead then
HeadcutInfo.OffsetX = {}
for i = 1, #PtSortedHead do
table.insert( HeadcutInfo.OffsetX, Part.b3Part:getMax():getX() - PtSortedHead[i]:getX())
end
end
local TailcutInfo = {}
local PtSortedTail = BeamLib.GetSortedVertices( TailProc)
if PtSortedTail then
TailcutInfo.OffsetX = {}
for i = 1, #PtSortedHead do
table.insert( TailcutInfo.OffsetX, Part.b3Part:getMin():getX() - PtSortedTail[i]:getX())
end
end
-- per nesting, si settano come info le normali delle facce di taglio
HeadcutInfo.vtN = HeadProc.Faces[1].vtN
TailcutInfo.vtN = TailProc.Faces[1].vtN
return vProcSingleRot, HeadcutInfo, TailcutInfo
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
@@ -983,6 +1131,9 @@ local function CalculateStrategies( vProcSingleRot, Part)
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99 Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99
end end
if not Proc.AvailableStrategies.dAllStrategiesTotalTime then
Proc.AvailableStrategies.dAllStrategiesTotalTime = 0
end
Proc.AvailableStrategies.dAllStrategiesTotalTime = Proc.AvailableStrategies.dAllStrategiesTotalTime + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine Proc.AvailableStrategies.dAllStrategiesTotalTime = Proc.AvailableStrategies.dAllStrategiesTotalTime + Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine
-- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa -- se scelta strategia in modalità base o standard, esco subito alla prima che trovo completa
if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Complete' then
@@ -1192,7 +1343,11 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
local StrategyScriptName = Proc.ChosenStrategy.sStrategyId .. '\\' .. Proc.ChosenStrategy.sStrategyId local StrategyScriptName = Proc.ChosenStrategy.sStrategyId .. '\\' .. Proc.ChosenStrategy.sStrategyId
local StrategyScript = require( StrategyScriptName) local StrategyScript = require( StrategyScriptName)
-- eseguo la strategia e si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati -- eseguo la strategia e si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
_, _ = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy) local _, Result = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy)
-- per i tagli di testa e coda, che non hanno girato nel CalculateStrategies, si devono settare i risultati
if ID.IsHeadCut( Proc) or ID.IsTailCut( Proc) then
Proc.ChosenStrategy.Result = Result
end
-- 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) local nOffsetIndex = EgtIf( Part.bPartInCombiIsInverted, 4, 0)
@@ -1244,12 +1399,16 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
-- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti -- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
local bCalcInverted = bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion local bCalcInverted = bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion
local nCycles = EgtIf( bCalcInverted, 2, 1) local nCycles = EgtIf( bCalcInverted, 2, 1)
PARTS[nPart].HeadcutInfo = {}
PARTS[nPart].TailcutInfo = {}
-- per ogni inversione -- per ogni inversione
for nInvertIndex = 1, nCycles do for nInvertIndex = 1, nCycles do
-- per ogni rotazione -- per ogni rotazione
for nRotIndex = 1, 4 do for nRotIndex = 1, 4 do
local nOffsetIndex = EgtIf( nInvertIndex == 2, 4, 0) local nOffsetIndex = EgtIf( nInvertIndex == 2, 4, 0)
-- le rotazioni sono 1,2,3,4 (0, 90, 180, 270) e 5,6,7,8 (le stesse invertite)
local nIndex = nRotIndex + nOffsetIndex local nIndex = nRotIndex + nOffsetIndex
local HeadcutInfo, TailcutInfo
-- si calcolano le feature solo se la rotazione può essere presa in considerazione -- si calcolano le feature solo se la rotazione può essere presa in considerazione
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
@@ -1257,11 +1416,23 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
-- 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], HeadcutInfo, TailcutInfo = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart])
else else
-- inserisco una tabella vuota -- inserisco una tabella vuota
table.insert( vProcRot, {}) table.insert( vProcRot, {})
end end
if HeadcutInfo then
PARTS[nPart].HeadcutInfo[nIndex] = {
OffsetX = HeadcutInfo.OffsetX,
vtN = HeadcutInfo.vtN
}
end
if TailcutInfo then
PARTS[nPart].TailcutInfo[nIndex] = {
OffsetX = TailcutInfo.OffsetX,
vtN = TailcutInfo.vtN
}
end
-- rotazione pezzo di 90° per volta -- rotazione pezzo di 90° per volta
BeamLib.RotateRawPart( PARTS[nPart], 1) BeamLib.RotateRawPart( PARTS[nPart], 1)
-- aggiorno info pezzo -- aggiorno info pezzo
@@ -1491,13 +1662,15 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
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 local ProcOnFirstRotation = ProcessingsOnPart.Rotation[1][nProc]
ProcessingsOnPart.Rotation[1][nProc].nIndexRotation = nUnloadPos if ProcOnFirstRotation.nFlg == 0 and ProcOnFirstRotation.nIndexMasterProc then
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[1][nProc]) ProcOnFirstRotation.nIndexRotation = nUnloadPos
table.insert( SingleCombination.Rot0, ProcOnFirstRotation)
SingleCombination.nComplete = SingleCombination.nComplete + 1 SingleCombination.nComplete = SingleCombination.nComplete + 1
else else
local nOffsetIndex = EgtIf( SingleCombination.bPartInCombiIsInverted, 4, 0) local nOffsetIndex = EgtIf( SingleCombination.bPartInCombiIsInverted, 4, 0)
if not ID.IsHeadCut( ProcessingsOnPart.Rotation[1][nProc]) and not ID.IsTailCut( ProcessingsOnPart.Rotation[1][nProc]) then if not ( ( ID.IsHeadCut( ProcOnFirstRotation) and ProcOnFirstRotation.bIsOriginalHeadcut)
or ( ID.IsTailCut( ProcOnFirstRotation) and ProcOnFirstRotation.bIsOriginalTailcut)) then
-- ciclo sulle rotazioni -- ciclo sulle rotazioni
local nNextRot = nUnloadPos local nNextRot = nUnloadPos
local ResultsList = {} local ResultsList = {}
@@ -1523,34 +1696,40 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1) nNextRot = EgtIf( nNextRot + 1 > 4, nNextRot + 1 - 4, nNextRot + 1)
end end
-- se la feature può essere lavorata in almeno una rotazione -- se la feature può essere lavorata in almeno una rotazione e non è un taglio di testa o coda
if #ResultsList > 0 then if ID.IsHeadCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo) SingleCombination.nIndexHeadCutInVProc = nProc
Proc.nIndexRotation = Data.nIndexRotation elseif ID.IsTailCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
-- inserisco la Proc nell'apposita lista SingleCombination.nIndexTailCutInVProc = nProc
if Data.nIndexRotation == nUnloadPos then
table.insert( SingleCombination.Rot0, Proc)
elseif Data.nIndexRotation == nUnloadPos + 1 then
table.insert( SingleCombination.Rot90, Proc)
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
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nIndexRotation = nUnloadPos if #ResultsList > 0 then
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nFlg = 0 local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo)
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc]) Proc.nIndexRotation = Data.nIndexRotation
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1 -- inserisco la Proc nell'apposita lista
if Data.nIndexRotation == nUnloadPos then
table.insert( SingleCombination.Rot0, Proc)
elseif Data.nIndexRotation == nUnloadPos + 1 then
table.insert( SingleCombination.Rot90, Proc)
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
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nIndexRotation = nUnloadPos
ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc].nFlg = 0
table.insert( SingleCombination.Rot0, ProcessingsOnPart.Rotation[nUnloadPos+nOffsetIndex][nProc])
SingleCombination.nNotExecute = SingleCombination.nNotExecute + 1
end
end end
else else
if ID.IsHeadCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then if ID.IsHeadCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) then
@@ -1665,7 +1844,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
nPhase = nPhase} nPhase = nPhase}
table.insert( DB_MACH_APPLIED, MachExtraInfo) table.insert( DB_MACH_APPLIED, MachExtraInfo)
else else
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, 0) BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, 0)
end end
-- si sposta il pezzo nella posizione originale, di quando è stata fatta la collect. In questo modo tutti i dati calcolati nella collect restano validi. -- 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. -- Altrimenti bisognava ricalcolare tutto, aumentando tempo di calcolo.
@@ -1772,8 +1951,9 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
local nInitialPosition = MatrixResult.nInitialPosition local nInitialPosition = MatrixResult.nInitialPosition
-- PREROTAZIONE PEZZO -- PREROTAZIONE PEZZO
if MatrixResult.nInitialPosition ~= 1 or PARTS[nPart].bPartInCombiIsInverted then if MatrixResult.nInitialPosition ~= 1 or PARTS[nPart].bPartInCombiIsInverted then
-- si toglie il pezzo dal grezzo per poter fare operazioni -- si esce dalle lavorazioni e si torna in disegna
EgtRemovePartFromRawPart( PARTS[nPart].id) local nCurrMachGroup = EgtGetCurrMachGroup()
EgtResetCurrMachGroup()
-- salvo situazione precedente su lista BEAM ( scrittura variabili globali per interfaccia) -- salvo situazione precedente su lista BEAM ( scrittura variabili globali per interfaccia)
if bIsFlipRot then if bIsFlipRot then
@@ -1795,11 +1975,8 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
EgtRotate( PARTS[nPart].id, ptRot, X_AX(), nRotationDeg, GDB_RT.GLOB) EgtRotate( PARTS[nPart].id, ptRot, X_AX(), nRotationDeg, GDB_RT.GLOB)
end end
-- si rimette il pezzo nel grezzo -- si riattiva il MachGroup, i pezzi son rimasti dove erano
EgtAddPartToRawPart( PARTS[nPart].id, {0,0,0}, PARTS[nPart].idRaw) EgtSetCurrMachGroup( nCurrMachGroup)
-- dico che il pezzo originale è nella posizione iniziale come arriva da BTL ( è stato appena ruotato qui sopra)
nInitialPosition = 1
end end
-- salvo sul PART la posizione di partenza che è stata scelta -- salvo sul PART la posizione di partenza che è stata scelta
@@ -1825,7 +2002,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition) BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -2) EgtSetInfo( idDisp, 'ROT', -2)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN') bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'DOWN')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess bProcess = bProcess or bTryToReProcess
end end
@@ -1834,7 +2011,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
if MatrixResult.bSomeFeatureSide then if MatrixResult.bSomeFeatureSide then
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima -- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown then if MatrixResult.bSomeFeatureDown then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0)) BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase() nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase) idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd) EgtSetInfo( idDisp, 'ORD', nOrd)
@@ -1853,14 +2030,14 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition) BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -1) EgtSetInfo( idDisp, 'ROT', -1)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE') bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'SIDE')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess bProcess = bProcess or bTryToReProcess
end end
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima -- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0)) BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase() nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase) idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd) EgtSetInfo( idDisp, 'ORD', nOrd)
@@ -1879,7 +2056,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1) BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
-- aggiunta lavorazioni in ultima fase -- aggiunta lavorazioni in ultima fase
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD') _, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'STD')
bProcess = bProcess or bTryToReProcess bProcess = bProcess or bTryToReProcess
-- se bisogna riprocessare, si annulla tutto -- se bisogna riprocessare, si annulla tutto
@@ -1895,8 +2072,6 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
if PARTS[nPart].bPartInCombiIsInverted then if PARTS[nPart].bPartInCombiIsInverted then
BeamLib.InvertRawPart( PARTS[nPart], -2) BeamLib.InvertRawPart( PARTS[nPart], -2)
end end
-- ripristino anche eventuali pre-rotazioni
nInitialPosition = nInitialPosition + ( BEAM.PREROTATE90 or 0)
-- si ribalta il pezzo in posizione iniziale -- si ribalta il pezzo in posizione iniziale
BeamLib.RotateRawPart( PARTS[nPart], 1 - nInitialPosition) BeamLib.RotateRawPart( PARTS[nPart], 1 - nInitialPosition)
else else
@@ -1921,7 +2096,7 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
-- ===== finiti i pezzi, si scarica il restante ===== -- ===== finiti i pezzi, si scarica il restante =====
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw) local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0) BeamLib.AddPhaseWithRawParts( PARTS, #PARTS + 1, BeamData.ptOriXR, BeamData.dPosXR, 0)
local nPhase = EgtGetCurrPhase() local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase) local idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'TYPE', 'REST') EgtSetInfo( idDisp, 'TYPE', 'REST')
@@ -1966,8 +2141,8 @@ end
function BeamExec.ProcessAlternatives( PARTS) function BeamExec.ProcessAlternatives( PARTS)
-- inizializzazione variabili globali per interfaccia -- inizializzazione variabili globali per interfaccia
BEAM.ALTERNATIVESNEST2D = '' local Alternatives = {}
BEAM.ALTERNATIVES = '' local AlternativesNest2D = {}
-- ciclo sui pezzi -- ciclo sui pezzi
local BestCombination = {} local BestCombination = {}
@@ -2197,7 +2372,7 @@ function BeamExec.ProcessAlternatives( PARTS)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition) BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -2) EgtSetInfo( idDisp, 'ROT', -2)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'DOWN') bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'DOWN')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess bProcess = bProcess or bTryToReProcess
end end
@@ -2206,7 +2381,7 @@ function BeamExec.ProcessAlternatives( PARTS)
if MatrixResult.bSomeFeatureSide then if MatrixResult.bSomeFeatureSide then
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima -- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown then if MatrixResult.bSomeFeatureDown then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0)) BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase() nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase) idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd) EgtSetInfo( idDisp, 'ORD', nOrd)
@@ -2225,14 +2400,14 @@ function BeamExec.ProcessAlternatives( PARTS)
BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition) BeamLib.RotateRawPart( PARTS[nPart], nRotation - nCurrPosition)
nCurrPosition = nRotation nCurrPosition = nRotation
EgtSetInfo( idDisp, 'ROT', -1) EgtSetInfo( idDisp, 'ROT', -1)
bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'SIDE') bAreAllMachiningApplyOk, sErr, bSplitExecutedOnRot, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'SIDE')
bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot bSplitAlreadyExecuted = bSplitAlreadyExecuted or bSplitExecutedOnRot
bProcess = bProcess or bTryToReProcess bProcess = bProcess or bTryToReProcess
end end
-- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima -- se ci sono state lavorazioni in rotazione precedente devo creare altra fase. Altrimenti già creata da prima
if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then if MatrixResult.bSomeFeatureDown or MatrixResult.bSomeFeatureSide then
BeamLib.AddPhaseWithRawParts( PARTS[nPart].idRaw, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0)) BeamLib.AddPhaseWithRawParts( PARTS, nPart, BeamData.ptOriXR, BeamData.dPosXR, EgtIf( bSplitAlreadyExecuted, BeamData.RAW_OFFSET, 0))
nPhase = EgtGetCurrPhase() nPhase = EgtGetCurrPhase()
idDisp = EgtGetPhaseDisposition( nPhase) idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'ORD', nOrd) EgtSetInfo( idDisp, 'ORD', nOrd)
@@ -2251,7 +2426,7 @@ function BeamExec.ProcessAlternatives( PARTS)
BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1) BeamLib.RotateRawPart( PARTS[nPart], nInitialPosition - 1)
-- aggiunta lavorazioni in ultima fase -- aggiunta lavorazioni in ultima fase
_, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS[nPart], 'STD') _, _, _, bTryToReProcess = MachiningLib.AddOperations( MACHININGS, PARTS, PARTS[nPart], 'STD')
bProcess = bProcess or bTryToReProcess bProcess = bProcess or bTryToReProcess
-- se bisogna riprocessare, si annulla tutto -- se bisogna riprocessare, si annulla tutto
@@ -2285,7 +2460,7 @@ function BeamExec.ProcessAlternatives( PARTS)
-- ===== finiti i pezzi, si scarica il restante ===== -- ===== finiti i pezzi, si scarica il restante =====
local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw) local idRestPart = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then if idRestPart and EgtGetRawPartBBox( idRestPart):getDimX() >= BeamData.dMinRaw then
BeamLib.AddPhaseWithRawParts( idRestPart, BeamData.ptOriXR, BeamData.dPosXR, 0) BeamLib.AddPhaseWithRawParts( PARTS, #PARTS + 1, BeamData.ptOriXR, BeamData.dPosXR, 0)
local nPhase = EgtGetCurrPhase() local nPhase = EgtGetCurrPhase()
local idDisp = EgtGetPhaseDisposition( nPhase) local idDisp = EgtGetPhaseDisposition( nPhase)
EgtSetInfo( idDisp, 'TYPE', 'REST') EgtSetInfo( idDisp, 'TYPE', 'REST')
@@ -2296,23 +2471,14 @@ function BeamExec.ProcessAlternatives( PARTS)
local bApplOk, _, _ = EgtApplyAllMachinings() local bApplOk, _, _ = EgtApplyAllMachinings()
-- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia -- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia
if bApplOk then if bApplOk then
local Alternatives = {}
local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '') local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '')
if TotalCombiToTest[z].bIsNesting2D then if TotalCombiToTest[z].bIsNesting2D then
if BEAM.ALTERNATIVESNEST2D and BEAM.ALTERNATIVESNEST2D ~= "" then table.insert( AlternativesNest2D, sBitIndexCombinationWithInvert)
table.insert( Alternatives, BEAM.ALTERNATIVESNEST2D)
end
table.insert( Alternatives, sBitIndexCombinationWithInvert)
BEAM.ALTERNATIVESNEST2D = table.concat( Alternatives, ', ')
else else
if BEAM.ALTERNATIVES and BEAM.ALTERNATIVES ~= "" then
table.insert( Alternatives, BEAM.ALTERNATIVES)
end
table.insert( Alternatives, sBitIndexCombinationWithInvert) table.insert( Alternatives, sBitIndexCombinationWithInvert)
BEAM.ALTERNATIVES = table.concat( Alternatives, ', ')
end end
end end
-- se ultima combinazione, si esce e non si riporta in posizione inizale. Verrà infatti cancellata -- se ultima combinazione, si esce e non si riporta in posizione iniziale. Verrà infatti cancellata
if z == #TotalCombiToTest then break end if z == #TotalCombiToTest then break end
-- si riporta pezzo in posizione iniziale -- si riporta pezzo in posizione iniziale
@@ -2326,6 +2492,23 @@ function BeamExec.ProcessAlternatives( PARTS)
end end
-- passaggio info a interfaccia da scrivere sul pezzo
BEAM.INFONGEPART = {}
table.insert( BEAM.INFONGEPART, 'INITIALPOSITION=' .. PARTS[nPart].nInitialPosition)
for i = 1, #AlternativesNest2D do
local sRotation = BeamLib.ConvertBitIndexToRotationIndex( AlternativesNest2D[i])
if PARTS[nPart].HeadcutInfo then
local sOffsetX = table.concat( PARTS[nPart].HeadcutInfo[sRotation].OffsetX, ',')
local sVtN = ( tostring( PARTS[nPart].HeadcutInfo[sRotation].vtN)):gsub("^%(", ""):gsub("%)$", "")
table.insert( BEAM.INFONGEPART, 'ALT' .. AlternativesNest2D[i].. '_H' .. '=' .. sOffsetX .. ';' .. sVtN )
end
if PARTS[nPart].TailcutInfo then
local sOffsetX = table.concat( PARTS[nPart].TailcutInfo[sRotation].OffsetX, ',')
local sVtN = ( tostring( PARTS[nPart].TailcutInfo[sRotation].vtN)):gsub("^%(", ""):gsub("%)$", "")
table.insert( BEAM.INFONGEPART, 'ALT' .. AlternativesNest2D[i] .. '_T' .. '=' .. sOffsetX .. ';' .. sVtN)
end
end
-- si cancella eventuale mach group creato per le alternative -- si cancella eventuale mach group creato per le alternative
EgtRemoveMachGroup( nTempMachGroupName) EgtRemoveMachGroup( nTempMachGroupName)
+153 -10
View File
@@ -161,17 +161,45 @@ function BeamLib.GetPartSplittingPoints( Part)
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
function BeamLib.AddPhaseWithRawParts( idRaw, OriXR, PosXR, dDeltaSucc) function BeamLib.AddPhaseWithRawParts( PARTS, nPartIndex, OriXR, PosXR, dDeltaSucc)
local nPhase = EgtAddPhase() local nPhase = EgtAddPhase()
local Part
local idRaw
-- se l'indice è oltre significa che è l'ultimo grezzo senza pezzi
if nPartIndex > #PARTS then
idRaw = EgtGetNextRawPart( PARTS[#PARTS].idRaw)
else
Part = PARTS[nPartIndex]
idRaw = Part.idRaw
end
-- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola -- si aprono i limiti tavola per permettere rotazioni di pezzi più larghi della tavola
EgtSetTableAreaOffset( 2000, 2000, 2000, 2000) EgtSetTableAreaOffset( 2000, 2000, 2000, 2000)
local dRawMove = 0 local dRawMove = 0
local bIsFirstRaw = true
local dPosXFirst = 0
while idRaw do while idRaw do
local dPosX
for i = 1, #PARTS do
local CurrentPart = PARTS[i]
if CurrentPart.idRaw == idRaw then
dPosX = CurrentPart.dPosX
if bIsFirstRaw then
dPosXFirst = dPosX
end
break
end
if i == #PARTS then
dPosX = PARTS[i].dPosX + PARTS[i].b3Raw:getDimX()
end
end
if bIsFirstRaw then
bIsFirstRaw = false
else
dRawMove = dDeltaSucc + dPosX - dPosXFirst
end
EgtKeepRawPart( idRaw) EgtKeepRawPart( idRaw)
EgtMoveToCornerRawPart( idRaw, OriXR, PosXR) EgtMoveToCornerRawPart( idRaw, OriXR, PosXR)
EgtMoveRawPart( idRaw, Vector3d( - dRawMove, 0, 0)) EgtMoveRawPart( idRaw, Vector3d( - dRawMove, 0, 0))
if dRawMove == 0 then dRawMove = dRawMove + dDeltaSucc end
dRawMove = dRawMove + EgtGetRawPartBBox( idRaw):getDimX()
idRaw = EgtGetNextRawPart( idRaw) idRaw = EgtGetNextRawPart( idRaw)
end end
-- salvo info nuova fase aggiunta -- salvo info nuova fase aggiunta
@@ -395,6 +423,24 @@ function BeamLib.GetAddGroup( PartId)
return AddGrpId, sMchGrp return AddGrpId, sMchGrp
end end
-------------------------------------------------------------------------------------------------------------
-- Funzione prossimo nome MachGroup libero (numero intero)
function BeamLib.GetNewMachGroupName()
local idMachGroup = EgtGetFirstMachGroup()
if not idMachGroup then return 1 end
local nMaxMachGroup = 0
while idMachGroup do
local sMachGroupName = EgtGetMachGroupName( idMachGroup)
local nMachGroupName = tonumber( sMachGroupName)
if nMachGroupName > nMaxMachGroup then
nMaxMachGroup = nMachGroupName
end
idMachGroup = EgtGetNextMachGroup( idMachGroup)
end
return nMaxMachGroup + 1
end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- restituisce le facce della parte interessate dalla feature Proc -- restituisce le facce della parte interessate dalla feature Proc
-- TODO da spostare in FeatureLib??? -- TODO da spostare in FeatureLib???
@@ -516,6 +562,65 @@ function BeamLib.GetDirectionFromSCC( nSCC)
return vtSCC return vtSCC
end end
-------------------------------------------------------------------------------------------------------------
-- Restituisce una tabella con i punti ai vertici della faccia, in globale
-- ordinati partendo da quello ai valori minimi degli assi e i successivi secondo rotazione destrorsa X+;
-- solo per Proc a 1 faccia
function BeamLib.GetSortedVertices( Proc)
local PtVerticesSorted = {}
-- se più di una faccia si esce subito
if Proc.nFct > 1 then
return
end
local PtVertices = {}
local nFirstIndex
local dMinYZ = GEO.INFINITO
for i = 1, #Proc.Faces[1].Edges do
local Edge = Proc.Faces[1].Edges[i]
table.insert( PtVertices, Edge.ptStart)
if ( Edge.ptStart:getY() + Edge.ptStart:getZ() < dMinYZ) then
nFirstIndex = i
dMinYZ = Edge.ptStart:getY() + Edge.ptStart:getZ()
end
end
table.insert( PtVerticesSorted, PtVertices[nFirstIndex])
local nCurrentIndex = nFirstIndex
-- faccia che guarda verso X+, ordine ok
if Proc.Faces[1].vtN:getX() > GEO.EPS_SMALL then
for _ = 1, #PtVertices - 1 do
_, nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
end
-- faccia che guarda verso X-, ordine da invertire
else
for _ = 1, #PtVertices - 1 do
nCurrentIndex = BeamLib.GetAdjacentIndices( nCurrentIndex, #PtVertices)
table.insert( PtVerticesSorted, PtVertices[nCurrentIndex])
end
end
return PtVerticesSorted
end
-------------------------------------------------------------------------------------------------------------
-- restituisce il precedente e prossimo indice 1-based, tenendo conto del massimo indice
function BeamLib.GetAdjacentIndices( nCurrentIndex, nMaxIndex)
local nPreviousIndex, nNextIndex
if ( nCurrentIndex < 1) or ( nCurrentIndex > nMaxIndex) then
return
end
-- circular indexing 1-based
nPreviousIndex = ((nCurrentIndex - 2 + nMaxIndex) % nMaxIndex) + 1
nNextIndex = (nCurrentIndex % nMaxIndex) + 1
return nPreviousIndex, nNextIndex
end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce -- Funzione per determinare se la faccia ha lati molto corti (trascurabili) ed è quindi approssimabile ad una 3 facce
function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId) function BeamLib.Is3EdgesApprox( Proc, idFace, nAddGrpId)
@@ -788,14 +893,15 @@ function BeamLib.BinaryToDecimal( dNumber)
for i = #sNumberToConvert, 1, -1 do for i = #sNumberToConvert, 1, -1 do
k = k + 1 k = k + 1
local n = string.sub(sNumberToConvert, k, k) local n = string.sub( sNumberToConvert, k, k)
dResult = dResult + n*(2^(i-1)) dResult = dResult + n * ( 2^( i-1))
end end
return dResult return dResult
end end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- TODO si può sostituire con funzione EgtNumToBitString
function BeamLib.DecimalToBinary( dNumber) function BeamLib.DecimalToBinary( dNumber)
local sNumberToConvert = tostring( dNumber) local sNumberToConvert = tostring( dNumber)
local n = sNumberToConvert local n = sNumberToConvert
@@ -803,12 +909,12 @@ function BeamLib.DecimalToBinary( dNumber)
local sResult = "" local sResult = ""
for i = sNumberToConvert, 0, -1 do for i = sNumberToConvert, 0, -1 do
local q = math.modf(n) local q = math.modf( n)
n = n/2 n = n / 2
local b = q%2 local b = q % 2
table.insert(tmp, b) table.insert( tmp, b)
if (q == 1) then if ( q == 1) then
break break
end end
end end
@@ -830,6 +936,43 @@ function BeamLib.CalculateStringBinaryFormat( dNumber, CharNumber)
return NumberString return NumberString
end end
-------------------------------------------------------------------------------------------------------------
function BeamLib.ConvertBitIndexToRotationIndex( sBitIndexCombination)
local nRotationIndex
if sBitIndexCombination == '1000' then
return 1
elseif sBitIndexCombination == '0100' then
return 2
elseif sBitIndexCombination == '0010' then
return 3
elseif sBitIndexCombination == '0001' then
return 4
elseif sBitIndexCombination == '1000_INV' then
return 5
elseif sBitIndexCombination == '0100_INV' then
return 6
elseif sBitIndexCombination == '0010_INV' then
return 7
elseif sBitIndexCombination == '0001_INV' then
return 8
end
return nRotationIndex
end
-------------------------------------------------------------------------------------------------------------
-- reindicizza una tabella passata ripartendo dall'indice nStartIndex e mantenendo l'ordine
function BeamLib.RotateTableFromIndex( Table, nStartIndex)
local RotatedTable = {}
for i = 1, #Table do
RotatedTable[#RotatedTable + 1] = Table[((RotatedTable + i - 2) % #Table) + 1]
end
return RotatedTable
end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
--- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle --- copia una tabella lua in modo ricorsivo, ossia mantiene indipendenti anche tutte le sottotabelle
--- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs --- ATTENZIONE: in caso di modifiche vanno gestiti anche i tipi custom; sarebbe meglio metterla nel LuaLibs
+1 -1
View File
@@ -453,7 +453,7 @@ function DiceCut.GetDice( Part, Face1, Face2, OptionalParameters)
-- se piani non ortogonali, diminuisco la distanza di offset opportunamente -- 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
+5 -2
View File
@@ -43,7 +43,7 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra -- restituisce vero se la feature con box b3Proc taglia l'intera sezione della barra
local function IsFeatureCuttingEntireSection( b3Proc, Part) function FeatureLib.IsFeatureCuttingEntireSection( b3Proc, Part)
return ( b3Proc:getDimY() > ( Part.b3Part:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Part:getDimZ() - 500 * GEO.EPS_SMALL)) return ( b3Proc:getDimY() > ( Part.b3Part:getDimY() - 500 * GEO.EPS_SMALL) and b3Proc:getDimZ() > ( Part.b3Part:getDimZ() - 500 * GEO.EPS_SMALL))
end end
@@ -198,7 +198,7 @@ function FeatureLib.ClassifyTopology( Proc, Part)
if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end if not Proc.AffectedFaces then Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part) end
local bIsFeatureCuttingEntireSection = IsFeatureCuttingEntireSection( Proc.b3Box, Part) local bIsFeatureCuttingEntireSection = FeatureLib.IsFeatureCuttingEntireSection( Proc.b3Box, Part)
local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part) local bIsFeatureCuttingEntireLength = IsFeatureCuttingEntireLength( Proc.b3Box, Part)
local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part) local bIsAnyDimensionLongAsPart = IsAnyDimensionLongAsPart( Proc, Part)
local vAdj = Proc.AdjacencyMatrix local vAdj = Proc.AdjacencyMatrix
@@ -337,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
+34 -17
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
@@ -512,6 +523,18 @@ function MachiningLib.FindMill( Proc, ToolSearchParameters)
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
-- calcolo riduzione del massimo materiale utilizzabile -- calcolo riduzione del massimo materiale utilizzabile
@@ -579,13 +602,11 @@ 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 = {}
-- parametri obbligatori -- parametri obbligatori
if type( ToolSearchParameters.FaceToMachine) ~= 'table' then
error( 'FindBlade : missing face info')
end
if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then if type( ToolSearchParameters.bAllowTopHead) ~= 'boolean' then
error( 'FindBlade : missing top head info') error( 'FindBlade : missing top head info')
end end
@@ -607,6 +628,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 +662,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)
@@ -649,12 +672,6 @@ function MachiningLib.FindBlade( Proc, ToolSearchParameters)
if not bIsBladeOk then if not bIsBladeOk then
bIsToolCompatible = false bIsToolCompatible = false
end end
-- se si ha solo la faccia si può verificare se questa è orientata correttamente
elseif FaceToMachine then
if MachiningLib.IsFaceZOutOfRange( FaceToMachine.vtN, TOOLS[i]) then
bIsToolCompatible = false
end
end end
end end
@@ -1158,7 +1175,7 @@ end
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
-- funzione per aggiungere una nuova lavorazione -- funzione per aggiungere una nuova lavorazione
function MachiningLib.AddOperations( MACHININGS, Part, sRotation) function MachiningLib.AddOperations( MACHININGS, PARTS, Part, sRotation)
local nErr local nErr
local sErr = '' local sErr = ''
local bAreAllMachiningApplyOk = true local bAreAllMachiningApplyOk = true
@@ -1426,7 +1443,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
bSplitExecuted = true bSplitExecuted = true
MACHININGS.Info.bSplitExecuted = true MACHININGS.Info.bSplitExecuted = true
BeamLib.AddPhaseWithRawParts( Part.idRaw, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET) BeamLib.AddPhaseWithRawParts( PARTS, Part.nIndexInParts, BeamData.ptOriXR, BeamData.dPosXR, BeamData.RAW_OFFSET)
-- se grezzo successivo senza pezzi e finale, va tolto -- se grezzo successivo senza pezzi e finale, va tolto
local nNextRawId = EgtGetNextRawPart( Part.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
@@ -1443,7 +1460,7 @@ function MachiningLib.AddOperations( MACHININGS, Part, sRotation)
local idDisp = EgtGetPhaseDisposition( nPhase) local idDisp = EgtGetPhaseDisposition( nPhase)
-- posizione iniziale considerando eventuiali prerotazioni -- posizione iniziale considerando eventuiali prerotazioni
local nRealInitialPosition = Part.nInitialPosition - ( BEAM.PREROTATE90 or 0) local nRealInitialPosition = Part.nInitialPosition
if sRotation == 'DOWN' then if sRotation == 'DOWN' then
local nRotation = EgtIf( nRealInitialPosition + 2 > 4, nRealInitialPosition + 2 - 4, nRealInitialPosition + 2) - 1 local nRotation = EgtIf( nRealInitialPosition + 2 > 4, nRealInitialPosition + 2 - 4, nRealInitialPosition + 2) - 1
BeamLib.RotateRawPart( Part, nRotation) BeamLib.RotateRawPart( Part, nRotation)
+134 -65
View File
@@ -113,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)
@@ -269,32 +269,70 @@ function PreSimulationLib.CheckOutOfStrokeFromGeometry( idGeometry, vtHead, nSCC
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
@@ -306,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
@@ -325,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
@@ -355,6 +404,7 @@ 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
@@ -364,34 +414,19 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
-- 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:isSmall() 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
@@ -413,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 {}
@@ -423,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)
@@ -432,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
@@ -455,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
+617 -398
View File
File diff suppressed because it is too large Load Diff
+477
View File
@@ -0,0 +1,477 @@
-- BeamNestProcess.lua by Egaltech s.r.l. 2023/01/15
-- Gestione nesting automatico travi
-- 2022/10/05 Piccole modifiche per far funzionare correttamente i compilati.
-- 2022/10/06 Corretto bug che moltiplicava i pezzi se erano presenti più grezzi della stessa sezione.
-- 2023/01/15 Piccole correzioni.
-- Intestazioni
require( 'EgtBase')
_ENV = EgtProtectGlobal()
EgtEnableDebug( false)
-- Per test
--NEST = {}
--NEST.FILE = 'c:\\TechnoEssetre7\\EgtData\\Prods\\0010\\Bar_10_1.btl'
--NEST.MACHINE = 'Essetre-90480019_MW'
--NEST.FLAG = 3
local sLog = ' +++ BeamNestProcess : ' .. NEST.FILE .. ', ' .. NEST.MACHINE .. ', ' .. LEN[1]
EgtOutLog( sLog)
-- flag per abilitare statistiche in log
local bLogStat = false
-- Cancello file di log specifico
local sLogFile = EgtChangePathExtension( NEST.FILE, '.txt')
EgtEraseFile( sLogFile)
-- Funzioni per scrittura su file di log specifico
local function WriteErrToLogFile( nErr, sMsg, nRot, nCutId, nTaskId)
local hFile = io.open( sLogFile, 'a')
hFile:write( 'ERR=' .. tostring( nErr) .. '\n')
hFile:write( sMsg .. '\n')
hFile:write( 'ROT=' .. tostring( nRot or 0) .. '\n')
hFile:write( 'CUTID=' .. tostring( nCutId or 0) .. '\n')
hFile:write( 'TASKID=' .. tostring( nTaskId or 0) .. '\n')
hFile:close()
end
local function WriteTimeToLogFile( dTime)
local hFile = io.open( sLogFile, 'a')
hFile:write( 'TIME=' .. EgtNumToString( dTime) .. '\n')
hFile:close()
end
-- Funzione per gestire visualizzazione dopo errore
local function PostErrView( nErr, sMsg)
if nErr ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
EgtSetView( SCE_VD.ISO_SW, false)
EgtZoom( SCE_ZM.ALL)
EgtOutBox( sMsg, 'BatchProcess (err=' .. tostring( nErr) .. ')', 'ERRORS')
end
end
-- Funzione per gestire visualizzazione dopo warning
local function PostWarnView( nWarn, sMsg)
if nWarn ~= 0 and ( NEST.FLAG == 1 or NEST.FLAG == 2 or NEST.FLAG == 5) then
EgtSetView( SCE_VD.ISO_SW, false)
EgtZoom( SCE_ZM.ALL)
EgtOutBox( sMsg, 'BatchProcess (wrn=' .. tostring( nWarn) .. ')', 'WARNINGS')
end
end
-- Funzione per aggiornare dati ausiliari
local function UpdateAuxData( sAuxFile)
local bModif = false
-- Se definito LOAD90, aggiorno
local sLoad90 = EgtGetStringFromIni( 'AuxData', 'LOAD90', '', sAuxFile)
if sLoad90 ~= '' then
local BtlInfoId = EgtGetFirstNameInGroup( GDB_ID.ROOT, 'BtlInfo') or GDB_ID.NULL
EgtSetInfo( BtlInfoId, 'LOAD90', sLoad90)
bModif = true
end
return bModif
end
local function PartsToFill( Parts)
local nToFill = 0
for i = 1, #Parts do
if Parts[i].Cnt > 0 then
nToFill = nToFill + Parts[i].Cnt
end
end
return nToFill
end
local function ExecMaximumFilling( Raw, Parts)
-- Inizializzo maximum filler
EgtMaxFillerStart()
-- Inserisco i pezzi
for i = 1, #Parts do
EgtMaxFillerAddPart( i, Parts[i].Len, Parts[i].DispLen or Parts[i].Len, Parts[i].Cnt or 1)
end
-- Eseguo l'ottimizzazione
EgtMaxFillerCompute( Raw.LenToFill, Raw.StartGap, Raw.MidGap, Raw.EndGap, Raw.SortType)
-- Recupero i risultati
local nFilledParts, nDiffParts, dTotFillRatio = EgtMaxFillerGetResults()
local OneRes = {}
for i = 0, nDiffParts - 1 do
local nPartId, nCount = EgtMaxFillerGetOneResult( i)
table.insert( OneRes, { Id=nPartId, Count=nCount})
end
--return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Time=dTime, Data=OneRes}
return { FilledParts=nFilledParts, DiffParts=nDiffParts, FillRatio=dTotFillRatio, Data=OneRes}
end
-- Funzione per trovare nome MachGroup
local function NewMachGroupName()
local nMachGroupId = EgtGetFirstMachGroup()
if not nMachGroupId then return 1 end
local nMaxMachGroup = 0
while nMachGroupId do
sMachGroupName = EgtGetMachGroupName(nMachGroupId)
local nMachGroupName = tonumber(sMachGroupName)
if nMachGroupName > nMaxMachGroup then
nMaxMachGroup = nMachGroupName
end
nMachGroupId = EgtGetNextMachGroup(nMachGroupId)
end
return nMaxMachGroup + 1
end
local function TotRawCount(Raws)
local nTotRaws = 0
for RawIndex = 1, #Raws do
nTotRaws = nTotRaws + Raws[RawIndex].Count
end
return nTotRaws
end
local function TotPartLen(Parts)
local nTotPartLen = 0
for PartIndex = 1, #Parts do
nTotPartLen = nTotPartLen + ( Parts[PartIndex].Len * Parts[PartIndex].Cnt)
end
return nTotPartLen
end
-- Imposto direttorio libreria specializzata per Travi
EgtAddToPackagePath( NEST.BASEDIR .. '\\LuaLibs\\?.lua')
-- Imposto la macchina corrente e verifico sia abilitata per la lavorazione delle Travi
EgtSetCurrMachine( NEST.MACHINE)
local sMachDir = EgtGetCurrMachineDir()
if not EgtExistsFile( sMachDir .. '\\Beam\\BeamData.lua') then
NEST.ERR = 12
NEST.MSG = 'Error not configured for beam machine : ' .. sMachine
WriteErrToLogFile( NEST.ERR, NEST.MSG)
PostErrView( NEST.ERR, NEST.MSG)
return
end
-- Elimino direttori altre macchine e imposto direttorio macchina corrente per ricerca librerie
EgtRemoveBaseMachineDirFromPackagePath()
EgtAddToPackagePath( sMachDir .. '\\Beam\\?.lua')
-- Inizializzo contatori errori e avvisi
local nErrCnt = 0
local nWarnCnt = 0
-- Grezzi
local Raws = {}
-- creo tabella dei grezzi
for nIndex, nLen in pairs( LEN) do
Raws[tonumber(nIndex)] = {LenToFill = nLen, StartGap = NEST.STARTOFFSET, MidGap = NEST.OFFSET, EndGap = 0, SortType = -1}
end
for nIndex, nQty in pairs( QTY) do
Raws[tonumber(nIndex)].Count = nQty
end
-- cerco il grezzo con la lunghezza maggiore, epurata dello start gap
local maxRawLenToFillNoStartGap = 0
for RawIndex = 1, #Raws do
if Raws[RawIndex].Count > 0 then
maxRawLenToFillNoStartGap = max( maxRawLenToFillNoStartGap, Raws[RawIndex].LenToFill - Raws[RawIndex].StartGap)
end
end
-- Pezzi
local Parts = {}
-- ciclo su pezzi per aggiungerli al nesting
local dTotLen = 0
for nPartId, nCount in pairs( PART) do
-- recupero lunghezza pezzo
local Len = EgtGetInfo( nPartId, "L", 'd')
local DispLen = EgtIf( Len <= 1000, 2000, 0) --EgtIf( Len <= 2000, max( 2000, 6000 - Len), 0)
-- aggiungo il pezzo solo se ci sta nel grezzo più lungo a disposizione
if Len < maxRawLenToFillNoStartGap then
for nCntIndex = 1 , nCount do
table.insert( Parts, {Id = nPartId, Len = Len, DispLen = DispLen, Cnt = 1})
dTotLen = dTotLen + Len
end
end
end
-- lunghezza totale pezzi
local dTotPartLen = TotPartLen( Parts)
-- calcolo media delle barre necessarie
local NeededRawsForType = {}
for RawIndex = 1, #Raws do
NeededRawsForType[RawIndex] = min( ceil( dTotPartLen / Raws[RawIndex].LenToFill), Raws[RawIndex].Count)
end
local RawQtySum = 0
for NeededRawIndex = 1, #NeededRawsForType do
RawQtySum = RawQtySum + NeededRawsForType[NeededRawIndex]
end
local MediumRawQty = ceil( RawQtySum / #NeededRawsForType)
if MediumRawQty > 1 then
MediumRawQty = MediumRawQty - 1
end
-- lista dei risultati
local ResultList = {}
local BestResult = nil
local BestResultIndex = nil
-- riordino lista pezzi per lunghezza
table.sort( Parts, function( B1, B2) return B1.Len < B2.Len end)
local function NestSolutionByIndex( Index)
-- creo copia lista raw
local TempRaws = {}
for TempRawIndex = 1, #Raws do
table.insert(TempRaws, {LenToFill = Raws[TempRawIndex].LenToFill, StartGap = Raws[TempRawIndex].StartGap, MidGap = Raws[TempRawIndex].MidGap, EndGap = Raws[TempRawIndex].EndGap, SortType = Raws[TempRawIndex].SortType, Count = Raws[TempRawIndex].Count})
end
-- recupero pezzi corti
local ShortList = {}
local LongList = {}
for PartIndex = 1, #Parts do
if PartIndex <= Index then
table.insert( ShortList, Parts[PartIndex])
else
table.insert( LongList, Parts[PartIndex])
end
Parts[PartIndex].Cnt = 1
end
-- numero di pezzi piccoli per barra
local ShortCount = Index
local ShortForRaw = floor( ShortCount / MediumRawQty)
local ExtraShortForRaw = 0
if MediumRawQty > 0 then
ExtraShortForRaw = fmod( ShortCount, MediumRawQty)
end
-- creo lista pezzi corti singoli
local SingleShortList = {}
for ShortIndex = 1, #ShortList do
for ShortCount = 1, ShortList[ShortIndex].Cnt do
table.insert( SingleShortList, {Id = ShortList[ShortIndex].Id, Len = ShortList[ShortIndex].Len, DispLen = ShortList[ShortIndex].DispLen, Cnt = 1})
end
end
-- li divido per le barre previste
local RawsShortList = {}
local RawIndex = 0
local ShortRawIndex = 0
for ShortIndex = 1, #SingleShortList do
if ShortRawIndex > 0 then
table.insert( RawsShortList[RawIndex], SingleShortList[ShortIndex])
ShortRawIndex = ShortRawIndex - 1
else
table.insert( RawsShortList, {SingleShortList[ShortIndex]})
RawIndex = RawIndex + 1
ShortRawIndex = ShortForRaw + EgtIf( RawIndex <= ExtraShortForRaw, 1, 0) - 1
end
end
-- Ciclo fino ad esaurimento pezzi o barre
local dTotPartInRawLen = 0
local nRawTot = 0
local dRawTotLen = 0
local dTime = 0
local nCycle = 1
local CurrResult = {}
while TotRawCount( TempRaws) > 0 and PartsToFill( Parts) > 0 do
-- creo lista con pezzi lunghi e pezzi corti di questo Cycle
local PartsToNest = {}
for PartIndex = 1, #LongList do
table.insert( PartsToNest, LongList[PartIndex])
end
for CycleIndex = 1, #RawsShortList do
if CycleIndex <= nCycle then
for PartIndex = 1, #RawsShortList[CycleIndex] do
table.insert( PartsToNest, RawsShortList[CycleIndex][PartIndex])
end
end
end
-- se non ci sono pezzi da nestare, esco
if PartsToFill( PartsToNest) <= 0 then
break
end
-- Eseguo ottimizzazione per ogni lunghezza di barra
local Results = {}
for RawIndex = 1, #TempRaws do
if TempRaws[RawIndex].Count > 0 then
Results[RawIndex] = ExecMaximumFilling( TempRaws[RawIndex], PartsToNest)
else
Results[RawIndex] = { FillRatio = 0.001, LenToFill = 1000, DiffParts = 0}
end
end
-- verifico quale e' quella con meno scarto
local nMinWasteRawIndex = GDB_ID.NULL
local dMinWaste = 100000
for ResultIndex = 1, #Results do
if Results[ResultIndex] then
local dWaste = (1 - Results[ResultIndex].FillRatio) * TempRaws[ResultIndex].LenToFill
if Results[ResultIndex].DiffParts > 0 and dWaste < dMinWaste then
dMinWaste = dWaste
nMinWasteRawIndex = ResultIndex
end
end
end
-- verifico se ci sono pezzi
if nMinWasteRawIndex > 0 and Results[nMinWasteRawIndex] and Results[nMinWasteRawIndex].DiffParts > 0 then
-- riporto barra e pezzi nel risultato corrente
local CurrBar = { BarLen = TempRaws[nMinWasteRawIndex].LenToFill, Parts = {}}
local CurrX = TempRaws[nMinWasteRawIndex].StartGap
local nInfoIndex = 1
for i = 1, Results[nMinWasteRawIndex].DiffParts do
local PartIndex = Results[nMinWasteRawIndex].Data[i].Id
local PartId = PartsToNest[PartIndex].Id
local dLen = PartsToNest[PartIndex].Len
for j = 1, Results[nMinWasteRawIndex].Data[i].Count do
-- creo pezzo copia
CurrPart = { Index = nInfoIndex, PartId = PartId, PosX = CurrX}
table.insert( CurrBar.Parts, CurrPart)
CurrX = CurrX + dLen + TempRaws[nMinWasteRawIndex].MidGap
nInfoIndex = nInfoIndex + 1
end
end
table.insert( CurrResult, CurrBar)
dTotPartInRawLen = dTotPartInRawLen + ( Results[nMinWasteRawIndex].FillRatio * TempRaws[nMinWasteRawIndex].LenToFill)
nRawTot = nRawTot + 1
dRawTotLen = dRawTotLen + TempRaws[nMinWasteRawIndex].LenToFill
-- Aggiorno per prossima iterazione
TempRaws[nMinWasteRawIndex].Count = TempRaws[nMinWasteRawIndex].Count - 1
for i = 1, Results[nMinWasteRawIndex].DiffParts do
local PartId = Results[nMinWasteRawIndex].Data[i].Id
PartsToNest[PartId].Cnt = PartsToNest[PartId].Cnt - Results[nMinWasteRawIndex].Data[i].Count
end
else
-- se non sono riuscito ad inserire alcun pezzo esco dal ciclo perche' non ci sono pezzi inseribili
break
end
nCycle = nCycle + 1
end
-- riporto risultato in lista
ResultList[Index] = dTotPartInRawLen
if not BestResult or not BestResultIndex or
( dTotPartInRawLen > ResultList[BestResultIndex] + 0.02 or ( abs( dTotPartInRawLen - ResultList[BestResultIndex]) < 0.02 and dRawTotLen < BestResult.RawTotLen - 0.02)) then
BestResult = CurrResult
BestResult.RawTotLen = dRawTotLen
BestResultIndex = Index
end
end
local CycleCount = 0
local MinTime = 10 + pow( 3, ceil( log10( #Parts)) - 1)
if bLogStat then EgtOutLog('MinTime: ' .. MinTime ) end
local MaxTime = 30 + pow( 7, ceil( log10( #Parts)) - 1)
if bLogStat then EgtOutLog('MaxTime: ' .. MaxTime ) end
local TargetRatio = 0.98
local dTargetRatioLen = TargetRatio * dTotLen
if bLogStat then EgtOutLog('TargetRatioLen: ' .. dTargetRatioLen ) end
local CurrTime = 0
local function NestSolutionFromSP( StartingPoint, OscillationStep)
-- ciclo sulle possibilita' da un punto di origine con uno step fisso
local CurrResultIndex = StartingPoint
NestSolutionByIndex( StartingPoint)
if OscillationStep == 0 then return end
local CycleIndex = 1
local nOutOfBoundary = 0
while nOutOfBoundary ~= 3 do
CurrTime = EgtStopCounter() / 1000
if bLogStat then EgtOutLog('CurrTime: ' .. CurrTime ) end
if bLogStat then EgtOutLog('BestRatio: ' .. dTotLen / BestResult.RawTotLen ) end
-- se e' passato il tempo massimo, o e' passato il tempo minimo, ha inserito tutti i pezzi e la percentuale di utilizzo del materiale e' maggiore della soglia
if CurrTime > MaxTime or ( CurrTime > MinTime and ResultList[BestResultIndex] > dTotLen - 0.1 and ( dTotLen / BestResult.RawTotLen ) >= TargetRatio) then
if bLogStat then EgtOutLog('Brake') end
break
end
local bCurrOutOfBoundary = false
if CurrResultIndex < 0 then
bCurrOutOfBoundary = true
if nOutOfBoundary == 2 then
nOutOfBoundary = 3
else
nOutOfBoundary = 1
end
end
if CurrResultIndex > #Parts then
bCurrOutOfBoundary = true
if nOutOfBoundary == 1 then
nOutOfBoundary = 3
else
nOutOfBoundary = 2
end
end
if not bCurrOutOfBoundary and not ResultList[CurrResultIndex] then
NestSolutionByIndex( CurrResultIndex)
if bLogStat then EgtOutLog('CurrResultIndex: ' .. CurrResultIndex ) end
if bLogStat then EgtOutLog('Result: ' .. ResultList[CurrResultIndex]) end
CycleCount = CycleCount + 1
end
CurrResultIndex = StartingPoint + EgtIf( CycleIndex % 2 == 0, (CycleIndex / 2) * OscillationStep, -( ( CycleIndex + 1) / 2) * OscillationStep )
CycleIndex = CycleIndex + 1
end
end
-- lancio calcolo
EgtStartCounter()
local StartingResult = floor( #Parts * 0.3)
if bLogStat then EgtOutLog('StartingResult: ' .. StartingResult ) end
--local Step = floor( #Parts / 10) * floor( log10( #Parts))
local nDividendo = pow( 10, floor( log10( #Parts)) - 1)
nDividendo = EgtIf( nDividendo ~= 1, nDividendo, 10)
local Step = floor( #Parts / nDividendo) * floor( log10( #Parts))
if bLogStat then EgtOutLog('Step: ' .. Step ) end
NestSolutionFromSP( StartingResult, Step)
if Step > 1 then
NestSolutionFromSP( StartingResult, 1)
end
-- creo gruppi di lavorazione per risultato
for MachGroupIndex = 1, #BestResult do
local CurrMachGroup = BestResult[ MachGroupIndex]
-- creo gruppo di lavorazione
local MachGroupName = NewMachGroupName()
nMachGroup = EgtAddMachGroup( MachGroupName)
EgtSetInfo( nMachGroup, "BARLEN", CurrMachGroup.BarLen)
EgtSetInfo( nMachGroup, "MATERIAL", NEST.MATERIAL)
EgtSetInfo( nMachGroup, "AUTONEST", 1)
-- scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
EgtSetInfo( nMachGroup, "PRODID", NEST.PRODID)
EgtSetInfo( nMachGroup, "PATTID", nMachGroup)
-- Disegno i pezzi
for i = 1, #CurrMachGroup.Parts do
local CurrPart = CurrMachGroup.Parts[ i]
-- creo pezzo copia
local nPartDuploId = EgtDuploNew( CurrPart.PartId)
EgtSetInfo( nMachGroup, "PART" .. CurrPart.Index, nPartDuploId .. "," .. CurrPart.PosX)
end
end
-- creo grezzi per ogni gruppo di lavorazione
local nRawCnt = 0
local nRawTot = ResultList[BestResultIndex]
_G.BEAM = {}
BEAM.FILE = NEST.FILE
BEAM.MACHINE = NEST.MACHINE
BEAM.FLAG = 6 -- CREATE_PANEL
BEAM.BASEDIR = NEST.BASEDIR
nMachGroup = EgtGetFirstMachGroup()
while nMachGroup do
local nNextMachGroup = EgtGetNextMachGroup( nMachGroup)
EgtSetCurrMachGroup( nMachGroup)
if EgtGetInfo( nMachGroup, "AUTONEST",'i') == 1 then
EgtRemoveInfo( nMachGroup, "AUTONEST")
EgtSetInfo( nMachGroup, "UPDATEUI", 1)
local bOk, sErr = pcall( dofile, BEAM.BASEDIR .. "\\BatchProcessNew.lua")
if not bOk then
EgtOutLog( 'Error in BatchProcessNew.lua call (' .. ( sErr or '') ..')')
end
nRawCnt = nRawCnt + 1
-- aggiorno interfaccia
EgtProcessEvents( 200 + ( nRawCnt / nRawTot * 100), 0)
end
nMachGroup = nNextMachGroup
end
EgtResetCurrMachGroup()
NEST.ERR = 0
EgtOutLog( ' +++ BeamNestProcess completed')
+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" }]
} }
] ]
}, },
+30
View File
@@ -269,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 = {}
@@ -278,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)
@@ -309,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 = {}
@@ -318,6 +335,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)
+11 -10
View File
@@ -195,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)
@@ -241,16 +252,6 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
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
-- riferimenti locali per leggibilità e performance -- riferimenti locali per leggibilità e performance
local LongFace = Proc.MainFaces.LongFaces[1] local LongFace = Proc.MainFaces.LongFaces[1]
local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1] local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1]
+10 -10
View File
@@ -132,6 +132,16 @@ 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
@@ -145,16 +155,6 @@ function STR0004.Make( bAddMachining, Proc, Part, CustomParameters)
dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength dPocketHeight = Proc.MainFaces.BottomFaces[1].MainEdges.SideEdges[1].dLength
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
-- riferimenti locali per leggibilità e performance -- riferimenti locali per leggibilità e performance
local LongFace = Proc.MainFaces.LongFaces[1] local LongFace = Proc.MainFaces.LongFaces[1]
local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1] local OppositeEdge1 = LongFace.MainEdges.OppositeEdges[1]
+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
+8 -1
View File
@@ -215,6 +215,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
end end
-- se la lavorazione ostacola il pinzaggio, non posso farla, serve una lavorazioen che lasci il testimone -- se la lavorazione ostacola il pinzaggio, non posso farla, serve una lavorazioen che lasci il testimone
-- TODO Girando il pezzo trova sempre che limitano il pinzaggio se pezzo piccolo!! Il controllo non va bene. Da rifare
if MachiningLib.IsFeatureHinderingClamping( Proc, Part) then if MachiningLib.IsFeatureHinderingClamping( Proc, Part) then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable ( Feature hinders clamping)' local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable ( Feature hinders clamping)'
EgtOutLog( sErr) EgtOutLog( sErr)
@@ -253,6 +254,7 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
ToolSearchParameters.vtToolDirection = BottomFace1.vtN ToolSearchParameters.vtToolDirection = BottomFace1.vtN
ToolSearchParameters.bAllowTopHead = true ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = true ToolSearchParameters.bAllowBottomHead = true
ToolSearchParameters.sMillShape = 'STANDARD'
local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters) local ToolInfo = MachiningLib.FindMill( Proc, ToolSearchParameters)
local nToolIndex = ToolInfo.nToolIndex local nToolIndex = ToolInfo.nToolIndex
@@ -391,7 +393,12 @@ function STR0010.Make( bAddMachining, Proc, Part, CustomParameters)
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
@@ -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
+16 -2
View File
@@ -24,6 +24,8 @@ local function GetSCC( Machining)
if TOOLS[Machining.nToolIndex].SetupInfo.bToolOnAggregate then if TOOLS[Machining.nToolIndex].SetupInfo.bToolOnAggregate then
nSCC = MCH_SCC.ADIR_NEAR nSCC = MCH_SCC.ADIR_NEAR
elseif TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC then
nSCC = TOOLS[Machining.nToolIndex].SetupInfo.nBlockedSCC
elseif Machining.vtToolDirection:getY() <= 0 then elseif Machining.vtToolDirection:getY() <= 0 then
nSCC = MCH_SCC.ADIR_YM nSCC = MCH_SCC.ADIR_YM
else else
@@ -96,7 +98,7 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Machining.nSCC = GetSCC( Strategy.Machining) Strategy.Machining.nSCC = GetSCC( Strategy.Machining)
Strategy.Machining.nType = MCH_MY.MILLING Strategy.Machining.nType = MCH_MY.MILLING
Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, 5) Strategy.Machining.sDepth = EgtClamp( Strategy.Parameters.dMachiningDepth, -1, TOOLS[Strategy.Machining.nToolIndex].dMaxMaterial)
Strategy.Machining.nWorkside = MCH_MILL_WS.CENTER Strategy.Machining.nWorkside = MCH_MILL_WS.CENTER
-- LeadIn / LeadOut -- LeadIn / LeadOut
@@ -105,11 +107,23 @@ function STR0014.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.Machining.LeadIn.nType = MCH_MILL_LI.NONE Strategy.Machining.LeadIn.nType = MCH_MILL_LI.NONE
Strategy.Machining.LeadOut.nType = MCH_MILL_LI.NONE Strategy.Machining.LeadOut.nType = MCH_MILL_LI.NONE
-- se è una penna, si limita la lavorazione per evitare di partire fuori dal grezzo
if ToolSearchParameters.sMillShape == 'PEN' then
Strategy.Machining.LeadIn.dStartAddLength = -20
Strategy.Machining.LeadOut.dEndAddLength = -20
end
-- TODO gestire meglio
-- se utensile montato su aggregato flottante
if TOOLS[Strategy.Machining.nToolIndex].bToolOnFloatingTH then
Strategy.Machining.dMaxElev = Strategy.Parameters.dMachiningDepth
Strategy.Machining.dLongitudinalOffset = -5
end
-- stessi parametri cambia solo al geometria -- stessi parametri cambia solo al geometria
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)
+1 -1
View File
@@ -8,7 +8,7 @@ STR0005 = 1, 2 o 3 facce. Lama con taglio singolo o cubetti. Se richiesto o nece
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 mortasa (raggiata) 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
+16 -5
View File
@@ -795,6 +795,7 @@ 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
@@ -884,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
@@ -914,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)
@@ -964,10 +971,13 @@ 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
nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part, Face1) nToolIndex, sChosenBladeType = GetBestBlade( Proc, Part)
end end
-- se non trovata lama la lavorazione non è fattibile -- se non trovata lama la lavorazione non è fattibile
@@ -1008,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)
+11 -3
View File
@@ -211,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
@@ -231,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')
@@ -258,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
@@ -355,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)
@@ -472,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 )