-- 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