328ef638e8
- corretto calcolo sezione dello strand quando altezza maggiore di larghezza.
289 lines
13 KiB
Lua
289 lines
13 KiB
Lua
-- RunMachParamFromSWCalc.lua by Egaltech s.r.l. 2024/01/30
|
|
-- Calcolo dei parametri di stampa
|
|
|
|
-- Tabella per definizione modulo
|
|
local RunMachParamFromSWCalc = {}
|
|
|
|
-- Intestazioni
|
|
require( 'EgtBase')
|
|
|
|
EgtOutLog( ' RunMachParamFromSWCalc started', 1)
|
|
|
|
-- Costanti generali
|
|
local AMD = require( 'AddManData')
|
|
|
|
--local MACHINING = {}
|
|
--MACHINING.K = 103
|
|
--local MATERIAL = {}
|
|
--MATERIAL.Name = 'AKROMID® B3 ICF 40'
|
|
--MATERIAL.K_EXTRUSION = 110
|
|
--MATERIAL.K_LAYERTIME = 105
|
|
--MATERIAL.C1 = 0.8742
|
|
--MATERIAL.C2 = 0.8964
|
|
--MATERIAL.Density = 1.31
|
|
--MATERIAL.AMax = 48.33
|
|
--MATERIAL.ATrg = 49.9
|
|
--MATERIAL.AMin = 116.4
|
|
--MATERIAL.BMax = 1.667
|
|
--MATERIAL.BTrg = 2.2
|
|
--MATERIAL.BMin = 7.273
|
|
--MATERIAL.KW = 0.4
|
|
--MATERIAL.KZ = 0.9
|
|
--MATERIAL.KN = 0.3
|
|
|
|
---------------------------------------------------------------------
|
|
function RunMachParamFromSWCalc.Exec()
|
|
|
|
-- valori default per nuovi parametri
|
|
MATERIAL.K_LAYERTIME = MATERIAL.K_LAYERTIME or 100
|
|
MATERIAL.K_EXTRUSION = MATERIAL.K_EXTRUSION or 100
|
|
if not MACHINING then
|
|
MACHINING = {}
|
|
MACHINING.K = 100
|
|
end
|
|
|
|
-- layer dei risultati
|
|
local nResultLayerId = EgtGetFirstNameInGroup( GDB_ID.ROOT, LAY_TFSCALC)
|
|
if not nResultLayerId then
|
|
nResultLayerId = EgtGroup( GDB_ID.ROOT)
|
|
EgtSetName( nResultLayerId, LAY_TFSCALC)
|
|
EgtSetLevel( nResultLayerId, GDB_LV.SYSTEM)
|
|
end
|
|
-- recupero Speed minima e massima dalla macchina
|
|
local sMachIni = EgtGetCurrMachineDir() .. '\\' .. EgtGetCurrMachineName() .. '.ini'
|
|
local dSMin = tonumber( EgtGetStringFromIni( SEC_3DPRINTING, KEY_SPEED_MIN, 0, sMachIni))
|
|
local dSMax = tonumber( EgtGetStringFromIni( SEC_3DPRINTING, KEY_SPEED_MAX, 50000, sMachIni))
|
|
-- recupero Feed massima dalla macchina
|
|
local dFLimit = tonumber( EgtGetStringFromIni( SEC_3DPRINTING, KEY_FEED_MAX, 10000, sMachIni))
|
|
-- massa materiale utilizzato
|
|
local dPrintMass = 0
|
|
-- massimo indice di layer calcolato
|
|
local nMaxIndex = 0
|
|
-- ciclo sui pezzi
|
|
local nPartId = EgtGetFirstPart()
|
|
while nPartId do
|
|
if not EgtGetInfo( nPartId, KEY_PART_ON_TABLE, 'b') then
|
|
nPartId = EgtGetNextPart( nPartId)
|
|
goto continue
|
|
end
|
|
-- recupero i parametri di lavorazione del pezzo
|
|
local dSliceStep = EgtGetInfo( nPartId, KEY_SLICE_STEP, 'd')
|
|
local dStrand = EgtGetInfo( nPartId, KEY_STRAND, 'd')
|
|
local dStrandCount = EgtGetInfo( nPartId, KEY_SHELLS_NBR, 'd')
|
|
-- recupero numero di strati per progress
|
|
local nLastLayerId = EgtGetLastNameInGroup( nPartId, SLICE_LAYER .. '*') or GDB_ID.NULL
|
|
local nLayerQty = EgtGetInfo( nLastLayerId, KEY_SLICE_NBR, 'i') or 0
|
|
-- ciclo sui layer
|
|
local nLayerIndex = 1
|
|
local nLayerId = EgtGetFirstNameInGroup( nPartId, SLICE_LAYER .. nLayerIndex) or EgtGetFirstNameInGroup( nPartId, "__" .. SLICE_LAYER .. nLayerIndex)
|
|
while nLayerId do
|
|
-- rimuovo eventuale info precedente del tempo di attesa
|
|
EgtRemoveInfo( nLayerId, KEY_WAITING_TIME)
|
|
-- divido curve in base alla larghezza strand
|
|
local LengthCrvList = {}
|
|
-- calcolo lunghezza totale del layer
|
|
local dTotLayerLength = 0
|
|
local dTotLayerLengthForMass = 0
|
|
local dTotLayerArea = 0
|
|
local nCrvId = EgtGetFirstNameInGroup( nLayerId, CONTOUR_GRP .. '*')
|
|
while nCrvId do
|
|
local nToolPathId = EgtGetFirstNameInGroup( nCrvId, TOOLPATH_GRP)
|
|
-- recupero lunghezze percorsi
|
|
local dTotCrvLength = 0
|
|
local dTotCrvLengthForMass = 0
|
|
local nShellId = EgtGetFirstInGroup( nToolPathId)
|
|
while nShellId do
|
|
local dShellWidth = EgtGetInfo( nShellId, KEY_CRV_STRAND, "d")
|
|
local dShellLength = EgtCurveLength( nShellId)
|
|
local bFound = false
|
|
for LengthIndex = 1, #LengthCrvList do
|
|
if LengthCrvList[LengthIndex].Width == dShellWidth then
|
|
table.insert( LengthCrvList[LengthIndex].IdList, nShellId)
|
|
LengthCrvList[LengthIndex].Length = LengthCrvList[LengthIndex].Length + dShellLength
|
|
bFound = true
|
|
break
|
|
end
|
|
end
|
|
if not bFound then
|
|
table.insert( LengthCrvList, { Width = dShellWidth, IdList = { nShellId}, Length = dShellLength})
|
|
end
|
|
-- sommo per lunghezza totale
|
|
dTotCrvLength = dTotCrvLength + dShellLength
|
|
if EgtGetName( nShellId) ~= WIPE_CRV then
|
|
dTotCrvLengthForMass = dTotCrvLengthForMass + dShellLength
|
|
end
|
|
nShellId = EgtGetNext( nShellId)
|
|
end
|
|
dTotLayerLength = dTotLayerLength + dTotCrvLength
|
|
dTotLayerLengthForMass = dTotLayerLengthForMass + dTotCrvLengthForMass
|
|
-- recupero area
|
|
local nOuterCrvId = EgtGetFirstNameInGroup( nCrvId, OUTER_CRV)
|
|
if nOuterCrvId and dStrandCount > 0.5 then
|
|
local _, _, dTotCrvArea = EgtCurveArea( nOuterCrvId)
|
|
local dOuterLength = EgtCurveLength( nOuterCrvId)
|
|
-- recupero offset del part per aggiungerlo all'area interna
|
|
local dOffset = EgtGetInfo( nPartId, KEY_OFFSET_SLICE, 'd')
|
|
dTotCrvArea = dTotCrvArea + ( dOffset * dOuterLength)
|
|
dTotLayerArea = dTotLayerArea + dTotCrvArea
|
|
end
|
|
nCrvId = EgtGetNextName( nCrvId, CONTOUR_GRP .. '*')
|
|
end
|
|
-- recupero feed del layer
|
|
local dLayerFeed = 0
|
|
local dLayerWait = 0
|
|
local nLayerResultId = EgtGetFirstNameInGroup( nResultLayerId, nLayerIndex)
|
|
if nLayerResultId then
|
|
dLayerFeed = EgtGetInfo( nLayerResultId, KEY_FCUR, 'd') or 0
|
|
dLayerWait = EgtGetInfo( nLayerResultId, KEY_WAITING_TIME, 'd') or 0
|
|
else
|
|
nLayerResultId = EgtGroup( nResultLayerId)
|
|
EgtSetName( nLayerResultId, nLayerIndex)
|
|
end
|
|
-- riporto riferimento a layer del solido in layer del calcolo
|
|
local nOrigLayers = EgtGetInfo( nLayerResultId, KEY_SLICEID, 'vi') or {}
|
|
local bFound = false
|
|
for nIndex = 1, #nOrigLayers do
|
|
if nOrigLayers[nIndex] == nLayerId then
|
|
bFound = true
|
|
end
|
|
end
|
|
if not bFound then
|
|
table.insert( nOrigLayers, nLayerId)
|
|
end
|
|
EgtSetInfo( nLayerResultId, KEY_SLICEID, nOrigLayers)
|
|
-- calcolo strand medio (media ponderata sulla lunghezza)
|
|
local dStrandMean = 0
|
|
for nMeanIndex = 1, #LengthCrvList do
|
|
dStrandMean = dStrandMean + LengthCrvList[nMeanIndex].Width * LengthCrvList[nMeanIndex].Length
|
|
end
|
|
dStrandMean = dStrandMean / EgtIf( dTotLayerLength > 0.1, dTotLayerLength, 1)
|
|
-- calcolo costante MF
|
|
local dMF = 1
|
|
local dSC = 1
|
|
if dTotLayerArea > 1 then
|
|
dMF = dTotLayerLength * dStrandMean / dTotLayerArea * 100
|
|
dSC = dStrandCount
|
|
else
|
|
dMF = 100
|
|
local nRibsLayId = EgtGetFirstNameInGroup( nLayerId, RIBS_GRP) or GDB_ID.NULL
|
|
local nCrvId = EgtGetFirstInGroup( nRibsLayId)
|
|
while nCrvId do
|
|
if EgtGetInfo( nCrvId, KEY_RIBS_TYPE, 'i') == RIB_TYPE.UNBOUNDED then
|
|
dSC = ( EgtGetInfo( nCrvId, KEY_RIBS_SHELLS_NBR, 'd') or dSC) / 2
|
|
break
|
|
end
|
|
nCrvId = EgtGetNext( nCrvId)
|
|
end
|
|
end
|
|
-- calcolo tempi stimati del layer
|
|
local dTMin = ( MATERIAL.K_LAYERTIME / 100.0) * ( dMF + MATERIAL.AMin) / MATERIAL.BMin * pow( 0.25 * dStrandMean, MATERIAL.KW) * pow( dSliceStep, MATERIAL.KZ) * pow( dSC, MATERIAL.KN)
|
|
local dTTrg = ( MATERIAL.K_LAYERTIME / 100.0) * ( dMF + MATERIAL.ATrg) / MATERIAL.BTrg * pow( 0.25 * dStrandMean, MATERIAL.KW) * pow( dSliceStep, MATERIAL.KZ) * pow( dSC, MATERIAL.KN)
|
|
local dTMax = ( MATERIAL.K_LAYERTIME / 100.0) * ( dMF + MATERIAL.AMax) / MATERIAL.BMax * pow( 0.25 * dStrandMean, MATERIAL.KW) * pow( dSliceStep, MATERIAL.KZ) * pow( dSC, MATERIAL.KN)
|
|
local dFMin = dTotLayerLength / EgtIf( dTMax > 0.1, dTMax, 1) * 60
|
|
local dFTrg = dTotLayerLength / EgtIf( dTTrg > 0.1, dTTrg, 1) * 60
|
|
local dFMax = dTotLayerLength / EgtIf( dTMin > 0.1, dTMin, 1) * 60
|
|
local dLayerTime = dTTrg
|
|
if dLayerFeed == 0 then
|
|
dLayerFeed = dFTrg
|
|
else
|
|
dLayerTime = dTotLayerLength / dLayerFeed * 60
|
|
end
|
|
dLayerWait = floor( dTMin + 0.5) - floor( dLayerTime + 0.5)
|
|
-- sezione dello strand
|
|
local dSect = max( ( dStrandMean - dSliceStep) * dSliceStep, 0) + pi * dSliceStep * dSliceStep / 4
|
|
-- calcolo la portata
|
|
local Vf = dLayerFeed * dSect / 1000
|
|
-- calcolo speed
|
|
local dSpeed = ( MATERIAL.K_EXTRUSION / 100.0) * ( MACHINING.K / 100.0) * pow( Vf / MATERIAL.C1, 1 / MATERIAL.C2)
|
|
-- verifico se speed esce da minimo e massimo della macchina
|
|
local bSpeedOk = true
|
|
if dSpeed < dSMin then
|
|
bSpeedOk = false
|
|
dSpeed = dSMin
|
|
end
|
|
if dSpeed > dSMax then
|
|
bSpeedOk = false
|
|
dSpeed = dSMax
|
|
end
|
|
if not bSpeedOk then
|
|
if dTotLayerLength > 0.1 then
|
|
dLayerFeed = ( MATERIAL.C1 * pow( ( dSpeed / (( MATERIAL.K_EXTRUSION / 100.0) * ( MACHINING.K / 100.0))), MATERIAL.C2)) * 1000 / dSect
|
|
dLayerTime = dTotLayerLength / dLayerFeed * 60
|
|
end
|
|
dLayerWait = floor( dTMin + 0.5) - floor( dLayerTime + 0.5)
|
|
end
|
|
-- calcolo massa dello strato
|
|
local dLayerMass = dTotLayerLengthForMass * dSliceStep * dStrandMean * MATERIAL.Density * 1e-6
|
|
if dLayerMass and dLayerMass > 0 then
|
|
dPrintMass = dPrintMass + dLayerMass
|
|
end
|
|
-- scrivo info feed su tutti i tratti
|
|
local dFeedMax = 0
|
|
for nWidthIndex = 1, #LengthCrvList do
|
|
local CurrWidth = LengthCrvList[nWidthIndex]
|
|
local CurrFeed = EgtIf( CurrWidth.Width > 0, dLayerFeed * dStrandMean / CurrWidth.Width, dLayerFeed)
|
|
for nCurveIdIndex = 1, #CurrWidth.IdList do
|
|
local dNewFeed = CurrFeed
|
|
-- verifico se coefficiente moltiplicativo per feed
|
|
local dCoeff = EgtGetInfo( CurrWidth.IdList[nCurveIdIndex], KEY_FEED_COEFF, 'd')
|
|
if dCoeff then
|
|
dNewFeed = dCoeff * CurrFeed
|
|
if dNewFeed > dFLimit then
|
|
local dNewSpeed = dSpeed * dFLimit / dNewFeed
|
|
dNewSpeed = EgtClamp( dNewSpeed, dSMin, dSMax)
|
|
dNewFeed = dFLimit
|
|
EgtSetInfo( CurrWidth.IdList[nCurveIdIndex], KEY_SPEED, dNewSpeed)
|
|
end
|
|
end
|
|
EgtSetInfo( CurrWidth.IdList[nCurveIdIndex], KEY_FEED, dNewFeed)
|
|
if dNewFeed > dFeedMax then
|
|
dFeedMax = dNewFeed
|
|
end
|
|
end
|
|
end
|
|
-- scrivo info speed in group toolpath
|
|
nCrvId = EgtGetFirstNameInGroup( nLayerId, CONTOUR_GRP .. '*')
|
|
while nCrvId do
|
|
local nToolPathId = EgtGetFirstNameInGroup( nCrvId, TOOLPATH_GRP) or GDB_ID.NULL
|
|
EgtSetInfo( nToolPathId, KEY_FEED, dLayerFeed)
|
|
EgtSetInfo( nToolPathId, KEY_SPEED, dSpeed)
|
|
nCrvId = EgtGetNextName( nCrvId, CONTOUR_GRP .. '*')
|
|
end
|
|
-- scrivo info attesa
|
|
if dLayerWait > 0 then
|
|
EgtSetInfo( nLayerId, KEY_WAITING_TIME, dLayerWait)
|
|
EgtSetInfo( nLayerResultId, KEY_WAITING_TIME, dLayerWait)
|
|
end
|
|
-- scrivo valori in struttura dati
|
|
EgtSetInfo( nLayerResultId, KEY_TMIN, dTMin)
|
|
EgtSetInfo( nLayerResultId, KEY_TTRG, dTTrg)
|
|
EgtSetInfo( nLayerResultId, KEY_TMAX, dTMax)
|
|
EgtSetInfo( nLayerResultId, KEY_FTRG, dFTrg)
|
|
EgtSetInfo( nLayerResultId, KEY_FMAX, dFeedMax)
|
|
EgtSetInfo( nLayerResultId, KEY_TCUR, dLayerTime)
|
|
EgtSetInfo( nLayerResultId, KEY_FCUR, dLayerFeed)
|
|
EgtSetInfo( nLayerResultId, KEY_LENGTH, dTotLayerLength)
|
|
EgtSetInfo( nLayerResultId, KEY_SPEED, dSpeed)
|
|
EgtSetInfo( nLayerResultId, KEY_MF, dMF)
|
|
EgtSetInfo( nLayerResultId, KEY_TOTAREA, dTotLayerArea)
|
|
-- aggiorno interfaccia
|
|
if EgtProcessEvents( 500 + ( nLayerIndex / nLayerQty * 100), 0) == 1 then
|
|
EgtEmptyGroup( nResultLayerId)
|
|
return
|
|
end
|
|
-- passo al layer successivo
|
|
nLayerIndex = nLayerIndex + 1
|
|
nLayerId = EgtGetFirstNameInGroup( nPartId, SLICE_LAYER .. nLayerIndex) or EgtGetFirstNameInGroup( nPartId, "__" .. SLICE_LAYER .. nLayerIndex)
|
|
end
|
|
if nMaxIndex < nLayerIndex then nMaxIndex = nLayerIndex end
|
|
-- passo al pezzo successivo
|
|
nPartId = EgtGetNextPart( nPartId)
|
|
::continue::
|
|
end
|
|
-- imposto massa totale
|
|
EgtSetInfo( nResultLayerId, KEY_MASS, dPrintMass)
|
|
end
|
|
|
|
---------------------------------------------------------------------
|
|
return RunMachParamFromSWCalc
|