Files
databeamnew/StrategyLibs/BLADETOWASTE.lua
T

213 lines
7.5 KiB
Lua

-- BLADETOWASTE.lua by Egalware s.r.l. 2025/01/08
-- Libreria di supporto a strategie con funzioni comune a strategie diverse.
-- Tabella per definizione modulo
local BLADETOWASTE = {}
-- Include
require( 'EgtBase')
-- Carico i dati globali
local BeamData = require( 'BeamData')
local BeamLib = require( 'BeamLib')
local FaceData = require( 'FaceData')
local FeatureLib = require( 'FeatureLib')
local MachiningLib = require( 'MachiningLib')
local DiceCut = require( 'DiceCut')
-- strategie di base
local FaceByBlade = require('FACEBYBLADE')
EgtOutLog( ' BLADETOWASTE started', 1)
-------------------------------------------------------------------------------------------------------------
local function GetBestBladeForDicing( Proc, Part, Face, OptionalParameters)
local nChosenToolIndex
-- parametri opzionali
local dMinNzTopBladeIfEqual = OptionalParameters.dMinNzTopBlade or sin(-5)
local dMaxNyTopBlade = OptionalParameters.dMaxNyTopBlade or sin(1)
local dShortPartLength = OptionalParameters.dShortPartLength or BeamData.LEN_SHORT_PART
-- ricerca lama testa sopra
local ToolSearchParameters = {}
ToolSearchParameters.vtN = Face.vtN
ToolSearchParameters.bAllowTopHead = true
ToolSearchParameters.bAllowBottomHead = false
ToolSearchParameters.bForceLongcutBlade = false
ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
local nToolIndexTop = ToolInfo.nToolIndex
-- ricerca lama testa sotto
ToolSearchParameters = {}
ToolSearchParameters.vtN = Face.vtN
ToolSearchParameters.bAllowTopHead = false
ToolSearchParameters.bAllowBottomHead = true
ToolSearchParameters.bForceLongcutBlade = false
ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
local nToolIndexBottom = ToolInfo.nToolIndex
-- lama sopra e sotto
if nToolIndexTop and nToolIndexBottom then
-- angolo minimo che determina la preferenza tra lama sopra e sotto
local dMinNzTopBlade
-- entrambe le lame senza aggregato o entrambe con aggregato
if TOOLS[nToolIndexTop].SetupInfo.bIsCSymmetrical == TOOLS[nToolIndexBottom].SetupInfo.bIsCSymmetrical then
dMinNzTopBlade = dMinNzTopBladeIfEqual
-- lama sopra con aggregato - preferenza testa sopra
elseif not TOOLS[nToolIndexTop].SetupInfo.bIsCSymmetrical then
dMinNzTopBlade = OptionalParameters.dMinNzTopBlade or TOOLS[nToolIndexTop].SetupInfo.dMinNz / 2
-- lama sotto con aggregato - preferenza testa sotto
elseif not TOOLS[nToolIndexBottom].SetupInfo.bIsCSymmetrical then
dMinNzTopBlade = OptionalParameters.dMinNzTopBlade or TOOLS[nToolIndexBottom].SetupInfo.dMaxNz / 2
else
error( 'GetBestBladeForDicing : unknown blade type')
end
-- se la Z della faccia è sotto all'angolo minimo e inclinata in Y oppure il pezzo è corto, si preferisce la lama sotto
if Face.vtN:getZ() < dMinNzTopBlade - GEO.EPS_SMALL
and ( abs( Face.vtN:getY()) > dMaxNyTopBlade or Part.b3Raw:getDimX() < dShortPartLength - 10 * GEO.EPS_SMALL) then
nChosenToolIndex = nToolIndexBottom
else
nChosenToolIndex = nToolIndexTop
end
-- solo lama sopra
elseif nToolIndexTop then
nChosenToolIndex = nToolIndexTop
-- solo lama sotto
elseif nToolIndexBottom then
nChosenToolIndex = nToolIndexBottom
end
-- se non trovata alcuna lama ritorna nil
return nChosenToolIndex
end
function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters)
local Result = {}
local dCompletionPercentage = 0
-- disambiguazione feature vs id trimesh
local Proc
if type( ProcOrId) == "table" then
Proc = ProcOrId
elseif type( ProcOrId) == "number" then
Proc.id = ProcOrId
Proc.nFct = EgtSurfTmFacetCount( Proc.id) or 0
Proc.b3Box = EgtGetBBoxGlob( ProcOrId or GDB_ID.NULL, GDB_BB.STANDARD)
Proc.AffectedFaces = BeamLib.GetAffectedFaces( Proc, Part)
Proc.AdjacencyMatrix = FaceData.GetAdjacencyMatrix( Proc)
Proc.Faces = FaceData.GetFacesInfo( Proc, Part)
else
error( 'BLADETOWASTE : Only feature or trimesh supported')
end
-- controlli preventivi
if Proc.nFct > 2 then
error( 'BladeToWaste : max 2 faces supported')
elseif Proc.nFct == 2 then
if Proc.AdjacencyMatrix[1][2] > 10 * GEO.EPS_SMALL or Proc.AdjacencyMatrix[1][2] < -91 then
error( 'BladeToWaste : angle between faces must be concave and >= 90deg')
end
end
-- parametri opzionali e default
if not OptionalParameters then
OptionalParameters = {}
end
local nToolIndex = OptionalParameters.nToolIndex
local bDropWholeWaste = OptionalParameters.bDropWholeWaste or false
local dMaxWasteVolume = OptionalParameters.dMaxWasteVolume or 0
local dMaxWasteLength = OptionalParameters.dMaxWasteLength or 0
-- dimensioni feature
local dFeatureVolume = FeatureLib.GetFeatureVolume( Proc, Part)
local dFeatureMaxDimension = max( Proc.b3Box:getDimX(), Proc.b3Box:getDimY())
local bIsFeatureSmall = dFeatureVolume < dMaxWasteVolume + 10 * GEO.EPS_SMALL
and dFeatureMaxDimension < dMaxWasteLength + 10 * GEO.EPS_SMALL
-- si taglia tutto lo scarto in una sola lavorazione
if Proc.nFct == 1 and ( bIsFeatureSmall or bDropWholeWaste) then
local Cutting = {}
local EdgeToMachine = {}
local dDepthToMachine = 0
local ToolInfo = {}
-- ricerca utensile
if not nToolIndex then
local ToolSearchParameters = {}
for i = 1, #Proc.Faces[1].Edges do
if ( i == 1) or Proc.Faces[1].Edges[i].dElevation < EdgeToMachine.dElevation - 10 * GEO.EPS_SMALL then
EdgeToMachine = Proc.Faces[1].Edges[i]
end
end
dDepthToMachine = EdgeToMachine.dElevation + BeamData.CUT_EXTRA
ToolSearchParameters.dElevation = dDepthToMachine
ToolSearchParameters.vtN = Proc.Faces[1].vtN
ToolSearchParameters.bAllowTopHead = true
-- TODO bisognerà implementare anche la lama da sotto
ToolSearchParameters.bAllowBottomHead = false
ToolSearchParameters.bForceLongcutBlade = false
ToolInfo = MachiningLib.FindBlade( Proc, ToolSearchParameters)
nToolIndex = ToolInfo.nToolIndex
end
-- TODO qui gestire il caso in cui si può tagliare da due lati (inizialmente solo se vtN:Y è ~= 0?)
if ToolInfo.dResidualDepth < 10 * GEO.EPS_SMALL then
local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex}
Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade)
end
if Cutting.bIsApplicable or bDropWholeWaste then
table.insert( Result, Cutting)
dCompletionPercentage = Cutting.dCompletionPercentage or dCompletionPercentage
end
return Result, dCompletionPercentage
end
-- lavorazione con cubetti
-- se due facce, la faccia principale è la più grande
local Face1 = Proc.Faces[1]
local Face2 = {}
if Proc.nFct == 2 then
Face2 = Proc.Faces[2]
end
-- scelta lama da sopra o da sotto
if not nToolIndex then
nToolIndex = GetBestBladeForDicing( Proc, Part, Face1, OptionalParameters)
end
local OptionalParametersDiceCut = {}
local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut)
-- restituire tabella contenente lavorazioni, già con cloni se necessari
return Result, dCompletionPercentage
end
-------------------------------------------------------------------------------------------------------------
return BLADETOWASTE