-- 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 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( Proc, Part, OptionalParameters) local Result = {} local dCompletionPercentage = 0 -- 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