From 0ccfb2bfe6d6e03e7e3cb98f61c185d6b6571e76 Mon Sep 17 00:00:00 2001 From: "luca.mazzoleni" Date: Fri, 7 Mar 2025 17:42:21 +0100 Subject: [PATCH] - in FaceData GetEdgesInfo accetta anche l'id della trimesh - in BLADETOWASTE varie modifiche per tagli a cubetti e tagli singoli --- LuaLibs/FaceData.lua | 15 +++- StrategyLibs/BLADETOWASTE.lua | 150 ++++++++++++++++++++++------------ 2 files changed, 109 insertions(+), 56 deletions(-) diff --git a/LuaLibs/FaceData.lua b/LuaLibs/FaceData.lua index f78957c..ed94690 100644 --- a/LuaLibs/FaceData.lua +++ b/LuaLibs/FaceData.lua @@ -98,8 +98,19 @@ function FaceData.GetFacesByAdjacencyNumber( Proc) end ------------------------------------------------------------------------------------------------------------- -local function GetEdgesInfo( Proc, idFace ) +function FaceData.GetEdgesInfo( ProcOrId, idFace ) local Edges = {} + + -- disambiguazione feature vs id trimesh + local Proc = {} + if type( ProcOrId) == "table" then + Proc = ProcOrId + elseif type( ProcOrId) == "number" then + Proc.id = ProcOrId + else + error( 'GetEdgesInfo : Only feature or trimesh supported') + end + local nFaceType, EdgesEgt = EgtSurfTmGetFacetOutlineInfo( Proc.id, idFace, GDB_ID.ROOT) for i = 1, #EdgesEgt do @@ -165,7 +176,7 @@ function FaceData.GetFacesInfo( Proc, Part) local _, dLongEdgeDimension, dShortEdgeDimension = EgtSurfTmFacetMinAreaRectangle( Proc.id, i - 1, GDB_ID.ROOT) Faces[i].dArea = dShortEdgeDimension * dLongEdgeDimension - local nFaceType, Edges = GetEdgesInfo( Proc, i - 1) + local nFaceType, Edges = FaceData.GetEdgesInfo( Proc, i - 1) Faces[i].bIsOkForMachining = nFaceType < 1 Faces[i].Edges = Edges diff --git a/StrategyLibs/BLADETOWASTE.lua b/StrategyLibs/BLADETOWASTE.lua index f0ddcb7..043d1f8 100644 --- a/StrategyLibs/BLADETOWASTE.lua +++ b/StrategyLibs/BLADETOWASTE.lua @@ -20,8 +20,59 @@ local FaceByBlade = require('FACEBYBLADE') EgtOutLog( ' BLADETOWASTE started', 1) ------------------------------------------------------------------------------------------------------------- +local function CompareEdgesTopHead( EdgeA, EdgeB) + -- prima i lati a minore elevazione (se entro 5 mm si considerano uguali) + if EdgeA.dElevation < EdgeB.dElevation - 5 then + return true + elseif EdgeA.dElevation > EdgeB.dElevation + 5 then + return false + -- se stessa elevazione si preferiscono i lati più in basso (testa sopra) + else + if EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then + return true + elseif EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then + return false + -- se stessa Z si preferiscono i lati verso il fronte della trave + else + if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then + return true + elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then + return false + else + return false + end + end + end +end -local function GetBestBladeForDicing( Proc, Part, Face, OptionalParameters) + +local function CompareEdgesBottomHead( EdgeA, EdgeB) + -- prima i lati a minore elevazione (se entro 5 mm si considerano uguali) + if EdgeA.dElevation < EdgeB.dElevation - 5 then + return true + elseif EdgeA.dElevation > EdgeB.dElevation + 5 then + return false + -- se stessa elevazione si preferiscono i lati più in alto (testa sotto) + else + if EdgeA.vtN:getZ() < EdgeB.vtN:getZ() - 10 * GEO.EPS_SMALL then + return true + elseif EdgeA.vtN:getZ() > EdgeB.vtN:getZ() + 10 * GEO.EPS_SMALL then + return false + -- se stessa Z si preferiscono i lati verso il fronte della trave + else + if EdgeA.vtN:getY() > EdgeB.vtN:getY() + 10 * GEO.EPS_SMALL then + return true + elseif EdgeA.vtN:getY() < EdgeB.vtN:getY() - 10 * GEO.EPS_SMALL then + return false + else + return false + end + end + end +end + + +local function GetBestBlade( Proc, Part, Face, OptionalParameters) local nChosenToolIndex -- parametri opzionali @@ -61,7 +112,7 @@ local function GetBestBladeForDicing( Proc, Part, Face, OptionalParameters) elseif not TOOLS[nToolIndexBottom].SetupInfo.bIsCSymmetrical then dMinNzTopBlade = OptionalParameters.dMinNzTopBlade or TOOLS[nToolIndexBottom].SetupInfo.dMaxNz / 2 else - error( 'GetBestBladeForDicing : unknown blade type') + error( 'GetBestBlade : 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 @@ -85,6 +136,24 @@ local function GetBestBladeForDicing( Proc, Part, Face, OptionalParameters) end +local function GetEdgeToMachine( Edges, nToolIndex) + local EdgeToMachine = {} + local EdgesSorted = {} + + for i = 1, #Edges do + table.insert( EdgesSorted, Edges[i]) + end + if TOOLS[nToolIndex].SetupInfo.HeadType.bBottom then + table.sort( EdgesSorted, CompareEdgesBottomHead) + else + table.sort( EdgesSorted, CompareEdgesTopHead) + end + EdgeToMachine = EdgesSorted[1] + + return EdgeToMachine +end + + local function SetDiceFaceInfo( Proc, idDiceFace, bSaveAddedGeometries) EgtSetName( idDiceFace, 'Face' .. tostring( Proc.idFeature) .. '_Dice') -- TODO la scrittura del TaskId probabilmente non serve (è fatta nell'AddOperations) @@ -144,32 +213,25 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) and dFeatureMaxDimension < dMaxWasteLength + 10 * GEO.EPS_SMALL -- si taglia tutto lo scarto in una sola lavorazione + -- TODO qui si deve entrare anche se lo spessore lama è maggiore dell'elevazione delle faccia 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 + -- scelta lama da sopra o da sotto + if not nToolIndex then + -- quetsa deve anche verificare il lato migliore per lama sopra sotto e usare la sua elevazione per la ricerca (opzionalmente) + nToolIndex = GetBestBlade( Proc, Part, Proc.Faces[1], OptionalParameters) 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 + -- scelta lato da lavorare + EdgeToMachine = GetEdgeToMachine( Proc.Faces[1].Edges, nToolIndex) + local dResidualDepth = EdgeToMachine.dElevation - TOOLS[nToolIndex].dMaxMaterial -- 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 + if dResidualDepth < 10 * GEO.EPS_SMALL then local OptionalParametersFaceByBlade = { dDepthToMachine = dDepthToMachine, nToolIndex = nToolIndex} Cutting = FaceByBlade.Make( Proc, Part, Proc.Faces[1], EdgeToMachine, OptionalParametersFaceByBlade) end @@ -195,10 +257,12 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) local dMRR = dFeatureVolume / ( EdgeToMachine.dLength / TOOLS[nToolIndex].Feeds.dFeed) Result.dMRR = dMRR / pow( 10, 6) + -- TODO bisogna ritornare solo se ha successo return Machinings, Result end -- lavorazione con cubetti + -- scelta faccia da lavorare -- se due facce, la faccia principale Face1 è la più grande local Face1 = Proc.Faces[1] local Face2 = {} @@ -211,31 +275,32 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) -- scelta lama da sopra o da sotto if not nToolIndex then - nToolIndex = GetBestBladeForDicing( Proc, Part, Face1, OptionalParameters) + nToolIndex = GetBestBlade( Proc, Part, Face1, OptionalParameters) end - -- limite per taglio downUp - -- TODO tutte le macchine devono avere la funzione!! oppure mettere un default in BeamExec quando si lancia la GetSetupInfo?? - local dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, Face1.vtN) - -- se non trovata lama la lavorazione non è fattibile if not nToolIndex then return Machinings, Result end + -- limite per taglio downUp + local dMinNzDownUp = TOOLS[nToolIndex].SetupInfo.GetMinNzDownUp( Part.b3Raw, Face1.vtN) + -- calcolo dimensione cubetto e eventuale cubetto ridotto (tagli orizzontali con affondamento verticale) local dDiceDimension = min( TOOLS[nToolIndex].dMaxMaterial, BeamData.MAX_DIM_DICE) local dDiceDimensionReduced = dDiceDimension if TOOLS[nToolIndex].SetupInfo.dMaxMatDecrease then dDiceDimensionReduced = min( dDiceDimension, dDiceDimension - TOOLS[nToolIndex].SetupInfo.dMaxMatDecrease) end + dDiceDimension = dDiceDimension - BeamData.CUT_EXTRA + dDiceDimensionReduced = dDiceDimensionReduced - BeamData.CUT_EXTRA -- calcolo cubetti local OptionalParametersDiceCut = {} OptionalParametersDiceCut.dOffsetParallel = dDiceDimension OptionalParametersDiceCut.dOffsetOrthogonal = dDiceDimension - OptionalParameters.dOffsetOrthogonalReduced = dDiceDimensionReduced - OptionalParameters.dMinNzDownUp = dMinNzDownUp + OptionalParametersDiceCut.dOffsetOrthogonalReduced = dDiceDimensionReduced + OptionalParametersDiceCut.dMinNzDownUp = dMinNzDownUp local vCuts = DiceCut.GetDice( Part, Face1, Face2, OptionalParametersDiceCut) -- lavorazione cubetti @@ -288,18 +353,14 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) if vtO then vtToolDirection = Vector3d( vtO) * EgtIf( bAreOrthogonalCutsInverted, -1, 1) else - -- ricalcolo tipo taglio perché "bHorizCut" è calcolato sulla feature, mentre il cubetto potrebbe essere lavorato in un altro modo - local _, dFaceLength = BeamLib.GetFaceHvRefDim( vCuts[i][1], 0, Part.b3Raw) - local bCutDirection = bHorizCut - -- se bisogna tagliare di fianco ma la lunghezza faccia è più del massimo materiale, forzo lavorazione da sopra - if not bHorizCut and dFaceLength > TOOLS[nToolIndex].dMaxDepth then - bCutDirection = true - end + -- scelta lato da lavorare per stabilire la vtToolDirection + local EdgeToMachine = {} + EdgeToMachine = GetEdgeToMachine( vCuts[i][1], nToolIndex) if bCutDirection then vtToolDirection = Z_AX() else - if Face1.vtN:getZ() < dNzLimDwnUp then + if Face1.vtN:getZ() < dMinNzDownUp then vtToolDirection = EgtIf( Face1.vtN:getY() > -0.02, -Y_AX(), Y_AX()) else vtToolDirection = EgtIf( Face1.vtN:getY() > 0.02, Y_AX(), -Y_AX()) @@ -307,25 +368,6 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) end end end - local dDiceFaceMaxH = 0 - local dDiceFaceMinH = GEO.INFINITO - local bDoubleCut = false - local dCutExtra = BeamData.CUT_EXTRA - if TOOLS[nToolIndex].dMaxDepth < dDiceFaceMaxH + BeamData.CUT_EXTRA then - bDoubleCut = true - dCutExtra = - 0.5 * dDiceFaceMinH + BeamData.CUT_EXTRA_MIN - end - local nSurfToCut = EgtSurfTmBySewing( nAddGrpId, vCuts[i], false) - local nFaceUseCut1, nFaceUseCut2 = MCH_MILL_FU.ORTHO_BACK, MCH_MILL_FU.ORTHO_FRONT - if Proc.Tail then - nFaceUseCut1, nFaceUseCut2 = nFaceUseCut2, nFaceUseCut1 - end - if bDoubleCut then - local bOk, sErr = Fbs.MakeOne( nSurfToCut, 0, sCutting, dSawDiam, nFaceUseCut1, nil, dCutExtra, BeamData.CUT_SIC, 0, 0, 0, '', b3Raw, true) - if not bOk then return false, sErr end - end - local bOk2, sErr2 = Fbs.MakeOne( nSurfToCut, 0, sCutting, dSawDiam, nFaceUseCut2, nil, dCutExtra, BeamData.CUT_SIC, 0, 0, 0, '', b3Raw) - if not bOk2 then return false, sErr2 end -- caso standard -- lavoro la faccia for j = 1, #vCuts[i] do @@ -335,7 +377,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) if ( i % 2) == 0 and #vCuts[i] <= 2 then -- il primo elemento prende la direzione prevista, il secondo quella opposta local vtToolDirectionNew = Vector3d( vtToolDirection) - local dVzLimDwnUp = dNzLimDwnUp + local dVzLimDwnUp = dMinNzDownUp if j ~= 1 then vtToolDirectionNew = -vtToolDirection if BeamData.GetNzLimDownUp then @@ -366,7 +408,7 @@ function BLADETOWASTE.Make( ProcOrId, Part, OptionalParameters) dExtraCut = BD.CUT_EXTRA end end - local dVzLimDwnUp = dNzLimDwnUp + local dVzLimDwnUp = dMinNzDownUp if BeamData.GetNzLimDownUp then dVzLimDwnUp = BeamData.GetNzLimDownUp( b3Raw, Face1.vtN, V_NULL(), true) elseif not BeamData.C_SIMM and not BeamData.TURN and Face1.vtN:getZ() > 0.707 then