Compare commits

..

52 Commits

Author SHA1 Message Date
luca.mazzoleni 9bee171cef - in STR0003 rimosso MaxElev per sega a catena (entrava in rapido nella slot) 2026-07-16 18:17:19 +02:00
luca.mazzoleni 6dad1e14c4 - in BeamExec correzione 2026-07-16 15:46:01 +02:00
daniele.nicoli 32227ce33b In STR0003 - forzata uscita se tutte le lavorazioni di lama falliscono; In caso proverà STR0004. 2026-07-16 12:19:43 +02:00
luca.mazzoleni 1a25ebff1a - in BeamExec e NestProcess correzioni varie per Nesting obliquo
- in NestProcess aggiunto dump in/out per debug
2026-07-16 11:12:21 +02:00
Dario Sassi 35dc783c10 BeamNT :
- in Version assegnato nome BeamNT e versione a 3.1g1.
2026-07-16 09:26:01 +02:00
Dario Sassi 9cadb26603 BeamNT :
- corretta compilazione per evitare ripetizione direttorio destinazione bin sotto se stesso e per copiare immagini e messaggi.
2026-07-16 09:12:40 +02:00
Dario Sassi 37ab3b3bd2 BeamNT :
- aggiunta a immagine Process la scritta NT.
2026-07-15 17:31:59 +02:00
luca.mazzoleni 4837173ba1 Merge branch 'ClampingPrediction' into develop 2026-07-13 17:55:17 +02:00
luca.mazzoleni fb06c85aa5 - in BLADEKEEPWASTE si fa codolo anche se 2 facce convesse 2026-07-13 16:14:12 +02:00
luca.mazzoleni dd56772f63 - in BeamExec correzione 2026-07-13 15:47:34 +02:00
luca.mazzoleni b28cdf488d - in BeamExec se feature ignombra pinzaggio in qualche rotazione attiva si fa in ultima fase 2026-07-13 14:52:00 +02:00
luca.mazzoleni e1564c4995 - FeatureHindersClamping è calcolato direttamente nel Collect e contempla solo la rotazione corrente; andrà gestito bMoveToUnloadPhase per le feature in cui c'è almeno una rotazione HindersClamping 2026-07-10 18:14:13 +02:00
luca.mazzoleni 0b9ebbb15c - in FACEBYBLADE modifiche ai criteri di spostamento dopo separazione 2026-07-10 16:07:29 +02:00
luca.mazzoleni b9037b28f7 - in PreSimulationLib la flangia lama si controlla solo con il primo asse (prima veniva controllata inutilmente con tutti gli assi) 2026-07-10 10:11:05 +02:00
luca.mazzoleni aa7e0ae4c1 - in HEADCUT riabilitato skip 2026-07-09 18:36:53 +02:00
luca.mazzoleni 88bf36667d - in LeadInOutLib correzione a attacco speciale tangenziale 2026-07-09 18:07:52 +02:00
luca.mazzoleni 763f1200f5 - in BLADEKEEPWASTE correzione 2026-07-09 15:48:32 +02:00
luca.mazzoleni f5a526f6bf - in BLADEKEEPWASTE correzione per codolo perpendicolare corto 2026-07-09 12:15:09 +02:00
luca.mazzoleni 7b6066d47d Merge branch 'BladeKeepWastePerpendicularStrip' into develop 2026-07-08 11:17:16 +02:00
luca.mazzoleni b1fad0cd0c - in BLADEKEEPWASTE il codolo perpendicolare si fa solo se la feature arriva più in basso dell'altezza minima della morsa 2026-07-07 18:27:03 +02:00
luca.mazzoleni 73ec13f1a3 - in FACEBYBLADE la ToolMarkLength viene calcolata da LeadInOutLib, se non disponibile 2026-07-07 17:57:57 +02:00
luca.mazzoleni 866363a34b Merge branch 'develop' into BladeKeepWastePerpendicularStrip 2026-07-07 16:05:02 +02:00
luca.mazzoleni fe721f5cb3 - corretto commento 2026-07-07 15:23:50 +02:00
luca.mazzoleni 27ce6a30ce - per lama aggiunti attacchi speciali SpecialTangent e SpecialTangentInverted 2026-07-07 11:59:45 +02:00
luca.mazzoleni 3a1c98b8eb - in BeamExec si pulisce il tempgroup dopo ogni chiamata della Make di una strategia (evita problemi di memoria) 2026-07-03 10:16:03 +02:00
luca.mazzoleni 06a4316efa - in BeamExec.ProcessAlternatives per il calcolo delle info testa coda si usano sempre le feature nella rotazione principale e si ruotano direttamente i punti/versori 2026-07-02 16:36:10 +02:00
andrea.villa e83f2d5b69 - In STR0005 e STR0012 aggiunta lunghezza sotto la quale cubettare in caso di configurazuione AUTO
- Aggiunta topologia VGroove-2-Through
- Aggiunti messaggi
- In lettura parametri, se il default è nil, ma da json è settato, allora si prende il valore del json
2026-07-02 10:42:05 +02:00
andrea.villa eb6d2a1a1e Se feature corta non si fanno i codoli perpendicolari 2026-07-01 12:34:22 +02:00
andrea.villa 5c6d6951c9 Prima versione gestione codolo verticale con parametro bAllowPerpendicularStrip 2026-07-01 12:22:20 +02:00
luca.mazzoleni 14bb688e26 - in BLADEKEEPWASATE aggiunto bAllowPerpendicularStrip, da gestire 2026-06-30 18:09:02 +02:00
luca.mazzoleni d86e1c1c56 - in STR0005 aggiunto parametro bAllowPerpendicularStrip da passare a BLADEKEEPWASTE per codolo multiplo corto 2026-06-30 18:06:12 +02:00
luca.mazzoleni 2a8b7d37f6 Merge branch 'AvoidObliqueSplitIfNotApplicable' into develop 2026-06-30 17:43:21 +02:00
luca.mazzoleni 86bda3d3af - in BeamExec.ProcessAlternatives correzione 2026-06-30 16:58:51 +02:00
luca.mazzoleni 60d8387485 - in BeamExec.ProcessAlternatives correzione 2026-06-30 15:56:40 +02:00
luca.mazzoleni 60166eb995 - in BeamExec.ProcessAlternatives si scrivono offset e normali testa coda ruotati correttamente 2026-06-30 15:47:12 +02:00
luca.mazzoleni 3f0654c655 - in BLADETOWASTE correzione importante
- in BeamLib aggiunte funzioni ReverseTablePortionInPlace e RotateTableFromIndexInPlace
2026-06-30 15:04:16 +02:00
luca.mazzoleni 9706f218a8 - in BeamExec correzione 2026-06-30 12:48:04 +02:00
luca.mazzoleni c114794d0b - in HEADCUT per il momento si disattivano gli skip headcut 2026-06-30 12:10:19 +02:00
luca.mazzoleni 4ef7e0cc0e - in STR0012 correzione 2026-06-30 10:21:04 +02:00
luca.mazzoleni 6eff65e4ac - in BLADETOWASTE.CalculateDiceMachinings ora si passa la superficie corretta senza grezzo alla PreSimulation, a meno che non sia bCannotSplitRestLength 2026-06-30 10:18:03 +02:00
andrea.villa 236d9a43b0 Aggiunto parametro sCuttingStrategy a strategia STR0012 2026-06-30 09:09:18 +02:00
luca.mazzoleni e4ab69f749 - in BeamExec correzione alternative 2026-06-29 18:18:57 +02:00
luca.mazzoleni 2d72146ae0 - in BeamExec correzione 2026-06-29 17:54:59 +02:00
luca.mazzoleni 4552235383 - in BeamExec modifiche per calcolare le alternative in base ai tagli di testa e coda finali scelti 2026-06-29 17:28:09 +02:00
luca.mazzoleni 8aab3e9cbc - in BeamExec.GetCombinationListFromMatrix se combinazione con invesione si analizza la rotazione 5 invece della 1 2026-06-29 11:16:02 +02:00
luca.mazzoleni d2e0402a07 - in HEADCUT correzione 2026-06-29 09:20:34 +02:00
luca.mazzoleni 5a871ea134 - in HEADCUT e TAILCUT, se non è talgio originale, si forza sempre a Split 2026-06-26 17:04:39 +02:00
luca.mazzoleni 06d27a1df7 - modificate NestProcess e HEADCUT per saltare il taglio di testa se corrisponde al taglio di coda precedente 2026-06-26 14:51:48 +02:00
luca.mazzoleni aa4968787a - in TailCut e BeamExec correzione per scelta tagli di testa e coda originale nel caso quelli sostitutivi non fossero appplicabili 2026-06-26 10:47:33 +02:00
luca.mazzoleni 88b2e90ef7 - in BeamExec altre correzioni riguardanti la sostituzione dei tagli di testa o coda 2026-06-25 18:56:29 +02:00
luca.mazzoleni 53b2ef5e6a - in BeamExec.GetFeatureInfoAndDependency correzione 2026-06-25 18:25:54 +02:00
luca.mazzoleni 6832d1d95b - in BeamExec.CalculateStrategies se i tagli di testa o coda obliqui non funzionano si ripristinano quelli originali
- inHEADCUT e TAILCUT, se non è taglio originale, si calcola risultato anche per CalculateStrategies
2026-06-25 17:24:56 +02:00
26 changed files with 876 additions and 318 deletions
+6
View File
@@ -5,8 +5,14 @@ set LUAC=C:\EgtProg\Dll32\luac54.exe
set ROOT=%cd%\
set OUTBASE=bin
rmdir /s /q "%ROOT%\%OUTBASE%"
if not exist %OUTBASE% mkdir %OUTBASE%
xcopy "%ROOT%\Images" "%ROOT%\%OUTBASE%\Images" /E /H /C /I /Y
xcopy "%ROOT%\Messages" "%ROOT%\%OUTBASE%\Messages" /E /H /C /I /Y
REM Compile all .lua files excluding bin\ and any dot folders/files
for /f "delims=" %%F in ('dir /b /s /a-d *.lua ^| findstr /v /i /c:"\%OUTBASE%\"') do (
set FULL=%%F
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

+279 -169
View File
@@ -731,6 +731,8 @@ local function CollectFeatures( Part, dRotIndex)
end
-- calcolo riduzione lunghezza pinzabile testa/coda
Proc.NotClampableLength = FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
-- si verifica se la feature, lavorata in questa fase, compromette il pinzaggio
Proc.bFeatureHindersClamping = FeatureLib.IsMachiningLong( max( Proc.NotClampableLength.dNotClampableLengthHead, Proc.NotClampableLength.dNotClampableLengthTail), Part)
-- si verifica se la feature, lavorata in questa fase, compromette lettura misura laser
Proc.bHindersLaserMeasure = FeatureLib.CalculateFeatureHindersLaserMeasure( Proc, Part)
-- altrimenti errore (serviva riconoscimento topologico, ma non è stato possibile farlo)
@@ -822,7 +824,33 @@ local function AreDrillingsMirrored( Proc, ProcMirror, Part)
end
-------------------------------------------------------------------------------------------------------------
local function GetFeatureInfoAndDependency( vProcSingleRot, Part, bIsFlipRot)
local function GetHeadTailInfoForNesting( HeadProc, TailProc, Part)
-- 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, #PtSortedTail 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 = Vector3d( HeadProc.Faces[1].vtN)
TailcutInfo.vtN = Vector3d( TailProc.Faces[1].vtN)
return HeadcutInfo, TailcutInfo
end
-------------------------------------------------------------------------------------------------------------
local function GetFeatureInfoAndDependency( vProcSingleRot, Part)
-- gruppo per geometrie temporanee
local idTempGroup = BeamLib.GetTempGroup()
@@ -966,10 +994,6 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part, bIsFlipRot)
end
end
if not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then
return vProcSingleRot
end
-- si tiene via il riferimento alla Proc Head/Tail originale in caso si dovesse rimpiazzare
HeadProcOriginal.bIsOriginalHeadcut = true
TailProcOriginal.bIsOriginalTailcut = true
@@ -984,36 +1008,22 @@ local function GetFeatureInfoAndDependency( vProcSingleRot, Part, bIsFlipRot)
TailProc.TailProcOriginal = TailProcOriginal
end
if not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then
return vProcSingleRot
end
HeadProc.Topology = {}
TailProc.Topology = {}
HeadProc.Topology.bIsThrough = true
HeadProc.Topology.sFamily = 'HeadCut'
HeadProc.Topology.sName = 'HeadCut'
TailProc.Topology.bIsThrough = true
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, #PtSortedTail 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
return vProcSingleRot
end
-------------------------------------------------------------------------------------------------------------
@@ -1131,64 +1141,109 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che processa tutte le feature del pezzo
local function CalculateStrategies( vProcSingleRot, Part)
-- per ogni feature
for i = 1, #vProcSingleRot do
-- processo tutte le feature attive
local Proc = vProcSingleRot[i]
if Proc.nFlg ~= 0 then
-- controllo se ci sono strategie disponibili
if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then
-- se le strategie disponibili sono le basic, non si possono customizzare valori di default da interfaccia
-- si leggono allora eventuali parametri di default scritti come info sulla feature
if Proc.AvailableStrategies.bIsBasicStrategy then
-- si recuperano eventuali parametri custom
for j = 1, #Proc.AvailableStrategies do
-- essendo una strategia basic, la lista dei parametri custom dovrebbe essere sempre vuota. Si leggono ora
if not Proc.AvailableStrategies[j].ParameterList then
Proc.AvailableStrategies[j].ParameterList = BCS.GetParametersFromBasicCustomerStrategies( Proc, Proc.AvailableStrategies[j].sStrategyId)
local nCounter = 0
repeat
nCounter = nCounter + 1
local bToReprocess = false
-- per ogni feature
for i = 1, #vProcSingleRot do
-- processo tutte le feature attive
local Proc = vProcSingleRot[i]
if Proc.nFlg ~= 0 then
-- controllo se ci sono strategie disponibili
if Proc.AvailableStrategies and #Proc.AvailableStrategies > 0 then
-- se le strategie disponibili sono le basic, non si possono customizzare valori di default da interfaccia
-- si leggono allora eventuali parametri di default scritti come info sulla feature
if Proc.AvailableStrategies.bIsBasicStrategy then
-- si recuperano eventuali parametri custom
for j = 1, #Proc.AvailableStrategies do
-- essendo una strategia basic, la lista dei parametri custom dovrebbe essere sempre vuota. Si leggono ora
if not Proc.AvailableStrategies[j].ParameterList then
Proc.AvailableStrategies[j].ParameterList = BCS.GetParametersFromBasicCustomerStrategies( Proc, Proc.AvailableStrategies[j].sStrategyId)
end
end
-- si riprocessano le strategie dopo che sono stati letti i parametri
Proc.AvailableStrategies = BCS.UpdateStrategies( Proc.AvailableStrategies)
end
-- ciclo tutte le strategie della feature
for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do
-- eseguo file config con i parametri di default
local CurrentStrategy = {}
CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId)
-- controllo che le librerie siano state effettivamente caricate
if CurrentStrategy.Config and CurrentStrategy.Script then
-- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
_, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy])
-- pulizia eventuali geometrie aggiutive create dalla strategia
EgtEmptyGroup( Part.idTempGroup)
-- se taglio di testa o coda sostitutivo non applicabile si ripristina l'originale
if Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus ~= 'Completed' then
if ID.IsHeadCut( Proc) and not Proc.bIsOriginalHeadcut then
-- si riabilita taglio di testa originale
Proc.HeadProcOriginal.nFlg = 1
Proc.HeadProcOriginal.nIndexMasterProc = nil
-- il taglio attuale va riportato alla sua topologia originale
Proc.Topology = FeatureLib.ClassifyTopology( Proc, Part)
Proc.AvailableStrategies = GetStrategies( Proc, Part.sAISetupConfig)
for j = #Proc.SlaveProcIndexes, 1, -1 do
if Proc.SlaveProcIndexes[j] == Proc.HeadProcOriginal.nIndexInVProc then
table.remove( Proc.SlaveProcIndexes, j)
end
end
bToReprocess = true
break
elseif ID.IsTailCut( Proc) and not Proc.bIsOriginalTailcut then
-- si riabilita il taglio di coda originale
Proc.TailProcOriginal.nFlg = 1
Proc.TailProcOriginal.nIndexMasterProc = nil
-- il taglio attuale va riportato alla sua topologia originale
Proc.Topology = FeatureLib.ClassifyTopology( Proc, Part)
Proc.AvailableStrategies = GetStrategies( Proc, Part.sAISetupConfig)
for j = #Proc.SlaveProcIndexes, 1, -1 do
if Proc.SlaveProcIndexes[j] == Proc.TailProcOriginal.nIndexInVProc then
table.remove( Proc.SlaveProcIndexes, j)
end
end
bToReprocess = true
break
end
end
-- TODO da capire se dare un tempo molto alto oppure se dare errore perchè non deve mai capitare. Per ora si setta tempo alto
-- se tempo non calcolato, si setta un tempo molto alto, 99 minuti
if not Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine or Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine == 0 then
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99
end
if not Proc.AvailableStrategies.dAllStrategiesTotalTime then
Proc.AvailableStrategies.dAllStrategiesTotalTime = 0
end
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
if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Completed' then
break
end
-- se non trovo i file della strategia (Script e Config), scrivo che non è più disponibile
else
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {}
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found'
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus = 'Not-Applicable'
end
end
-- si riprocessano le strategie dopo che sono stati letti i parametri
Proc.AvailableStrategies = BCS.UpdateStrategies( Proc.AvailableStrategies)
end
-- ciclo tutte le strategie della feature
for nIndexCurrentStrategy = 1, #Proc.AvailableStrategies do
-- eseguo file config con i parametri di default
local CurrentStrategy = {}
CurrentStrategy = RunStrategyLibraries( Proc.AvailableStrategies[nIndexCurrentStrategy].sStrategyId)
-- controllo che le librerie siano state effettivamente caricate
if CurrentStrategy.Config and CurrentStrategy.Script then
-- eseguo la strategia solo come calcolo fattibilità e voto. Non si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
_, Proc.AvailableStrategies[nIndexCurrentStrategy].Result = CurrentStrategy.Script.Make( false, Proc, Part, Proc.AvailableStrategies[nIndexCurrentStrategy])
-- TODO da capire se dare un tempo molto alto oppure se dare errore perchè non deve mai capitare. Per ora si setta tempo alto
-- se tempo non calcolato, si setta un tempo molto alto, 99 minuti
if not Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine or Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine == 0 then
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.dTimeToMachine = 99
end
if not Proc.AvailableStrategies.dAllStrategiesTotalTime then
Proc.AvailableStrategies.dAllStrategiesTotalTime = 0
end
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
if Part.GeneralParameters.GEN_sMachiningStrategy == 'FIRST_IN_LIST' and Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus == 'Completed' then
break
end
-- se non trovo i file della strategia (Script e Config), scrivo che non è più disponibile
else
Proc.AvailableStrategies[nIndexCurrentStrategy].Result = {}
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sInfo = 'Strategy not found'
Proc.AvailableStrategies[nIndexCurrentStrategy].Result.sStatus = 'Not-Applicable'
if bToReprocess then
break
end
-- si calcola il composite rating delle strategie
Proc.AvailableStrategies = FeatureLib.CalculateStrategiesCompositeRating( Proc.AvailableStrategies, Part.GeneralParameters.GEN_sMachiningStrategy)
end
-- si calcola il composite rating delle strategie
Proc.AvailableStrategies = FeatureLib.CalculateStrategiesCompositeRating( Proc.AvailableStrategies, Part.GeneralParameters.GEN_sMachiningStrategy)
end
end
end
until ( not bToReprocess) or ( nCounter > 5)
return vProcSingleRot
end
@@ -1381,8 +1436,10 @@ local function CalculateMachinings( vProc, Part, nInitialRotation)
local StrategyScript = require( StrategyScriptName)
-- eseguo la strategia e si applicano le lavorazioni. Si passa la Proc e i parametri personalizzati
local _, Result = StrategyScript.Make( true, Proc, Part, Proc.ChosenStrategy)
-- pulizia eventuali geometrie aggiutive create dalla strategia
EgtEmptyGroup( Part.idTempGroup)
-- 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
if ( ID.IsHeadCut( Proc) or ID.IsTailCut( Proc)) and not Proc.ChosenStrategy.Result then
Proc.ChosenStrategy.Result = Result
end
-- se tutte le strategie disponibili non sono applicabili
@@ -1436,8 +1493,6 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
-- se è prerotazione, oltre al ciclo normale, si devono verificare anche invertiti
local bCalcInverted = bIsFlipRot and PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion
local nCycles = EgtIf( bCalcInverted, 2, 1)
PARTS[nPart].HeadcutInfo = {}
PARTS[nPart].TailcutInfo = {}
-- per ogni inversione
for nInvertIndex = 1, nCycles do
-- per ogni rotazione
@@ -1445,7 +1500,6 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
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 HeadcutInfo, TailcutInfo
-- si calcolano le feature solo se la rotazione può essere presa in considerazione
if PARTS[nPart].CombinationList.Rotations[nRotIndex] == 1 then
-- recupero le feature di lavorazione della trave
@@ -1453,23 +1507,11 @@ function BeamExec.GetProcessings( PARTS, bIsFlipRot)
-- recupero informazioni ausiliarie feature e dipendenze tra feature stesse
-- TODO le dipendenze cambiano in base alla rotazione del pezzo? probabilmente no
vProcRot[nIndex], HeadcutInfo, TailcutInfo = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart], bIsFlipRot)
vProcRot[nIndex] = GetFeatureInfoAndDependency( vProcRot[nIndex], PARTS[nPart])
else
-- inserisco una tabella vuota
table.insert( vProcRot, {})
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
BeamLib.RotateRawPart( PARTS[nPart], 1)
-- aggiorno info pezzo
@@ -1656,17 +1698,19 @@ end
-------------------------------------------------------------------------------------------------------------
-- funzione che calcola le combinazioni di rotazione per lavorare la trave e sceglie la migliore
local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bReProcessEmptyChosenStrategy, BitCombinationListToReprocess)
local function GetCombinationListFromMatrix( ProcessingsOnPart, Part, bReProcessEmptyChosenStrategy, BitCombinationListToReprocess)
local CombinationsList = { dAllCombinationsTotalTime = 0}
-- calcolo per tutte le combinazioni disponibili precedentemente verificate
for i = 1, #PartInfo.CombinationList do
for i = 1, #Part.CombinationList do
local bToProcess = false
-- controllo se debbano essere ricalcolate solo alcune soluzioni
local nSingleCombinationToReprocessIndex
if BitCombinationListToReprocess and #BitCombinationListToReprocess > 0 then
for c = 1, #BitCombinationListToReprocess do
if PartInfo.CombinationList[i].sBitIndexCombination == BitCombinationListToReprocess[c].sBitIndexCombination and
PartInfo.CombinationList[i].bPartInCombiIsInverted == BitCombinationListToReprocess[c].bPartInCombiIsInverted then
if Part.CombinationList[i].sBitIndexCombination == BitCombinationListToReprocess[c].sBitIndexCombination and
Part.CombinationList[i].bPartInCombiIsInverted == BitCombinationListToReprocess[c].bPartInCombiIsInverted then
nSingleCombinationToReprocessIndex = c
bToProcess = true
end
end
@@ -1677,7 +1721,7 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
if bToProcess then
local bRot90, bRot180
local SingleCombination = {}
local nUnloadPos = PartInfo.CombinationList[i].nUnloadPos
local nUnloadPos = Part.CombinationList[i].nUnloadPos
SingleCombination.nRotations = 0
SingleCombination.dTotalTimeToMachine = 0
SingleCombination.dTotalQuality = 0
@@ -1685,9 +1729,12 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
SingleCombination.nComplete = 0
SingleCombination.nNotComplete = 0
SingleCombination.nNotExecute = 0
SingleCombination.sBitIndexCombination = PartInfo.CombinationList[i].sBitIndexCombination
SingleCombination.sBitIndexCombination = Part.CombinationList[i].sBitIndexCombination
if nSingleCombinationToReprocessIndex then
SingleCombination.sBitIndexCombinationToNest = BitCombinationListToReprocess[nSingleCombinationToReprocessIndex].sBitIndexCombinationToNest
end
-- TODO se pezzo invertito bisogna considerare le rotazioni nell'array dalla 5 alla 8
SingleCombination.bPartInCombiIsInverted = PartInfo.CombinationList[i].bPartInCombiIsInverted
SingleCombination.bPartInCombiIsInverted = Part.CombinationList[i].bPartInCombiIsInverted
SingleCombination.nUnloadPos = nUnloadPos
-- creo liste dei proc suddivisi per rotazione
SingleCombination.Rot0 = {}
@@ -1697,30 +1744,49 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
-- ciclo su tutte le feature, ad eccezione dei tagli testa/coda che dipendono dal risultato delle altre
-- tagli testa e coda vengono aggiunti sempre alla fine
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 (ma dall'inversione sì!)
-- se feature disattivata perchè eseguita da master a lei associata dichiaro comunque eseguita
local ProcOnFirstRotation = ProcessingsOnPart.Rotation[1][nProc]
local nOffsetIndex = EgtIf( SingleCombination.bPartInCombiIsInverted, 4, 0)
local ProcOnFirstRotation = ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]
if ProcOnFirstRotation.nFlg == 0 and ProcOnFirstRotation.nIndexMasterProc then
ProcOnFirstRotation.nIndexRotation = nUnloadPos
table.insert( SingleCombination.Rot0, ProcOnFirstRotation)
SingleCombination.nComplete = SingleCombination.nComplete + 1
else
local nOffsetIndex = EgtIf( SingleCombination.bPartInCombiIsInverted, 4, 0)
if not ( ( ID.IsHeadCut( ProcOnFirstRotation) and ProcOnFirstRotation.bIsOriginalHeadcut)
or ( ID.IsTailCut( ProcOnFirstRotation) and ProcOnFirstRotation.bIsOriginalTailcut)) then
if not ( ( ID.IsHeadCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) and ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc].bIsOriginalHeadcut)
or ( ID.IsTailCut( ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc]) and ProcessingsOnPart.Rotation[1+nOffsetIndex][nProc].bIsOriginalTailcut)) then
-- primo ciclo sulle rotazioni per vedere se la feature interferisce con il pinzaggio, in una qualunque rotazione
local dMaxNotClampableLengthHead = 0
local dMaxNotClampableLengthTail = 0
local dMaxNotClampableLength = 0
for nRotation = 1, 4 do
-- si considera solo rotazione attiva
if string.sub( Part.CombinationList[i].sBitIndexCombination, nRotation, nRotation) == '1' and ( ProcessingsOnPart.Rotation[nRotation+nOffsetIndex][nProc].nFlg > 0) then
dMaxNotClampableLengthHead = max( ProcessingsOnPart.Rotation[nRotation+nOffsetIndex][nProc].NotClampableLength.dNotClampableLengthHead, dMaxNotClampableLengthHead)
dMaxNotClampableLengthTail = max( ProcessingsOnPart.Rotation[nRotation+nOffsetIndex][nProc].NotClampableLength.dNotClampableLengthTail, dMaxNotClampableLengthTail)
end
end
dMaxNotClampableLength = max( dMaxNotClampableLengthHead, dMaxNotClampableLengthTail)
-- ciclo sulle rotazioni
local nNextRot = nUnloadPos
local ResultsList = {}
local bExecInLastRotation = false
for nRotation = 1, 3 do
-- se rotazione abilitata da combinazione
if string.sub( PartInfo.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
if string.sub( Part.CombinationList[i].sBitIndexCombination, nNextRot, nNextRot) == '1' then
local CurrProc = ProcessingsOnPart.Rotation[nNextRot+nOffsetIndex][nProc]
-- se è ultima rotazione oppure se feature non impatta su misura laser, allora è valida e può essere effettivamente considerata
if nNextRot == nUnloadPos or not( CurrProc.bHindersLaserMeasure) then
-- se non è settata la ChosenStrtegy, provo a cercare comunque tra quelle disponibili
if not CurrProc.ChosenStrategy and bReProcessEmptyChosenStrategy then
CurrProc = GetFeatureBestStrategy( CurrProc, PartInfo)
end
-- se non è settata la ChosenStrategy, provo a cercare comunque tra quelle disponibili
if not CurrProc.ChosenStrategy and bReProcessEmptyChosenStrategy then
CurrProc = GetFeatureBestStrategy( CurrProc, Part)
end
-- si verifica se la feature compromette il pinzaggio
local bIgnoreNotClampableLength = false
if CurrProc.ChosenStrategy then
bIgnoreNotClampableLength = CurrProc.ChosenStrategy.Result.bIgnoreNotClampableLength
end
bExecInLastRotation = ( not bIgnoreNotClampableLength) and FeatureLib.IsMachiningLong( dMaxNotClampableLength, Part)
-- se la feature impatta sulla lettura laser o compromette il pinzaggio è valida solo se fatta in ultima rotazione; negli altri casi è sempre valida
if nNextRot == nUnloadPos or not( CurrProc.bHindersLaserMeasure or bExecInLastRotation) then
-- controllo se è stata scelta una strategia
if CurrProc.ChosenStrategy then
local Proc = {}
@@ -1740,7 +1806,7 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
SingleCombination.nIndexTailCutInVProc = nProc
else
if #ResultsList > 0 then
local Proc, Data = GetProcBestMachRotationFromList( ResultsList, PartInfo)
local Proc, Data = GetProcBestMachRotationFromList( ResultsList, Part)
Proc.nIndexRotation = Data.nIndexRotation
-- inserisco la Proc nell'apposita lista
if Data.nIndexRotation == nUnloadPos then
@@ -1791,7 +1857,7 @@ local function GetCombinationListFromMatrix( ProcessingsOnPart, PartInfo, bRePro
end
-- si calsola il total rating
CombinationsList = FeatureLib.CalculateCombinationsCompositeRating( CombinationsList, PartInfo.GeneralParameters.GEN_sMachiningStrategy)
CombinationsList = FeatureLib.CalculateCombinationsCompositeRating( CombinationsList, Part.GeneralParameters.GEN_sMachiningStrategy)
return CombinationsList
end
@@ -1938,30 +2004,34 @@ function BeamExec.ProcessMachinings( PARTS, bIsFlipRot)
if nRotSplitCut > 4 then
nRotSplitCut = nRotSplitCut - 4
end
local HeadCut = PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc]
local TailCut = PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc]
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
HeadCut.nIndexRotation = nRotHeadCut
TailCut.nIndexRotation = nRotSplitCut
-- si imposta flag rotazione per taglio di testa
if MACHININGS.Info.nHeadCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = true
HeadCut.bSide = true
elseif MACHININGS.Info.nHeadCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = true
HeadCut.bDown = true
else
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = true
HeadCut.bStd = true
end
-- si imposta flag rotazione per taglio di coda
if MACHININGS.Info.nSplitCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = true
TailCut.bSide = true
elseif MACHININGS.Info.nSplitCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = true
TailCut.bDown = true
else
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = true
TailCut.bStd = true
end
local vProcHeadTail = {}
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc])
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc])
table.insert( vProcHeadTail, HeadCut)
table.insert( vProcHeadTail, TailCut)
MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
@@ -2233,40 +2303,55 @@ function BeamExec.ProcessAlternatives( PARTS)
end
-- se serve calcolare posizione per ottimizzazione tagli in nesting (le soluzioni non possono avere ribaltamenti)
-- il pezzo è il posizione 0 in questo momento, ma l'automatismo ha già fatto la prerotazione, se abilitata
-- le combinazioni vanno testate considerando come 0 la posizione preruotata
-- allo stesso modo, le alternative devono considerare come 0 quello preruotato
if PARTS[nPart].GeneralParameters.GEN_bGetAlternativesNesting2D then
-- POSIZIONE 0 (e invertito)
local sCombinationToCheck = BeamLib.StringReplaceChar( '0000', PARTS[nPart].nInitialPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
local sBitIndexCombinationToCheck = BeamLib.StringReplaceChar( '0000', PARTS[nPart].nInitialPosition, "1")
local sBitIndexCombinationToNest = '1000'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
sBitIndexCombinationToNest = '1000_INV'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = not PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
end
-- POSIZIONE 180 (e invertito)
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'STD_PRE_ROTATION' then
local nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 2 > 4, PARTS[nPart].nInitialPosition + 2 - 4, PARTS[nPart].nInitialPosition + 2)
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
sBitIndexCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
sBitIndexCombinationToNest = '0010'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
sBitIndexCombinationToNest = '0010_INV'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = not PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
end
end
-- POSIZIONE 90/270 (e invertito)
if PARTS[nPart].GeneralParameters.GEN_sPiecesLoadingPosition == 'FULL_PRE_ROTATION' then
local nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 1 > 4, PARTS[nPart].nInitialPosition + 1 - 4, PARTS[nPart].nInitialPosition + 1)
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
sBitIndexCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
sBitIndexCombinationToNest = '0100'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
sBitIndexCombinationToNest = '0100_INV'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = not PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
end
nOtherPosition = EgtIf( PARTS[nPart].nInitialPosition + 3 > 4, PARTS[nPart].nInitialPosition + 3 - 4, PARTS[nPart].nInitialPosition + 3)
sCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck}, bIsNesting2D = true})
sBitIndexCombinationToCheck = BeamLib.StringReplaceChar( '0000', nOtherPosition, "1")
sBitIndexCombinationToNest = '0001'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
if PARTS[nPart].GeneralParameters.GEN_bAllowPieceInversion then
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sCombinationToCheck, bPartInCombiIsInverted = true}, bIsNesting2D = true})
sBitIndexCombinationToNest = '0001_INV'
table.insert( TotalCombiToTest, {{ sBitIndexCombination = sBitIndexCombinationToCheck, sBitIndexCombinationToNest = sBitIndexCombinationToNest, bPartInCombiIsInverted = not PARTS[nPart].bPartInCombiIsInverted}, bIsNesting2D = true})
end
end
end
-- informazioni tagli di testa e coda da passare a nesting
PARTS[nPart].HeadcutInfo = {}
PARTS[nPart].TailcutInfo = {}
-- fino a che ci sono soluzioni da testare
for z = 1, #TotalCombiToTest do
-- si svuota il machgroup e si resettano le variabili
@@ -2341,42 +2426,70 @@ function BeamExec.ProcessAlternatives( PARTS)
if nRotSplitCut > 4 then
nRotSplitCut = nRotSplitCut - 4
end
local HeadCut = PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc]
local TailCut = PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc]
local HeadCutOnFirstRotation = PROCESSINGS[nPart].Rotation[1+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc]
local TailCutOnFirstRotation = PROCESSINGS[nPart].Rotation[1+nOffsetIndex][MatrixResult.nIndexTailCutInVProc]
-- setto nella Proc l'indice rotazione nella quale deve essere lavorata
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].nIndexRotation = nRotHeadCut
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].nIndexRotation = nRotSplitCut
HeadCut.nIndexRotation = nRotHeadCut
TailCut.nIndexRotation = nRotSplitCut
-- si imposta flag rotazione per taglio di testa
if MACHININGS.Info.nHeadCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = true
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = nil
HeadCut.bDown = nil
HeadCut.bSide = true
HeadCut.bStd = nil
elseif MACHININGS.Info.nHeadCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = true
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = nil
HeadCut.bDown = true
HeadCut.bSide = nil
HeadCut.bStd = nil
else
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc].bStd = true
HeadCut.bDown = nil
HeadCut.bSide = nil
HeadCut.bStd = true
end
-- si imposta flag rotazione per taglio di coda
if MACHININGS.Info.nSplitCutRotation == 2 then
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = true
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = nil
TailCut.bDown = nil
TailCut.bSide = true
TailCut.bStd = nil
elseif MACHININGS.Info.nSplitCutRotation == 3 then
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = true
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = nil
TailCut.bDown = true
TailCut.bSide = nil
TailCut.bStd = nil
else
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bDown = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bSide = nil
PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc].bStd = true
TailCut.bDown = nil
TailCut.bSide = nil
TailCut.bStd = true
end
local vProcHeadTail = {}
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotHeadCut+nOffsetIndex][MatrixResult.nIndexHeadCutInVProc])
table.insert( vProcHeadTail, PROCESSINGS[nPart].Rotation[nRotSplitCut+nOffsetIndex][MatrixResult.nIndexTailCutInVProc])
table.insert( vProcHeadTail, HeadCut)
table.insert( vProcHeadTail, TailCut)
-- aggiornamento info testa/coda per Nesting
local nRotation = BeamLib.ConvertBitIndexToRotationIndex( BestCombination.sBitIndexCombination)
local HeadcutInfo, TailcutInfo = GetHeadTailInfoForNesting( HeadCutOnFirstRotation, TailCutOnFirstRotation, PARTS[nPart])
if HeadcutInfo then
-- offset e vettori vanno adeguati alla rotazione attuale (inversione è già corretta)
BeamLib.RotateTableFromIndexInPlace( HeadcutInfo.OffsetX, nRotation)
HeadcutInfo.vtN:rotate( X_AX(), ( nRotation - 1) * 90)
PARTS[nPart].HeadcutInfo[BestCombination.sBitIndexCombinationToNest] = {
OffsetX = HeadcutInfo.OffsetX,
vtN = HeadcutInfo.vtN
}
end
if TailcutInfo then
-- offset e vettori vanno adeguati alla rotazione attuale (inversione è già corretta)
BeamLib.RotateTableFromIndexInPlace( TailcutInfo.OffsetX, nRotation)
TailcutInfo.vtN:rotate( X_AX(), ( nRotation - 1) * 90)
PARTS[nPart].TailcutInfo[BestCombination.sBitIndexCombinationToNest] = {
OffsetX = TailcutInfo.OffsetX,
vtN = TailcutInfo.vtN
}
end
MACHININGS = CalculateMachinings( vProcHeadTail, PARTS[nPart], MatrixResult.nInitialPosition)
@@ -2508,11 +2621,10 @@ function BeamExec.ProcessAlternatives( PARTS)
local bApplOk, _, _ = EgtApplyAllMachinings()
-- se non ci sono errori, soluzione alternativa valida: scrittura variabili globali per interfaccia
if bApplOk then
local sBitIndexCombinationWithInvert = BestCombination.sBitIndexCombination .. EgtIf( BestCombination.bPartInCombiIsInverted, '_INV', '')
if TotalCombiToTest[z].bIsNesting2D then
table.insert( AlternativesNest2D, sBitIndexCombinationWithInvert)
table.insert( AlternativesNest2D, BestCombination.sBitIndexCombinationToNest)
else
table.insert( Alternatives, sBitIndexCombinationWithInvert)
table.insert( Alternatives, BestCombination.sBitIndexCombinationToNest)
end
end
-- se ultima combinazione, si esce e non si riporta in posizione iniziale. Verrà infatti cancellata
@@ -2531,17 +2643,15 @@ function BeamExec.ProcessAlternatives( PARTS)
-- 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("%)$", "")
local sOffsetX = table.concat( PARTS[nPart].HeadcutInfo[AlternativesNest2D[i]].OffsetX, ',')
local sVtN = ( tostring( PARTS[nPart].HeadcutInfo[AlternativesNest2D[i]].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("%)$", "")
local sOffsetX = table.concat( PARTS[nPart].TailcutInfo[AlternativesNest2D[i]].OffsetX, ',')
local sVtN = ( tostring( PARTS[nPart].TailcutInfo[AlternativesNest2D[i]].vtN)):gsub("^%(", ""):gsub("%)$", "")
table.insert( BEAM.INFONGEPART, 'ALT' .. AlternativesNest2D[i] .. '_T' .. '=' .. sOffsetX .. ';' .. sVtN)
end
end
+31 -19
View File
@@ -764,7 +764,7 @@ function BeamLib.LoadCustomParametersInStrategy( Proc, Part, CustomParameters, D
if DefaultStrategyParamList.ParameterList[i].sType == 'b' then
UpdatedParameters[DefaultStrategyParamList.ParameterList[i].sName] = xParameterValue == 'true' or xParameterValue == '1' or xParameterValue == true
elseif DefaultStrategyParamList.ParameterList[i].sType == 'd' then
if #DefaultStrategyParamList.ParameterList[i].sValue > 0 then
if #DefaultStrategyParamList.ParameterList[i].sValue > 0 or #xParameterValue > 0 then
UpdatedParameters[DefaultStrategyParamList.ParameterList[i].sName] = tonumber( xParameterValue)
-- stringa vuota equivale a non passare alcun valore (deciderà la strategia)
else
@@ -940,37 +940,49 @@ end
function BeamLib.ConvertBitIndexToRotationIndex( sBitIndexCombination)
local nRotationIndex
if sBitIndexCombination == '1000' then
if EgtStartsWith( sBitIndexCombination, '1000') then
return 1
elseif sBitIndexCombination == '0100' then
elseif EgtStartsWith( sBitIndexCombination, '0100') then
return 2
elseif sBitIndexCombination == '0010' then
elseif EgtStartsWith( sBitIndexCombination, '0010') then
return 3
elseif sBitIndexCombination == '0001' then
elseif EgtStartsWith( 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
-------------------------------------------------------------------------------------------------------------
-- inverte la porzione tra nStartIndex e nEndIndex della tabella passata
local function ReverseTablePortionInPlace( Table, nStartIndex, nEndIndex)
while nStartIndex < nEndIndex do
Table[nStartIndex], Table[nEndIndex] = Table[nEndIndex], Table[nStartIndex]
nStartIndex = nStartIndex + 1
nEndIndex = nEndIndex - 1
end
return Table
end
-------------------------------------------------------------------------------------------------------------
-- reindicizza una tabella passata ripartendo dall'indice nStartIndex e mantenendo l'ordine
function BeamLib.RotateTableFromIndex( Table, nStartIndex)
local RotatedTable = {}
function BeamLib.RotateTableFromIndexInPlace( Table, nStartIndex)
local dLen = #Table
for i = 1, #Table do
RotatedTable[#RotatedTable + 1] = Table[((RotatedTable + i - 2) % #Table) + 1]
end
-- Nessuna rotazione necessaria se la tabella è vuota, ha 1 solo elemento, o la rotazione è dall'indice 1
if dLen <= 1 or nStartIndex <= 1 or nStartIndex > dLen then
return Table
end
return RotatedTable
local k = nStartIndex - 1
ReverseTablePortionInPlace( Table, 1, k) -- 1. Inverte la parte inziale
ReverseTablePortionInPlace( Table, k + 1, dLen) -- 2. Inverte la parte finale
ReverseTablePortionInPlace( Table, 1, dLen) -- 3. Inverte tutto
return Table
end
-------------------------------------------------------------------------------------------------------------
+1 -1
View File
@@ -955,7 +955,7 @@ function FeatureLib.CalculateFeatureNotClampableLengths( Proc, Part)
local dNotClampableLengthTail = 0
-- se il grezzo non è definito, prendo il box del pezzo
-- TODO 1- si sta passando b3part per riferimento, 2- non dovrebbe essre sempre definito?
-- TODO 1- si sta passando b3part per riferimento, è giusto? 2- non dovrebbe essre sempre definito?
if not Part.b3Raw then
Part.b3Raw = Part.b3Part
end
+54 -2
View File
@@ -93,7 +93,7 @@ end
-------------------------------------------------------------------------------------------------------------
local function GetToolAddLength( dToolDiameter, dDepthToMachine)
function LeadInOutLib.GetToolAddLength( dToolDiameter, dDepthToMachine)
local dCheckDepth = min( dToolDiameter / 2, dDepthToMachine)
local dToolAddLength = sqrt( dCheckDepth * dToolDiameter - dCheckDepth * dCheckDepth)
@@ -119,7 +119,7 @@ function LeadInOutLib.CalculateLeadInOut( sLeadInOutType, Parameters, OptionalPa
local bIsEndClosed = not Edge.bIsEndOpen
-- accorciamento per lati chiusi
LeadInOut.dToolAddLength = GetToolAddLength( Tool.dDiameter, dDepthToMachine)
LeadInOut.dToolAddLength = LeadInOutLib.GetToolAddLength( Tool.dDiameter, dDepthToMachine)
LeadInOut.dExtraAddLengthStart, LeadInOut.dExtraAddLengthEnd = GetExtraAddLengthInclinedSides( Face, Edge)
-- allungamento per faccia singola (aperta in tutte le direzioni)
LeadInOut.dAddedLengthOpenFace = BeamData.CUT_EXTRA
@@ -215,6 +215,50 @@ function LeadInOutLib.CalculateLeadInOut( sLeadInOutType, Parameters, OptionalPa
-- punti dell'attacco
LeadIn.ptPoint = Point3d( ptStartAtDepth - Edge.vtEdge * dLeadInLength)
LeadOut.ptPoint = Point3d( ptEndAtDepth + Edge.vtEdge * dLeadOutLength)
elseif sLeadInOutType == 'SpecialTangent' then
-- uscita con componente aggiuntiva perpendicolare
LeadOut.nType = MCH_MILL_LO.PERP_TG
local dStartEndOffset = 10
local ptEndAtDepthWithOffset = ptEndAtDepth + Edge.vtN * dStartEndOffset
local ptEndBladeCenterWithOffset = ptEndBladeCenter + Edge.vtN * dStartEndOffset
-- calcolo distanza per uscire dal box con questa lama nella direzione tangenziale
local dLeadInLength = CalculateLeadInOutLength( ptStartBladeCenter, Face.vtN, b3BoxPartExpanded, -Edge.vtEdge, Tool)
local dLeadOutLength = -CalculateLeadInOutLength( ptEndBladeCenterWithOffset, Face.vtN, b3BoxPartExpanded, -Edge.vtEdge, Tool)
-- componenti dell'attacco
LeadIn.dPerpDistance = 0
LeadIn.dTangentDistance = dLeadInLength
LeadOut.dPerpDistance = dStartEndOffset
LeadOut.dTangentDistance = dLeadOutLength
-- punti dell'attacco
LeadIn.ptPoint = Point3d( ptStartAtDepth - Edge.vtEdge * dLeadInLength)
LeadOut.ptPoint = Point3d( ptEndAtDepthWithOffset + Edge.vtEdge * dLeadOutLength)
elseif sLeadInOutType == 'SpecialTangentInverted' then
-- ingresso con componente aggiuntiva perpendicolare
LeadIn.nType = MCH_MILL_LI.TG_PERP
local dStartEndOffset = 10
local ptStartAtDepthWithOffset = ptStartAtDepth + Edge.vtN * dStartEndOffset
local ptStartBladeCenterWithOffset = ptStartBladeCenter + Edge.vtN * dStartEndOffset
-- calcolo distanza per uscire dal box con questa lama nella direzione tangenziale
local dLeadInLength = -CalculateLeadInOutLength( ptStartBladeCenterWithOffset, Face.vtN, b3BoxPartExpanded, Edge.vtEdge, Tool)
local dLeadOutLength = CalculateLeadInOutLength( ptEndBladeCenter, Face.vtN, b3BoxPartExpanded, Edge.vtEdge, Tool)
-- componenti dell'attacco
LeadIn.dPerpDistance = dStartEndOffset
LeadIn.dTangentDistance = dLeadInLength
LeadOut.dPerpDistance = 0
LeadOut.dTangentDistance = dLeadOutLength
-- punti dell'attacco
LeadIn.ptPoint = Point3d( ptStartAtDepthWithOffset - Edge.vtEdge * dLeadInLength)
LeadOut.ptPoint = Point3d( ptEndAtDepth + Edge.vtEdge * dLeadOutLength)
end
-- lunghezza totale attacco
@@ -233,6 +277,8 @@ function LeadInOutLib.InvertLeadInOut( LeadIn, LeadOut)
local dOriginalStartAddLength = LeadIn.dStartAddLength
local dOriginalEndAddLength = LeadOut.dEndAddLength
local nOriginalLeadInType = LeadIn.nType
local nOriginalLeadOutType = LeadOut.nType
LeadIn, LeadOut = LeadOut, LeadIn
@@ -240,6 +286,12 @@ function LeadInOutLib.InvertLeadInOut( LeadIn, LeadOut)
LeadOut.dEndAddLength = dOriginalStartAddLength
LeadIn.dEndAddLength = nil
LeadOut.dStartAddLength = nil
if nOriginalLeadInType == MCH_MILL_LI.TG_PERP then
LeadOut.nType = MCH_MILL_LO.PERP_TG
end
if nOriginalLeadOutType == MCH_MILL_LO.PERP_TG then
LeadIn.nType = MCH_MILL_LI.TG_PERP
end
return LeadIn, LeadOut
end
+52 -10
View File
@@ -96,16 +96,6 @@ function MachiningLib.CanExtendAfterTail( sCanDamageNextPiece, Part)
return bCanExtendAfterTail
end
-------------------------------------------------------------------------------------------------------------
function MachiningLib.IsFeatureHinderingClamping( Proc, Part)
local bFeatureHindersClamping
local dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail = FeatureLib.GetFeatureMaxNotClampableLengths( Proc, Part)
bFeatureHindersClamping = FeatureLib.IsMachiningLong( max( dFeatureMaxNotClampableLengthHead, dFeatureMaxNotClampableLengthTail), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
return bFeatureHindersClamping
end
-------------------------------------------------------------------------------------------------------------
function MachiningLib.GetMachiningSteps( bIsSlot, dMachiningDepth, dStep)
local MachiningSteps = {}
@@ -203,12 +193,17 @@ function MachiningLib.GetSplitMachinings( Machinings, SplittingPoints, Part)
end
if not bIsLastSegment then
Machinings[nCurrentMachiningIndex].sStage = ''
Machinings[nCurrentMachiningIndex].nSCC = MCH_SCC.ADIR_XP
else
Machinings[nCurrentMachiningIndex].sStage = sOriginalStage
Machinings[nCurrentMachiningIndex].nSCC = MCH_SCC.ADIR_XM
end
Machinings[nCurrentMachiningIndex].nFeatureSegment = j
Machinings[nCurrentMachiningIndex].dLengthToMachine = Machinings[nCurrentMachiningIndex].dEdgeLength + Machinings[nCurrentMachiningIndex].LeadIn.dStartAddLength + Machinings[nCurrentMachiningIndex].LeadOut.dEndAddLength
Machinings[nCurrentMachiningIndex].dTimeToMachine = MachiningLib.GetTimeToMachineAllStepsWithLeadInOut( Machinings[nCurrentMachiningIndex], Part)
Machinings[nCurrentMachiningIndex].bIsFirstSegment = ( j == 1)
Machinings[nCurrentMachiningIndex].bIsLastSegment = bIsLastSegment
Machinings[nCurrentMachiningIndex].bIsMachiningSplitted = true
end
-- anche le lavorazioni non splittate necessitano del segmento assegnato
else
@@ -411,6 +406,53 @@ local function TestEngagement( sBladeEngagement, Parameters, OptionalParameters)
end
end
-- se attacco tangenziale standard non possibile si prova l'attacco tangenziale speciale tutto da un lato
if not LeadInOut.Tangent then
-- prima si prova l'invertito (il più frequente)
TangentLeadInOut = LeadInOutLib.CalculateLeadInOut( 'SpecialTangentInverted', Parameters, LeadInOutOptionalParameters)
-- check extracorsa nei punti di attacco
PointsOnToolTipCenter = {
PreSimulationLib.GetPointOnToolTipCenter( TangentLeadInOut.LeadIn.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool),
PreSimulationLib.GetPointOnToolTipCenter( TangentLeadInOut.LeadOut.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool)
}
bOutOfStrokeTangent = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
-- attacco tangenziale non in extracorsa: si verifica se è in collisione
if not bOutOfStrokeTangent then
CheckCollisionOptionalParameters.PointsToCheck = {}
table.insert( CheckCollisionOptionalParameters.PointsToCheck, TangentLeadInOut.LeadIn.ptPoint)
table.insert( CheckCollisionOptionalParameters.PointsToCheck, TangentLeadInOut.LeadOut.ptPoint)
local bCollisionFoundTangent, bMoveAfterSplitTangent = PreSimulationLib.CheckCollision( CheckCollisionParameters, CheckCollisionOptionalParameters)
-- attacco tangenziale possibile
if not bCollisionFoundTangent then
LeadInOut.Tangent = TangentLeadInOut
LeadInOut.Tangent.bMoveAfterSplit = bMoveAfterSplitTangent
end
end
if not LeadInOut.Tangent then
-- se speciale invertito non applicabile si prova lo speciale non invertito
TangentLeadInOut = LeadInOutLib.CalculateLeadInOut( 'SpecialTangent', Parameters, LeadInOutOptionalParameters)
-- check extracorsa nei punti di attacco
PointsOnToolTipCenter = {
PreSimulationLib.GetPointOnToolTipCenter( TangentLeadInOut.LeadIn.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool),
PreSimulationLib.GetPointOnToolTipCenter( TangentLeadInOut.LeadOut.ptPoint, vtHead, Face.vtN, Edge.vtN, Tool)
}
bOutOfStrokeTangent = PreSimulationLib.CheckOutOfStrokeFromPoints( PointsOnToolTipCenter, vtHead, nSCC, Tool)
-- attacco tangenziale non in extracorsa: si verifica se è in collisione
if not bOutOfStrokeTangent then
CheckCollisionOptionalParameters.PointsToCheck = {}
table.insert( CheckCollisionOptionalParameters.PointsToCheck, TangentLeadInOut.LeadIn.ptPoint)
table.insert( CheckCollisionOptionalParameters.PointsToCheck, TangentLeadInOut.LeadOut.ptPoint)
local bCollisionFoundTangent, bMoveAfterSplitTangent = PreSimulationLib.CheckCollision( CheckCollisionParameters, CheckCollisionOptionalParameters)
-- attacco tangenziale possibile
if not bCollisionFoundTangent then
LeadInOut.Tangent = TangentLeadInOut
LeadInOut.Tangent.bMoveAfterSplit = bMoveAfterSplitTangent
end
end
end
end
-- se disponibili più attacchi si sceglie il più corto, altrimenti quello possibile
if LeadInOut.Perpendicular and LeadInOut.Tangent then
if LeadInOut.Perpendicular.dTotalLength > LeadInOut.Tangent.dTotalLength + 10 then
+5 -1
View File
@@ -403,6 +403,7 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
local sRestLengthSideForPreSimulation = OptionalParameters.sRestLengthSideForPreSimulation or 'Tail'
local bCannotSplitRestLength = OptionalParameters.bCannotSplitRestLength or false
local vtAux = OptionalParameters.vtAux
local bCheckFlange = OptionalParameters.bCheckFlange
-- se normale faccia non parallela a direzione testa c'è qualcosa che non va
if not AreSameOrOppositeVectorApprox( vtNFace, vtHead) then
@@ -426,7 +427,7 @@ local function CheckCollisionWithAxis( sAxis, MachiningParameters, OptionalParam
-- se lama con flangia si aggiunge quest'ultima ai solidi di collisione, ipotizzandola grande fino al dMaxDepth + sicurezza
local idAddedCollisionSurfTm
if Tool.sType == 'SAW_FLAT' then
if bCheckFlange and Tool.sType == 'SAW_FLAT' then
local ptCenterFlange = PointsOnToolTipCenter[i] + vtHead * Tool.dThickness
local frHead = Frame3d( ptCenterFlange, vtHead)
local dExtraSafety = 2 -- valore empirico che serve nei casi molto inclinati, ci potrebbero essere casi in cui va aumentato
@@ -532,7 +533,10 @@ function PreSimulationLib.CheckCollision( Parameters, OptionalParameters)
local sR1 = AxesNames[4]
-- ultimo asse lineare prima dei rotativi (solitamente Z) si controlla sempre
-- qui si controlla anche la collisione con flangia lama, se necessario
OptionalParametersCheckCollisionWithAxis.bCheckFlange = true
bCollisionFound, bMoveAfterSplitL3 = CheckCollisionWithAxis( sL3, Parameters, OptionalParametersCheckCollisionWithAxis)
OptionalParametersCheckCollisionWithAxis.bCheckFlange = false
if sR3 and not bCollisionFound then
bCollisionFound, bMoveAfterSplitR3 = CheckCollisionWithAxis( sR3, Parameters, OptionalParametersCheckCollisionWithAxis)
+4
View File
@@ -319,4 +319,8 @@
1000316=Autocam will apply a machining on the theoretical zero, to avoid collision if the theoretical piece length doesn't correspond to the real length
1000317=Finish with mill
1000318=Use a mill to finish the surface if split with chain saw
1000319=Allow multiple short strips
1000320=Allow multiple short strips
1000321=Length limit to drop the waste
1000322=If Cutting Strategy is set on AUTO, up to this length the software drop the waste, otherwise it'll keep attached
// ----- End -----
+4
View File
@@ -319,4 +319,8 @@
1000316=Autocam applicherà una lavorazione sullo zero teorico per evitare collisioni se la lunghezza teorica del pezzo non corrisponde alla lunghezza reale
1000317=Finisci con la fresa
1000318=Utilizza una fresa per rifinire la superficie se tagliata con la sega a catena
1000319=Permettere codoli multipli
1000320=Permettere codoli multipli
1000321=Lunghezza limite fino alla quale lo scarto viene staccato
1000322=Se la strategia di taglio è impostata su AUTO, fino a questa lunghezza il software stacca gli scarti, altrimenti li mantiene attaccati
// ----- End -----
+4
View File
@@ -319,4 +319,8 @@
1000316=Autocam past een bewerking toe op het theoretische nulpunt om botsingen te voorkomen als de theoretische lengte niet overeenkomt met de werkelijke lengte
1000317=Afwerken met frees
1000318=Gebruik een frees om het oppervlak na te bewerken als dit met de kettingzaag is gespleten
1000319=Sta meerdere korte verbindingsstrips toe
1000320=Sta meerdere korte verbindingsstrips toe
1000321=Maximale lengte voor het uitwerpen van het reststuk
1000322=Als de snijstrategie op AUTO staat, wordt het reststuk tot deze maximale lengte automatisch uitgeworpen; bij grotere lengtes blijft het reststuk aan het werkstuk bevestigd.
// ----- End -----
+124 -9
View File
@@ -223,7 +223,8 @@ function PartTemplates:AddPart( id)
end
-- info eventuali rotazioni / inversioni custom e forzature manuali
local bIsManualFlipRot = ( ( EgtGetInfo( id, 'MANUALROT', 'i') or 0) == 1) or ( ( EgtGetInfo( id, 'MANUALFLIP', 'i') or 0) == 1)
-- TODO ignorare gli stati calcolati porta a problemi, valutare se eliminare del tutto la dipendenza da bIsManualFlipRot
--local bIsManualFlipRot = ( ( EgtGetInfo( id, 'MANUALROT', 'i') or 0) == 1) or ( ( EgtGetInfo( id, 'MANUALFLIP', 'i') or 0) == 1)
if not bIsManualFlipRot then
@@ -392,7 +393,8 @@ local function CalculateMove( Beam, dPartLength, sState, State)
end
-- Bonus Shared Cut: se le normali sono opposte, si risparmia un taglio/posizionamento
if AreOppositeVectorApprox( Beam.LastVtN, State.Tail.vtN) then
local bSharedCut = AreOppositeVectorApprox( Beam.LastVtN, State.Tail.vtN)
if bSharedCut then
dScore = dScore + CONFIG.BONUS_SHARED_CUT
end
@@ -405,7 +407,8 @@ local function CalculateMove( Beam, dPartLength, sState, State)
sState = sState,
dScore = dScore,
dSafeOverlap = dSafeOverlap,
dFutureResidualLength = dFutureResidualLength
dFutureResidualLength = dFutureResidualLength,
bSharedCut = bSharedCut
}
return Move
end
@@ -527,13 +530,110 @@ local function CommitBestMove( BestMove)
sState = BestMove.sState,
dSafeOverlap = BestMove.dSafeOverlap,
dLength = Template.dLength,
dPosX = BestMove.dFutureResidualLength
dPosX = BestMove.dFutureResidualLength,
bSharedCut = BestMove.bSharedCut
})
-- chiusura job
Job.bNested = true
end
----------------------------------------------------------------------------------------------------------
-- Dump diagnostico Input/Output
function RawInventory:DumpNestingData()
EgtOutLog("\n##########################################################################################")
EgtOutLog("### EGALWARE NESTING - DIAGNOSTIC DUMP ###")
EgtOutLog("##########################################################################################\n")
-- 1. AMBIENTE & CONFIGURAZIONE
EgtOutLog("--- [1. NESTING ENVIRONMENT & PARAMETERS] ---")
EgtOutLog(string.format("NEST.STARTOFFSET = %s", tostring(NEST.STARTOFFSET)))
EgtOutLog(string.format("NEST.MATERIAL = %s", tostring(NEST.MATERIAL)))
EgtOutLog(string.format("NEST.MACHINE = %s", tostring(NEST.MACHINE)))
for k, v in pairs(CONFIG) do
EgtOutLog(string.format("CONFIG.%s = %s", tostring(k), tostring(v)))
end
-- 2. MATERIALE DISPONIBILE (STOCK)
EgtOutLog("\n--- [2. RAW STOCK INVENTORY INPUTS] ---")
for i = 1, #self.Stock do
EgtOutLog(string.format("Stock Index %d: Length = %.4f mm | Qty Available = %d", i, self.Stock[i].dLength, self.Stock[i].nCount))
end
-- 3. COMMESSA PEZZI RICHIESTI (DEMANDED PARTS)
EgtOutLog("\n--- [3. DEMANDED PARTS (PART TABLE)] ---")
for id, count in pairs(PART) do
local sInitialPos = tostring(EgtGetInfo(id, 'INITIALPOSITION', 'i') or 0)
local sManualRot = tostring(EgtGetInfo(id, 'MANUALROT', 'i') or 0)
local sManualFlip = tostring(EgtGetInfo(id, 'MANUALFLIP', 'i') or 0)
EgtOutLog(string.format("Part ID: %5s | Demand Count: %d | CAD Base Length: %.4f mm | InitialPos: %s | ManualRot: %s | ManualFlip: %s",
tostring(id), count, EgtGetInfo(id, 'L', 'd') or 0, sInitialPos, sManualRot, sManualFlip))
end
-- 4. DATABASE GEOMETRICO COMPLETO (PART TEMPLATES)
EgtOutLog("\n--- [4. DETAILED GEOMETRIC TEMPLATES (ALL READABLE STATES)] ---")
for id, Template in pairs(PartTemplates) do
if type(Template) == "table" and Template.dLength then
EgtOutLog(string.format("\nPART ID: %s | Math Length: %.4f | MaxGlobalTailRecess: %.4f", tostring(id), Template.dLength, Template.dMaxGlobalTailRecess))
for sState, State in pairs(Template.States) do
EgtOutLog(string.format(" -> State [%s]:", sState))
-- Stringhe Grezze lette dal CAD
EgtOutLog(string.format(" Raw ALT_H String: %s", tostring(EgtGetInfo(id, 'ALT'..sState..'_H'))))
EgtOutLog(string.format(" Raw ALT_T String: %s", tostring(EgtGetInfo(id, 'ALT'..sState..'_T'))))
-- Valori matematici interpretati dal Nesting
local hOX = table.concat(State.Head.OffsetX, ", ")
local tOX = table.concat(State.Tail.OffsetX, ", ")
EgtOutLog(string.format(" HEAD Math -> OffsetX: [%s] | vtN: [X:%.6f, Y:%.6f, Z:%.6f] | vtNXabs: %.6f | dMaxHeadRecess: %.4f",
hOX, State.Head.vtN:getX(), State.Head.vtN:getY(), State.Head.vtN:getZ(), State.Head.vtNXabs, State.dMaxHeadRecess))
EgtOutLog(string.format(" TAIL Math -> OffsetX: [%s] | vtN: [X:%.6f, Y:%.6f, Z:%.6f] | vtNXabs: %.6f | dMaxTailRecess: %.4f",
tOX, State.Tail.vtN:getX(), State.Tail.vtN:getY(), State.Tail.vtN:getZ(), State.Tail.vtNXabs, State.dMaxTailRecess))
end
end
end
-- 5. ANALISI DETTAGLIATA DELL'OUTPUT FINALE SULLE BARRE (ACTIVE BEAMS)
EgtOutLog("\n--- [5. FINAL NESTING SOLUTIONS AND SPATIAL COORDS] ---")
for i = 1, #self.ActiveBeams do
local Beam = self.ActiveBeams[i]
local dStartOffset = NEST.STARTOFFSET or 0
EgtOutLog(string.format("\n=========================================================================================="))
EgtOutLog(string.format("ACTIVE BEAM [%d] -> Total Length: %.4f mm | Nesting Residual Space: %.4f mm",
i, Beam.dTotalLength, Beam.dResidualLength))
EgtOutLog(string.format("=========================================================================================="))
-- Ordine di Nesting (dall'ultimo appoggio a destra fino a sinistra)
EgtOutLog(" A. Array Storage Order (Nesting Logic - from Right to Left):")
for j = 1, #Beam.NestedParts do
local Part = Beam.NestedParts[j]
EgtOutLog(string.format(" [%d] ID: %5s | State: %12s | Length: %9.4f | Math PosX: %9.4f | Overlap: %9.4f | SharedCut: %s",
j, tostring(Part.id), tostring(Part.sState), Part.dLength, Part.dPosX, Part.dSafeOverlap, tostring(Part.bSharedCut)))
end
-- Ordine di posizionamento sul Gruppo Macchina (da Sinistra X=0 a Destra)
EgtOutLog(" B. CAD Positioning Order (Output Macro - from Left X=0 to Right):")
local nIndex = 1
for j = #Beam.NestedParts, 1, -1 do
local Part = Beam.NestedParts[j]
local dPosX = Part.dPosX - Beam.dResidualLength + dStartOffset
-- Distanza dal pezzo precedente a sinistra (se esiste)
local sPrevDist = "N/A (First Part on Left)"
if j < #Beam.NestedParts then
local PrevPart = Beam.NestedParts[j+1]
local dPrevPosX = PrevPart.dPosX - Beam.dResidualLength + dStartOffset
sPrevDist = string.format("%.4f mm", dPosX - dPrevPosX)
end
EgtOutLog(string.format(" PART%d -> ID: %5s | Chosen State: %12s | CAD Target PosX: %9.4f mm | Gap from left: %s",
nIndex, tostring(Part.id), tostring(Part.sState), dPosX, sPrevDist))
nIndex = nIndex + 1
end
end
EgtOutLog("\n##########################################################################################")
EgtOutLog("### END OF DUMP ###")
EgtOutLog("##########################################################################################\n")
end
----------------------------------------------------------------------------------------------------------
-- script principale
@@ -625,9 +725,10 @@ for i = 1, #RawInventory.ActiveBeams do
-- Spostamento pezzi verso la testa della barra e aggiunta duplo
local nIndex = 1
local bSkipNextHeadCut = false
for j = #Beam.NestedParts, 1, -1 do
local Part = Beam.NestedParts[j]
local nInitialPosition = EgtGetInfo( Part.id, 'INITIALPOSITION', 'i')
-- spostamento verso la testa della barra
local dPosX = Part.dPosX - Beam.dResidualLength + dStartOffset
@@ -635,9 +736,14 @@ for i = 1, #RawInventory.ActiveBeams do
-- copia del pezzo (aggiunta duplo)
local idDuplo = EgtDuploNew( Part.id)
-- pezzo già intestato dal Tailcut precedente: si segnala all'automatismo che si può saltare Headcut
if bSkipNextHeadCut then
EgtSetInfo( idDuplo, "SKIP_HEADCUT", 1)
end
-- eventuale rotazione
if ( EgtStartsWith( Part.sState, '0010') and nInitialPosition == 1)
or ( EgtStartsWith( Part.sState, '1000') and nInitialPosition == 3) then
local bIsRotationNeeded = EgtStartsWith( Part.sState, '0010')
if bIsRotationNeeded then
local idSurfTmBoxDuplo = EgtGetFirstNameInGroup( idDuplo, "Box")
local b3Duplo = EgtGetBBoxGlob( idSurfTmBoxDuplo, GDB_BB.STANDARD)
EgtRotate( idDuplo, b3Duplo:getCenter(), X_AX(), 180, GDB_RT.GLOB)
@@ -645,7 +751,9 @@ for i = 1, #RawInventory.ActiveBeams do
end
-- eventuale inversione
if EgtEndsWith( Part.sState, 'INV') then
-- TODO conta anche l'ordine rotazione-inversione?
local bIsInversionNeeded = EgtEndsWith( Part.sState, 'INV')
if bIsInversionNeeded then
local idSurfTmBoxDuplo = EgtGetFirstNameInGroup( idDuplo, "Box")
local b3Duplo = EgtGetBBoxGlob( idSurfTmBoxDuplo, GDB_BB.STANDARD)
EgtRotate( idDuplo, b3Duplo:getCenter(), Z_AX(), 180, GDB_RT.GLOB)
@@ -656,6 +764,8 @@ for i = 1, #RawInventory.ActiveBeams do
EgtSetInfo( idMachGroup, "PART" .. nIndex, idDuplo .. "," .. dPosX)
nIndex = nIndex + 1
bSkipNextHeadCut = Part.bSharedCut
end
end
@@ -693,4 +803,9 @@ EgtResetCurrMachGroup()
NEST.ERR = 0
-- calcolo bontà soluzione
RawInventory:PrintDiagnosticReport()
RawInventory:PrintDiagnosticReport()
-- Dump diagnostico - solo per debug
if EgtGetDebugLevel() >= 3 then
RawInventory:DumpNestingData()
end
+40
View File
@@ -108,6 +108,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -151,6 +155,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -196,6 +204,10 @@
{ "sName": "Rabbet-2-Through",
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
}
]
},
@@ -224,6 +236,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -271,6 +287,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -314,6 +334,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -368,6 +392,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -455,6 +483,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -520,6 +552,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
@@ -575,6 +611,10 @@
"sImage": "ConfigStrategy\\Rabbet-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "VGroove-2-Through",
"sImage": "ConfigStrategy\\VGroove-2-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" }, { "sStrategyId": "STR0010"} ]
},
{ "sName": "Cut-1-Through",
"sImage": "ConfigStrategy\\Cut-1-Through.png",
"StrategyList" : [ { "sStrategyId": "STR0002" }, { "sStrategyId": "STR0005" } ]
+35 -28
View File
@@ -22,6 +22,31 @@ local function MakeChamfer()
-- TODO funzionalità da aggiungere
end
-------------------------------------------------------------------------------------------------------------
local function CalculateHeadCut( Proc, Part)
-- si recuperano gli estremi del box del materiale di testa da togliere
local b3PartWithHead = BeamLib.GetPartBoxWithHeadTail( Part, 'Head')
local ptStartRestLength = Point3d( Part.b3Part:getMax():getX() - 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
local ptEndRestLength = Point3d( b3PartWithHead:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
local OptionalParametersBladeToWaste = {}
OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength)
OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath
OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Head'
OptionalParametersBladeToWaste.bCannotSplitRestLength = true
local Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
-- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti)
if ( not Machinings) or ( #Machinings == 0) then
OptionalParametersBladeToWaste.bReduceBladePath = true
Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
end
return Machinings
end
-------------------------------------------------------------------------------------------------------------
function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
local StrategyLib = {}
@@ -47,7 +72,7 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
end
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then
if Strategy.Parameters.bExecutePreCut or not Proc.bIsOriginalHeadcut then
Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters)
-- se non faccio tagli PRECUT, imposto tabella Result direttamente. Non serve verificare che riesca a rimuovere il materiale extra
-- if not Strategy.SplitStrategy or #Strategy.SplitStrategy == 0 then
@@ -65,8 +90,9 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- TODO di quale utensile si deve impostare la qualità qui?
Strategy.Result.dQuality = FeatureLib.GetStrategyQuality( 'SAWBLADE')
-- se coincide con inizio grezzo, non va fatto
if abs( Proc.b3Box:getCenter():getX() - Part.b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL then
-- se settato da saltare o coincide con inizio grezzo, non va fatto
local bSkipHeadCut = ( EgtGetInfo( Part.id, "SKIP_HEADCUT", 'i') or 0) == 1
if bSkipHeadCut or ( abs( Proc.b3Box:getCenter():getX() - Part.b3Raw:getMax():getX()) < 10 * GEO.EPS_SMALL) then
return true, Strategy.Result
end
@@ -80,16 +106,14 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
local MachiningsToAdd = {}
local bExecutePrecutOnly = false
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then
bExecutePrecutOnly = Part.dHeadOverMaterial < 20
if Strategy.Parameters.bExecutePreCut or not Proc.bIsOriginalHeadcut then
bExecutePrecutOnly = ( Part.dHeadOverMaterial < 20) or not Proc.bIsOriginalHeadcut
if Strategy.SplitStrategy and #Strategy.SplitStrategy > 0 then
for i = 1, #Strategy.SplitStrategy do
local TempList = {}
TempList = Strategy.SplitStrategy[i]
if bExecutePrecutOnly then
TempList.dLongitudinalOffset = 0
else
if not bExecutePrecutOnly then
TempList.bIsPreCut = true
TempList.dLongitudinalOffset = Part.dHeadOverMaterial
end
@@ -101,25 +125,8 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
if not bExecutePrecutOnly then
-- si recuperano gli estremi del box del materiale di testa da togliere
local b3PartWithHead = BeamLib.GetPartBoxWithHeadTail( Part, 'Head')
local ptStartRestLength = Point3d( Part.b3Part:getMax():getX() - 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
local ptEndRestLength = Point3d( b3PartWithHead:getMax():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
Strategy.Machining = CalculateHeadCut( Proc, Part)
local OptionalParametersBladeToWaste = {}
OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength)
OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath
OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Head'
OptionalParametersBladeToWaste.bCannotSplitRestLength = true
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
-- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti)
if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then
OptionalParametersBladeToWaste.bReduceBladePath = true
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
end
if Strategy.Machining and #Strategy.Machining > 0 then
for i = 1, #Strategy.Machining do
local TempList = {}
@@ -139,9 +146,9 @@ function HEADCUT.Make( bAddMachining, Proc, Part, CustomParameters)
end
return bAreAllMachiningsAdded, Strategy.Result
else
return nil, Strategy.Result
end
return nil, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
+1 -1
View File
@@ -596,7 +596,7 @@ function STR0002.Make( bAddMachining, Proc, Part, CustomParameters)
return false, Strategy.Result
end
-- se la lavorazione ostacola il pinzaggio, non posso farla, serve una lavorazioen che lasci il testimone
if MachiningLib.IsFeatureHinderingClamping( Proc, Part) then
if Proc.bFeatureHindersClamping then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable ( Feature hinders clamping)'
EgtOutLog( sErr)
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
+6 -17
View File
@@ -360,10 +360,15 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
-- non ha senso che STR0003 lama+catena sia applicabile se la lama non può lavorare, in quel caso deve essere scelta la STR0004 solo catena
else
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
Strategy.Parameters.bFinishWithChainSaw = false
end
return bAreAllMachiningsAdded, Strategy.Result
else
-- non ha senso che STR0003 lama+catena sia applicabile se la lama non può lavorare, in quel caso deve essere scelta la STR0004 solo catena
if #Blade.Result.Sorted == 0 then
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable()
return false, Strategy.Result
end
end
-- TODO funzione separata
@@ -406,12 +411,8 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
-- si lavora tutto il fondo
else
OptionalParameters.dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters.dMaxElev = nil
end
-- ancora materiale residuo - se possibile si lavora dal lato
@@ -452,14 +453,12 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
end
if BottomEdge.bIsStartOpen then
OptionalParameters.dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA
OptionalParameters.OppositeToolDirectionMode = 'Enabled'
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters)
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine)
elseif BottomEdge.bIsEndOpen then
OptionalParameters.dMaxElev = dBladeResidualDepth + BeamData.CUT_EXTRA
OptionalParameters.OppositeToolDirectionMode = 'Enabled'
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters)
@@ -475,12 +474,8 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
if Blade.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then
-- si lavora tutto il fondo
OptionalParameters.dMaxElev = Blade.Result.Bottom[1].dResidualDepth + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, BottomEdge, OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters.dMaxElev = nil
-- ancora materiale residuo - si lavorano i lati
if Chainsaw.Result.Bottom[1].dResidualDepth > 10 * GEO.EPS_SMALL then
@@ -531,7 +526,6 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
else
OptionalParameters.dDepthToMachine = SideEdge1.dElevation + BeamData.CUT_EXTRA
OptionalParameters.dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA
OptionalParameters.OppositeToolDirectionMode = 'Enabled'
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters)
@@ -544,14 +538,12 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
Chainsaw.Result.Side[1].bIsApplicable = false
OptionalParameters.dDepthToMachine = SideEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN
OptionalParameters.dMaxElev = Blade.Result.Side[1].dResidualDepth + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge1, OptionalParameters)
Mortising.dAreaToMachine = Mortising.dDepthToMachine * ( Mortising.dEdgeLength - Chainsaw.Result.Bottom[1].dDepthToMachine)
Chainsaw.AddResult( Mortising)
OptionalParameters.dDepthToMachine = SideEdge2.dElevation / 2 + BeamData.CUT_EXTRA_MIN
OptionalParameters.dMaxElev = Blade.Result.Side[2].dResidualDepth + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, SideEdge2, OptionalParameters)
Mortising.dAreaToMachine = 0
@@ -633,7 +625,6 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
-- si lavora tutto il lato
else
OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation + BeamData.CUT_EXTRA
OptionalParameters.dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters)
Chainsaw.AddResult( Mortising)
@@ -643,13 +634,11 @@ function STR0003.Make( bAddMachining, Proc, Part, CustomParameters)
Chainsaw.Result.Opposite[1].bIsApplicable = false
OptionalParameters.dDepthToMachine = OppositeEdge1.dElevation / 2 + BeamData.CUT_EXTRA_MIN
OptionalParameters.dMaxElev = Blade.Result.Opposite[1].dResidualDepth + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge1, OptionalParameters)
Chainsaw.AddResult( Mortising)
OptionalParameters.dDepthToMachine = OppositeEdge2.dElevation / 2 + BeamData.CUT_EXTRA_MIN
OptionalParameters.dMaxElev = Blade.Result.Opposite[2].dResidualDepth + BeamData.CUT_EXTRA
Mortising = FaceByChainsaw.Make( Proc, Part, LongFace, OppositeEdge2, OptionalParameters)
Chainsaw.AddResult( Mortising)
+24
View File
@@ -100,6 +100,18 @@
}
]
},
{
"sName": "dLengthLimitToDropWaste",
"sNameNge": "LEN_DROP_WASTE",
"sValue": "",
"sDescriptionShort": "Length limit to drop the waste",
"sDescriptionLong": "If Cutting Strategy is set on AUTO, up to this length the software drop the waste, otherwise it'll keep attached",
"idDescriptionShortMsg": 1000321,
"idDescriptionLongMsg": 1000322,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bDisableDicing",
"sNameNge": "DISABLE_DICING",
@@ -136,6 +148,18 @@
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bAllowPerpendicularStrip",
"sNameNge": "ALLOW_PERPENDICULAR_STRIP",
"sValue": "false",
"sDescriptionShort": "Allow multiple short strips",
"sDescriptionLong": "Allow multiple short strips",
"idDescriptionShortMsg": 1000319,
"idDescriptionLongMsg": 1000320,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bFinishWithMill",
"sNameNge": "ALLOW_FINISH_MILL",
+9 -4
View File
@@ -100,19 +100,24 @@ function STR0005.Make( bAddMachining, Proc, Part, CustomParameters)
-- considerazioni necessarie a determinare se lavorare con codolo oppure no
local bKeepWasteAttached = ( Strategy.Parameters.sCuttingStrategy == 'KEEP_WASTE_ATTACHED')
local bDropWaste = ( Strategy.Parameters.sCuttingStrategy == 'DROP_WASTE')
local bFeatureHindersClamping = MachiningLib.IsFeatureHinderingClamping( Proc, Part)
local dLengthLimitToDropWaste = Strategy.Parameters.dLengthLimitToDropWaste
local bIsFeatureLong = FeatureLib.IsMachiningLong( Proc.b3Box:getDimX(), Part, { dMaxSegmentLength = BeamData.LONGCUT_ENDLEN})
local bIsTwoFacesCommonEdgeTooLong = ( ( Proc.Topology and ( Proc.Topology.sName == 'Rabbet-2-Through' or Proc.Topology.sName == 'Bevel-2-Blind')) and IsTwoFacesCommonEdgeTooLong( Proc, Part))
-- lavorazione con codolo
if ( Proc.nFct > 2 and bIsFeatureLong)
or ( bFeatureHindersClamping and not bDropWaste)
or ( Proc.bFeatureHindersClamping and not bDropWaste)
or ( dLengthLimitToDropWaste and Proc.b3Box:getDimX() > dLengthLimitToDropWaste)
or bKeepWasteAttached then
local BladeKeepWasteResult
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = Strategy.Parameters.dStripWidth, bForced = bKeepWasteAttached}
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail,
dStripWidth = Strategy.Parameters.dStripWidth,
bAllowPerpendicularStrip = Strategy.Parameters.bAllowPerpendicularStrip,
bFinishWithMill = Strategy.Parameters.bFinishWithMill,
bForced = bKeepWasteAttached
}
AuxiliaryData.bIgnoreNotClampableLength = true
Blade.Result, BladeKeepWasteResult = BladeKeepWaste.Make( Proc, Part, OptionalParameters)
dTimeToMachine = BladeKeepWasteResult.dTimeToMachine
+2 -2
View File
@@ -214,8 +214,8 @@ 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
if MachiningLib.IsFeatureHinderingClamping( Proc, Part) then
-- se la lavorazione ostacola il pinzaggio non posso farla, serve una lavorazioen che lasci il testimone
if Proc.bFeatureHindersClamping then
local sErr = 'Feature '.. Proc.idFeature .. ' : strategy ' .. StrategyLib.Config.sStrategyId .. ' not applicable ( Feature hinders clamping)'
EgtOutLog( sErr)
Strategy.Result = FeatureLib.GetStrategyResultNotApplicable( sErr)
+73
View File
@@ -14,6 +14,55 @@
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "sCuttingStrategy",
"sNameNge": "CUTTING_STRATEGY",
"sValue": "AUTO",
"sDescriptionShort": "Cutting strategy",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000117,
"idDescriptionLongMsg": 1000118,
"sType": "combo",
"sMinUserLevel": "1",
"Choices": [
{
"sValue": "AUTO",
"sDescriptionShort": "Automatic",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000119,
"idDescriptionLongMsg": 1000120,
"sMessageId": ""
},
{
"sValue": "DROP_WASTE",
"sDescriptionShort": "Drop waste",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000121,
"idDescriptionLongMsg": 1000122,
"sMessageId": ""
},
{
"sValue": "KEEP_WASTE_ATTACHED",
"sDescriptionShort": "Keep waste attached",
"sDescriptionLong": "",
"idDescriptionShortMsg": 1000123,
"idDescriptionLongMsg": 1000124,
"sMessageId": ""
}
]
},
{
"sName": "dLengthLimitToDropWaste",
"sNameNge": "LEN_DROP_WASTE",
"sValue": "",
"sDescriptionShort": "Length limit to drop the waste",
"sDescriptionLong": "If Cutting Strategy is set on AUTO, up to this length the software drop the waste, otherwise it'll keep attached",
"idDescriptionShortMsg": 1000321,
"idDescriptionLongMsg": 1000322,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "sCanDamageNextPiece",
"sNameNge": "DAMAGE_NEXT_PIECE",
@@ -88,6 +137,30 @@
}
]
},
{
"sName": "dStripWidth",
"sNameNge": "STRIP_WIDTH",
"sValue": "5",
"sDescriptionShort": "Strip width",
"sDescriptionLong": "In case the waste is still kept attached, this is the wigth dimension of the strip",
"idDescriptionShortMsg": 1000129,
"idDescriptionLongMsg": 1000130,
"sType": "d",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "bAllowPerpendicularStrip",
"sNameNge": "ALLOW_PERPENDICULAR_STRIP",
"sValue": "false",
"sDescriptionShort": "Allow multiple short strips",
"sDescriptionLong": "Allow multiple short strips",
"idDescriptionShortMsg": 1000319,
"idDescriptionLongMsg": 1000320,
"sType": "b",
"sMessageId": " ",
"sMinUserLevel": "1"
},
{
"sName": "dMaxWasteLength",
"sSource": "GEN_dMaxWasteLength",
+10 -7
View File
@@ -94,14 +94,17 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters)
-- considerazioni necessarie a determinare se lavorare con codolo oppure no
local bKeepWasteAttached = ( Strategy.Parameters.sCuttingStrategy == 'KEEP_WASTE_ATTACHED')
local bDropWaste = ( Strategy.Parameters.sCuttingStrategy == 'DROP_WASTE')
local bFeatureHindersClamping = MachiningLib.IsFeatureHinderingClamping( Proc, Part)
local dLengthLimitToDropWaste = Strategy.Parameters.dLengthLimitToDropWaste
-- lavorazione con codolo
if ( bFeatureHindersClamping and not bDropWaste)
if ( Proc.bFeatureHindersClamping and not bDropWaste)
or ( dLengthLimitToDropWaste and Proc.b3Box:getDimX() > dLengthLimitToDropWaste)
or bKeepWasteAttached then
local BladeKeepWasteResult
local OptionalParameters = { dExtendAfterTail = dExtendAfterTail, dStripWidth = 5, bFinishWithMill = false}
local OptionalParameters = { bAllowPerpendicularStrip = Strategy.Parameters.bAllowPerpendicularStrip,
dStripWidth = Strategy.Parameters.dStripWidth,
dExtendAfterTail = dExtendAfterTail, bFinishWithMill = false}
AuxiliaryData.bIgnoreNotClampableLength = true
TwoFaces.Result, BladeKeepWasteResult = BladeKeepWaste.Make( NewProc, Part, OptionalParameters)
dTimeToMachine = BladeKeepWasteResult.dTimeToMachine
@@ -113,10 +116,10 @@ function STR0012.Make( bAddMachining, Proc, Part, CustomParameters)
else
local BladeToWasteResult
local OptionalParameters = { dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume,
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength,
bSaveAddedGeometries = bAddMachining,
dExtendAfterTail = dExtendAfterTail,
bReduceBladePath = Strategy.Parameters.bReduceBladePath
dMaxWasteLength = Strategy.Parameters.dMaxWasteLength,
bSaveAddedGeometries = bAddMachining,
dExtendAfterTail = dExtendAfterTail,
bReduceBladePath = Strategy.Parameters.bReduceBladePath
}
AuxiliaryData.bIgnoreNotClampableLength = false
TwoFaces.Result, BladeToWasteResult = BladeToWaste.Make( NewProc, Part, OptionalParameters)
+40 -26
View File
@@ -22,6 +22,31 @@ local function MakeChamfer()
-- TODO funzionalità da aggiungere
end
-------------------------------------------------------------------------------------------------------------
local function CalculateTailCut( Proc, Part)
-- si recuperano gli estremi del box del materiale di coda da rimuovere
local b3PartWithTail = BeamLib.GetPartBoxWithHeadTail( Part, 'Tail')
local ptStartRestLength = Point3d( Part.b3Part:getMin():getX() + 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
local ptEndRestLength = Point3d( b3PartWithTail:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
local OptionalParametersBladeToWaste = {}
OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength)
OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath
OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Tail'
OptionalParametersBladeToWaste.bCannotSplitRestLength = true
local Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
-- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti)
if ( not Machinings) or ( #Machinings == 0) then
OptionalParametersBladeToWaste.bReduceBladePath = true
Machinings = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
end
return Machinings
end
-------------------------------------------------------------------------------------------------------------
function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
local StrategyLib = {}
@@ -51,7 +76,7 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
Strategy.bSplit = not( Part.bIsLastPart) or Part.dRestLength >= BeamData.dMinRaw
-- se devo fare split perchè c'è un grezzo da scaricare o un altro pezzo
if Strategy.bSplit then
if Strategy.bSplit or not Proc.bIsOriginalTailcut then
OptionalParameters.dOffset = 0
OptionalParameters.bDisableDicing = true
Strategy.SplitStrategy, Strategy.Result = SPLITCUT.GetMachining( Proc, Part, OptionalParameters)
@@ -64,7 +89,7 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- se devo rimuovere tutto il restante
else
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then
if Strategy.Parameters.bExecutePreCut and not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then
if Part.dRestLength < 20 then
bExecutePrecutOnly = true
OptionalParameters.dOffset = 0
@@ -101,16 +126,22 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
local MachiningsToAdd = {}
-- se devo fare split perchè c'è un grezzo da scaricare o un altro pezzo
if Strategy.bSplit then
if Strategy.bSplit or not Proc.bIsOriginalTailcut then
if Strategy.SplitStrategy and #Strategy.SplitStrategy > 0 then
for i = 1, #Strategy.SplitStrategy do
local TempList = {}
TempList.Splitting = Strategy.SplitStrategy[i]
local sNoteFinalCut = 'Split;'
local sNoteOtherCuts = 'Presplit;'
if not Strategy.bSplit then
sNoteFinalCut = 'Cut;'
sNoteOtherCuts = 'Precut;'
end
if i == #Strategy.SplitStrategy then
TempList.Splitting.sUserNotes = 'Split;'
TempList.Splitting.sUserNotes = sNoteFinalCut
TempList.AuxiliaryData = { bIsSplitOrCut = true}
else
TempList.Splitting.sUserNotes = 'Presplit;'
TempList.Splitting.sUserNotes = sNoteOtherCuts
end
table.insert( MachiningsToAdd, TempList)
end
@@ -119,7 +150,7 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
-- se devo rimuovere tutto il restante
else
-- se abilitato, faccio tagli di PRECUT a zero (come SPLIT)
if Strategy.Parameters.bExecutePreCut then
if Strategy.Parameters.bExecutePreCut and not Part.GeneralParameters.GEN_bGetAlternativesNesting2D then
if Strategy.SplitStrategy and #Strategy.SplitStrategy > 0 then
for i = 1, #Strategy.SplitStrategy do
local TempList = {}
@@ -140,25 +171,8 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
if not bExecutePrecutOnly then
-- si recuperano gli estremi del box del materiale di coda da rimuovere
local b3PartWithTail = BeamLib.GetPartBoxWithHeadTail( Part, 'Tail')
local ptStartRestLength = Point3d( Part.b3Part:getMin():getX() + 1, Part.b3Part:getMax():getY(), Part.b3Part:getMax():getZ())
local ptEndRestLength = Point3d( b3PartWithTail:getMin():getX(), Part.b3Part:getMin():getY(), Part.b3Part:getMin():getZ())
Strategy.Machining = CalculateTailCut( Proc, Part)
local OptionalParametersBladeToWaste = {}
OptionalParametersBladeToWaste.b3BoxDicing = BBox3d( ptStartRestLength, ptEndRestLength)
OptionalParametersBladeToWaste.dMaxWasteVolume = Strategy.Parameters.dMaxWasteVolume
OptionalParametersBladeToWaste.dMaxWasteLength = Strategy.Parameters.dMaxWasteLength
OptionalParametersBladeToWaste.bReduceBladePath = Strategy.Parameters.bReduceBladePath
OptionalParametersBladeToWaste.sRestLengthSideForPreSimulation = 'Tail'
OptionalParametersBladeToWaste.bCannotSplitRestLength = true
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
-- se taglio non riuscito, si riprova con il riduci percorso forzato (collisione possibile in separazione pezzi alti)
if ( not Strategy.Machining) or ( #Strategy.Machining == 0) then
OptionalParametersBladeToWaste.bReduceBladePath = true
Strategy.Machining, _ = BladeToWaste.Make( Proc, Part, OptionalParametersBladeToWaste)
end
if Strategy.Machining and #Strategy.Machining > 0 then
for i = 1, #Strategy.Machining do
local TempList = {}
@@ -185,9 +199,9 @@ function TAILCUT.Make( bAddMachining, Proc, Part, CustomParameters)
end
return bAreAllMachiningsAdded, Strategy.Result
else
return nil, Strategy.Result
end
return nil, Strategy.Result
end
-------------------------------------------------------------------------------------------------------------
+49 -12
View File
@@ -11,7 +11,8 @@ require( 'EgtBase')
local FeatureLib = require( 'FeatureLib')
local FaceData = require( 'FaceData')
local MachiningLib = require( 'MachiningLib')
local BeamLib = require('BeamLib')
local BeamLib = require( 'BeamLib')
local BeamData = require( 'BeamDataNew')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
local FaceByMill = require( 'FACEBYMILL')
@@ -146,10 +147,12 @@ local function MakeBottomFace( Proc, Part, BottomFace, EdgeToMachine, Parameters
local dExtendAfterTail = Parameters.dExtendAfterTail
local nToolIndex = Parameters.nToolIndex
local dStripWidth = Parameters.dStripWidth
local bAllowPerpendicularStrip = Parameters.bAllowPerpendicularStrip
local OtherBottomFace = Parameters.OtherBottomFace
local dDepthToMachine = EdgeToMachine.dElevation / 2 - dStripWidth / 2
local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature, dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
local OptionalParametersFaceByBlade1 = { dDepthToMachine = dDepthToMachine, bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail, nToolIndex = nToolIndex}
local EdgeToMachineOpposite = BeamLib.FindEdgeBestOrientedAsDirection( BottomFace.Edges, -EdgeToMachine.vtN)
-- primo lato
@@ -175,7 +178,13 @@ local function MakeBottomFace( Proc, Part, BottomFace, EdgeToMachine, Parameters
if OtherBottomFace and ( EdgeToMachine.idAdjacentFace == OtherBottomFace.id) then
dStripWidth = TOOLS[Cutting2.nToolIndex].dThickness + 2 * dStripWidth
end
dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
-- se richiesto, si calcola il codolo verticale
if bAllowPerpendicularStrip and FeatureLib.IsMachiningLong( Cutting1.dEdgeLength, Part) then
dDepthToMachine = TOOLS[Cutting2.nToolIndex].dMaxMaterial - 10
else
dDepthToMachine = min( TOOLS[Cutting2.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
end
OptionalParametersFaceByBlade2.dDepthToMachine = dDepthToMachine
Cutting2 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade2)
@@ -189,7 +198,13 @@ local function MakeBottomFace( Proc, Part, BottomFace, EdgeToMachine, Parameters
if OtherBottomFace and ( EdgeToMachine.idAdjacentFace == OtherBottomFace.id) then
dStripWidth = TOOLS[Cutting1.nToolIndex].dThickness + 2 * dStripWidth
end
dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
-- se richiesto, si calcola il codolo verticale
if bAllowPerpendicularStrip and FeatureLib.IsMachiningLong( Cutting2.dEdgeLength, Part) then
dDepthToMachine = TOOLS[Cutting1.nToolIndex].dMaxMaterial - 10
else
dDepthToMachine = min( TOOLS[Cutting1.nToolIndex].dMaxMaterial, EdgeToMachine.dElevation - dStripWidth)
end
OptionalParametersFaceByBlade1.dDepthToMachine = dDepthToMachine
Cutting1 = FaceByBlade.Make( Proc, Part, BottomFace, EdgeToMachine, OptionalParametersFaceByBlade1)
@@ -219,12 +234,6 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
if Proc.nFct > 3 and Proc.Topology.sFamily ~= 'DoubleBevel' then
Result = FeatureLib.GetStrategyResultNotApplicable( 'BladeKeepWaste : max 3 faces supported')
return Machinings, Result
elseif Proc.nFct == 2 then
-- per angolo tra le facce >= 90deg (feature convessa) non applicabile
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
Result = FeatureLib.GetStrategyResultNotApplicable()
return Machinings, Result
end
elseif Proc.nFct == 3 then
-- caso speciale RidgeLap - per angolo tra le facce >= 90deg (feature convessa) non applicabile
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
@@ -250,6 +259,7 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
local bFinishWithMill = ( OptionalParameters.bFinishWithMill ~= false)
local dMillingOffsetFromSide = OptionalParameters.dMillingOffsetFromSide or 1
local dStripWidth = OptionalParameters.dStripWidth or 5
local bAllowPerpendicularStrip = ( OptionalParameters.bAllowPerpendicularStrip and ( Part.b3Raw:getMin():getZ() + BeamData.VICE_MINH > Proc.b3Box:getMin():getZ() - 10 * GEO.EPS_SMALL)) or false
local bForced = OptionalParameters.bForced or false
-- volume della feature
@@ -296,6 +306,7 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
dExtendAfterTail = dExtendAfterTail,
nToolIndex = nToolIndex,
dStripWidth = dStripWidth,
bAllowPerpendicularStrip = bAllowPerpendicularStrip,
OtherBottomFace = BottomFace2
}
local Cuttings1 = MakeBottomFace( Proc, Part, BottomFace1, BottomEdgeToMachine1, Parameters1)
@@ -366,7 +377,6 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
end
end
local OptionalParametersMilling = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
dRadialStepSpan = dToolMarkLength,
dDepthToMachine = dDepthToMachine
@@ -396,7 +406,6 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
end
end
local OptionalParametersMilling = {
bIsSplitFeature = bIsSplitFeature,
dExtendAfterTail = dExtendAfterTail,
dRadialStepSpan = dToolMarkLength,
dDepthToMachine = dDepthToMachine
@@ -427,6 +436,32 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
Machinings = MachiningLib.GetSplitMachinings( Machinings, FeatureSplittingPoints, Part)
end
-- se codoli perpendicolari, si accorciano LeadIn/LeadOut
if bAllowPerpendicularStrip then
for j = 1, #Machinings do
local Machining = Machinings[j]
if Machining.bIsMachiningSplitted then
local dOriginalStartAddLength = Machining.LeadIn.dStartAddLength
local dOriginalEndAddLength = Machining.LeadOut.dEndAddLength
local bStartsLeftSide = MachiningLib.StartsLeftSide( Machining)
Machining.LeadIn.dStartAddLength = dOriginalStartAddLength - Machining.dToolMarkLength - dStripWidth
Machining.LeadOut.dEndAddLength = dOriginalEndAddLength - Machining.dToolMarkLength - dStripWidth
if Machining.bIsStartClosed and
( ( Machining.bIsLastSegment and bStartsLeftSide) or
( Machining.bIsFirstSegment and not bStartsLeftSide)) then
Machining.LeadIn.dStartAddLength = dOriginalStartAddLength - dStripWidth
end
if Machining.bIsEndClosed and
( ( Machining.bIsFirstSegment and bStartsLeftSide) or
( Machining.bIsLastSegment and not bStartsLeftSide)) then
Machining.LeadOut.dEndAddLength = dOriginalEndAddLength - dStripWidth
end
end
end
end
-- ordinamento
table.sort( Machinings, SortMachiningsBySegment)
@@ -437,6 +472,8 @@ function BLADEKEEPWASTE.Make( Proc, Part, OptionalParameters)
Result.dQuality = FeatureLib.GetStrategyQuality( Machinings)
Result.dTimeToMachine = FeatureLib.GetStrategyTimeToMachine( Machinings)
Result.dMRR = ( dFeatureVolume / Result.dTimeToMachine) / pow( 10, 6)
-- il codolo non compromette mai il pinzaggio
Result.bIgnoreNotClampableLength = true
if Result.dCompletionPercentage > 100 - 10 * GEO.EPS_SMALL then
Result.sStatus = 'Completed'
if bForced then
+6 -2
View File
@@ -845,8 +845,12 @@ local function CalculateDiceMachinings( vCuts, Parameters)
local bReduceDiceDepth = Parameters.bReduceDiceDepth
-- trimesh con RestLength
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
local idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
local idCheckCollisionTm = EgtCopyGlob( Part.idBoxTm, Part.idTempGroup)
-- se testa o coda attaccate, si considerano nella superficie di collisione
if bCannotSplitRestLength then
local b3CheckCollision = BeamLib.GetPartBoxWithHeadTail( Part, sRestLengthSideForPreSimulation)
idCheckCollisionTm = EgtSurfTmBBox( Part.idTempGroup, b3CheckCollision, false, GDB_RT.GLOB)
end
-- eventuale inversione tagli ortogonali e aggiunta informazioni alla geometria
local bAreOrthogonalCutsInverted = false
+12 -3
View File
@@ -583,6 +583,8 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.dToolMarkLength = abs( Cutting.LeadIn.dStartAddLength)
elseif Cutting.bIsEndClosed then
Cutting.dToolMarkLength = abs( Cutting.LeadOut.dEndAddLength)
else
Cutting.dToolMarkLength = LeadInOutLib.GetToolAddLength( TOOLS[Cutting.nToolIndex].dDiameter, dDepthToMachine)
end
-- area lavorata
Cutting.dAreaToMachine = min( EdgeToMachine.dElevation, Cutting.dDepthToMachine) * ( min( Cutting.dEdgeLength, Cutting.dLengthToMachine + 2 * Cutting.dToolMarkLength))
@@ -594,12 +596,19 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
Cutting.sOperationName = 'Cut_' .. ( EgtGetName( Cutting.idProc) or tostring( Cutting.idProc)) .. '_' .. tostring( FaceToMachine.id + 1)
-- se lavorazione aperta sulla coda, eventuali aggiustamenti
-- TODO valutare se fare funzione a parte
-- TODO fare funzione a parte: bisogna guardare il lato (e forse la faccia) lavorato comprensivo di attacchi, non la Proc
-- TODO già guardare se il box della faccia è aperto sulla coda, invece di tutta la trimesh, escluderebbe tanti casi
Cutting.bMoveAfterSplit = Cutting.bMoveAfterSplit or Cutting.LeadIn.bMoveAfterSplit or Cutting.LeadOut.bMoveAfterSplit
local bIsTruncatingCutOnTail = Proc.Topology and ( Proc.Topology.sName == 'Cut-1-Through' or Proc.Topology.sName == 'TailCut') and Proc.AffectedFaces.bLeft
if Cutting.bMoveAfterSplit or bIsTruncatingCutOnTail then
Cutting.sStage = 'AfterTail'
elseif Proc.AffectedFaces.bLeft and ( EdgeToMachine.sType == 'Bottom' or ( Cutting.vtToolDirection:getX() < 0.707)) then
elseif Proc.AffectedFaces.bLeft and
( EdgeToMachine.sType == 'Bottom' or
( Cutting.vtToolDirection:getX() < 0.707 and
not ( Cutting.vtToolDirection:getX() > - 10 * GEO.EPS_SMALL and
( AreSameOrOppositeVectorApprox( EdgeToMachine.vtEdge, Z_AX()) or
AreSameOrOppositeVectorApprox( EdgeToMachine.vtEdge, Y_AX()))))) then
local dLengthOnX = Cutting.dLengthOnX
-- se feature splittata non si considera la lunghezza della feature per il check spostamento dopo separazione
if bIsSplitFeature then
@@ -633,7 +642,7 @@ function FACEBYBLADE.Make( Proc, Part, FaceToMachine, EdgeToMachine, OptionalPar
end
return Cutting
end
-------------------------------------------------------------------------------------------------------------
+5 -5
View File
@@ -1,6 +1,6 @@
-- Version.lua by EgalWare s.r.l. 2024/04/02
-- Gestione della versione di Beam
-- Version.lua by EgalWare s.r.l. 2026/07/16
-- Gestione della versione di BeamNT
NAME = 'Beam'
VERSION = '3.1e1'
MIN_EXE = '3.1e1'
NAME = 'BeamNT'
VERSION = '3.1g1'
MIN_EXE = '3.1g1'